diff options
author | daniel0916 <theschokolps@gmail.com> | 2014-04-07 20:12:17 +0200 |
---|---|---|
committer | daniel0916 <theschokolps@gmail.com> | 2014-04-07 20:12:17 +0200 |
commit | 2e9754ac1cf0537c12ab7974cf55c451c0724540 (patch) | |
tree | 713c5b8c8f22f77893b30b9c8cefca4a7c491483 /lib | |
parent | Fixed merge conflict (diff) | |
parent | Fixed some more minor issues with the redstone simulator. (diff) | |
download | cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar.gz cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar.bz2 cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar.lz cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar.xz cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.tar.zst cuberite-2e9754ac1cf0537c12ab7974cf55c451c0724540.zip |
Diffstat (limited to 'lib')
213 files changed, 5206 insertions, 52104 deletions
diff --git a/lib/cryptopp/CMakeLists.txt b/lib/cryptopp/CMakeLists.txt deleted file mode 100644 index 3497b3346..000000000 --- a/lib/cryptopp/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ - -cmake_minimum_required (VERSION 2.6) -project (cryptopp) - -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCRYPTOPP_DISABLE_ASM") -endif() -include_directories ("${PROJECT_SOURCE_DIR}/../../src/") - -file(GLOB cryptopp_SRC - "*.cpp" -) - -add_library(cryptopp ${cryptopp_SRC}) diff --git a/lib/cryptopp/Doxyfile b/lib/cryptopp/Doxyfile deleted file mode 100644 index c221fdf56..000000000 --- a/lib/cryptopp/Doxyfile +++ /dev/null @@ -1,1634 +0,0 @@ -# Doxyfile 1.7.1 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = Crypto++ - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = doc - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = YES - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = NO - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = YES - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this -# tag. The format is ext=language, where ext is a file extension, and language -# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, -# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions -# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen to replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penality. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will rougly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespace are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = NO - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command <command> <input-file>, where <command> is the value of -# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. The create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. - -LAYOUT_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = NO - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = NO - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = . - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 - -FILE_PATTERNS = *.h \ - *.cpp - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = adhoc.cpp - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = . - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command <filter> <input-file>, where <filter> -# is the value of the INPUT_FILTER tag, and <input-file> is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = NO - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 3 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the stylesheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = YES - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = YES - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> -# Qt Help Project / Custom Filters</a>. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> -# Qt Help Project / Filter Attributes</a>. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - -FORMULA_TRANSPARENT = YES - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = NO - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a PHP enabled web server instead of at the web client -# using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server -# based approach is that it scales better to large projects and allows -# full text search. The disadvances is that it is more difficult to setup -# and does not have live searching capabilities. - -SERVER_BASED_SEARCH = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4 - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = YES - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = . - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = _WIN32 \ - _WINDOWS \ - __FreeBSD__ \ - CRYPTOPP_DOXYGEN_PROCESSING - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance -# between CPU load and processing speed. - -DOT_NUM_THREADS = 0 - -# By default doxygen will write a font called FreeSans.ttf to the output -# directory and reference it in all dot files that doxygen generates. This -# font does not include all possible unicode characters however, so when you need -# these (or just want a differently looking font) you can specify the font name -# using DOT_FONTNAME. You need need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. - -DOT_FONTNAME = FreeSans.ttf - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/lib/cryptopp/License.txt b/lib/cryptopp/License.txt deleted file mode 100644 index c5d3f34b1..000000000 --- a/lib/cryptopp/License.txt +++ /dev/null @@ -1,51 +0,0 @@ -Compilation Copyright (c) 1995-2013 by Wei Dai. All rights reserved. -This copyright applies only to this software distribution package -as a compilation, and does not imply a copyright on any particular -file in the package. - -All individual files in this compilation are placed in the public domain by -Wei Dai and other contributors. - -I would like to thank the following authors for placing their works into -the public domain: - -Joan Daemen - 3way.cpp -Leonard Janke - cast.cpp, seal.cpp -Steve Reid - cast.cpp -Phil Karn - des.cpp -Andrew M. Kuchling - md2.cpp, md4.cpp -Colin Plumb - md5.cpp -Seal Woods - rc6.cpp -Chris Morgan - rijndael.cpp -Paulo Baretto - rijndael.cpp, skipjack.cpp, square.cpp -Richard De Moliner - safer.cpp -Matthew Skala - twofish.cpp -Kevin Springle - camellia.cpp, shacal2.cpp, ttmac.cpp, whrlpool.cpp, ripemd.cpp -Ronny Van Keer - sha3.cpp - -The Crypto++ Library (as a compilation) is currently licensed under the Boost -Software License 1.0 (http://www.boost.org/users/license.html). - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE.
\ No newline at end of file diff --git a/lib/cryptopp/Readme.txt b/lib/cryptopp/Readme.txt deleted file mode 100644 index 5f3b4525d..000000000 --- a/lib/cryptopp/Readme.txt +++ /dev/null @@ -1,452 +0,0 @@ -Crypto++: a C++ Class Library of Cryptographic Schemes -Version 5.6.2 - 2/20/2013 - -Crypto++ Library is a free C++ class library of cryptographic schemes. -Currently the library contains the following algorithms: - - algorithm type name - - authenticated encryption schemes GCM, CCM, EAX - - high speed stream ciphers Panama, Sosemanuk, Salsa20, XSalsa20 - - AES and AES candidates AES (Rijndael), RC6, MARS, Twofish, Serpent, - CAST-256 - - IDEA, Triple-DES (DES-EDE2 and DES-EDE3), - other block ciphers Camellia, SEED, RC5, Blowfish, TEA, XTEA, - Skipjack, SHACAL-2 - - block cipher modes of operation ECB, CBC, CBC ciphertext stealing (CTS), - CFB, OFB, counter mode (CTR) - - message authentication codes VMAC, HMAC, GMAC, CMAC, CBC-MAC, DMAC, - Two-Track-MAC - - SHA-1, SHA-2 (SHA-224, SHA-256, SHA-384, and - hash functions SHA-512), SHA-3, Tiger, WHIRLPOOL, RIPEMD-128, - RIPEMD-256, RIPEMD-160, RIPEMD-320 - - RSA, DSA, ElGamal, Nyberg-Rueppel (NR), - public-key cryptography Rabin-Williams (RW), LUC, LUCELG, - DLIES (variants of DHAES), ESIGN - - padding schemes for public-key PKCS#1 v2.0, OAEP, PSS, PSSR, IEEE P1363 - systems EMSA2 and EMSA5 - - Diffie-Hellman (DH), Unified Diffie-Hellman - key agreement schemes (DH2), Menezes-Qu-Vanstone (MQV), LUCDIF, - XTR-DH - - elliptic curve cryptography ECDSA, ECNR, ECIES, ECDH, ECMQV - - insecure or obsolescent MD2, MD4, MD5, Panama Hash, DES, ARC4, SEAL -algorithms retained for backwards 3.0, WAKE-OFB, DESX (DES-XEX3), RC2, - compatibility and historical SAFER, 3-WAY, GOST, SHARK, CAST-128, Square - value - -Other features include: - - * pseudo random number generators (PRNG): ANSI X9.17 appendix C, RandomPool - * password based key derivation functions: PBKDF1 and PBKDF2 from PKCS #5, - PBKDF from PKCS #12 appendix B - * Shamir's secret sharing scheme and Rabin's information dispersal algorithm - (IDA) - * fast multi-precision integer (bignum) and polynomial operations - * finite field arithmetics, including GF(p) and GF(2^n) - * prime number generation and verification - * useful non-cryptographic algorithms - + DEFLATE (RFC 1951) compression/decompression with gzip (RFC 1952) and - zlib (RFC 1950) format support - + hex, base-32, and base-64 coding/decoding - + 32-bit CRC and Adler32 checksum - * class wrappers for these operating system features (optional): - + high resolution timers on Windows, Unix, and Mac OS - + Berkeley and Windows style sockets - + Windows named pipes - + /dev/random, /dev/urandom, /dev/srandom - + Microsoft's CryptGenRandom on Windows - * A high level interface for most of the above, using a filter/pipeline - metaphor - * benchmarks and validation testing - * x86, x86-64 (x64), MMX, and SSE2 assembly code for the most commonly used - algorithms, with run-time CPU feature detection and code selection - * some versions are available in FIPS 140-2 validated form - -You are welcome to use it for any purpose without paying me, but see -License.txt for the fine print. - -The following compilers are supported for this release. Please visit -http://www.cryptopp.com the most up to date build instructions and porting notes. - - * MSVC 6.0 - 2010 - * GCC 3.3 - 4.5 - * C++Builder 2010 - * Intel C++ Compiler 9 - 11.1 - * Sun Studio 12u1, Express 11/08, Express 06/10 - -*** Important Usage Notes *** - -1. If a constructor for A takes a pointer to an object B (except primitive -types such as int and char), then A owns B and will delete B at A's -destruction. If a constructor for A takes a reference to an object B, -then the caller retains ownership of B and should not destroy it until -A no longer needs it. - -2. Crypto++ is thread safe at the class level. This means you can use -Crypto++ safely in a multithreaded application, but you must provide -synchronization when multiple threads access a common Crypto++ object. - -*** MSVC-Specific Information *** - -On Windows, Crypto++ can be compiled into 3 forms: a static library -including all algorithms, a DLL with only FIPS Approved algorithms, and -a static library with only algorithms not in the DLL. -(FIPS Approved means Approved according to the FIPS 140-2 standard.) -The DLL may be used by itself, or it may be used together with the second -form of the static library. MSVC project files are included to build -all three forms, and sample applications using each of the three forms -are also included. - -To compile Crypto++ with MSVC, open the "cryptest.dsw" (for MSVC 6 and MSVC .NET -2003) or "cryptest.sln" (for MSVC 2005 - 2010) workspace file and build one or -more of the following projects: - -cryptopp - This builds the DLL. Please note that if you wish to use Crypto++ - as a FIPS validated module, you must use a pre-built DLL that has undergone - the FIPS validation process instead of building your own. -dlltest - This builds a sample application that only uses the DLL. -cryptest Non-DLL-Import Configuration - This builds the full static library - along with a full test driver. -cryptest DLL-Import Configuration - This builds a static library containing - only algorithms not in the DLL, along with a full test driver that uses - both the DLL and the static library. - -To use the Crypto++ DLL in your application, #include "dll.h" before including -any other Crypto++ header files, and place the DLL in the same directory as -your .exe file. dll.h includes the line #pragma comment(lib, "cryptopp") -so you don't have to explicitly list the import library in your project -settings. To use a static library form of Crypto++, make the "cryptlib" -project a dependency of your application project, or specify it as -an additional library to link with in your project settings. -In either case you should check the compiler options to -make sure that the library and your application are using the same C++ -run-time libraries and calling conventions. - -*** DLL Memory Management *** - -Because it's possible for the Crypto++ DLL to delete objects allocated -by the calling application, they must use the same C++ memory heap. Three -methods are provided to achieve this. -1. The calling application can tell Crypto++ what heap to use. This method - is required when the calling application uses a non-standard heap. -2. Crypto++ can tell the calling application what heap to use. This method - is required when the calling application uses a statically linked C++ Run - Time Library. (Method 1 does not work in this case because the Crypto++ DLL - is initialized before the calling application's heap is initialized.) -3. Crypto++ can automatically use the heap provided by the calling application's - dynamically linked C++ Run Time Library. The calling application must - make sure that the dynamically linked C++ Run Time Library is initialized - before Crypto++ is loaded. (At this time it is not clear if it is possible - to control the order in which DLLs are initialized on Windows 9x machines, - so it might be best to avoid using this method.) - -When Crypto++ attaches to a new process, it searches all modules loaded -into the process space for exported functions "GetNewAndDeleteForCryptoPP" -and "SetNewAndDeleteFromCryptoPP". If one of these functions is found, -Crypto++ uses methods 1 or 2, respectively, by calling the function. -Otherwise, method 3 is used. - -*** GCC-Specific Information *** - -A makefile is included for you to compile Crypto++ with GCC. Make sure -you are using GNU Make and GNU ld. The make process will produce two files, -libcryptopp.a and cryptest.exe. Run "cryptest.exe v" for the validation -suite. - -*** Documentation and Support *** - -Crypto++ is documented through inline comments in header files, which are -processed through Doxygen to produce an HTML reference manual. You can find -a link to the manual from http://www.cryptopp.com. Also at that site is -the Crypto++ FAQ, which you should browse through before attempting to -use this library, because it will likely answer many of questions that -may come up. - -If you run into any problems, please try the Crypto++ mailing list. -The subscription information and the list archive are available on -http://www.cryptopp.com. You can also email me directly by visiting -http://www.weidai.com, but you will probably get a faster response through -the mailing list. - -*** History *** - -1.0 - First public release. Withdrawn at the request of RSA DSI. - - included Blowfish, BBS, DES, DH, Diamond, DSA, ElGamal, IDEA, - MD5, RC4, RC5, RSA, SHA, WAKE, secret sharing, DEFLATE compression - - had a serious bug in the RSA key generation code. - -1.1 - Removed RSA, RC4, RC5 - - Disabled calls to RSAREF's non-public functions - - Minor bugs fixed - -2.0 - a completely new, faster multiprecision integer class - - added MD5-MAC, HAVAL, 3-WAY, TEA, SAFER, LUC, Rabin, BlumGoldwasser, - elliptic curve algorithms - - added the Lucas strong probable primality test - - ElGamal encryption and signature schemes modified to avoid weaknesses - - Diamond changed to Diamond2 because of key schedule weakness - - fixed bug in WAKE key setup - - SHS class renamed to SHA - - lots of miscellaneous optimizations - -2.1 - added Tiger, HMAC, GOST, RIPE-MD160, LUCELG, LUCDIF, XOR-MAC, - OAEP, PSSR, SHARK - - added precomputation to DH, ElGamal, DSA, and elliptic curve algorithms - - added back RC5 and a new RSA - - optimizations in elliptic curves over GF(p) - - changed Rabin to use OAEP and PSSR - - changed many classes to allow copy constructors to work correctly - - improved exception generation and handling - -2.2 - added SEAL, CAST-128, Square - - fixed bug in HAVAL (padding problem) - - fixed bug in triple-DES (decryption order was reversed) - - fixed bug in RC5 (couldn't handle key length not a multiple of 4) - - changed HMAC to conform to RFC-2104 (which is not compatible - with the original HMAC) - - changed secret sharing and information dispersal to use GF(2^32) - instead of GF(65521) - - removed zero knowledge prover/verifier for graph isomorphism - - removed several utility classes in favor of the C++ standard library - -2.3 - ported to EGCS - - fixed incomplete workaround of min/max conflict in MSVC - -3.0 - placed all names into the "CryptoPP" namespace - - added MD2, RC2, RC6, MARS, RW, DH2, MQV, ECDHC, CBC-CTS - - added abstract base classes PK_SimpleKeyAgreementDomain and - PK_AuthenticatedKeyAgreementDomain - - changed DH and LUCDIF to implement the PK_SimpleKeyAgreementDomain - interface and to perform domain parameter and key validation - - changed interfaces of PK_Signer and PK_Verifier to sign and verify - messages instead of message digests - - changed OAEP to conform to PKCS#1 v2.0 - - changed benchmark code to produce HTML tables as output - - changed PSSR to track IEEE P1363a - - renamed ElGamalSignature to NR and changed it to track IEEE P1363 - - renamed ECKEP to ECMQVC and changed it to track IEEE P1363 - - renamed several other classes for clarity - - removed support for calling RSAREF - - removed option to compile old SHA (SHA-0) - - removed option not to throw exceptions - -3.1 - added ARC4, Rijndael, Twofish, Serpent, CBC-MAC, DMAC - - added interface for querying supported key lengths of symmetric ciphers - and MACs - - added sample code for RSA signature and verification - - changed CBC-CTS to be compatible with RFC 2040 - - updated SEAL to version 3.0 of the cipher specification - - optimized multiprecision squaring and elliptic curves over GF(p) - - fixed bug in MARS key setup - - fixed bug with attaching objects to Deflator - -3.2 - added DES-XEX3, ECDSA, DefaultEncryptorWithMAC - - renamed DES-EDE to DES-EDE2 and TripleDES to DES-EDE3 - - optimized ARC4 - - generalized DSA to allow keys longer than 1024 bits - - fixed bugs in GF2N and ModularArithmetic that can cause calculation errors - - fixed crashing bug in Inflator when given invalid inputs - - fixed endian bug in Serpent - - fixed padding bug in Tiger - -4.0 - added Skipjack, CAST-256, Panama, SHA-2 (SHA-256, SHA-384, and SHA-512), - and XTR-DH - - added a faster variant of Rabin's Information Dispersal Algorithm (IDA) - - added class wrappers for these operating system features: - - high resolution timers on Windows, Unix, and MacOS - - Berkeley and Windows style sockets - - Windows named pipes - - /dev/random and /dev/urandom on Linux and FreeBSD - - Microsoft's CryptGenRandom on Windows - - added support for SEC 1 elliptic curve key format and compressed points - - added support for X.509 public key format (subjectPublicKeyInfo) for - RSA, DSA, and elliptic curve schemes - - added support for DER and OpenPGP signature format for DSA - - added support for ZLIB compressed data format (RFC 1950) - - changed elliptic curve encryption to use ECIES (as defined in SEC 1) - - changed MARS key schedule to reflect the latest specification - - changed BufferedTransformation interface to support multiple channels - and messages - - changed CAST and SHA-1 implementations to use public domain source code - - fixed bug in StringSource - - optmized multi-precision integer code for better performance - -4.1 - added more support for the recommended elliptic curve parameters in SEC 2 - - added Panama MAC, MARC4 - - added IV stealing feature to CTS mode - - added support for PKCS #8 private key format for RSA, DSA, and elliptic - curve schemes - - changed Deflate, MD5, Rijndael, and Twofish to use public domain code - - fixed a bug with flushing compressed streams - - fixed a bug with decompressing stored blocks - - fixed a bug with EC point decompression using non-trinomial basis - - fixed a bug in NetworkSource::GeneralPump() - - fixed a performance issue with EC over GF(p) decryption - - fixed syntax to allow GCC to compile without -fpermissive - - relaxed some restrictions in the license - -4.2 - added support for longer HMAC keys - - added MD4 (which is not secure so use for compatibility purposes only) - - added compatibility fixes/workarounds for STLport 4.5, GCC 3.0.2, - and MSVC 7.0 - - changed MD2 to use public domain code - - fixed a bug with decompressing multiple messages with the same object - - fixed a bug in CBC-MAC with MACing multiple messages with the same object - - fixed a bug in RC5 and RC6 with zero-length keys - - fixed a bug in Adler32 where incorrect checksum may be generated - -5.0 - added ESIGN, DLIES, WAKE-OFB, PBKDF1 and PBKDF2 from PKCS #5 - - added key validation for encryption and signature public/private keys - - renamed StreamCipher interface to SymmetricCipher, which is now implemented - by both stream ciphers and block cipher modes including ECB and CBC - - added keying interfaces to support resetting of keys and IVs without - having to destroy and recreate objects - - changed filter interface to support non-blocking input/output - - changed SocketSource and SocketSink to use overlapped I/O on Microsoft Windows - - grouped related classes inside structs to help templates, for example - AESEncryption and AESDecryption are now AES::Encryption and AES::Decryption - - where possible, typedefs have been added to improve backwards - compatibility when the CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY macro is defined - - changed Serpent, HAVAL and IDEA to use public domain code - - implemented SSE2 optimizations for Integer operations - - fixed a bug in HMAC::TruncatedFinal() - - fixed SKIPJACK byte ordering following NIST clarification dated 5/9/02 - -5.01 - added known answer test for X9.17 RNG in FIPS 140 power-up self test - - submitted to NIST/CSE, but not publicly released - -5.02 - changed EDC test to MAC integrity check using HMAC/SHA1 - - improved performance of integrity check - - added blinding to defend against RSA timing attack - -5.03 - created DLL version of Crypto++ for FIPS 140-2 validation - - fixed vulnerabilities in GetNextIV for CTR and OFB modes - -5.0.4 - Removed DES, SHA-256, SHA-384, SHA-512 from DLL - -5.1 - added PSS padding and changed PSSR to track IEEE P1363a draft standard - - added blinding for RSA and Rabin to defend against timing attacks - on decryption operations - - changed signing and decryption APIs to support the above - - changed WaitObjectContainer to allow waiting for more than 64 - objects at a time on Win32 platforms - - fixed a bug in CBC and ECB modes with processing non-aligned data - - fixed standard conformance bugs in DLIES (DHAES mode) and RW/EMSA2 - signature scheme (these fixes are not backwards compatible) - - fixed a number of compiler warnings, minor bugs, and portability problems - - removed Sapphire - -5.2 - merged in changes for 5.01 - 5.0.4 - - added support for using encoding parameters and key derivation parameters - with public key encryption (implemented by OAEP and DL/ECIES) - - added Camellia, SHACAL-2, Two-Track-MAC, Whirlpool, RIPEMD-320, - RIPEMD-128, RIPEMD-256, Base-32 coding, FIPS variant of CFB mode - - added ThreadUserTimer for timing thread CPU usage - - added option for password-based key derivation functions - to iterate until a mimimum elapsed thread CPU time is reached - - added option (on by default) for DEFLATE compression to detect - uncompressible files and process them more quickly - - improved compatibility and performance on 64-bit platforms, - including Alpha, IA-64, x86-64, PPC64, Sparc64, and MIPS64 - - fixed ONE_AND_ZEROS_PADDING to use 0x80 instead 0x01 as padding. - - fixed encoding/decoding of PKCS #8 privateKeyInfo to properly - handle optional attributes - -5.2.1 - fixed bug in the "dlltest" DLL testing program - - fixed compiling with STLport using VC .NET - - fixed compiling with -fPIC using GCC - - fixed compiling with -msse2 on systems without memalign() - - fixed inability to instantiate PanamaMAC - - fixed problems with inline documentation - -5.2.2 - added SHA-224 - - put SHA-256, SHA-384, SHA-512, RSASSA-PSS into DLL - -5.2.3 - fixed issues with FIPS algorithm test vectors - - put RSASSA-ISO into DLL - -5.3 - ported to MSVC 2005 with support for x86-64 - - added defense against AES timing attacks, and more AES test vectors - - changed StaticAlgorithmName() of Rijndael to "AES", CTR to "CTR" - -5.4 - added Salsa20 - - updated Whirlpool to version 3.0 - - ported to GCC 4.1, Sun C++ 5.8, and Borland C++Builder 2006 - -5.5 - added VMAC and Sosemanuk (with x86-64 and SSE2 assembly) - - improved speed of integer arithmetic, AES, SHA-512, Tiger, Salsa20, - Whirlpool, and PANAMA cipher using assembly (x86-64, MMX, SSE2) - - optimized Camellia and added defense against timing attacks - - updated benchmarks code to show cycles per byte and to time key/IV setup - - started using OpenMP for increased multi-core speed - - enabled GCC optimization flags by default in GNUmakefile - - added blinding and computational error checking for RW signing - - changed RandomPool, X917RNG, GetNextIV, DSA/NR/ECDSA/ECNR to reduce - the risk of reusing random numbers and IVs after virtual machine state - rollback - - changed default FIPS mode RNG from AutoSeededX917RNG<DES_EDE3> to - AutoSeededX917RNG<AES> - - fixed PANAMA cipher interface to accept 256-bit key and 256-bit IV - - moved MD2, MD4, MD5, PanamaHash, ARC4, WAKE_CFB into the namespace "Weak" - - removed HAVAL, MD5-MAC, XMAC - -5.5.1 - fixed VMAC validation failure on 32-bit big-endian machines - -5.5.2 - ported x64 assembly language code for AES, Salsa20, Sosemanuk, and Panama - to MSVC 2005 (using MASM since MSVC doesn't support inline assembly on x64) - - fixed Salsa20 initialization crash on non-SSE2 machines - - fixed Whirlpool crash on Pentium 2 machines - - fixed possible branch prediction analysis (BPA) vulnerability in - MontgomeryReduce(), which may affect security of RSA, RW, LUC - - fixed link error with MSVC 2003 when using "debug DLL" form of runtime library - - fixed crash in SSE2_Add on P4 machines when compiled with - MSVC 6.0 SP5 with Processor Pack - - ported to MSVC 2008, GCC 4.2, Sun CC 5.9, Intel C++ Compiler 10.0, - and Borland C++Builder 2007 - -5.6.0 - added AuthenticatedSymmetricCipher interface class and Filter wrappers - - added CCM, GCM (with SSE2 assembly), EAX, CMAC, XSalsa20, and SEED - - added support for variable length IVs - - added OIDs for Brainpool elliptic curve parameters - - improved AES and SHA-256 speed on x86 and x64 - - changed BlockTransformation interface to no longer assume data alignment - - fixed incorrect VMAC computation on message lengths - that are >64 mod 128 (x86 assembly version is not affected) - - fixed compiler error in vmac.cpp on x86 with GCC -fPIC - - fixed run-time validation error on x86-64 with GCC 4.3.2 -O2 - - fixed HashFilter bug when putMessage=true - - fixed AES-CTR data alignment bug that causes incorrect encryption on ARM - - removed WORD64_AVAILABLE; compiler support for 64-bit int is now required - - ported to GCC 4.3, C++Builder 2009, Sun CC 5.10, Intel C++ Compiler 11 - -5.6.1 - added support for AES-NI and CLMUL instruction sets in AES and GMAC/GCM - - removed WAKE-CFB - - fixed several bugs in the SHA-256 x86/x64 assembly code: - * incorrect hash on non-SSE2 x86 machines on non-aligned input - * incorrect hash on x86 machines when input crosses 0x80000000 - * incorrect hash on x64 when compiled with GCC with optimizations enabled - - fixed bugs in AES x86 and x64 assembly causing crashes in some MSVC build configurations - - switched to a public domain implementation of MARS - - ported to MSVC 2010, GCC 4.5.1, Sun Studio 12u1, C++Builder 2010, Intel C++ Compiler 11.1 - - renamed the MSVC DLL project to "cryptopp" for compatibility with MSVC 2010 - -5.6.2 - changed license to Boost Software License 1.0 - - added SHA-3 (Keccak) - - updated DSA to FIPS 186-3 (see DSA2 class) - - fixed Blowfish minimum keylength to be 4 bytes (32 bits) - - fixed Salsa validation failure when compiling with GCC 4.6 - - fixed infinite recursion when on x64, assembly disabled, and no AESNI - - ported to MSVC 2012, GCC 4.7, Clang 3.2, Solaris Studio 12.3, Intel C++ Compiler 13.0 - -Written by Wei Dai diff --git a/lib/cryptopp/adler32.cpp b/lib/cryptopp/adler32.cpp deleted file mode 100644 index 0d52c0838..000000000 --- a/lib/cryptopp/adler32.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// adler32.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "adler32.h" - -NAMESPACE_BEGIN(CryptoPP) - -void Adler32::Update(const byte *input, size_t length) -{ - const unsigned long BASE = 65521; - - unsigned long s1 = m_s1; - unsigned long s2 = m_s2; - - if (length % 8 != 0) - { - do - { - s1 += *input++; - s2 += s1; - length--; - } while (length % 8 != 0); - - if (s1 >= BASE) - s1 -= BASE; - s2 %= BASE; - } - - while (length > 0) - { - s1 += input[0]; s2 += s1; - s1 += input[1]; s2 += s1; - s1 += input[2]; s2 += s1; - s1 += input[3]; s2 += s1; - s1 += input[4]; s2 += s1; - s1 += input[5]; s2 += s1; - s1 += input[6]; s2 += s1; - s1 += input[7]; s2 += s1; - - length -= 8; - input += 8; - - if (s1 >= BASE) - s1 -= BASE; - if (length % 0x8000 == 0) - s2 %= BASE; - } - - assert(s1 < BASE); - assert(s2 < BASE); - - m_s1 = (word16)s1; - m_s2 = (word16)s2; -} - -void Adler32::TruncatedFinal(byte *hash, size_t size) -{ - ThrowIfInvalidTruncatedSize(size); - - switch (size) - { - default: - hash[3] = byte(m_s1); - case 3: - hash[2] = byte(m_s1 >> 8); - case 2: - hash[1] = byte(m_s2); - case 1: - hash[0] = byte(m_s2 >> 8); - case 0: - ; - } - - Reset(); -} - -NAMESPACE_END diff --git a/lib/cryptopp/adler32.h b/lib/cryptopp/adler32.h deleted file mode 100644 index 0ed803da9..000000000 --- a/lib/cryptopp/adler32.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef CRYPTOPP_ADLER32_H -#define CRYPTOPP_ADLER32_H - -#include "cryptlib.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! ADLER-32 checksum calculations -class Adler32 : public HashTransformation -{ -public: - CRYPTOPP_CONSTANT(DIGESTSIZE = 4) - Adler32() {Reset();} - void Update(const byte *input, size_t length); - void TruncatedFinal(byte *hash, size_t size); - unsigned int DigestSize() const {return DIGESTSIZE;} - static const char * StaticAlgorithmName() {return "Adler32";} - std::string AlgorithmName() const {return StaticAlgorithmName();} - -private: - void Reset() {m_s1 = 1; m_s2 = 0;} - - word16 m_s1, m_s2; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/aes.h b/lib/cryptopp/aes.h deleted file mode 100644 index 008754256..000000000 --- a/lib/cryptopp/aes.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef CRYPTOPP_AES_H -#define CRYPTOPP_AES_H - -#include "rijndael.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! <a href="http://www.cryptolounge.org/wiki/AES">AES</a> winner, announced on 10/2/2000 -DOCUMENTED_TYPEDEF(Rijndael, AES); - -typedef RijndaelEncryption AESEncryption; -typedef RijndaelDecryption AESDecryption; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/algebra.cpp b/lib/cryptopp/algebra.cpp deleted file mode 100644 index 958e63701..000000000 --- a/lib/cryptopp/algebra.cpp +++ /dev/null @@ -1,340 +0,0 @@ -// algebra.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_ALGEBRA_CPP // SunCC workaround: compiler could cause this file to be included twice -#define CRYPTOPP_ALGEBRA_CPP - -#include "algebra.h" -#include "integer.h" - -#include <vector> - -NAMESPACE_BEGIN(CryptoPP) - -template <class T> const T& AbstractGroup<T>::Double(const Element &a) const -{ - return this->Add(a, a); -} - -template <class T> const T& AbstractGroup<T>::Subtract(const Element &a, const Element &b) const -{ - // make copy of a in case Inverse() overwrites it - Element a1(a); - return this->Add(a1, Inverse(b)); -} - -template <class T> T& AbstractGroup<T>::Accumulate(Element &a, const Element &b) const -{ - return a = this->Add(a, b); -} - -template <class T> T& AbstractGroup<T>::Reduce(Element &a, const Element &b) const -{ - return a = this->Subtract(a, b); -} - -template <class T> const T& AbstractRing<T>::Square(const Element &a) const -{ - return this->Multiply(a, a); -} - -template <class T> const T& AbstractRing<T>::Divide(const Element &a, const Element &b) const -{ - // make copy of a in case MultiplicativeInverse() overwrites it - Element a1(a); - return this->Multiply(a1, this->MultiplicativeInverse(b)); -} - -template <class T> const T& AbstractEuclideanDomain<T>::Mod(const Element &a, const Element &b) const -{ - Element q; - this->DivisionAlgorithm(result, q, a, b); - return result; -} - -template <class T> const T& AbstractEuclideanDomain<T>::Gcd(const Element &a, const Element &b) const -{ - Element g[3]={b, a}; - unsigned int i0=0, i1=1, i2=2; - - while (!this->Equal(g[i1], this->Identity())) - { - g[i2] = this->Mod(g[i0], g[i1]); - unsigned int t = i0; i0 = i1; i1 = i2; i2 = t; - } - - return result = g[i0]; -} - -template <class T> const typename QuotientRing<T>::Element& QuotientRing<T>::MultiplicativeInverse(const Element &a) const -{ - Element g[3]={m_modulus, a}; - Element v[3]={m_domain.Identity(), m_domain.MultiplicativeIdentity()}; - Element y; - unsigned int i0=0, i1=1, i2=2; - - while (!this->Equal(g[i1], this->Identity())) - { - // y = g[i0] / g[i1]; - // g[i2] = g[i0] % g[i1]; - m_domain.DivisionAlgorithm(g[i2], y, g[i0], g[i1]); - // v[i2] = v[i0] - (v[i1] * y); - v[i2] = m_domain.Subtract(v[i0], m_domain.Multiply(v[i1], y)); - unsigned int t = i0; i0 = i1; i1 = i2; i2 = t; - } - - return m_domain.IsUnit(g[i0]) ? m_domain.Divide(v[i0], g[i0]) : m_domain.Identity(); -} - -template <class T> T AbstractGroup<T>::ScalarMultiply(const Element &base, const Integer &exponent) const -{ - Element result; - this->SimultaneousMultiply(&result, base, &exponent, 1); - return result; -} - -template <class T> T AbstractGroup<T>::CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const -{ - const unsigned expLen = STDMAX(e1.BitCount(), e2.BitCount()); - if (expLen==0) - return this->Identity(); - - const unsigned w = (expLen <= 46 ? 1 : (expLen <= 260 ? 2 : 3)); - const unsigned tableSize = 1<<w; - std::vector<Element> powerTable(tableSize << w); - - powerTable[1] = x; - powerTable[tableSize] = y; - if (w==1) - powerTable[3] = this->Add(x,y); - else - { - powerTable[2] = this->Double(x); - powerTable[2*tableSize] = this->Double(y); - - unsigned i, j; - - for (i=3; i<tableSize; i+=2) - powerTable[i] = Add(powerTable[i-2], powerTable[2]); - for (i=1; i<tableSize; i+=2) - for (j=i+tableSize; j<(tableSize<<w); j+=tableSize) - powerTable[j] = Add(powerTable[j-tableSize], y); - - for (i=3*tableSize; i<(tableSize<<w); i+=2*tableSize) - powerTable[i] = Add(powerTable[i-2*tableSize], powerTable[2*tableSize]); - for (i=tableSize; i<(tableSize<<w); i+=2*tableSize) - for (j=i+2; j<i+tableSize; j+=2) - powerTable[j] = Add(powerTable[j-1], x); - } - - Element result; - unsigned power1 = 0, power2 = 0, prevPosition = expLen-1; - bool firstTime = true; - - for (int i = expLen-1; i>=0; i--) - { - power1 = 2*power1 + e1.GetBit(i); - power2 = 2*power2 + e2.GetBit(i); - - if (i==0 || 2*power1 >= tableSize || 2*power2 >= tableSize) - { - unsigned squaresBefore = prevPosition-i; - unsigned squaresAfter = 0; - prevPosition = i; - while ((power1 || power2) && power1%2 == 0 && power2%2==0) - { - power1 /= 2; - power2 /= 2; - squaresBefore--; - squaresAfter++; - } - if (firstTime) - { - result = powerTable[(power2<<w) + power1]; - firstTime = false; - } - else - { - while (squaresBefore--) - result = this->Double(result); - if (power1 || power2) - Accumulate(result, powerTable[(power2<<w) + power1]); - } - while (squaresAfter--) - result = this->Double(result); - power1 = power2 = 0; - } - } - return result; -} - -template <class Element, class Iterator> Element GeneralCascadeMultiplication(const AbstractGroup<Element> &group, Iterator begin, Iterator end) -{ - if (end-begin == 1) - return group.ScalarMultiply(begin->base, begin->exponent); - else if (end-begin == 2) - return group.CascadeScalarMultiply(begin->base, begin->exponent, (begin+1)->base, (begin+1)->exponent); - else - { - Integer q, t; - Iterator last = end; - --last; - - std::make_heap(begin, end); - std::pop_heap(begin, end); - - while (!!begin->exponent) - { - // last->exponent is largest exponent, begin->exponent is next largest - t = last->exponent; - Integer::Divide(last->exponent, q, t, begin->exponent); - - if (q == Integer::One()) - group.Accumulate(begin->base, last->base); // avoid overhead of ScalarMultiply() - else - group.Accumulate(begin->base, group.ScalarMultiply(last->base, q)); - - std::push_heap(begin, end); - std::pop_heap(begin, end); - } - - return group.ScalarMultiply(last->base, last->exponent); - } -} - -struct WindowSlider -{ - WindowSlider(const Integer &expIn, bool fastNegate, unsigned int windowSizeIn=0) - : exp(expIn), windowModulus(Integer::One()), windowSize(windowSizeIn), windowBegin(0), fastNegate(fastNegate), firstTime(true), finished(false) - { - if (windowSize == 0) - { - unsigned int expLen = exp.BitCount(); - windowSize = expLen <= 17 ? 1 : (expLen <= 24 ? 2 : (expLen <= 70 ? 3 : (expLen <= 197 ? 4 : (expLen <= 539 ? 5 : (expLen <= 1434 ? 6 : 7))))); - } - windowModulus <<= windowSize; - } - - void FindNextWindow() - { - unsigned int expLen = exp.WordCount() * WORD_BITS; - unsigned int skipCount = firstTime ? 0 : windowSize; - firstTime = false; - while (!exp.GetBit(skipCount)) - { - if (skipCount >= expLen) - { - finished = true; - return; - } - skipCount++; - } - - exp >>= skipCount; - windowBegin += skipCount; - expWindow = word32(exp % (word(1) << windowSize)); - - if (fastNegate && exp.GetBit(windowSize)) - { - negateNext = true; - expWindow = (word32(1) << windowSize) - expWindow; - exp += windowModulus; - } - else - negateNext = false; - } - - Integer exp, windowModulus; - unsigned int windowSize, windowBegin; - word32 expWindow; - bool fastNegate, negateNext, firstTime, finished; -}; - -template <class T> -void AbstractGroup<T>::SimultaneousMultiply(T *results, const T &base, const Integer *expBegin, unsigned int expCount) const -{ - std::vector<std::vector<Element> > buckets(expCount); - std::vector<WindowSlider> exponents; - exponents.reserve(expCount); - unsigned int i; - - for (i=0; i<expCount; i++) - { - assert(expBegin->NotNegative()); - exponents.push_back(WindowSlider(*expBegin++, InversionIsFast(), 0)); - exponents[i].FindNextWindow(); - buckets[i].resize(1<<(exponents[i].windowSize-1), Identity()); - } - - unsigned int expBitPosition = 0; - Element g = base; - bool notDone = true; - - while (notDone) - { - notDone = false; - for (i=0; i<expCount; i++) - { - if (!exponents[i].finished && expBitPosition == exponents[i].windowBegin) - { - Element &bucket = buckets[i][exponents[i].expWindow/2]; - if (exponents[i].negateNext) - Accumulate(bucket, Inverse(g)); - else - Accumulate(bucket, g); - exponents[i].FindNextWindow(); - } - notDone = notDone || !exponents[i].finished; - } - - if (notDone) - { - g = Double(g); - expBitPosition++; - } - } - - for (i=0; i<expCount; i++) - { - Element &r = *results++; - r = buckets[i][buckets[i].size()-1]; - if (buckets[i].size() > 1) - { - for (int j = (int)buckets[i].size()-2; j >= 1; j--) - { - Accumulate(buckets[i][j], buckets[i][j+1]); - Accumulate(r, buckets[i][j]); - } - Accumulate(buckets[i][0], buckets[i][1]); - r = Add(Double(r), buckets[i][0]); - } - } -} - -template <class T> T AbstractRing<T>::Exponentiate(const Element &base, const Integer &exponent) const -{ - Element result; - SimultaneousExponentiate(&result, base, &exponent, 1); - return result; -} - -template <class T> T AbstractRing<T>::CascadeExponentiate(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const -{ - return MultiplicativeGroup().AbstractGroup<T>::CascadeScalarMultiply(x, e1, y, e2); -} - -template <class Element, class Iterator> Element GeneralCascadeExponentiation(const AbstractRing<Element> &ring, Iterator begin, Iterator end) -{ - return GeneralCascadeMultiplication<Element>(ring.MultiplicativeGroup(), begin, end); -} - -template <class T> -void AbstractRing<T>::SimultaneousExponentiate(T *results, const T &base, const Integer *exponents, unsigned int expCount) const -{ - MultiplicativeGroup().AbstractGroup<T>::SimultaneousMultiply(results, base, exponents, expCount); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/algebra.h b/lib/cryptopp/algebra.h deleted file mode 100644 index 13038bd80..000000000 --- a/lib/cryptopp/algebra.h +++ /dev/null @@ -1,285 +0,0 @@ -#ifndef CRYPTOPP_ALGEBRA_H -#define CRYPTOPP_ALGEBRA_H - -#include "config.h" - -NAMESPACE_BEGIN(CryptoPP) - -class Integer; - -// "const Element&" returned by member functions are references -// to internal data members. Since each object may have only -// one such data member for holding results, the following code -// will produce incorrect results: -// abcd = group.Add(group.Add(a,b), group.Add(c,d)); -// But this should be fine: -// abcd = group.Add(a, group.Add(b, group.Add(c,d)); - -//! Abstract Group -template <class T> class CRYPTOPP_NO_VTABLE AbstractGroup -{ -public: - typedef T Element; - - virtual ~AbstractGroup() {} - - virtual bool Equal(const Element &a, const Element &b) const =0; - virtual const Element& Identity() const =0; - virtual const Element& Add(const Element &a, const Element &b) const =0; - virtual const Element& Inverse(const Element &a) const =0; - virtual bool InversionIsFast() const {return false;} - - virtual const Element& Double(const Element &a) const; - virtual const Element& Subtract(const Element &a, const Element &b) const; - virtual Element& Accumulate(Element &a, const Element &b) const; - virtual Element& Reduce(Element &a, const Element &b) const; - - virtual Element ScalarMultiply(const Element &a, const Integer &e) const; - virtual Element CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const; - - virtual void SimultaneousMultiply(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; -}; - -//! Abstract Ring -template <class T> class CRYPTOPP_NO_VTABLE AbstractRing : public AbstractGroup<T> -{ -public: - typedef T Element; - - AbstractRing() {m_mg.m_pRing = this;} - AbstractRing(const AbstractRing &source) {m_mg.m_pRing = this;} - AbstractRing& operator=(const AbstractRing &source) {return *this;} - - virtual bool IsUnit(const Element &a) const =0; - virtual const Element& MultiplicativeIdentity() const =0; - virtual const Element& Multiply(const Element &a, const Element &b) const =0; - virtual const Element& MultiplicativeInverse(const Element &a) const =0; - - virtual const Element& Square(const Element &a) const; - virtual const Element& Divide(const Element &a, const Element &b) const; - - virtual Element Exponentiate(const Element &a, const Integer &e) const; - virtual Element CascadeExponentiate(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const; - - virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; - - virtual const AbstractGroup<T>& MultiplicativeGroup() const - {return m_mg;} - -private: - class MultiplicativeGroupT : public AbstractGroup<T> - { - public: - const AbstractRing<T>& GetRing() const - {return *m_pRing;} - - bool Equal(const Element &a, const Element &b) const - {return GetRing().Equal(a, b);} - - const Element& Identity() const - {return GetRing().MultiplicativeIdentity();} - - const Element& Add(const Element &a, const Element &b) const - {return GetRing().Multiply(a, b);} - - Element& Accumulate(Element &a, const Element &b) const - {return a = GetRing().Multiply(a, b);} - - const Element& Inverse(const Element &a) const - {return GetRing().MultiplicativeInverse(a);} - - const Element& Subtract(const Element &a, const Element &b) const - {return GetRing().Divide(a, b);} - - Element& Reduce(Element &a, const Element &b) const - {return a = GetRing().Divide(a, b);} - - const Element& Double(const Element &a) const - {return GetRing().Square(a);} - - Element ScalarMultiply(const Element &a, const Integer &e) const - {return GetRing().Exponentiate(a, e);} - - Element CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const - {return GetRing().CascadeExponentiate(x, e1, y, e2);} - - void SimultaneousMultiply(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const - {GetRing().SimultaneousExponentiate(results, base, exponents, exponentsCount);} - - const AbstractRing<T> *m_pRing; - }; - - MultiplicativeGroupT m_mg; -}; - -// ******************************************************** - -//! Base and Exponent -template <class T, class E = Integer> -struct BaseAndExponent -{ -public: - BaseAndExponent() {} - BaseAndExponent(const T &base, const E &exponent) : base(base), exponent(exponent) {} - bool operator<(const BaseAndExponent<T, E> &rhs) const {return exponent < rhs.exponent;} - T base; - E exponent; -}; - -// VC60 workaround: incomplete member template support -template <class Element, class Iterator> - Element GeneralCascadeMultiplication(const AbstractGroup<Element> &group, Iterator begin, Iterator end); -template <class Element, class Iterator> - Element GeneralCascadeExponentiation(const AbstractRing<Element> &ring, Iterator begin, Iterator end); - -// ******************************************************** - -//! Abstract Euclidean Domain -template <class T> class CRYPTOPP_NO_VTABLE AbstractEuclideanDomain : public AbstractRing<T> -{ -public: - typedef T Element; - - virtual void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const =0; - - virtual const Element& Mod(const Element &a, const Element &b) const =0; - virtual const Element& Gcd(const Element &a, const Element &b) const; - -protected: - mutable Element result; -}; - -// ******************************************************** - -//! EuclideanDomainOf -template <class T> class EuclideanDomainOf : public AbstractEuclideanDomain<T> -{ -public: - typedef T Element; - - EuclideanDomainOf() {} - - bool Equal(const Element &a, const Element &b) const - {return a==b;} - - const Element& Identity() const - {return Element::Zero();} - - const Element& Add(const Element &a, const Element &b) const - {return result = a+b;} - - Element& Accumulate(Element &a, const Element &b) const - {return a+=b;} - - const Element& Inverse(const Element &a) const - {return result = -a;} - - const Element& Subtract(const Element &a, const Element &b) const - {return result = a-b;} - - Element& Reduce(Element &a, const Element &b) const - {return a-=b;} - - const Element& Double(const Element &a) const - {return result = a.Doubled();} - - const Element& MultiplicativeIdentity() const - {return Element::One();} - - const Element& Multiply(const Element &a, const Element &b) const - {return result = a*b;} - - const Element& Square(const Element &a) const - {return result = a.Squared();} - - bool IsUnit(const Element &a) const - {return a.IsUnit();} - - const Element& MultiplicativeInverse(const Element &a) const - {return result = a.MultiplicativeInverse();} - - const Element& Divide(const Element &a, const Element &b) const - {return result = a/b;} - - const Element& Mod(const Element &a, const Element &b) const - {return result = a%b;} - - void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const - {Element::Divide(r, q, a, d);} - - bool operator==(const EuclideanDomainOf<T> &rhs) const - {return true;} - -private: - mutable Element result; -}; - -//! Quotient Ring -template <class T> class QuotientRing : public AbstractRing<typename T::Element> -{ -public: - typedef T EuclideanDomain; - typedef typename T::Element Element; - - QuotientRing(const EuclideanDomain &domain, const Element &modulus) - : m_domain(domain), m_modulus(modulus) {} - - const EuclideanDomain & GetDomain() const - {return m_domain;} - - const Element& GetModulus() const - {return m_modulus;} - - bool Equal(const Element &a, const Element &b) const - {return m_domain.Equal(m_domain.Mod(m_domain.Subtract(a, b), m_modulus), m_domain.Identity());} - - const Element& Identity() const - {return m_domain.Identity();} - - const Element& Add(const Element &a, const Element &b) const - {return m_domain.Add(a, b);} - - Element& Accumulate(Element &a, const Element &b) const - {return m_domain.Accumulate(a, b);} - - const Element& Inverse(const Element &a) const - {return m_domain.Inverse(a);} - - const Element& Subtract(const Element &a, const Element &b) const - {return m_domain.Subtract(a, b);} - - Element& Reduce(Element &a, const Element &b) const - {return m_domain.Reduce(a, b);} - - const Element& Double(const Element &a) const - {return m_domain.Double(a);} - - bool IsUnit(const Element &a) const - {return m_domain.IsUnit(m_domain.Gcd(a, m_modulus));} - - const Element& MultiplicativeIdentity() const - {return m_domain.MultiplicativeIdentity();} - - const Element& Multiply(const Element &a, const Element &b) const - {return m_domain.Mod(m_domain.Multiply(a, b), m_modulus);} - - const Element& Square(const Element &a) const - {return m_domain.Mod(m_domain.Square(a), m_modulus);} - - const Element& MultiplicativeInverse(const Element &a) const; - - bool operator==(const QuotientRing<T> &rhs) const - {return m_domain == rhs.m_domain && m_modulus == rhs.m_modulus;} - -protected: - EuclideanDomain m_domain; - Element m_modulus; -}; - -NAMESPACE_END - -#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES -#include "algebra.cpp" -#endif - -#endif diff --git a/lib/cryptopp/algparam.cpp b/lib/cryptopp/algparam.cpp deleted file mode 100644 index a70d5dd95..000000000 --- a/lib/cryptopp/algparam.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// algparam.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "algparam.h" - -NAMESPACE_BEGIN(CryptoPP) - -PAssignIntToInteger g_pAssignIntToInteger = NULL; - -bool CombinedNameValuePairs::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const -{ - if (strcmp(name, "ValueNames") == 0) - return m_pairs1.GetVoidValue(name, valueType, pValue) && m_pairs2.GetVoidValue(name, valueType, pValue); - else - return m_pairs1.GetVoidValue(name, valueType, pValue) || m_pairs2.GetVoidValue(name, valueType, pValue); -} - -void AlgorithmParametersBase::operator=(const AlgorithmParametersBase& rhs) -{ - assert(false); -} - -bool AlgorithmParametersBase::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const -{ - if (strcmp(name, "ValueNames") == 0) - { - NameValuePairs::ThrowIfTypeMismatch(name, typeid(std::string), valueType); - if (m_next.get()) - m_next->GetVoidValue(name, valueType, pValue); - (*reinterpret_cast<std::string *>(pValue) += m_name) += ";"; - return true; - } - else if (strcmp(name, m_name) == 0) - { - AssignValue(name, valueType, pValue); - m_used = true; - return true; - } - else if (m_next.get()) - return m_next->GetVoidValue(name, valueType, pValue); - else - return false; -} - -AlgorithmParameters::AlgorithmParameters() - : m_defaultThrowIfNotUsed(true) -{ -} - -AlgorithmParameters::AlgorithmParameters(const AlgorithmParameters &x) - : m_defaultThrowIfNotUsed(x.m_defaultThrowIfNotUsed) -{ - m_next.reset(const_cast<AlgorithmParameters &>(x).m_next.release()); -} - -AlgorithmParameters & AlgorithmParameters::operator=(const AlgorithmParameters &x) -{ - m_next.reset(const_cast<AlgorithmParameters &>(x).m_next.release()); - return *this; -} - -bool AlgorithmParameters::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const -{ - if (m_next.get()) - return m_next->GetVoidValue(name, valueType, pValue); - else - return false; -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/algparam.h b/lib/cryptopp/algparam.h deleted file mode 100644 index ea5129c22..000000000 --- a/lib/cryptopp/algparam.h +++ /dev/null @@ -1,398 +0,0 @@ -#ifndef CRYPTOPP_ALGPARAM_H -#define CRYPTOPP_ALGPARAM_H - -#include "cryptlib.h" -#include "smartptr.h" -#include "secblock.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! used to pass byte array input as part of a NameValuePairs object -/*! the deepCopy option is used when the NameValuePairs object can't - keep a copy of the data available */ -class ConstByteArrayParameter -{ -public: - ConstByteArrayParameter(const char *data = NULL, bool deepCopy = false) - { - Assign((const byte *)data, data ? strlen(data) : 0, deepCopy); - } - ConstByteArrayParameter(const byte *data, size_t size, bool deepCopy = false) - { - Assign(data, size, deepCopy); - } - template <class T> ConstByteArrayParameter(const T &string, bool deepCopy = false) - { - CRYPTOPP_COMPILE_ASSERT(sizeof(CPP_TYPENAME T::value_type) == 1); - Assign((const byte *)string.data(), string.size(), deepCopy); - } - - void Assign(const byte *data, size_t size, bool deepCopy) - { - if (deepCopy) - m_block.Assign(data, size); - else - { - m_data = data; - m_size = size; - } - m_deepCopy = deepCopy; - } - - const byte *begin() const {return m_deepCopy ? m_block.begin() : m_data;} - const byte *end() const {return m_deepCopy ? m_block.end() : m_data + m_size;} - size_t size() const {return m_deepCopy ? m_block.size() : m_size;} - -private: - bool m_deepCopy; - const byte *m_data; - size_t m_size; - SecByteBlock m_block; -}; - -class ByteArrayParameter -{ -public: - ByteArrayParameter(byte *data = NULL, unsigned int size = 0) - : m_data(data), m_size(size) {} - ByteArrayParameter(SecByteBlock &block) - : m_data(block.begin()), m_size(block.size()) {} - - byte *begin() const {return m_data;} - byte *end() const {return m_data + m_size;} - size_t size() const {return m_size;} - -private: - byte *m_data; - size_t m_size; -}; - -class CRYPTOPP_DLL CombinedNameValuePairs : public NameValuePairs -{ -public: - CombinedNameValuePairs(const NameValuePairs &pairs1, const NameValuePairs &pairs2) - : m_pairs1(pairs1), m_pairs2(pairs2) {} - - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; - -private: - const NameValuePairs &m_pairs1, &m_pairs2; -}; - -template <class T, class BASE> -class GetValueHelperClass -{ -public: - GetValueHelperClass(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst) - : m_pObject(pObject), m_name(name), m_valueType(&valueType), m_pValue(pValue), m_found(false), m_getValueNames(false) - { - if (strcmp(m_name, "ValueNames") == 0) - { - m_found = m_getValueNames = true; - NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(std::string), *m_valueType); - if (searchFirst) - searchFirst->GetVoidValue(m_name, valueType, pValue); - if (typeid(T) != typeid(BASE)) - pObject->BASE::GetVoidValue(m_name, valueType, pValue); - ((*reinterpret_cast<std::string *>(m_pValue) += "ThisPointer:") += typeid(T).name()) += ';'; - } - - if (!m_found && strncmp(m_name, "ThisPointer:", 12) == 0 && strcmp(m_name+12, typeid(T).name()) == 0) - { - NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(T *), *m_valueType); - *reinterpret_cast<const T **>(pValue) = pObject; - m_found = true; - return; - } - - if (!m_found && searchFirst) - m_found = searchFirst->GetVoidValue(m_name, valueType, pValue); - - if (!m_found && typeid(T) != typeid(BASE)) - m_found = pObject->BASE::GetVoidValue(m_name, valueType, pValue); - } - - operator bool() const {return m_found;} - - template <class R> - GetValueHelperClass<T,BASE> & operator()(const char *name, const R & (T::*pm)() const) - { - if (m_getValueNames) - (*reinterpret_cast<std::string *>(m_pValue) += name) += ";"; - if (!m_found && strcmp(name, m_name) == 0) - { - NameValuePairs::ThrowIfTypeMismatch(name, typeid(R), *m_valueType); - *reinterpret_cast<R *>(m_pValue) = (m_pObject->*pm)(); - m_found = true; - } - return *this; - } - - GetValueHelperClass<T,BASE> &Assignable() - { -#ifndef __INTEL_COMPILER // ICL 9.1 workaround: Intel compiler copies the vTable pointer for some reason - if (m_getValueNames) - ((*reinterpret_cast<std::string *>(m_pValue) += "ThisObject:") += typeid(T).name()) += ';'; - if (!m_found && strncmp(m_name, "ThisObject:", 11) == 0 && strcmp(m_name+11, typeid(T).name()) == 0) - { - NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(T), *m_valueType); - *reinterpret_cast<T *>(m_pValue) = *m_pObject; - m_found = true; - } -#endif - return *this; - } - -private: - const T *m_pObject; - const char *m_name; - const std::type_info *m_valueType; - void *m_pValue; - bool m_found, m_getValueNames; -}; - -template <class BASE, class T> -GetValueHelperClass<T, BASE> GetValueHelper(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst=NULL, BASE *dummy=NULL) -{ - return GetValueHelperClass<T, BASE>(pObject, name, valueType, pValue, searchFirst); -} - -template <class T> -GetValueHelperClass<T, T> GetValueHelper(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst=NULL) -{ - return GetValueHelperClass<T, T>(pObject, name, valueType, pValue, searchFirst); -} - -// ******************************************************** - -template <class R> -R Hack_DefaultValueFromConstReferenceType(const R &) -{ - return R(); -} - -template <class R> -bool Hack_GetValueIntoConstReference(const NameValuePairs &source, const char *name, const R &value) -{ - return source.GetValue(name, const_cast<R &>(value)); -} - -template <class T, class BASE> -class AssignFromHelperClass -{ -public: - AssignFromHelperClass(T *pObject, const NameValuePairs &source) - : m_pObject(pObject), m_source(source), m_done(false) - { - if (source.GetThisObject(*pObject)) - m_done = true; - else if (typeid(BASE) != typeid(T)) - pObject->BASE::AssignFrom(source); - } - - template <class R> - AssignFromHelperClass & operator()(const char *name, void (T::*pm)(R)) // VC60 workaround: "const R &" here causes compiler error - { - if (!m_done) - { - R value = Hack_DefaultValueFromConstReferenceType(reinterpret_cast<R>(*(int *)NULL)); - if (!Hack_GetValueIntoConstReference(m_source, name, value)) - throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name + "'"); - (m_pObject->*pm)(value); - } - return *this; - } - - template <class R, class S> - AssignFromHelperClass & operator()(const char *name1, const char *name2, void (T::*pm)(R, S)) // VC60 workaround: "const R &" here causes compiler error - { - if (!m_done) - { - R value1 = Hack_DefaultValueFromConstReferenceType(reinterpret_cast<R>(*(int *)NULL)); - if (!Hack_GetValueIntoConstReference(m_source, name1, value1)) - throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name1 + "'"); - S value2 = Hack_DefaultValueFromConstReferenceType(reinterpret_cast<S>(*(int *)NULL)); - if (!Hack_GetValueIntoConstReference(m_source, name2, value2)) - throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name2 + "'"); - (m_pObject->*pm)(value1, value2); - } - return *this; - } - -private: - T *m_pObject; - const NameValuePairs &m_source; - bool m_done; -}; - -template <class BASE, class T> -AssignFromHelperClass<T, BASE> AssignFromHelper(T *pObject, const NameValuePairs &source, BASE *dummy=NULL) -{ - return AssignFromHelperClass<T, BASE>(pObject, source); -} - -template <class T> -AssignFromHelperClass<T, T> AssignFromHelper(T *pObject, const NameValuePairs &source) -{ - return AssignFromHelperClass<T, T>(pObject, source); -} - -// ******************************************************** - -// to allow the linker to discard Integer code if not needed. -typedef bool (CRYPTOPP_API * PAssignIntToInteger)(const std::type_info &valueType, void *pInteger, const void *pInt); -CRYPTOPP_DLL extern PAssignIntToInteger g_pAssignIntToInteger; - -CRYPTOPP_DLL const std::type_info & CRYPTOPP_API IntegerTypeId(); - -class CRYPTOPP_DLL AlgorithmParametersBase -{ -public: - class ParameterNotUsed : public Exception - { - public: - ParameterNotUsed(const char *name) : Exception(OTHER_ERROR, std::string("AlgorithmParametersBase: parameter \"") + name + "\" not used") {} - }; - - // this is actually a move, not a copy - AlgorithmParametersBase(const AlgorithmParametersBase &x) - : m_name(x.m_name), m_throwIfNotUsed(x.m_throwIfNotUsed), m_used(x.m_used) - { - m_next.reset(const_cast<AlgorithmParametersBase &>(x).m_next.release()); - x.m_used = true; - } - - AlgorithmParametersBase(const char *name, bool throwIfNotUsed) - : m_name(name), m_throwIfNotUsed(throwIfNotUsed), m_used(false) {} - - virtual ~AlgorithmParametersBase() - { -#ifdef CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE - if (!std::uncaught_exception()) -#else - try -#endif - { - if (m_throwIfNotUsed && !m_used) - throw ParameterNotUsed(m_name); - } -#ifndef CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE - catch(...) - { - } -#endif - } - - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; - -protected: - friend class AlgorithmParameters; - void operator=(const AlgorithmParametersBase& rhs); // assignment not allowed, declare this for VC60 - - virtual void AssignValue(const char *name, const std::type_info &valueType, void *pValue) const =0; - virtual void MoveInto(void *p) const =0; // not really const - - const char *m_name; - bool m_throwIfNotUsed; - mutable bool m_used; - member_ptr<AlgorithmParametersBase> m_next; -}; - -template <class T> -class AlgorithmParametersTemplate : public AlgorithmParametersBase -{ -public: - AlgorithmParametersTemplate(const char *name, const T &value, bool throwIfNotUsed) - : AlgorithmParametersBase(name, throwIfNotUsed), m_value(value) - { - } - - void AssignValue(const char *name, const std::type_info &valueType, void *pValue) const - { - // special case for retrieving an Integer parameter when an int was passed in - if (!(g_pAssignIntToInteger != NULL && typeid(T) == typeid(int) && g_pAssignIntToInteger(valueType, pValue, &m_value))) - { - NameValuePairs::ThrowIfTypeMismatch(name, typeid(T), valueType); - *reinterpret_cast<T *>(pValue) = m_value; - } - } - - void MoveInto(void *buffer) const - { - AlgorithmParametersTemplate<T>* p = new(buffer) AlgorithmParametersTemplate<T>(*this); - } - -protected: - T m_value; -}; - -CRYPTOPP_DLL_TEMPLATE_CLASS AlgorithmParametersTemplate<bool>; -CRYPTOPP_DLL_TEMPLATE_CLASS AlgorithmParametersTemplate<int>; -CRYPTOPP_DLL_TEMPLATE_CLASS AlgorithmParametersTemplate<ConstByteArrayParameter>; - -class CRYPTOPP_DLL AlgorithmParameters : public NameValuePairs -{ -public: - AlgorithmParameters(); - -#ifdef __BORLANDC__ - template <class T> - AlgorithmParameters(const char *name, const T &value, bool throwIfNotUsed=true) - : m_next(new AlgorithmParametersTemplate<T>(name, value, throwIfNotUsed)) - , m_defaultThrowIfNotUsed(throwIfNotUsed) - { - } -#endif - - AlgorithmParameters(const AlgorithmParameters &x); - - AlgorithmParameters & operator=(const AlgorithmParameters &x); - - template <class T> - AlgorithmParameters & operator()(const char *name, const T &value, bool throwIfNotUsed) - { - member_ptr<AlgorithmParametersBase> p(new AlgorithmParametersTemplate<T>(name, value, throwIfNotUsed)); - p->m_next.reset(m_next.release()); - m_next.reset(p.release()); - m_defaultThrowIfNotUsed = throwIfNotUsed; - return *this; - } - - template <class T> - AlgorithmParameters & operator()(const char *name, const T &value) - { - return operator()(name, value, m_defaultThrowIfNotUsed); - } - - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; - -protected: - member_ptr<AlgorithmParametersBase> m_next; - bool m_defaultThrowIfNotUsed; -}; - -//! Create an object that implements NameValuePairs for passing parameters -/*! \param throwIfNotUsed if true, the object will throw an exception if the value is not accessed - \note throwIfNotUsed is ignored if using a compiler that does not support std::uncaught_exception(), - such as MSVC 7.0 and earlier. - \note A NameValuePairs object containing an arbitrary number of name value pairs may be constructed by - repeatedly using operator() on the object returned by MakeParameters, for example: - AlgorithmParameters parameters = MakeParameters(name1, value1)(name2, value2)(name3, value3); -*/ -#ifdef __BORLANDC__ -typedef AlgorithmParameters MakeParameters; -#else -template <class T> -AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed = true) -{ - return AlgorithmParameters()(name, value, throwIfNotUsed); -} -#endif - -#define CRYPTOPP_GET_FUNCTION_ENTRY(name) (Name::name(), &ThisClass::Get##name) -#define CRYPTOPP_SET_FUNCTION_ENTRY(name) (Name::name(), &ThisClass::Set##name) -#define CRYPTOPP_SET_FUNCTION_ENTRY2(name1, name2) (Name::name1(), Name::name2(), &ThisClass::Set##name1##And##name2) - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/argnames.h b/lib/cryptopp/argnames.h deleted file mode 100644 index e96172521..000000000 --- a/lib/cryptopp/argnames.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef CRYPTOPP_ARGNAMES_H -#define CRYPTOPP_ARGNAMES_H - -#include "cryptlib.h" - -NAMESPACE_BEGIN(CryptoPP) - -DOCUMENTED_NAMESPACE_BEGIN(Name) - -#define CRYPTOPP_DEFINE_NAME_STRING(name) inline const char *name() {return #name;} - -CRYPTOPP_DEFINE_NAME_STRING(ValueNames) //!< string, a list of value names with a semicolon (';') after each name -CRYPTOPP_DEFINE_NAME_STRING(Version) //!< int -CRYPTOPP_DEFINE_NAME_STRING(Seed) //!< ConstByteArrayParameter -CRYPTOPP_DEFINE_NAME_STRING(Key) //!< ConstByteArrayParameter -CRYPTOPP_DEFINE_NAME_STRING(IV) //!< ConstByteArrayParameter, also accepts const byte * for backwards compatibility -CRYPTOPP_DEFINE_NAME_STRING(StolenIV) //!< byte * -CRYPTOPP_DEFINE_NAME_STRING(Rounds) //!< int -CRYPTOPP_DEFINE_NAME_STRING(FeedbackSize) //!< int -CRYPTOPP_DEFINE_NAME_STRING(WordSize) //!< int, in bytes -CRYPTOPP_DEFINE_NAME_STRING(BlockSize) //!< int, in bytes -CRYPTOPP_DEFINE_NAME_STRING(EffectiveKeyLength) //!< int, in bits -CRYPTOPP_DEFINE_NAME_STRING(KeySize) //!< int, in bits -CRYPTOPP_DEFINE_NAME_STRING(ModulusSize) //!< int, in bits -CRYPTOPP_DEFINE_NAME_STRING(SubgroupOrderSize) //!< int, in bits -CRYPTOPP_DEFINE_NAME_STRING(PrivateExponentSize)//!< int, in bits -CRYPTOPP_DEFINE_NAME_STRING(Modulus) //!< Integer -CRYPTOPP_DEFINE_NAME_STRING(PublicExponent) //!< Integer -CRYPTOPP_DEFINE_NAME_STRING(PrivateExponent) //!< Integer -CRYPTOPP_DEFINE_NAME_STRING(PublicElement) //!< Integer -CRYPTOPP_DEFINE_NAME_STRING(SubgroupOrder) //!< Integer -CRYPTOPP_DEFINE_NAME_STRING(Cofactor) //!< Integer -CRYPTOPP_DEFINE_NAME_STRING(SubgroupGenerator) //!< Integer, ECP::Point, or EC2N::Point -CRYPTOPP_DEFINE_NAME_STRING(Curve) //!< ECP or EC2N -CRYPTOPP_DEFINE_NAME_STRING(GroupOID) //!< OID -CRYPTOPP_DEFINE_NAME_STRING(PointerToPrimeSelector) //!< const PrimeSelector * -CRYPTOPP_DEFINE_NAME_STRING(Prime1) //!< Integer -CRYPTOPP_DEFINE_NAME_STRING(Prime2) //!< Integer -CRYPTOPP_DEFINE_NAME_STRING(ModPrime1PrivateExponent) //!< Integer -CRYPTOPP_DEFINE_NAME_STRING(ModPrime2PrivateExponent) //!< Integer -CRYPTOPP_DEFINE_NAME_STRING(MultiplicativeInverseOfPrime2ModPrime1) //!< Integer -CRYPTOPP_DEFINE_NAME_STRING(QuadraticResidueModPrime1) //!< Integer -CRYPTOPP_DEFINE_NAME_STRING(QuadraticResidueModPrime2) //!< Integer -CRYPTOPP_DEFINE_NAME_STRING(PutMessage) //!< bool -CRYPTOPP_DEFINE_NAME_STRING(TruncatedDigestSize) //!< int -CRYPTOPP_DEFINE_NAME_STRING(BlockPaddingScheme) //!< StreamTransformationFilter::BlockPaddingScheme -CRYPTOPP_DEFINE_NAME_STRING(HashVerificationFilterFlags) //!< word32 -CRYPTOPP_DEFINE_NAME_STRING(AuthenticatedDecryptionFilterFlags) //!< word32 -CRYPTOPP_DEFINE_NAME_STRING(SignatureVerificationFilterFlags) //!< word32 -CRYPTOPP_DEFINE_NAME_STRING(InputBuffer) //!< ConstByteArrayParameter -CRYPTOPP_DEFINE_NAME_STRING(OutputBuffer) //!< ByteArrayParameter -CRYPTOPP_DEFINE_NAME_STRING(InputFileName) //!< const char * -CRYPTOPP_DEFINE_NAME_STRING(InputFileNameWide) //!< const wchar_t * -CRYPTOPP_DEFINE_NAME_STRING(InputStreamPointer) //!< std::istream * -CRYPTOPP_DEFINE_NAME_STRING(InputBinaryMode) //!< bool -CRYPTOPP_DEFINE_NAME_STRING(OutputFileName) //!< const char * -CRYPTOPP_DEFINE_NAME_STRING(OutputFileNameWide) //!< const wchar_t * -CRYPTOPP_DEFINE_NAME_STRING(OutputStreamPointer) //!< std::ostream * -CRYPTOPP_DEFINE_NAME_STRING(OutputBinaryMode) //!< bool -CRYPTOPP_DEFINE_NAME_STRING(EncodingParameters) //!< ConstByteArrayParameter -CRYPTOPP_DEFINE_NAME_STRING(KeyDerivationParameters) //!< ConstByteArrayParameter -CRYPTOPP_DEFINE_NAME_STRING(Separator) //< ConstByteArrayParameter -CRYPTOPP_DEFINE_NAME_STRING(Terminator) //< ConstByteArrayParameter -CRYPTOPP_DEFINE_NAME_STRING(Uppercase) //< bool -CRYPTOPP_DEFINE_NAME_STRING(GroupSize) //< int -CRYPTOPP_DEFINE_NAME_STRING(Pad) //< bool -CRYPTOPP_DEFINE_NAME_STRING(PaddingByte) //< byte -CRYPTOPP_DEFINE_NAME_STRING(Log2Base) //< int -CRYPTOPP_DEFINE_NAME_STRING(EncodingLookupArray) //< const byte * -CRYPTOPP_DEFINE_NAME_STRING(DecodingLookupArray) //< const byte * -CRYPTOPP_DEFINE_NAME_STRING(InsertLineBreaks) //< bool -CRYPTOPP_DEFINE_NAME_STRING(MaxLineLength) //< int -CRYPTOPP_DEFINE_NAME_STRING(DigestSize) //!< int, in bytes -CRYPTOPP_DEFINE_NAME_STRING(L1KeyLength) //!< int, in bytes -CRYPTOPP_DEFINE_NAME_STRING(TableSize) //!< int, in bytes - -DOCUMENTED_NAMESPACE_END - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/asn.cpp b/lib/cryptopp/asn.cpp deleted file mode 100644 index 8ae1ad65a..000000000 --- a/lib/cryptopp/asn.cpp +++ /dev/null @@ -1,597 +0,0 @@ -// asn.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "asn.h" - -#include <iomanip> -#include <time.h> - -NAMESPACE_BEGIN(CryptoPP) -USING_NAMESPACE(std) - -/// DER Length -size_t DERLengthEncode(BufferedTransformation &bt, lword length) -{ - size_t i=0; - if (length <= 0x7f) - { - bt.Put(byte(length)); - i++; - } - else - { - bt.Put(byte(BytePrecision(length) | 0x80)); - i++; - for (int j=BytePrecision(length); j; --j) - { - bt.Put(byte(length >> (j-1)*8)); - i++; - } - } - return i; -} - -bool BERLengthDecode(BufferedTransformation &bt, lword &length, bool &definiteLength) -{ - byte b; - - if (!bt.Get(b)) - return false; - - if (!(b & 0x80)) - { - definiteLength = true; - length = b; - } - else - { - unsigned int lengthBytes = b & 0x7f; - - if (lengthBytes == 0) - { - definiteLength = false; - return true; - } - - definiteLength = true; - length = 0; - while (lengthBytes--) - { - if (length >> (8*(sizeof(length)-1))) - BERDecodeError(); // length about to overflow - - if (!bt.Get(b)) - return false; - - length = (length << 8) | b; - } - } - return true; -} - -bool BERLengthDecode(BufferedTransformation &bt, size_t &length) -{ - lword lw; - bool definiteLength; - if (!BERLengthDecode(bt, lw, definiteLength)) - BERDecodeError(); - if (!SafeConvert(lw, length)) - BERDecodeError(); - return definiteLength; -} - -void DEREncodeNull(BufferedTransformation &out) -{ - out.Put(TAG_NULL); - out.Put(0); -} - -void BERDecodeNull(BufferedTransformation &in) -{ - byte b; - if (!in.Get(b) || b != TAG_NULL) - BERDecodeError(); - size_t length; - if (!BERLengthDecode(in, length) || length != 0) - BERDecodeError(); -} - -/// ASN Strings -size_t DEREncodeOctetString(BufferedTransformation &bt, const byte *str, size_t strLen) -{ - bt.Put(OCTET_STRING); - size_t lengthBytes = DERLengthEncode(bt, strLen); - bt.Put(str, strLen); - return 1+lengthBytes+strLen; -} - -size_t DEREncodeOctetString(BufferedTransformation &bt, const SecByteBlock &str) -{ - return DEREncodeOctetString(bt, str.begin(), str.size()); -} - -size_t BERDecodeOctetString(BufferedTransformation &bt, SecByteBlock &str) -{ - byte b; - if (!bt.Get(b) || b != OCTET_STRING) - BERDecodeError(); - - size_t bc; - if (!BERLengthDecode(bt, bc)) - BERDecodeError(); - - str.resize(bc); - if (bc != bt.Get(str, bc)) - BERDecodeError(); - return bc; -} - -size_t BERDecodeOctetString(BufferedTransformation &bt, BufferedTransformation &str) -{ - byte b; - if (!bt.Get(b) || b != OCTET_STRING) - BERDecodeError(); - - size_t bc; - if (!BERLengthDecode(bt, bc)) - BERDecodeError(); - - bt.TransferTo(str, bc); - return bc; -} - -size_t DEREncodeTextString(BufferedTransformation &bt, const std::string &str, byte asnTag) -{ - bt.Put(asnTag); - size_t lengthBytes = DERLengthEncode(bt, str.size()); - bt.Put((const byte *)str.data(), str.size()); - return 1+lengthBytes+str.size(); -} - -size_t BERDecodeTextString(BufferedTransformation &bt, std::string &str, byte asnTag) -{ - byte b; - if (!bt.Get(b) || b != asnTag) - BERDecodeError(); - - size_t bc; - if (!BERLengthDecode(bt, bc)) - BERDecodeError(); - - SecByteBlock temp(bc); - if (bc != bt.Get(temp, bc)) - BERDecodeError(); - str.assign((char *)temp.begin(), bc); - return bc; -} - -/// ASN BitString -size_t DEREncodeBitString(BufferedTransformation &bt, const byte *str, size_t strLen, unsigned int unusedBits) -{ - bt.Put(BIT_STRING); - size_t lengthBytes = DERLengthEncode(bt, strLen+1); - bt.Put((byte)unusedBits); - bt.Put(str, strLen); - return 2+lengthBytes+strLen; -} - -size_t BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits) -{ - byte b; - if (!bt.Get(b) || b != BIT_STRING) - BERDecodeError(); - - size_t bc; - if (!BERLengthDecode(bt, bc)) - BERDecodeError(); - - byte unused; - if (!bt.Get(unused)) - BERDecodeError(); - unusedBits = unused; - str.resize(bc-1); - if ((bc-1) != bt.Get(str, bc-1)) - BERDecodeError(); - return bc-1; -} - -void DERReencode(BufferedTransformation &source, BufferedTransformation &dest) -{ - byte tag; - source.Peek(tag); - BERGeneralDecoder decoder(source, tag); - DERGeneralEncoder encoder(dest, tag); - if (decoder.IsDefiniteLength()) - decoder.TransferTo(encoder, decoder.RemainingLength()); - else - { - while (!decoder.EndReached()) - DERReencode(decoder, encoder); - } - decoder.MessageEnd(); - encoder.MessageEnd(); -} - -void OID::EncodeValue(BufferedTransformation &bt, word32 v) -{ - for (unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U)-7; i != 0; i-=7) - bt.Put((byte)(0x80 | ((v >> i) & 0x7f))); - bt.Put((byte)(v & 0x7f)); -} - -size_t OID::DecodeValue(BufferedTransformation &bt, word32 &v) -{ - byte b; - size_t i=0; - v = 0; - while (true) - { - if (!bt.Get(b)) - BERDecodeError(); - i++; - if (v >> (8*sizeof(v)-7)) // v about to overflow - BERDecodeError(); - v <<= 7; - v += b & 0x7f; - if (!(b & 0x80)) - return i; - } -} - -void OID::DEREncode(BufferedTransformation &bt) const -{ - assert(m_values.size() >= 2); - ByteQueue temp; - temp.Put(byte(m_values[0] * 40 + m_values[1])); - for (size_t i=2; i<m_values.size(); i++) - EncodeValue(temp, m_values[i]); - bt.Put(OBJECT_IDENTIFIER); - DERLengthEncode(bt, temp.CurrentSize()); - temp.TransferTo(bt); -} - -void OID::BERDecode(BufferedTransformation &bt) -{ - byte b; - if (!bt.Get(b) || b != OBJECT_IDENTIFIER) - BERDecodeError(); - - size_t length; - if (!BERLengthDecode(bt, length) || length < 1) - BERDecodeError(); - - if (!bt.Get(b)) - BERDecodeError(); - - length--; - m_values.resize(2); - m_values[0] = b / 40; - m_values[1] = b % 40; - - while (length > 0) - { - word32 v; - size_t valueLen = DecodeValue(bt, v); - if (valueLen > length) - BERDecodeError(); - m_values.push_back(v); - length -= valueLen; - } -} - -void OID::BERDecodeAndCheck(BufferedTransformation &bt) const -{ - OID oid(bt); - if (*this != oid) - BERDecodeError(); -} - -inline BufferedTransformation & EncodedObjectFilter::CurrentTarget() -{ - if (m_flags & PUT_OBJECTS) - return *AttachedTransformation(); - else - return TheBitBucket(); -} - -void EncodedObjectFilter::Put(const byte *inString, size_t length) -{ - if (m_nCurrentObject == m_nObjects) - { - AttachedTransformation()->Put(inString, length); - return; - } - - LazyPutter lazyPutter(m_queue, inString, length); - - while (m_queue.AnyRetrievable()) - { - switch (m_state) - { - case IDENTIFIER: - if (!m_queue.Get(m_id)) - return; - m_queue.TransferTo(CurrentTarget(), 1); - m_state = LENGTH; // fall through - case LENGTH: - { - byte b; - if (m_level > 0 && m_id == 0 && m_queue.Peek(b) && b == 0) - { - m_queue.TransferTo(CurrentTarget(), 1); - m_level--; - m_state = IDENTIFIER; - break; - } - ByteQueue::Walker walker(m_queue); - bool definiteLength; - if (!BERLengthDecode(walker, m_lengthRemaining, definiteLength)) - return; - m_queue.TransferTo(CurrentTarget(), walker.GetCurrentPosition()); - if (!((m_id & CONSTRUCTED) || definiteLength)) - BERDecodeError(); - if (!definiteLength) - { - if (!(m_id & CONSTRUCTED)) - BERDecodeError(); - m_level++; - m_state = IDENTIFIER; - break; - } - m_state = BODY; // fall through - } - case BODY: - m_lengthRemaining -= m_queue.TransferTo(CurrentTarget(), m_lengthRemaining); - - if (m_lengthRemaining == 0) - m_state = IDENTIFIER; - } - - if (m_state == IDENTIFIER && m_level == 0) - { - // just finished processing a level 0 object - ++m_nCurrentObject; - - if (m_flags & PUT_MESSANGE_END_AFTER_EACH_OBJECT) - AttachedTransformation()->MessageEnd(); - - if (m_nCurrentObject == m_nObjects) - { - if (m_flags & PUT_MESSANGE_END_AFTER_ALL_OBJECTS) - AttachedTransformation()->MessageEnd(); - - if (m_flags & PUT_MESSANGE_SERIES_END_AFTER_ALL_OBJECTS) - AttachedTransformation()->MessageSeriesEnd(); - - m_queue.TransferAllTo(*AttachedTransformation()); - return; - } - } - } -} - -BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag) - : m_inQueue(inQueue), m_finished(false) -{ - Init(asnTag); -} - -BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag) - : m_inQueue(inQueue), m_finished(false) -{ - Init(asnTag); -} - -void BERGeneralDecoder::Init(byte asnTag) -{ - byte b; - if (!m_inQueue.Get(b) || b != asnTag) - BERDecodeError(); - - if (!BERLengthDecode(m_inQueue, m_length, m_definiteLength)) - BERDecodeError(); - - if (!m_definiteLength && !(asnTag & CONSTRUCTED)) - BERDecodeError(); // cannot be primitive and have indefinite length -} - -BERGeneralDecoder::~BERGeneralDecoder() -{ - try // avoid throwing in constructor - { - if (!m_finished) - MessageEnd(); - } - catch (...) - { - } -} - -bool BERGeneralDecoder::EndReached() const -{ - if (m_definiteLength) - return m_length == 0; - else - { // check end-of-content octets - word16 i; - return (m_inQueue.PeekWord16(i)==2 && i==0); - } -} - -byte BERGeneralDecoder::PeekByte() const -{ - byte b; - if (!Peek(b)) - BERDecodeError(); - return b; -} - -void BERGeneralDecoder::CheckByte(byte check) -{ - byte b; - if (!Get(b) || b != check) - BERDecodeError(); -} - -void BERGeneralDecoder::MessageEnd() -{ - m_finished = true; - if (m_definiteLength) - { - if (m_length != 0) - BERDecodeError(); - } - else - { // remove end-of-content octets - word16 i; - if (m_inQueue.GetWord16(i) != 2 || i != 0) - BERDecodeError(); - } -} - -size_t BERGeneralDecoder::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) -{ - if (m_definiteLength && transferBytes > m_length) - transferBytes = m_length; - size_t blockedBytes = m_inQueue.TransferTo2(target, transferBytes, channel, blocking); - ReduceLength(transferBytes); - return blockedBytes; -} - -size_t BERGeneralDecoder::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const -{ - if (m_definiteLength) - end = STDMIN(m_length, end); - return m_inQueue.CopyRangeTo2(target, begin, end, channel, blocking); -} - -lword BERGeneralDecoder::ReduceLength(lword delta) -{ - if (m_definiteLength) - { - if (m_length < delta) - BERDecodeError(); - m_length -= delta; - } - return delta; -} - -DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag) - : m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag) -{ -} - -DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag) - : m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag) -{ -} - -DERGeneralEncoder::~DERGeneralEncoder() -{ - try // avoid throwing in constructor - { - if (!m_finished) - MessageEnd(); - } - catch (...) - { - } -} - -void DERGeneralEncoder::MessageEnd() -{ - m_finished = true; - lword length = CurrentSize(); - m_outQueue.Put(m_asnTag); - DERLengthEncode(m_outQueue, length); - TransferTo(m_outQueue); -} - -// ************************************************************* - -void X509PublicKey::BERDecode(BufferedTransformation &bt) -{ - BERSequenceDecoder subjectPublicKeyInfo(bt); - BERSequenceDecoder algorithm(subjectPublicKeyInfo); - GetAlgorithmID().BERDecodeAndCheck(algorithm); - bool parametersPresent = algorithm.EndReached() ? false : BERDecodeAlgorithmParameters(algorithm); - algorithm.MessageEnd(); - - BERGeneralDecoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING); - subjectPublicKey.CheckByte(0); // unused bits - BERDecodePublicKey(subjectPublicKey, parametersPresent, (size_t)subjectPublicKey.RemainingLength()); - subjectPublicKey.MessageEnd(); - subjectPublicKeyInfo.MessageEnd(); -} - -void X509PublicKey::DEREncode(BufferedTransformation &bt) const -{ - DERSequenceEncoder subjectPublicKeyInfo(bt); - - DERSequenceEncoder algorithm(subjectPublicKeyInfo); - GetAlgorithmID().DEREncode(algorithm); - DEREncodeAlgorithmParameters(algorithm); - algorithm.MessageEnd(); - - DERGeneralEncoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING); - subjectPublicKey.Put(0); // unused bits - DEREncodePublicKey(subjectPublicKey); - subjectPublicKey.MessageEnd(); - - subjectPublicKeyInfo.MessageEnd(); -} - -void PKCS8PrivateKey::BERDecode(BufferedTransformation &bt) -{ - BERSequenceDecoder privateKeyInfo(bt); - word32 version; - BERDecodeUnsigned<word32>(privateKeyInfo, version, INTEGER, 0, 0); // check version - - BERSequenceDecoder algorithm(privateKeyInfo); - GetAlgorithmID().BERDecodeAndCheck(algorithm); - bool parametersPresent = algorithm.EndReached() ? false : BERDecodeAlgorithmParameters(algorithm); - algorithm.MessageEnd(); - - BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING); - BERDecodePrivateKey(octetString, parametersPresent, (size_t)privateKeyInfo.RemainingLength()); - octetString.MessageEnd(); - - if (!privateKeyInfo.EndReached()) - BERDecodeOptionalAttributes(privateKeyInfo); - privateKeyInfo.MessageEnd(); -} - -void PKCS8PrivateKey::DEREncode(BufferedTransformation &bt) const -{ - DERSequenceEncoder privateKeyInfo(bt); - DEREncodeUnsigned<word32>(privateKeyInfo, 0); // version - - DERSequenceEncoder algorithm(privateKeyInfo); - GetAlgorithmID().DEREncode(algorithm); - DEREncodeAlgorithmParameters(algorithm); - algorithm.MessageEnd(); - - DERGeneralEncoder octetString(privateKeyInfo, OCTET_STRING); - DEREncodePrivateKey(octetString); - octetString.MessageEnd(); - - DEREncodeOptionalAttributes(privateKeyInfo); - privateKeyInfo.MessageEnd(); -} - -void PKCS8PrivateKey::BERDecodeOptionalAttributes(BufferedTransformation &bt) -{ - DERReencode(bt, m_optionalAttributes); -} - -void PKCS8PrivateKey::DEREncodeOptionalAttributes(BufferedTransformation &bt) const -{ - m_optionalAttributes.CopyTo(bt); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/asn.h b/lib/cryptopp/asn.h deleted file mode 100644 index c35126bc3..000000000 --- a/lib/cryptopp/asn.h +++ /dev/null @@ -1,369 +0,0 @@ -#ifndef CRYPTOPP_ASN_H -#define CRYPTOPP_ASN_H - -#include "filters.h" -#include "queue.h" -#include <vector> - -NAMESPACE_BEGIN(CryptoPP) - -// these tags and flags are not complete -enum ASNTag -{ - BOOLEAN = 0x01, - INTEGER = 0x02, - BIT_STRING = 0x03, - OCTET_STRING = 0x04, - TAG_NULL = 0x05, - OBJECT_IDENTIFIER = 0x06, - OBJECT_DESCRIPTOR = 0x07, - EXTERNAL = 0x08, - REAL = 0x09, - ENUMERATED = 0x0a, - UTF8_STRING = 0x0c, - SEQUENCE = 0x10, - SET = 0x11, - NUMERIC_STRING = 0x12, - PRINTABLE_STRING = 0x13, - T61_STRING = 0x14, - VIDEOTEXT_STRING = 0x15, - IA5_STRING = 0x16, - UTC_TIME = 0x17, - GENERALIZED_TIME = 0x18, - GRAPHIC_STRING = 0x19, - VISIBLE_STRING = 0x1a, - GENERAL_STRING = 0x1b -}; - -enum ASNIdFlag -{ - UNIVERSAL = 0x00, -// DATA = 0x01, -// HEADER = 0x02, - CONSTRUCTED = 0x20, - APPLICATION = 0x40, - CONTEXT_SPECIFIC = 0x80, - PRIVATE = 0xc0 -}; - -inline void BERDecodeError() {throw BERDecodeErr();} - -class CRYPTOPP_DLL UnknownOID : public BERDecodeErr -{ -public: - UnknownOID() : BERDecodeErr("BER decode error: unknown object identifier") {} - UnknownOID(const char *err) : BERDecodeErr(err) {} -}; - -// unsigned int DERLengthEncode(unsigned int length, byte *output=0); -CRYPTOPP_DLL size_t CRYPTOPP_API DERLengthEncode(BufferedTransformation &out, lword length); -// returns false if indefinite length -CRYPTOPP_DLL bool CRYPTOPP_API BERLengthDecode(BufferedTransformation &in, size_t &length); - -CRYPTOPP_DLL void CRYPTOPP_API DEREncodeNull(BufferedTransformation &out); -CRYPTOPP_DLL void CRYPTOPP_API BERDecodeNull(BufferedTransformation &in); - -CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeOctetString(BufferedTransformation &out, const byte *str, size_t strLen); -CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeOctetString(BufferedTransformation &out, const SecByteBlock &str); -CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeOctetString(BufferedTransformation &in, SecByteBlock &str); -CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeOctetString(BufferedTransformation &in, BufferedTransformation &str); - -// for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING -CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeTextString(BufferedTransformation &out, const std::string &str, byte asnTag); -CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeTextString(BufferedTransformation &in, std::string &str, byte asnTag); - -CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeBitString(BufferedTransformation &out, const byte *str, size_t strLen, unsigned int unusedBits=0); -CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeBitString(BufferedTransformation &in, SecByteBlock &str, unsigned int &unusedBits); - -// BER decode from source and DER reencode into dest -CRYPTOPP_DLL void CRYPTOPP_API DERReencode(BufferedTransformation &source, BufferedTransformation &dest); - -//! Object Identifier -class CRYPTOPP_DLL OID -{ -public: - OID() {} - OID(word32 v) : m_values(1, v) {} - OID(BufferedTransformation &bt) {BERDecode(bt);} - - inline OID & operator+=(word32 rhs) {m_values.push_back(rhs); return *this;} - - void DEREncode(BufferedTransformation &bt) const; - void BERDecode(BufferedTransformation &bt); - - // throw BERDecodeErr() if decoded value doesn't equal this OID - void BERDecodeAndCheck(BufferedTransformation &bt) const; - - std::vector<word32> m_values; - -private: - static void EncodeValue(BufferedTransformation &bt, word32 v); - static size_t DecodeValue(BufferedTransformation &bt, word32 &v); -}; - -class EncodedObjectFilter : public Filter -{ -public: - enum Flag {PUT_OBJECTS=1, PUT_MESSANGE_END_AFTER_EACH_OBJECT=2, PUT_MESSANGE_END_AFTER_ALL_OBJECTS=4, PUT_MESSANGE_SERIES_END_AFTER_ALL_OBJECTS=8}; - EncodedObjectFilter(BufferedTransformation *attachment = NULL, unsigned int nObjects = 1, word32 flags = 0); - - void Put(const byte *inString, size_t length); - - unsigned int GetNumberOfCompletedObjects() const {return m_nCurrentObject;} - unsigned long GetPositionOfObject(unsigned int i) const {return m_positions[i];} - -private: - BufferedTransformation & CurrentTarget(); - - word32 m_flags; - unsigned int m_nObjects, m_nCurrentObject, m_level; - std::vector<unsigned int> m_positions; - ByteQueue m_queue; - enum State {IDENTIFIER, LENGTH, BODY, TAIL, ALL_DONE} m_state; - byte m_id; - lword m_lengthRemaining; -}; - -//! BER General Decoder -class CRYPTOPP_DLL BERGeneralDecoder : public Store -{ -public: - explicit BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag); - explicit BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag); - ~BERGeneralDecoder(); - - bool IsDefiniteLength() const {return m_definiteLength;} - lword RemainingLength() const {assert(m_definiteLength); return m_length;} - bool EndReached() const; - byte PeekByte() const; - void CheckByte(byte b); - - size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); - size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; - - // call this to denote end of sequence - void MessageEnd(); - -protected: - BufferedTransformation &m_inQueue; - bool m_finished, m_definiteLength; - lword m_length; - -private: - void Init(byte asnTag); - void StoreInitialize(const NameValuePairs ¶meters) {assert(false);} - lword ReduceLength(lword delta); -}; - -//! DER General Encoder -class CRYPTOPP_DLL DERGeneralEncoder : public ByteQueue -{ -public: - explicit DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED); - explicit DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED); - ~DERGeneralEncoder(); - - // call this to denote end of sequence - void MessageEnd(); - -private: - BufferedTransformation &m_outQueue; - bool m_finished; - - byte m_asnTag; -}; - -//! BER Sequence Decoder -class CRYPTOPP_DLL BERSequenceDecoder : public BERGeneralDecoder -{ -public: - explicit BERSequenceDecoder(BufferedTransformation &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED) - : BERGeneralDecoder(inQueue, asnTag) {} - explicit BERSequenceDecoder(BERSequenceDecoder &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED) - : BERGeneralDecoder(inQueue, asnTag) {} -}; - -//! DER Sequence Encoder -class CRYPTOPP_DLL DERSequenceEncoder : public DERGeneralEncoder -{ -public: - explicit DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED) - : DERGeneralEncoder(outQueue, asnTag) {} - explicit DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED) - : DERGeneralEncoder(outQueue, asnTag) {} -}; - -//! BER Set Decoder -class CRYPTOPP_DLL BERSetDecoder : public BERGeneralDecoder -{ -public: - explicit BERSetDecoder(BufferedTransformation &inQueue, byte asnTag = SET | CONSTRUCTED) - : BERGeneralDecoder(inQueue, asnTag) {} - explicit BERSetDecoder(BERSetDecoder &inQueue, byte asnTag = SET | CONSTRUCTED) - : BERGeneralDecoder(inQueue, asnTag) {} -}; - -//! DER Set Encoder -class CRYPTOPP_DLL DERSetEncoder : public DERGeneralEncoder -{ -public: - explicit DERSetEncoder(BufferedTransformation &outQueue, byte asnTag = SET | CONSTRUCTED) - : DERGeneralEncoder(outQueue, asnTag) {} - explicit DERSetEncoder(DERSetEncoder &outQueue, byte asnTag = SET | CONSTRUCTED) - : DERGeneralEncoder(outQueue, asnTag) {} -}; - -template <class T> -class ASNOptional : public member_ptr<T> -{ -public: - void BERDecode(BERSequenceDecoder &seqDecoder, byte tag, byte mask = ~CONSTRUCTED) - { - byte b; - if (seqDecoder.Peek(b) && (b & mask) == tag) - reset(new T(seqDecoder)); - } - void DEREncode(BufferedTransformation &out) - { - if (this->get() != NULL) - this->get()->DEREncode(out); - } -}; - -//! _ -template <class BASE> -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1CryptoMaterial : public ASN1Object, public BASE -{ -public: - void Save(BufferedTransformation &bt) const - {BEREncode(bt);} - void Load(BufferedTransformation &bt) - {BERDecode(bt);} -}; - -//! encodes/decodes subjectPublicKeyInfo -class CRYPTOPP_DLL X509PublicKey : public ASN1CryptoMaterial<PublicKey> -{ -public: - void BERDecode(BufferedTransformation &bt); - void DEREncode(BufferedTransformation &bt) const; - - virtual OID GetAlgorithmID() const =0; - virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt) - {BERDecodeNull(bt); return false;} - virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const - {DEREncodeNull(bt); return false;} // see RFC 2459, section 7.3.1 - - //! decode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header - virtual void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size) =0; - //! encode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header - virtual void DEREncodePublicKey(BufferedTransformation &bt) const =0; -}; - -//! encodes/decodes privateKeyInfo -class CRYPTOPP_DLL PKCS8PrivateKey : public ASN1CryptoMaterial<PrivateKey> -{ -public: - void BERDecode(BufferedTransformation &bt); - void DEREncode(BufferedTransformation &bt) const; - - virtual OID GetAlgorithmID() const =0; - virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt) - {BERDecodeNull(bt); return false;} - virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const - {DEREncodeNull(bt); return false;} // see RFC 2459, section 7.3.1 - - //! decode privateKey part of privateKeyInfo, without the OCTET STRING header - virtual void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size) =0; - //! encode privateKey part of privateKeyInfo, without the OCTET STRING header - virtual void DEREncodePrivateKey(BufferedTransformation &bt) const =0; - - //! decode optional attributes including context-specific tag - /*! /note default implementation stores attributes to be output in DEREncodeOptionalAttributes */ - virtual void BERDecodeOptionalAttributes(BufferedTransformation &bt); - //! encode optional attributes including context-specific tag - virtual void DEREncodeOptionalAttributes(BufferedTransformation &bt) const; - -protected: - ByteQueue m_optionalAttributes; -}; - -// ******************************************************** - -//! DER Encode Unsigned -/*! for INTEGER, BOOLEAN, and ENUM */ -template <class T> -size_t DEREncodeUnsigned(BufferedTransformation &out, T w, byte asnTag = INTEGER) -{ - byte buf[sizeof(w)+1]; - unsigned int bc; - if (asnTag == BOOLEAN) - { - buf[sizeof(w)] = w ? 0xff : 0; - bc = 1; - } - else - { - buf[0] = 0; - for (unsigned int i=0; i<sizeof(w); i++) - buf[i+1] = byte(w >> (sizeof(w)-1-i)*8); - bc = sizeof(w); - while (bc > 1 && buf[sizeof(w)+1-bc] == 0) - --bc; - if (buf[sizeof(w)+1-bc] & 0x80) - ++bc; - } - out.Put(asnTag); - size_t lengthBytes = DERLengthEncode(out, bc); - out.Put(buf+sizeof(w)+1-bc, bc); - return 1+lengthBytes+bc; -} - -//! BER Decode Unsigned -// VC60 workaround: std::numeric_limits<T>::max conflicts with MFC max macro -// CW41 workaround: std::numeric_limits<T>::max causes a template error -template <class T> -void BERDecodeUnsigned(BufferedTransformation &in, T &w, byte asnTag = INTEGER, - T minValue = 0, T maxValue = 0xffffffff) -{ - byte b; - if (!in.Get(b) || b != asnTag) - BERDecodeError(); - - size_t bc; - BERLengthDecode(in, bc); - - SecByteBlock buf(bc); - - if (bc != in.Get(buf, bc)) - BERDecodeError(); - - const byte *ptr = buf; - while (bc > sizeof(w) && *ptr == 0) - { - bc--; - ptr++; - } - if (bc > sizeof(w)) - BERDecodeError(); - - w = 0; - for (unsigned int i=0; i<bc; i++) - w = (w << 8) | ptr[i]; - - if (w < minValue || w > maxValue) - BERDecodeError(); -} - -inline bool operator==(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs) - {return lhs.m_values == rhs.m_values;} -inline bool operator!=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs) - {return lhs.m_values != rhs.m_values;} -inline bool operator<(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs) - {return std::lexicographical_compare(lhs.m_values.begin(), lhs.m_values.end(), rhs.m_values.begin(), rhs.m_values.end());} -inline ::CryptoPP::OID operator+(const ::CryptoPP::OID &lhs, unsigned long rhs) - {return ::CryptoPP::OID(lhs)+=rhs;} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/authenc.cpp b/lib/cryptopp/authenc.cpp deleted file mode 100644 index f93662efb..000000000 --- a/lib/cryptopp/authenc.cpp +++ /dev/null @@ -1,180 +0,0 @@ -// authenc.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "authenc.h" - -NAMESPACE_BEGIN(CryptoPP) - -void AuthenticatedSymmetricCipherBase::AuthenticateData(const byte *input, size_t len) -{ - unsigned int blockSize = AuthenticationBlockSize(); - unsigned int &num = m_bufferedDataLength; - byte* data = m_buffer.begin(); - - if (num != 0) // process left over data - { - if (num+len >= blockSize) - { - memcpy(data+num, input, blockSize-num); - AuthenticateBlocks(data, blockSize); - input += (blockSize-num); - len -= (blockSize-num); - num = 0; - // drop through and do the rest - } - else - { - memcpy(data+num, input, len); - num += (unsigned int)len; - return; - } - } - - // now process the input data in blocks of blockSize bytes and save the leftovers to m_data - if (len >= blockSize) - { - size_t leftOver = AuthenticateBlocks(input, len); - input += (len - leftOver); - len = leftOver; - } - - memcpy(data, input, len); - num = (unsigned int)len; -} - -void AuthenticatedSymmetricCipherBase::SetKey(const byte *userKey, size_t keylength, const NameValuePairs ¶ms) -{ - m_bufferedDataLength = 0; - m_state = State_Start; - - SetKeyWithoutResync(userKey, keylength, params); - m_state = State_KeySet; - - size_t length; - const byte *iv = GetIVAndThrowIfInvalid(params, length); - if (iv) - Resynchronize(iv, (int)length); -} - -void AuthenticatedSymmetricCipherBase::Resynchronize(const byte *iv, int length) -{ - if (m_state < State_KeySet) - throw BadState(AlgorithmName(), "Resynchronize", "key is set"); - - m_bufferedDataLength = 0; - m_totalHeaderLength = m_totalMessageLength = m_totalFooterLength = 0; - m_state = State_KeySet; - - Resync(iv, this->ThrowIfInvalidIVLength(length)); - m_state = State_IVSet; -} - -void AuthenticatedSymmetricCipherBase::Update(const byte *input, size_t length) -{ - if (length == 0) - return; - - switch (m_state) - { - case State_Start: - case State_KeySet: - throw BadState(AlgorithmName(), "Update", "setting key and IV"); - case State_IVSet: - AuthenticateData(input, length); - m_totalHeaderLength += length; - break; - case State_AuthUntransformed: - case State_AuthTransformed: - AuthenticateLastConfidentialBlock(); - m_bufferedDataLength = 0; - m_state = State_AuthFooter; - // fall through - case State_AuthFooter: - AuthenticateData(input, length); - m_totalFooterLength += length; - break; - default: - assert(false); - } -} - -void AuthenticatedSymmetricCipherBase::ProcessData(byte *outString, const byte *inString, size_t length) -{ - m_totalMessageLength += length; - if (m_state >= State_IVSet && m_totalMessageLength > MaxMessageLength()) - throw InvalidArgument(AlgorithmName() + ": message length exceeds maximum"); - -reswitch: - switch (m_state) - { - case State_Start: - case State_KeySet: - throw BadState(AlgorithmName(), "ProcessData", "setting key and IV"); - case State_AuthFooter: - throw BadState(AlgorithmName(), "ProcessData was called after footer input has started"); - case State_IVSet: - AuthenticateLastHeaderBlock(); - m_bufferedDataLength = 0; - m_state = AuthenticationIsOnPlaintext()==IsForwardTransformation() ? State_AuthUntransformed : State_AuthTransformed; - goto reswitch; - case State_AuthUntransformed: - AuthenticateData(inString, length); - AccessSymmetricCipher().ProcessData(outString, inString, length); - break; - case State_AuthTransformed: - AccessSymmetricCipher().ProcessData(outString, inString, length); - AuthenticateData(outString, length); - break; - default: - assert(false); - } -} - -void AuthenticatedSymmetricCipherBase::TruncatedFinal(byte *mac, size_t macSize) -{ - if (m_totalHeaderLength > MaxHeaderLength()) - throw InvalidArgument(AlgorithmName() + ": header length of " + IntToString(m_totalHeaderLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength())); - - if (m_totalFooterLength > MaxFooterLength()) - { - if (MaxFooterLength() == 0) - throw InvalidArgument(AlgorithmName() + ": additional authenticated data (AAD) cannot be input after data to be encrypted or decrypted"); - else - throw InvalidArgument(AlgorithmName() + ": footer length of " + IntToString(m_totalFooterLength) + " exceeds the maximum of " + IntToString(MaxFooterLength())); - } - - switch (m_state) - { - case State_Start: - case State_KeySet: - throw BadState(AlgorithmName(), "TruncatedFinal", "setting key and IV"); - - case State_IVSet: - AuthenticateLastHeaderBlock(); - m_bufferedDataLength = 0; - // fall through - - case State_AuthUntransformed: - case State_AuthTransformed: - AuthenticateLastConfidentialBlock(); - m_bufferedDataLength = 0; - // fall through - - case State_AuthFooter: - AuthenticateLastFooterBlock(mac, macSize); - m_bufferedDataLength = 0; - break; - - default: - assert(false); - } - - m_state = State_KeySet; -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/authenc.h b/lib/cryptopp/authenc.h deleted file mode 100644 index 5bb2a51c8..000000000 --- a/lib/cryptopp/authenc.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef CRYPTOPP_AUTHENC_H -#define CRYPTOPP_AUTHENC_H - -#include "cryptlib.h" -#include "secblock.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! . -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedSymmetricCipherBase : public AuthenticatedSymmetricCipher -{ -public: - AuthenticatedSymmetricCipherBase() : m_state(State_Start) {} - - bool IsRandomAccess() const {return false;} - bool IsSelfInverting() const {return true;} - void UncheckedSetKey(const byte *,unsigned int,const CryptoPP::NameValuePairs &) {assert(false);} - - void SetKey(const byte *userKey, size_t keylength, const NameValuePairs ¶ms); - void Restart() {if (m_state > State_KeySet) m_state = State_KeySet;} - void Resynchronize(const byte *iv, int length=-1); - void Update(const byte *input, size_t length); - void ProcessData(byte *outString, const byte *inString, size_t length); - void TruncatedFinal(byte *mac, size_t macSize); - -protected: - void AuthenticateData(const byte *data, size_t len); - const SymmetricCipher & GetSymmetricCipher() const {return const_cast<AuthenticatedSymmetricCipherBase *>(this)->AccessSymmetricCipher();}; - - virtual SymmetricCipher & AccessSymmetricCipher() =0; - virtual bool AuthenticationIsOnPlaintext() const =0; - virtual unsigned int AuthenticationBlockSize() const =0; - virtual void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms) =0; - virtual void Resync(const byte *iv, size_t len) =0; - virtual size_t AuthenticateBlocks(const byte *data, size_t len) =0; - virtual void AuthenticateLastHeaderBlock() =0; - virtual void AuthenticateLastConfidentialBlock() {} - virtual void AuthenticateLastFooterBlock(byte *mac, size_t macSize) =0; - - enum State {State_Start, State_KeySet, State_IVSet, State_AuthUntransformed, State_AuthTransformed, State_AuthFooter}; - State m_state; - unsigned int m_bufferedDataLength; - lword m_totalHeaderLength, m_totalMessageLength, m_totalFooterLength; - AlignedSecByteBlock m_buffer; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/base32.cpp b/lib/cryptopp/base32.cpp deleted file mode 100644 index 0568f0729..000000000 --- a/lib/cryptopp/base32.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// base32.cpp - written and placed in the public domain by Frank Palazzolo, based on hex.cpp by Wei Dai - -#include "pch.h" -#include "base32.h" - -NAMESPACE_BEGIN(CryptoPP) - -static const byte s_vecUpper[] = "ABCDEFGHIJKMNPQRSTUVWXYZ23456789"; -static const byte s_vecLower[] = "abcdefghijkmnpqrstuvwxyz23456789"; - -void Base32Encoder::IsolatedInitialize(const NameValuePairs ¶meters) -{ - bool uppercase = parameters.GetValueWithDefault(Name::Uppercase(), true); - m_filter->Initialize(CombinedNameValuePairs( - parameters, - MakeParameters(Name::EncodingLookupArray(), uppercase ? &s_vecUpper[0] : &s_vecLower[0], false)(Name::Log2Base(), 5, true))); -} - -void Base32Decoder::IsolatedInitialize(const NameValuePairs ¶meters) -{ - BaseN_Decoder::Initialize(CombinedNameValuePairs( - parameters, - MakeParameters(Name::DecodingLookupArray(), GetDefaultDecodingLookupArray(), false)(Name::Log2Base(), 5, true))); -} - -const int *Base32Decoder::GetDefaultDecodingLookupArray() -{ - static volatile bool s_initialized = false; - static int s_array[256]; - - if (!s_initialized) - { - InitializeDecodingLookupArray(s_array, s_vecUpper, 32, true); - s_initialized = true; - } - return s_array; -} - -NAMESPACE_END diff --git a/lib/cryptopp/base32.h b/lib/cryptopp/base32.h deleted file mode 100644 index cb1e1af8d..000000000 --- a/lib/cryptopp/base32.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef CRYPTOPP_BASE32_H -#define CRYPTOPP_BASE32_H - -#include "basecode.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! Converts given data to base 32, the default code is based on draft-ietf-idn-dude-02.txt -/*! To specify alternative code, call Initialize() with EncodingLookupArray parameter. */ -class Base32Encoder : public SimpleProxyFilter -{ -public: - Base32Encoder(BufferedTransformation *attachment = NULL, bool uppercase = true, int outputGroupSize = 0, const std::string &separator = ":", const std::string &terminator = "") - : SimpleProxyFilter(new BaseN_Encoder(new Grouper), attachment) - { - IsolatedInitialize(MakeParameters(Name::Uppercase(), uppercase)(Name::GroupSize(), outputGroupSize)(Name::Separator(), ConstByteArrayParameter(separator))); - } - - void IsolatedInitialize(const NameValuePairs ¶meters); -}; - -//! Decode base 32 data back to bytes, the default code is based on draft-ietf-idn-dude-02.txt -/*! To specify alternative code, call Initialize() with DecodingLookupArray parameter. */ -class Base32Decoder : public BaseN_Decoder -{ -public: - Base32Decoder(BufferedTransformation *attachment = NULL) - : BaseN_Decoder(GetDefaultDecodingLookupArray(), 5, attachment) {} - - void IsolatedInitialize(const NameValuePairs ¶meters); - -private: - static const int * CRYPTOPP_API GetDefaultDecodingLookupArray(); -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/base64.cpp b/lib/cryptopp/base64.cpp deleted file mode 100644 index 7571f2b8c..000000000 --- a/lib/cryptopp/base64.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// base64.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "base64.h" - -NAMESPACE_BEGIN(CryptoPP) - -static const byte s_vec[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -static const byte s_padding = '='; - -void Base64Encoder::IsolatedInitialize(const NameValuePairs ¶meters) -{ - bool insertLineBreaks = parameters.GetValueWithDefault(Name::InsertLineBreaks(), true); - int maxLineLength = parameters.GetIntValueWithDefault(Name::MaxLineLength(), 72); - - const char *lineBreak = insertLineBreaks ? "\n" : ""; - - m_filter->Initialize(CombinedNameValuePairs( - parameters, - MakeParameters(Name::EncodingLookupArray(), &s_vec[0], false) - (Name::PaddingByte(), s_padding) - (Name::GroupSize(), insertLineBreaks ? maxLineLength : 0) - (Name::Separator(), ConstByteArrayParameter(lineBreak)) - (Name::Terminator(), ConstByteArrayParameter(lineBreak)) - (Name::Log2Base(), 6, true))); -} - -const int *Base64Decoder::GetDecodingLookupArray() -{ - static volatile bool s_initialized = false; - static int s_array[256]; - - if (!s_initialized) - { - InitializeDecodingLookupArray(s_array, s_vec, 64, false); - s_initialized = true; - } - return s_array; -} - -NAMESPACE_END diff --git a/lib/cryptopp/base64.h b/lib/cryptopp/base64.h deleted file mode 100644 index 5a9e184b2..000000000 --- a/lib/cryptopp/base64.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef CRYPTOPP_BASE64_H -#define CRYPTOPP_BASE64_H - -#include "basecode.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! Base64 Encoder Class -class Base64Encoder : public SimpleProxyFilter -{ -public: - Base64Encoder(BufferedTransformation *attachment = NULL, bool insertLineBreaks = true, int maxLineLength = 72) - : SimpleProxyFilter(new BaseN_Encoder(new Grouper), attachment) - { - IsolatedInitialize(MakeParameters(Name::InsertLineBreaks(), insertLineBreaks)(Name::MaxLineLength(), maxLineLength)); - } - - void IsolatedInitialize(const NameValuePairs ¶meters); -}; - -//! Base64 Decoder Class -class Base64Decoder : public BaseN_Decoder -{ -public: - Base64Decoder(BufferedTransformation *attachment = NULL) - : BaseN_Decoder(GetDecodingLookupArray(), 6, attachment) {} - - void IsolatedInitialize(const NameValuePairs ¶meters) {} - -private: - static const int * CRYPTOPP_API GetDecodingLookupArray(); -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/basecode.cpp b/lib/cryptopp/basecode.cpp deleted file mode 100644 index 0c98b2271..000000000 --- a/lib/cryptopp/basecode.cpp +++ /dev/null @@ -1,238 +0,0 @@ -// basecode.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "basecode.h" -#include "fltrimpl.h" -#include <ctype.h> - -NAMESPACE_BEGIN(CryptoPP) - -void BaseN_Encoder::IsolatedInitialize(const NameValuePairs ¶meters) -{ - parameters.GetRequiredParameter("BaseN_Encoder", Name::EncodingLookupArray(), m_alphabet); - - parameters.GetRequiredIntParameter("BaseN_Encoder", Name::Log2Base(), m_bitsPerChar); - if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8) - throw InvalidArgument("BaseN_Encoder: Log2Base must be between 1 and 7 inclusive"); - - byte padding; - bool pad; - if (parameters.GetValue(Name::PaddingByte(), padding)) - pad = parameters.GetValueWithDefault(Name::Pad(), true); - else - pad = false; - m_padding = pad ? padding : -1; - - m_bytePos = m_bitPos = 0; - - int i = 8; - while (i%m_bitsPerChar != 0) - i += 8; - m_outputBlockSize = i/m_bitsPerChar; - - m_outBuf.New(m_outputBlockSize); -} - -size_t BaseN_Encoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) -{ - FILTER_BEGIN; - while (m_inputPosition < length) - { - if (m_bytePos == 0) - memset(m_outBuf, 0, m_outputBlockSize); - - { - unsigned int b = begin[m_inputPosition++], bitsLeftInSource = 8; - while (true) - { - assert(m_bitPos < m_bitsPerChar); - unsigned int bitsLeftInTarget = m_bitsPerChar-m_bitPos; - m_outBuf[m_bytePos] |= b >> (8-bitsLeftInTarget); - if (bitsLeftInSource >= bitsLeftInTarget) - { - m_bitPos = 0; - ++m_bytePos; - bitsLeftInSource -= bitsLeftInTarget; - if (bitsLeftInSource == 0) - break; - b <<= bitsLeftInTarget; - b &= 0xff; - } - else - { - m_bitPos += bitsLeftInSource; - break; - } - } - } - - assert(m_bytePos <= m_outputBlockSize); - if (m_bytePos == m_outputBlockSize) - { - int i; - for (i=0; i<m_bytePos; i++) - { - assert(m_outBuf[i] < (1 << m_bitsPerChar)); - m_outBuf[i] = m_alphabet[m_outBuf[i]]; - } - FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0); - - m_bytePos = m_bitPos = 0; - } - } - if (messageEnd) - { - if (m_bitPos > 0) - ++m_bytePos; - - int i; - for (i=0; i<m_bytePos; i++) - m_outBuf[i] = m_alphabet[m_outBuf[i]]; - - if (m_padding != -1 && m_bytePos > 0) - { - memset(m_outBuf+m_bytePos, m_padding, m_outputBlockSize-m_bytePos); - m_bytePos = m_outputBlockSize; - } - FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd); - m_bytePos = m_bitPos = 0; - } - FILTER_END_NO_MESSAGE_END; -} - -void BaseN_Decoder::IsolatedInitialize(const NameValuePairs ¶meters) -{ - parameters.GetRequiredParameter("BaseN_Decoder", Name::DecodingLookupArray(), m_lookup); - - parameters.GetRequiredIntParameter("BaseN_Decoder", Name::Log2Base(), m_bitsPerChar); - if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8) - throw InvalidArgument("BaseN_Decoder: Log2Base must be between 1 and 7 inclusive"); - - m_bytePos = m_bitPos = 0; - - int i = m_bitsPerChar; - while (i%8 != 0) - i += m_bitsPerChar; - m_outputBlockSize = i/8; - - m_outBuf.New(m_outputBlockSize); -} - -size_t BaseN_Decoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) -{ - FILTER_BEGIN; - while (m_inputPosition < length) - { - unsigned int value; - value = m_lookup[begin[m_inputPosition++]]; - if (value >= 256) - continue; - - if (m_bytePos == 0 && m_bitPos == 0) - memset(m_outBuf, 0, m_outputBlockSize); - - { - int newBitPos = m_bitPos + m_bitsPerChar; - if (newBitPos <= 8) - m_outBuf[m_bytePos] |= value << (8-newBitPos); - else - { - m_outBuf[m_bytePos] |= value >> (newBitPos-8); - m_outBuf[m_bytePos+1] |= value << (16-newBitPos); - } - - m_bitPos = newBitPos; - while (m_bitPos >= 8) - { - m_bitPos -= 8; - ++m_bytePos; - } - } - - if (m_bytePos == m_outputBlockSize) - { - FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0); - m_bytePos = m_bitPos = 0; - } - } - if (messageEnd) - { - FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd); - m_bytePos = m_bitPos = 0; - } - FILTER_END_NO_MESSAGE_END; -} - -void BaseN_Decoder::InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive) -{ - std::fill(lookup, lookup+256, -1); - - for (unsigned int i=0; i<base; i++) - { - if (caseInsensitive && isalpha(alphabet[i])) - { - assert(lookup[toupper(alphabet[i])] == -1); - lookup[toupper(alphabet[i])] = i; - assert(lookup[tolower(alphabet[i])] == -1); - lookup[tolower(alphabet[i])] = i; - } - else - { - assert(lookup[alphabet[i]] == -1); - lookup[alphabet[i]] = i; - } - } -} - -void Grouper::IsolatedInitialize(const NameValuePairs ¶meters) -{ - m_groupSize = parameters.GetIntValueWithDefault(Name::GroupSize(), 0); - ConstByteArrayParameter separator, terminator; - if (m_groupSize) - parameters.GetRequiredParameter("Grouper", Name::Separator(), separator); - else - parameters.GetValue(Name::Separator(), separator); - parameters.GetValue(Name::Terminator(), terminator); - - m_separator.Assign(separator.begin(), separator.size()); - m_terminator.Assign(terminator.begin(), terminator.size()); - m_counter = 0; -} - -size_t Grouper::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) -{ - FILTER_BEGIN; - if (m_groupSize) - { - while (m_inputPosition < length) - { - if (m_counter == m_groupSize) - { - FILTER_OUTPUT(1, m_separator, m_separator.size(), 0); - m_counter = 0; - } - - size_t len; - FILTER_OUTPUT2(2, len = STDMIN(length-m_inputPosition, m_groupSize-m_counter), - begin+m_inputPosition, len, 0); - m_inputPosition += len; - m_counter += len; - } - } - else - FILTER_OUTPUT(3, begin, length, 0); - - if (messageEnd) - { - FILTER_OUTPUT(4, m_terminator, m_terminator.size(), messageEnd); - m_counter = 0; - } - FILTER_END_NO_MESSAGE_END -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/basecode.h b/lib/cryptopp/basecode.h deleted file mode 100644 index cc44c4342..000000000 --- a/lib/cryptopp/basecode.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef CRYPTOPP_BASECODE_H -#define CRYPTOPP_BASECODE_H - -#include "filters.h" -#include "algparam.h" -#include "argnames.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! base n encoder, where n is a power of 2 -class CRYPTOPP_DLL BaseN_Encoder : public Unflushable<Filter> -{ -public: - BaseN_Encoder(BufferedTransformation *attachment=NULL) - {Detach(attachment);} - - BaseN_Encoder(const byte *alphabet, int log2base, BufferedTransformation *attachment=NULL, int padding=-1) - { - Detach(attachment); - IsolatedInitialize(MakeParameters(Name::EncodingLookupArray(), alphabet) - (Name::Log2Base(), log2base) - (Name::Pad(), padding != -1) - (Name::PaddingByte(), byte(padding))); - } - - void IsolatedInitialize(const NameValuePairs ¶meters); - size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); - -private: - const byte *m_alphabet; - int m_padding, m_bitsPerChar, m_outputBlockSize; - int m_bytePos, m_bitPos; - SecByteBlock m_outBuf; -}; - -//! base n decoder, where n is a power of 2 -class CRYPTOPP_DLL BaseN_Decoder : public Unflushable<Filter> -{ -public: - BaseN_Decoder(BufferedTransformation *attachment=NULL) - {Detach(attachment);} - - BaseN_Decoder(const int *lookup, int log2base, BufferedTransformation *attachment=NULL) - { - Detach(attachment); - IsolatedInitialize(MakeParameters(Name::DecodingLookupArray(), lookup)(Name::Log2Base(), log2base)); - } - - void IsolatedInitialize(const NameValuePairs ¶meters); - size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); - - static void CRYPTOPP_API InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive); - -private: - const int *m_lookup; - int m_padding, m_bitsPerChar, m_outputBlockSize; - int m_bytePos, m_bitPos; - SecByteBlock m_outBuf; -}; - -//! filter that breaks input stream into groups of fixed size -class CRYPTOPP_DLL Grouper : public Bufferless<Filter> -{ -public: - Grouper(BufferedTransformation *attachment=NULL) - {Detach(attachment);} - - Grouper(int groupSize, const std::string &separator, const std::string &terminator, BufferedTransformation *attachment=NULL) - { - Detach(attachment); - IsolatedInitialize(MakeParameters(Name::GroupSize(), groupSize) - (Name::Separator(), ConstByteArrayParameter(separator)) - (Name::Terminator(), ConstByteArrayParameter(terminator))); - } - - void IsolatedInitialize(const NameValuePairs ¶meters); - size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); - -private: - SecByteBlock m_separator, m_terminator; - size_t m_groupSize, m_counter; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/cbcmac.cpp b/lib/cryptopp/cbcmac.cpp deleted file mode 100644 index 6b0e8858e..000000000 --- a/lib/cryptopp/cbcmac.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "cbcmac.h" - -NAMESPACE_BEGIN(CryptoPP) - -void CBC_MAC_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) -{ - AccessCipher().SetKey(key, length, params); - m_reg.CleanNew(AccessCipher().BlockSize()); - m_counter = 0; -} - -void CBC_MAC_Base::Update(const byte *input, size_t length) -{ - unsigned int blockSize = AccessCipher().BlockSize(); - - while (m_counter && length) - { - m_reg[m_counter++] ^= *input++; - if (m_counter == blockSize) - ProcessBuf(); - length--; - } - - if (length >= blockSize) - { - size_t leftOver = AccessCipher().AdvancedProcessBlocks(m_reg, input, m_reg, length, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput); - input += (length - leftOver); - length = leftOver; - } - - while (length--) - { - m_reg[m_counter++] ^= *input++; - if (m_counter == blockSize) - ProcessBuf(); - } -} - -void CBC_MAC_Base::TruncatedFinal(byte *mac, size_t size) -{ - ThrowIfInvalidTruncatedSize(size); - - if (m_counter) - ProcessBuf(); - - memcpy(mac, m_reg, size); - memset(m_reg, 0, AccessCipher().BlockSize()); -} - -void CBC_MAC_Base::ProcessBuf() -{ - AccessCipher().ProcessBlock(m_reg); - m_counter = 0; -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/cbcmac.h b/lib/cryptopp/cbcmac.h deleted file mode 100644 index 4675dcb3d..000000000 --- a/lib/cryptopp/cbcmac.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef CRYPTOPP_CBCMAC_H -#define CRYPTOPP_CBCMAC_H - -#include "seckey.h" -#include "secblock.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_MAC_Base : public MessageAuthenticationCode -{ -public: - CBC_MAC_Base() {} - - void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); - void Update(const byte *input, size_t length); - void TruncatedFinal(byte *mac, size_t size); - unsigned int DigestSize() const {return const_cast<CBC_MAC_Base*>(this)->AccessCipher().BlockSize();} - -protected: - virtual BlockCipher & AccessCipher() =0; - -private: - void ProcessBuf(); - SecByteBlock m_reg; - unsigned int m_counter; -}; - -//! <a href="http://www.weidai.com/scan-mirror/mac.html#CBC-MAC">CBC-MAC</a> -/*! Compatible with FIPS 113. T should be a class derived from BlockCipherDocumentation. - Secure only for fixed length messages. For variable length messages use CMAC or DMAC. -*/ -template <class T> -class CBC_MAC : public MessageAuthenticationCodeImpl<CBC_MAC_Base, CBC_MAC<T> >, public SameKeyLengthAs<T> -{ -public: - CBC_MAC() {} - CBC_MAC(const byte *key, size_t length=SameKeyLengthAs<T>::DEFAULT_KEYLENGTH) - {this->SetKey(key, length);} - - static std::string StaticAlgorithmName() {return std::string("CBC-MAC(") + T::StaticAlgorithmName() + ")";} - -private: - BlockCipher & AccessCipher() {return m_cipher;} - typename T::Encryption m_cipher; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/ccm.cpp b/lib/cryptopp/ccm.cpp deleted file mode 100644 index 030828ad8..000000000 --- a/lib/cryptopp/ccm.cpp +++ /dev/null @@ -1,140 +0,0 @@ -// ccm.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "ccm.h" - -NAMESPACE_BEGIN(CryptoPP) - -void CCM_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms) -{ - BlockCipher &blockCipher = AccessBlockCipher(); - - blockCipher.SetKey(userKey, keylength, params); - - if (blockCipher.BlockSize() != REQUIRED_BLOCKSIZE) - throw InvalidArgument(AlgorithmName() + ": block size of underlying block cipher is not 16"); - - m_digestSize = params.GetIntValueWithDefault(Name::DigestSize(), DefaultDigestSize()); - if (m_digestSize % 2 > 0 || m_digestSize < 4 || m_digestSize > 16) - throw InvalidArgument(AlgorithmName() + ": DigestSize must be 4, 6, 8, 10, 12, 14, or 16"); - - m_buffer.Grow(2*REQUIRED_BLOCKSIZE); - m_L = 8; -} - -void CCM_Base::Resync(const byte *iv, size_t len) -{ - BlockCipher &cipher = AccessBlockCipher(); - - m_L = REQUIRED_BLOCKSIZE-1-(int)len; - assert(m_L >= 2); - if (m_L > 8) - m_L = 8; - - m_buffer[0] = byte(m_L-1); // flag - memcpy(m_buffer+1, iv, len); - memset(m_buffer+1+len, 0, REQUIRED_BLOCKSIZE-1-len); - - if (m_state >= State_IVSet) - m_ctr.Resynchronize(m_buffer, REQUIRED_BLOCKSIZE); - else - m_ctr.SetCipherWithIV(cipher, m_buffer); - - m_ctr.Seek(REQUIRED_BLOCKSIZE); - m_aadLength = 0; - m_messageLength = 0; -} - -void CCM_Base::UncheckedSpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength) -{ - if (m_state != State_IVSet) - throw BadState(AlgorithmName(), "SpecifyDataLengths", "or after State_IVSet"); - - m_aadLength = headerLength; - m_messageLength = messageLength; - - byte *cbcBuffer = CBC_Buffer(); - const BlockCipher &cipher = GetBlockCipher(); - - cbcBuffer[0] = byte(64*(headerLength>0) + 8*((m_digestSize-2)/2) + (m_L-1)); // flag - PutWord<word64>(true, BIG_ENDIAN_ORDER, cbcBuffer+REQUIRED_BLOCKSIZE-8, m_messageLength); - memcpy(cbcBuffer+1, m_buffer+1, REQUIRED_BLOCKSIZE-1-m_L); - cipher.ProcessBlock(cbcBuffer); - - if (headerLength>0) - { - assert(m_bufferedDataLength == 0); - - if (headerLength < ((1<<16) - (1<<8))) - { - PutWord<word16>(true, BIG_ENDIAN_ORDER, m_buffer, (word16)headerLength); - m_bufferedDataLength = 2; - } - else if (headerLength < (W64LIT(1)<<32)) - { - m_buffer[0] = 0xff; - m_buffer[1] = 0xfe; - PutWord<word32>(false, BIG_ENDIAN_ORDER, m_buffer+2, (word32)headerLength); - m_bufferedDataLength = 6; - } - else - { - m_buffer[0] = 0xff; - m_buffer[1] = 0xff; - PutWord<word64>(false, BIG_ENDIAN_ORDER, m_buffer+2, headerLength); - m_bufferedDataLength = 10; - } - } -} - -size_t CCM_Base::AuthenticateBlocks(const byte *data, size_t len) -{ - byte *cbcBuffer = CBC_Buffer(); - const BlockCipher &cipher = GetBlockCipher(); - return cipher.AdvancedProcessBlocks(cbcBuffer, data, cbcBuffer, len, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput); -} - -void CCM_Base::AuthenticateLastHeaderBlock() -{ - byte *cbcBuffer = CBC_Buffer(); - const BlockCipher &cipher = GetBlockCipher(); - - if (m_aadLength != m_totalHeaderLength) - throw InvalidArgument(AlgorithmName() + ": header length doesn't match that given in SpecifyDataLengths"); - - if (m_bufferedDataLength > 0) - { - xorbuf(cbcBuffer, m_buffer, m_bufferedDataLength); - cipher.ProcessBlock(cbcBuffer); - m_bufferedDataLength = 0; - } -} - -void CCM_Base::AuthenticateLastConfidentialBlock() -{ - byte *cbcBuffer = CBC_Buffer(); - const BlockCipher &cipher = GetBlockCipher(); - - if (m_messageLength != m_totalMessageLength) - throw InvalidArgument(AlgorithmName() + ": message length doesn't match that given in SpecifyDataLengths"); - - if (m_bufferedDataLength > 0) - { - xorbuf(cbcBuffer, m_buffer, m_bufferedDataLength); - cipher.ProcessBlock(cbcBuffer); - m_bufferedDataLength = 0; - } -} - -void CCM_Base::AuthenticateLastFooterBlock(byte *mac, size_t macSize) -{ - m_ctr.Seek(0); - m_ctr.ProcessData(mac, CBC_Buffer(), macSize); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/ccm.h b/lib/cryptopp/ccm.h deleted file mode 100644 index b1e5f00b9..000000000 --- a/lib/cryptopp/ccm.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef CRYPTOPP_CCM_H -#define CRYPTOPP_CCM_H - -#include "authenc.h" -#include "modes.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! . -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CCM_Base : public AuthenticatedSymmetricCipherBase -{ -public: - CCM_Base() - : m_digestSize(0), m_L(0) {} - - // AuthenticatedSymmetricCipher - std::string AlgorithmName() const - {return GetBlockCipher().AlgorithmName() + std::string("/CCM");} - size_t MinKeyLength() const - {return GetBlockCipher().MinKeyLength();} - size_t MaxKeyLength() const - {return GetBlockCipher().MaxKeyLength();} - size_t DefaultKeyLength() const - {return GetBlockCipher().DefaultKeyLength();} - size_t GetValidKeyLength(size_t n) const - {return GetBlockCipher().GetValidKeyLength(n);} - bool IsValidKeyLength(size_t n) const - {return GetBlockCipher().IsValidKeyLength(n);} - unsigned int OptimalDataAlignment() const - {return GetBlockCipher().OptimalDataAlignment();} - IV_Requirement IVRequirement() const - {return UNIQUE_IV;} - unsigned int IVSize() const - {return 8;} - unsigned int MinIVLength() const - {return 7;} - unsigned int MaxIVLength() const - {return 13;} - unsigned int DigestSize() const - {return m_digestSize;} - lword MaxHeaderLength() const - {return W64LIT(0)-1;} - lword MaxMessageLength() const - {return m_L<8 ? (W64LIT(1)<<(8*m_L))-1 : W64LIT(0)-1;} - bool NeedsPrespecifiedDataLengths() const - {return true;} - void UncheckedSpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength); - -protected: - // AuthenticatedSymmetricCipherBase - bool AuthenticationIsOnPlaintext() const - {return true;} - unsigned int AuthenticationBlockSize() const - {return GetBlockCipher().BlockSize();} - void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms); - void Resync(const byte *iv, size_t len); - size_t AuthenticateBlocks(const byte *data, size_t len); - void AuthenticateLastHeaderBlock(); - void AuthenticateLastConfidentialBlock(); - void AuthenticateLastFooterBlock(byte *mac, size_t macSize); - SymmetricCipher & AccessSymmetricCipher() {return m_ctr;} - - virtual BlockCipher & AccessBlockCipher() =0; - virtual int DefaultDigestSize() const =0; - - const BlockCipher & GetBlockCipher() const {return const_cast<CCM_Base *>(this)->AccessBlockCipher();}; - byte *CBC_Buffer() {return m_buffer+REQUIRED_BLOCKSIZE;} - - enum {REQUIRED_BLOCKSIZE = 16}; - int m_digestSize, m_L; - word64 m_messageLength, m_aadLength; - CTR_Mode_ExternalCipher::Encryption m_ctr; -}; - -//! . -template <class T_BlockCipher, int T_DefaultDigestSize, bool T_IsEncryption> -class CCM_Final : public CCM_Base -{ -public: - static std::string StaticAlgorithmName() - {return T_BlockCipher::StaticAlgorithmName() + std::string("/CCM");} - bool IsForwardTransformation() const - {return T_IsEncryption;} - -private: - BlockCipher & AccessBlockCipher() {return m_cipher;} - int DefaultDigestSize() const {return T_DefaultDigestSize;} - typename T_BlockCipher::Encryption m_cipher; -}; - -/// <a href="http://www.cryptolounge.org/wiki/CCM">CCM</a> -template <class T_BlockCipher, int T_DefaultDigestSize = 16> -struct CCM : public AuthenticatedSymmetricCipherDocumentation -{ - typedef CCM_Final<T_BlockCipher, T_DefaultDigestSize, true> Encryption; - typedef CCM_Final<T_BlockCipher, T_DefaultDigestSize, false> Decryption; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/channels.cpp b/lib/cryptopp/channels.cpp deleted file mode 100644 index 7359f54f7..000000000 --- a/lib/cryptopp/channels.cpp +++ /dev/null @@ -1,309 +0,0 @@ -// channels.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "channels.h" - -NAMESPACE_BEGIN(CryptoPP) -USING_NAMESPACE(std) - -#if 0 -void MessageSwitch::AddDefaultRoute(BufferedTransformation &destination, const std::string &channel) -{ - m_defaultRoutes.push_back(Route(&destination, channel)); -} - -void MessageSwitch::AddRoute(unsigned int begin, unsigned int end, BufferedTransformation &destination, const std::string &channel) -{ - RangeRoute route(begin, end, Route(&destination, channel)); - RouteList::iterator it = upper_bound(m_routes.begin(), m_routes.end(), route); - m_routes.insert(it, route); -} - -/* -class MessageRouteIterator -{ -public: - typedef MessageSwitch::RouteList::const_iterator RouteIterator; - typedef MessageSwitch::DefaultRouteList::const_iterator DefaultIterator; - - bool m_useDefault; - RouteIterator m_itRouteCurrent, m_itRouteEnd; - DefaultIterator m_itDefaultCurrent, m_itDefaultEnd; - - MessageRouteIterator(MessageSwitch &ms, const std::string &channel) - : m_channel(channel) - { - pair<MapIterator, MapIterator> range = cs.m_routeMap.equal_range(channel); - if (range.first == range.second) - { - m_useDefault = true; - m_itListCurrent = cs.m_defaultRoutes.begin(); - m_itListEnd = cs.m_defaultRoutes.end(); - } - else - { - m_useDefault = false; - m_itMapCurrent = range.first; - m_itMapEnd = range.second; - } - } - - bool End() const - { - return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd; - } - - void Next() - { - if (m_useDefault) - ++m_itListCurrent; - else - ++m_itMapCurrent; - } - - BufferedTransformation & Destination() - { - return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first; - } - - const std::string & Message() - { - if (m_useDefault) - return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel; - else - return m_itMapCurrent->second.second; - } -}; - -void MessageSwitch::Put(byte inByte); -void MessageSwitch::Put(const byte *inString, unsigned int length); - -void MessageSwitch::Flush(bool completeFlush, int propagation=-1); -void MessageSwitch::MessageEnd(int propagation=-1); -void MessageSwitch::PutMessageEnd(const byte *inString, unsigned int length, int propagation=-1); -void MessageSwitch::MessageSeriesEnd(int propagation=-1); -*/ -#endif - - -// -// ChannelRouteIterator -////////////////////////// - -void ChannelRouteIterator::Reset(const std::string &channel) -{ - m_channel = channel; - pair<MapIterator, MapIterator> range = m_cs.m_routeMap.equal_range(channel); - if (range.first == range.second) - { - m_useDefault = true; - m_itListCurrent = m_cs.m_defaultRoutes.begin(); - m_itListEnd = m_cs.m_defaultRoutes.end(); - } - else - { - m_useDefault = false; - m_itMapCurrent = range.first; - m_itMapEnd = range.second; - } -} - -bool ChannelRouteIterator::End() const -{ - return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd; -} - -void ChannelRouteIterator::Next() -{ - if (m_useDefault) - ++m_itListCurrent; - else - ++m_itMapCurrent; -} - -BufferedTransformation & ChannelRouteIterator::Destination() -{ - return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first; -} - -const std::string & ChannelRouteIterator::Channel() -{ - if (m_useDefault) - return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel; - else - return m_itMapCurrent->second.second; -} - - -// -// ChannelSwitch -/////////////////// - -size_t ChannelSwitch::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) -{ - if (m_blocked) - { - m_blocked = false; - goto WasBlocked; - } - - m_it.Reset(channel); - - while (!m_it.End()) - { -WasBlocked: - if (m_it.Destination().ChannelPut2(m_it.Channel(), begin, length, messageEnd, blocking)) - { - m_blocked = true; - return 1; - } - - m_it.Next(); - } - - return 0; -} - -void ChannelSwitch::IsolatedInitialize(const NameValuePairs ¶meters/* =g_nullNameValuePairs */) -{ - m_routeMap.clear(); - m_defaultRoutes.clear(); - m_blocked = false; -} - -bool ChannelSwitch::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking) -{ - if (m_blocked) - { - m_blocked = false; - goto WasBlocked; - } - - m_it.Reset(channel); - - while (!m_it.End()) - { - WasBlocked: - if (m_it.Destination().ChannelFlush(m_it.Channel(), completeFlush, propagation, blocking)) - { - m_blocked = true; - return true; - } - - m_it.Next(); - } - - return false; -} - -bool ChannelSwitch::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking) -{ - if (m_blocked) - { - m_blocked = false; - goto WasBlocked; - } - - m_it.Reset(channel); - - while (!m_it.End()) - { - WasBlocked: - if (m_it.Destination().ChannelMessageSeriesEnd(m_it.Channel(), propagation)) - { - m_blocked = true; - return true; - } - - m_it.Next(); - } - - return false; -} - -byte * ChannelSwitch::ChannelCreatePutSpace(const std::string &channel, size_t &size) -{ - m_it.Reset(channel); - if (!m_it.End()) - { - BufferedTransformation &target = m_it.Destination(); - const std::string &channel = m_it.Channel(); - m_it.Next(); - if (m_it.End()) // there is only one target channel - return target.ChannelCreatePutSpace(channel, size); - } - size = 0; - return NULL; -} - -size_t ChannelSwitch::ChannelPutModifiable2(const std::string &channel, byte *inString, size_t length, int messageEnd, bool blocking) -{ - ChannelRouteIterator it(*this); - it.Reset(channel); - - if (!it.End()) - { - BufferedTransformation &target = it.Destination(); - const std::string &targetChannel = it.Channel(); - it.Next(); - if (it.End()) // there is only one target channel - return target.ChannelPutModifiable2(targetChannel, inString, length, messageEnd, blocking); - } - - return ChannelPut2(channel, inString, length, messageEnd, blocking); -} - -void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination) -{ - m_defaultRoutes.push_back(DefaultRoute(&destination, value_ptr<std::string>(NULL))); -} - -void ChannelSwitch::RemoveDefaultRoute(BufferedTransformation &destination) -{ - for (DefaultRouteList::iterator it = m_defaultRoutes.begin(); it != m_defaultRoutes.end(); ++it) - if (it->first == &destination && !it->second.get()) - { - m_defaultRoutes.erase(it); - break; - } -} - -void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination, const std::string &outChannel) -{ - m_defaultRoutes.push_back(DefaultRoute(&destination, outChannel)); -} - -void ChannelSwitch::RemoveDefaultRoute(BufferedTransformation &destination, const std::string &outChannel) -{ - for (DefaultRouteList::iterator it = m_defaultRoutes.begin(); it != m_defaultRoutes.end(); ++it) - if (it->first == &destination && (it->second.get() && *it->second == outChannel)) - { - m_defaultRoutes.erase(it); - break; - } -} - -void ChannelSwitch::AddRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel) -{ - m_routeMap.insert(RouteMap::value_type(inChannel, Route(&destination, outChannel))); -} - -void ChannelSwitch::RemoveRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel) -{ - typedef ChannelSwitch::RouteMap::iterator MapIterator; - pair<MapIterator, MapIterator> range = m_routeMap.equal_range(inChannel); - - for (MapIterator it = range.first; it != range.second; ++it) - if (it->second.first == &destination && it->second.second == outChannel) - { - m_routeMap.erase(it); - break; - } -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/channels.h b/lib/cryptopp/channels.h deleted file mode 100644 index 837415615..000000000 --- a/lib/cryptopp/channels.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef CRYPTOPP_CHANNELS_H -#define CRYPTOPP_CHANNELS_H - -#include "simple.h" -#include "smartptr.h" -#include <map> -#include <list> - -NAMESPACE_BEGIN(CryptoPP) - -#if 0 -//! Route input on default channel to different and/or multiple channels based on message sequence number -class MessageSwitch : public Sink -{ -public: - void AddDefaultRoute(BufferedTransformation &destination, const std::string &channel); - void AddRoute(unsigned int begin, unsigned int end, BufferedTransformation &destination, const std::string &channel); - - void Put(byte inByte); - void Put(const byte *inString, unsigned int length); - - void Flush(bool completeFlush, int propagation=-1); - void MessageEnd(int propagation=-1); - void PutMessageEnd(const byte *inString, unsigned int length, int propagation=-1); - void MessageSeriesEnd(int propagation=-1); - -private: - typedef std::pair<BufferedTransformation *, std::string> Route; - struct RangeRoute - { - RangeRoute(unsigned int begin, unsigned int end, const Route &route) - : begin(begin), end(end), route(route) {} - bool operator<(const RangeRoute &rhs) const {return begin < rhs.begin;} - unsigned int begin, end; - Route route; - }; - - typedef std::list<RangeRoute> RouteList; - typedef std::list<Route> DefaultRouteList; - - RouteList m_routes; - DefaultRouteList m_defaultRoutes; - unsigned int m_nCurrentMessage; -}; -#endif - -class ChannelSwitchTypedefs -{ -public: - typedef std::pair<BufferedTransformation *, std::string> Route; - typedef std::multimap<std::string, Route> RouteMap; - - typedef std::pair<BufferedTransformation *, value_ptr<std::string> > DefaultRoute; - typedef std::list<DefaultRoute> DefaultRouteList; - - // SunCC workaround: can't use const_iterator here - typedef RouteMap::iterator MapIterator; - typedef DefaultRouteList::iterator ListIterator; -}; - -class ChannelSwitch; - -class ChannelRouteIterator : public ChannelSwitchTypedefs -{ -public: - ChannelSwitch& m_cs; - std::string m_channel; - bool m_useDefault; - MapIterator m_itMapCurrent, m_itMapEnd; - ListIterator m_itListCurrent, m_itListEnd; - - ChannelRouteIterator(ChannelSwitch &cs) : m_cs(cs) {} - void Reset(const std::string &channel); - bool End() const; - void Next(); - BufferedTransformation & Destination(); - const std::string & Channel(); -}; - -//! Route input to different and/or multiple channels based on channel ID -class CRYPTOPP_DLL ChannelSwitch : public Multichannel<Sink>, public ChannelSwitchTypedefs -{ -public: - ChannelSwitch() : m_it(*this), m_blocked(false) {} - ChannelSwitch(BufferedTransformation &destination) : m_it(*this), m_blocked(false) - { - AddDefaultRoute(destination); - } - ChannelSwitch(BufferedTransformation &destination, const std::string &outChannel) : m_it(*this), m_blocked(false) - { - AddDefaultRoute(destination, outChannel); - } - - void IsolatedInitialize(const NameValuePairs ¶meters=g_nullNameValuePairs); - - size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking); - size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking); - - bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true); - bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true); - - byte * ChannelCreatePutSpace(const std::string &channel, size_t &size); - - void AddDefaultRoute(BufferedTransformation &destination); - void RemoveDefaultRoute(BufferedTransformation &destination); - void AddDefaultRoute(BufferedTransformation &destination, const std::string &outChannel); - void RemoveDefaultRoute(BufferedTransformation &destination, const std::string &outChannel); - void AddRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel); - void RemoveRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel); - -private: - RouteMap m_routeMap; - DefaultRouteList m_defaultRoutes; - - ChannelRouteIterator m_it; - bool m_blocked; - - friend class ChannelRouteIterator; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/cmac.cpp b/lib/cryptopp/cmac.cpp deleted file mode 100644 index a31d5f8b0..000000000 --- a/lib/cryptopp/cmac.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// cmac.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "cmac.h" - -NAMESPACE_BEGIN(CryptoPP) - -static void MulU(byte *k, unsigned int length) -{ - byte carry = 0; - - for (int i=length-1; i>=1; i-=2) - { - byte carry2 = k[i] >> 7; - k[i] += k[i] + carry; - carry = k[i-1] >> 7; - k[i-1] += k[i-1] + carry2; - } - - if (carry) - { - switch (length) - { - case 8: - k[7] ^= 0x1b; - break; - case 16: - k[15] ^= 0x87; - break; - case 32: - k[30] ^= 4; - k[31] ^= 0x23; - break; - default: - throw InvalidArgument("CMAC: " + IntToString(length) + " is not a supported cipher block size"); - } - } -} - -void CMAC_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) -{ - BlockCipher &cipher = AccessCipher(); - unsigned int blockSize = cipher.BlockSize(); - - cipher.SetKey(key, length, params); - m_reg.CleanNew(3*blockSize); - m_counter = 0; - - cipher.ProcessBlock(m_reg, m_reg+blockSize); - MulU(m_reg+blockSize, blockSize); - memcpy(m_reg+2*blockSize, m_reg+blockSize, blockSize); - MulU(m_reg+2*blockSize, blockSize); -} - -void CMAC_Base::Update(const byte *input, size_t length) -{ - if (!length) - return; - - BlockCipher &cipher = AccessCipher(); - unsigned int blockSize = cipher.BlockSize(); - - if (m_counter > 0) - { - unsigned int len = UnsignedMin(blockSize - m_counter, length); - xorbuf(m_reg+m_counter, input, len); - length -= len; - input += len; - m_counter += len; - - if (m_counter == blockSize && length > 0) - { - cipher.ProcessBlock(m_reg); - m_counter = 0; - } - } - - if (length > blockSize) - { - assert(m_counter == 0); - size_t leftOver = 1 + cipher.AdvancedProcessBlocks(m_reg, input, m_reg, length-1, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput); - input += (length - leftOver); - length = leftOver; - } - - if (length > 0) - { - assert(m_counter + length <= blockSize); - xorbuf(m_reg+m_counter, input, length); - m_counter += (unsigned int)length; - } - - assert(m_counter > 0); -} - -void CMAC_Base::TruncatedFinal(byte *mac, size_t size) -{ - ThrowIfInvalidTruncatedSize(size); - - BlockCipher &cipher = AccessCipher(); - unsigned int blockSize = cipher.BlockSize(); - - if (m_counter < blockSize) - { - m_reg[m_counter] ^= 0x80; - cipher.AdvancedProcessBlocks(m_reg, m_reg+2*blockSize, m_reg, blockSize, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput); - } - else - cipher.AdvancedProcessBlocks(m_reg, m_reg+blockSize, m_reg, blockSize, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput); - - memcpy(mac, m_reg, size); - - m_counter = 0; - memset(m_reg, 0, blockSize); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/cmac.h b/lib/cryptopp/cmac.h deleted file mode 100644 index d8a1b391d..000000000 --- a/lib/cryptopp/cmac.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef CRYPTOPP_CMAC_H -#define CRYPTOPP_CMAC_H - -#include "seckey.h" -#include "secblock.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CMAC_Base : public MessageAuthenticationCode -{ -public: - CMAC_Base() {} - - void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); - void Update(const byte *input, size_t length); - void TruncatedFinal(byte *mac, size_t size); - unsigned int DigestSize() const {return GetCipher().BlockSize();} - unsigned int OptimalBlockSize() const {return GetCipher().BlockSize();} - unsigned int OptimalDataAlignment() const {return GetCipher().OptimalDataAlignment();} - -protected: - friend class EAX_Base; - - const BlockCipher & GetCipher() const {return const_cast<CMAC_Base*>(this)->AccessCipher();} - virtual BlockCipher & AccessCipher() =0; - - void ProcessBuf(); - SecByteBlock m_reg; - unsigned int m_counter; -}; - -/// <a href="http://www.cryptolounge.org/wiki/CMAC">CMAC</a> -/*! Template parameter T should be a class derived from BlockCipherDocumentation, for example AES, with a block size of 8, 16, or 32 */ -template <class T> -class CMAC : public MessageAuthenticationCodeImpl<CMAC_Base, CMAC<T> >, public SameKeyLengthAs<T> -{ -public: - CMAC() {} - CMAC(const byte *key, size_t length=SameKeyLengthAs<T>::DEFAULT_KEYLENGTH) - {this->SetKey(key, length);} - - static std::string StaticAlgorithmName() {return std::string("CMAC(") + T::StaticAlgorithmName() + ")";} - -private: - BlockCipher & AccessCipher() {return m_cipher;} - typename T::Encryption m_cipher; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/config.h b/lib/cryptopp/config.h deleted file mode 100644 index edbfd00ef..000000000 --- a/lib/cryptopp/config.h +++ /dev/null @@ -1,462 +0,0 @@ -#ifndef CRYPTOPP_CONFIG_H -#define CRYPTOPP_CONFIG_H - -// ***************** Important Settings ******************** - -// define this if running on a big-endian CPU -#if !defined(IS_LITTLE_ENDIAN) && (defined(__BIG_ENDIAN__) || defined(__sparc) || defined(__sparc__) || defined(__hppa__) || defined(__MIPSEB__) || defined(__ARMEB__) || (defined(__MWERKS__) && !defined(__INTEL__))) -# define IS_BIG_ENDIAN -#endif - -// define this if running on a little-endian CPU -// big endian will be assumed if IS_LITTLE_ENDIAN is not defined -#ifndef IS_BIG_ENDIAN -# define IS_LITTLE_ENDIAN -#endif - -// define this if you want to disable all OS-dependent features, -// such as sockets and OS-provided random number generators -#define NO_OS_DEPENDENCE - -// Define this to use features provided by Microsoft's CryptoAPI. -// Currently the only feature used is random number generation. -// This macro will be ignored if NO_OS_DEPENDENCE is defined. -// #define USE_MS_CRYPTOAPI - -// Define this to 1 to enforce the requirement in FIPS 186-2 Change Notice 1 that only 1024 bit moduli be used -#ifndef DSA_1024_BIT_MODULUS_ONLY -# define DSA_1024_BIT_MODULUS_ONLY 1 -#endif - -// ***************** Less Important Settings *************** - -// define this to retain (as much as possible) old deprecated function and class names -// #define CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - -#define GZIP_OS_CODE 0 - -// Try this if your CPU has 256K internal cache or a slow multiply instruction -// and you want a (possibly) faster IDEA implementation using log tables -// #define IDEA_LARGECACHE - -// Define this if, for the linear congruential RNG, you want to use -// the original constants as specified in S.K. Park and K.W. Miller's -// CACM paper. -// #define LCRNG_ORIGINAL_NUMBERS - -// choose which style of sockets to wrap (mostly useful for cygwin which has both) -#define PREFER_BERKELEY_STYLE_SOCKETS -// #define PREFER_WINDOWS_STYLE_SOCKETS - -// set the name of Rijndael cipher, was "Rijndael" before version 5.3 -#define CRYPTOPP_RIJNDAEL_NAME "AES" - -// ***************** Important Settings Again ******************** -// But the defaults should be ok. - -// namespace support is now required -#ifdef NO_NAMESPACE -# error namespace support is now required -#endif - -// Define this to workaround a Microsoft CryptoAPI bug where -// each call to CryptAcquireContext causes a 100 KB memory leak. -// Defining this will cause Crypto++ to make only one call to CryptAcquireContext. -#define WORKAROUND_MS_BUG_Q258000 - -#ifdef CRYPTOPP_DOXYGEN_PROCESSING -// Avoid putting "CryptoPP::" in front of everything in Doxygen output -# define CryptoPP -# define NAMESPACE_BEGIN(x) -# define NAMESPACE_END -// Get Doxygen to generate better documentation for these typedefs -# define DOCUMENTED_TYPEDEF(x, y) class y : public x {}; -#else -# define NAMESPACE_BEGIN(x) namespace x { -# define NAMESPACE_END } -# define DOCUMENTED_TYPEDEF(x, y) typedef x y; -#endif -#define ANONYMOUS_NAMESPACE_BEGIN namespace { -#define USING_NAMESPACE(x) using namespace x; -#define DOCUMENTED_NAMESPACE_BEGIN(x) namespace x { -#define DOCUMENTED_NAMESPACE_END } - -// What is the type of the third parameter to bind? -// For Unix, the new standard is ::socklen_t (typically unsigned int), and the old standard is int. -// Unfortunately there is no way to tell whether or not socklen_t is defined. -// To work around this, TYPE_OF_SOCKLEN_T is a macro so that you can change it from the makefile. -#ifndef TYPE_OF_SOCKLEN_T -# if defined(_WIN32) || defined(__CYGWIN__) -# define TYPE_OF_SOCKLEN_T int -# else -# define TYPE_OF_SOCKLEN_T ::socklen_t -# endif -#endif - -#if defined(__CYGWIN__) && defined(PREFER_WINDOWS_STYLE_SOCKETS) -# define __USE_W32_SOCKETS -#endif - -typedef unsigned char byte; // put in global namespace to avoid ambiguity with other byte typedefs - -NAMESPACE_BEGIN(CryptoPP) - -typedef unsigned short word16; -typedef unsigned int word32; - -#if defined(_MSC_VER) || defined(__BORLANDC__) - typedef unsigned __int64 word64; - #define W64LIT(x) x##ui64 -#else - typedef unsigned long long word64; - #define W64LIT(x) x##ULL -#endif - -// define large word type, used for file offsets and such -typedef word64 lword; -const lword LWORD_MAX = W64LIT(0xffffffffffffffff); - -#ifdef __GNUC__ - #define CRYPTOPP_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#endif - -// define hword, word, and dword. these are used for multiprecision integer arithmetic -// Intel compiler won't have _umul128 until version 10.0. See http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/30231625.aspx -#if (defined(_MSC_VER) && (!defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1000) && (defined(_M_X64) || defined(_M_IA64))) || (defined(__DECCXX) && defined(__alpha__)) || (defined(__INTEL_COMPILER) && defined(__x86_64__)) || (defined(__SUNPRO_CC) && defined(__x86_64__)) - typedef word32 hword; - typedef word64 word; -#else - #define CRYPTOPP_NATIVE_DWORD_AVAILABLE - #if defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) || defined(__x86_64__) || defined(__mips64) || defined(__sparc64__) - #if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !(CRYPTOPP_GCC_VERSION == 40001 && defined(__APPLE__)) && CRYPTOPP_GCC_VERSION >= 30400 - // GCC 4.0.1 on MacOS X is missing __umodti3 and __udivti3 - // mode(TI) division broken on amd64 with GCC earlier than GCC 3.4 - typedef word32 hword; - typedef word64 word; - typedef __uint128_t dword; - typedef __uint128_t word128; - #define CRYPTOPP_WORD128_AVAILABLE - #else - // if we're here, it means we're on a 64-bit CPU but we don't have a way to obtain 128-bit multiplication results - typedef word16 hword; - typedef word32 word; - typedef word64 dword; - #endif - #else - // being here means the native register size is probably 32 bits or less - #define CRYPTOPP_BOOL_SLOW_WORD64 1 - typedef word16 hword; - typedef word32 word; - typedef word64 dword; - #endif -#endif -#ifndef CRYPTOPP_BOOL_SLOW_WORD64 - #define CRYPTOPP_BOOL_SLOW_WORD64 0 -#endif - -const unsigned int WORD_SIZE = sizeof(word); -const unsigned int WORD_BITS = WORD_SIZE * 8; - -NAMESPACE_END - -#ifndef CRYPTOPP_L1_CACHE_LINE_SIZE - // This should be a lower bound on the L1 cache line size. It's used for defense against timing attacks. - #if defined(_M_X64) || defined(__x86_64__) - #define CRYPTOPP_L1_CACHE_LINE_SIZE 64 - #else - // L1 cache line size is 32 on Pentium III and earlier - #define CRYPTOPP_L1_CACHE_LINE_SIZE 32 - #endif -#endif - -#if defined(_MSC_VER) - #if _MSC_VER == 1200 - #include <malloc.h> - #endif - #if _MSC_VER > 1200 || defined(_mm_free) - #define CRYPTOPP_MSVC6PP_OR_LATER // VC 6 processor pack or later - #else - #define CRYPTOPP_MSVC6_NO_PP // VC 6 without processor pack - #endif -#endif - -#ifndef CRYPTOPP_ALIGN_DATA - #if defined(CRYPTOPP_MSVC6PP_OR_LATER) - #define CRYPTOPP_ALIGN_DATA(x) __declspec(align(x)) - #elif defined(__GNUC__) - #define CRYPTOPP_ALIGN_DATA(x) __attribute__((aligned(x))) - #else - #define CRYPTOPP_ALIGN_DATA(x) - #endif -#endif - -#ifndef CRYPTOPP_SECTION_ALIGN16 - #if defined(__GNUC__) && !defined(__APPLE__) - // the alignment attribute doesn't seem to work without this section attribute when -fdata-sections is turned on - #define CRYPTOPP_SECTION_ALIGN16 __attribute__((section ("CryptoPP_Align16"))) - #else - #define CRYPTOPP_SECTION_ALIGN16 - #endif -#endif - -#if defined(_MSC_VER) || defined(__fastcall) - #define CRYPTOPP_FASTCALL __fastcall -#else - #define CRYPTOPP_FASTCALL -#endif - -// VC60 workaround: it doesn't allow typename in some places -#if defined(_MSC_VER) && (_MSC_VER < 1300) -#define CPP_TYPENAME -#else -#define CPP_TYPENAME typename -#endif - -// VC60 workaround: can't cast unsigned __int64 to float or double -#if defined(_MSC_VER) && !defined(CRYPTOPP_MSVC6PP_OR_LATER) -#define CRYPTOPP_VC6_INT64 (__int64) -#else -#define CRYPTOPP_VC6_INT64 -#endif - -#ifdef _MSC_VER -#define CRYPTOPP_NO_VTABLE __declspec(novtable) -#else -#define CRYPTOPP_NO_VTABLE -#endif - -#ifdef _MSC_VER - // 4231: nonstandard extension used : 'extern' before template explicit instantiation - // 4250: dominance - // 4251: member needs to have dll-interface - // 4275: base needs to have dll-interface - // 4660: explicitly instantiating a class that's already implicitly instantiated - // 4661: no suitable definition provided for explicit template instantiation request - // 4786: identifer was truncated in debug information - // 4355: 'this' : used in base member initializer list - // 4910: '__declspec(dllexport)' and 'extern' are incompatible on an explicit instantiation -# pragma warning(disable: 4231 4250 4251 4275 4660 4661 4786 4355 4910) -#endif - -#ifdef __BORLANDC__ -// 8037: non-const function called for const object. needed to work around BCB2006 bug -# pragma warn -8037 -#endif - -#if (defined(_MSC_VER) && _MSC_VER <= 1300) || defined(__MWERKS__) || defined(_STLPORT_VERSION) || defined(ANDROID_NDK) -#define CRYPTOPP_DISABLE_UNCAUGHT_EXCEPTION -#endif - -#ifndef CRYPTOPP_DISABLE_UNCAUGHT_EXCEPTION -#define CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE -#endif - -#ifdef CRYPTOPP_DISABLE_X86ASM // for backwards compatibility: this macro had both meanings -#define CRYPTOPP_DISABLE_ASM -#define CRYPTOPP_DISABLE_SSE2 -#endif - -#if !defined(CRYPTOPP_DISABLE_ASM) && ((defined(_MSC_VER) && defined(_M_IX86)) || (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))) - // C++Builder 2010 does not allow "call label" where label is defined within inline assembly - #define CRYPTOPP_X86_ASM_AVAILABLE - - #if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(CRYPTOPP_MSVC6PP_OR_LATER) || CRYPTOPP_GCC_VERSION >= 30300) - #define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 1 - #else - #define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 0 - #endif - - // SSSE3 was actually introduced in GNU as 2.17, which was released 6/23/2006, but we can't tell what version of binutils is installed. - // GCC 4.1.2 was released on 2/13/2007, so we'll use that as a proxy for the binutils version. - #if !defined(CRYPTOPP_DISABLE_SSSE3) && (_MSC_VER >= 1400 || CRYPTOPP_GCC_VERSION >= 40102) - #define CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE 1 - #else - #define CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE 0 - #endif -#endif - -#if !defined(CRYPTOPP_DISABLE_ASM) && defined(_MSC_VER) && defined(_M_X64) - #define CRYPTOPP_X64_MASM_AVAILABLE -#endif - -#if !defined(CRYPTOPP_DISABLE_ASM) && defined(__GNUC__) && defined(__x86_64__) - #define CRYPTOPP_X64_ASM_AVAILABLE -#endif - -#if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(CRYPTOPP_MSVC6PP_OR_LATER) || defined(__SSE2__)) - #define CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 1 -#else - #define CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 0 -#endif - -#if !defined(CRYPTOPP_DISABLE_SSSE3) && !defined(CRYPTOPP_DISABLE_AESNI) && CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE && (CRYPTOPP_GCC_VERSION >= 40400 || _MSC_FULL_VER >= 150030729 || __INTEL_COMPILER >= 1110) - #define CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE 1 -#else - #define CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE 0 -#endif - -#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) - #define CRYPTOPP_BOOL_ALIGN16_ENABLED 1 -#else - #define CRYPTOPP_BOOL_ALIGN16_ENABLED 0 -#endif - -// how to allocate 16-byte aligned memory (for SSE2) -#if defined(CRYPTOPP_MSVC6PP_OR_LATER) - #define CRYPTOPP_MM_MALLOC_AVAILABLE -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) - #define CRYPTOPP_MALLOC_ALIGNMENT_IS_16 -#elif defined(__linux__) || defined(__sun__) || defined(__CYGWIN__) - #define CRYPTOPP_MEMALIGN_AVAILABLE -#else - #define CRYPTOPP_NO_ALIGNED_ALLOC -#endif - -// how to disable inlining -#if defined(_MSC_VER) && _MSC_VER >= 1300 -# define CRYPTOPP_NOINLINE_DOTDOTDOT -# define CRYPTOPP_NOINLINE __declspec(noinline) -#elif defined(__GNUC__) -# define CRYPTOPP_NOINLINE_DOTDOTDOT -# define CRYPTOPP_NOINLINE __attribute__((noinline)) -#else -# define CRYPTOPP_NOINLINE_DOTDOTDOT ... -# define CRYPTOPP_NOINLINE -#endif - -// how to declare class constants -#if (defined(_MSC_VER) && _MSC_VER <= 1300) || defined(__INTEL_COMPILER) -# define CRYPTOPP_CONSTANT(x) enum {x}; -#else -# define CRYPTOPP_CONSTANT(x) static const int x; -#endif - -#if defined(_M_X64) || defined(__x86_64__) - #define CRYPTOPP_BOOL_X64 1 -#else - #define CRYPTOPP_BOOL_X64 0 -#endif - -// see http://predef.sourceforge.net/prearch.html -#if defined(_M_IX86) || defined(__i386__) || defined(__i386) || defined(_X86_) || defined(__I86__) || defined(__INTEL__) - #define CRYPTOPP_BOOL_X86 1 -#else - #define CRYPTOPP_BOOL_X86 0 -#endif - -#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 || defined(__powerpc__) - #define CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS -#endif - -#define CRYPTOPP_VERSION 562 - -// ***************** determine availability of OS features ******************** - -#ifndef NO_OS_DEPENDENCE - -#if defined(_WIN32) || defined(__CYGWIN__) -#define CRYPTOPP_WIN32_AVAILABLE -#endif - -#if defined(__unix__) || defined(__MACH__) || defined(__NetBSD__) || defined(__sun) -#define CRYPTOPP_UNIX_AVAILABLE -#endif - -#if defined(CRYPTOPP_WIN32_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE) -# define HIGHRES_TIMER_AVAILABLE -#endif - -#ifdef CRYPTOPP_UNIX_AVAILABLE -# define HAS_BERKELEY_STYLE_SOCKETS -#endif - -#ifdef CRYPTOPP_WIN32_AVAILABLE -# define HAS_WINDOWS_STYLE_SOCKETS -#endif - -#if defined(HIGHRES_TIMER_AVAILABLE) && (defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(HAS_WINDOWS_STYLE_SOCKETS)) -# define SOCKETS_AVAILABLE -#endif - -#if defined(HAS_WINDOWS_STYLE_SOCKETS) && (!defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(PREFER_WINDOWS_STYLE_SOCKETS)) -# define USE_WINDOWS_STYLE_SOCKETS -#else -# define USE_BERKELEY_STYLE_SOCKETS -#endif - -#if defined(HIGHRES_TIMER_AVAILABLE) && defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(USE_BERKELEY_STYLE_SOCKETS) -# define WINDOWS_PIPES_AVAILABLE -#endif - -#if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(USE_MS_CRYPTOAPI) -# define NONBLOCKING_RNG_AVAILABLE -# define OS_RNG_AVAILABLE -#endif - -#if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING) -# define NONBLOCKING_RNG_AVAILABLE -# define BLOCKING_RNG_AVAILABLE -# define OS_RNG_AVAILABLE -# define HAS_PTHREADS -# define THREADS_AVAILABLE -#endif - -#ifdef CRYPTOPP_WIN32_AVAILABLE -# define HAS_WINTHREADS -# define THREADS_AVAILABLE -#endif - -#endif // NO_OS_DEPENDENCE - -// ***************** DLL related ******************** - -#if defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) - -#ifdef CRYPTOPP_EXPORTS -#define CRYPTOPP_IS_DLL -#define CRYPTOPP_DLL __declspec(dllexport) -#elif defined(CRYPTOPP_IMPORTS) -#define CRYPTOPP_IS_DLL -#define CRYPTOPP_DLL __declspec(dllimport) -#else -#define CRYPTOPP_DLL -#endif - -#define CRYPTOPP_API __cdecl - -#else // CRYPTOPP_WIN32_AVAILABLE - -#define CRYPTOPP_DLL -#define CRYPTOPP_API - -#endif // CRYPTOPP_WIN32_AVAILABLE - -#if defined(__MWERKS__) -#define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS extern class CRYPTOPP_DLL -#elif defined(__BORLANDC__) || defined(__SUNPRO_CC) -#define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS template class CRYPTOPP_DLL -#else -#define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS extern template class CRYPTOPP_DLL -#endif - -#if defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) && !defined(CRYPTOPP_IMPORTS) -#define CRYPTOPP_DLL_TEMPLATE_CLASS template class CRYPTOPP_DLL -#else -#define CRYPTOPP_DLL_TEMPLATE_CLASS CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS -#endif - -#if defined(__MWERKS__) -#define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS extern class -#elif defined(__BORLANDC__) || defined(__SUNPRO_CC) -#define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS template class -#else -#define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS extern template class -#endif - -#if defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) && !defined(CRYPTOPP_EXPORTS) -#define CRYPTOPP_STATIC_TEMPLATE_CLASS template class -#else -#define CRYPTOPP_STATIC_TEMPLATE_CLASS CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS -#endif - -#endif diff --git a/lib/cryptopp/cpu.cpp b/lib/cryptopp/cpu.cpp deleted file mode 100644 index 3610a7c8e..000000000 --- a/lib/cryptopp/cpu.cpp +++ /dev/null @@ -1,199 +0,0 @@ -// cpu.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "cpu.h" -#include "misc.h" -#include <algorithm> - -#ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY -#include <signal.h> -#include <setjmp.h> -#endif - -#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE -#include <emmintrin.h> -#endif - -NAMESPACE_BEGIN(CryptoPP) - -#ifdef CRYPTOPP_CPUID_AVAILABLE - -#if _MSC_VER >= 1400 && CRYPTOPP_BOOL_X64 - -bool CpuId(word32 input, word32 *output) -{ - __cpuid((int *)output, input); - return true; -} - -#else - -#ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY -extern "C" { -typedef void (*SigHandler)(int); - -static jmp_buf s_jmpNoCPUID; -static void SigIllHandlerCPUID(int) -{ - longjmp(s_jmpNoCPUID, 1); -} - -static jmp_buf s_jmpNoSSE2; -static void SigIllHandlerSSE2(int) -{ - longjmp(s_jmpNoSSE2, 1); -} -} -#endif - -bool CpuId(word32 input, word32 *output) -{ -#ifdef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY - __try - { - __asm - { - mov eax, input - cpuid - mov edi, output - mov [edi], eax - mov [edi+4], ebx - mov [edi+8], ecx - mov [edi+12], edx - } - } - __except (1) - { - return false; - } - return true; -#else - SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID); - if (oldHandler == SIG_ERR) - return false; - - bool result = true; - if (setjmp(s_jmpNoCPUID)) - result = false; - else - { - asm - ( - // save ebx in case -fPIC is being used -#if CRYPTOPP_BOOL_X86 - "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" -#else - "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx" -#endif - : "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d" (output[3]) - : "a" (input) - ); - } - - signal(SIGILL, oldHandler); - return result; -#endif -} - -#endif - -static bool TrySSE2() -{ -#if CRYPTOPP_BOOL_X64 - return true; -#elif defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) - __try - { -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - AS2(por xmm0, xmm0) // executing SSE2 instruction -#elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE - __m128i x = _mm_setzero_si128(); - return _mm_cvtsi128_si32(x) == 0; -#endif - } - __except (1) - { - return false; - } - return true; -#else - SigHandler oldHandler = signal(SIGILL, SigIllHandlerSSE2); - if (oldHandler == SIG_ERR) - return false; - - bool result = true; - if (setjmp(s_jmpNoSSE2)) - result = false; - else - { -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - __asm __volatile ("por %xmm0, %xmm0"); -#elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE - __m128i x = _mm_setzero_si128(); - result = _mm_cvtsi128_si32(x) == 0; -#endif - } - - signal(SIGILL, oldHandler); - return result; -#endif -} - -bool g_x86DetectionDone = false; -bool g_hasISSE = false, g_hasSSE2 = false, g_hasSSSE3 = false, g_hasMMX = false, g_hasAESNI = false, g_hasCLMUL = false, g_isP4 = false; -word32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; - -void DetectX86Features() -{ - word32 cpuid[4], cpuid1[4]; - if (!CpuId(0, cpuid)) - return; - if (!CpuId(1, cpuid1)) - return; - - g_hasMMX = (cpuid1[3] & (1 << 23)) != 0; - if ((cpuid1[3] & (1 << 26)) != 0) - g_hasSSE2 = TrySSE2(); - g_hasSSSE3 = g_hasSSE2 && (cpuid1[2] & (1<<9)); - g_hasAESNI = g_hasSSE2 && (cpuid1[2] & (1<<25)); - g_hasCLMUL = g_hasSSE2 && (cpuid1[2] & (1<<1)); - - if ((cpuid1[3] & (1 << 25)) != 0) - g_hasISSE = true; - else - { - word32 cpuid2[4]; - CpuId(0x080000000, cpuid2); - if (cpuid2[0] >= 0x080000001) - { - CpuId(0x080000001, cpuid2); - g_hasISSE = (cpuid2[3] & (1 << 22)) != 0; - } - } - - std::swap(cpuid[2], cpuid[3]); - if (memcmp(cpuid+1, "GenuineIntel", 12) == 0) - { - g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf; - g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1); - } - else if (memcmp(cpuid+1, "AuthenticAMD", 12) == 0) - { - CpuId(0x80000005, cpuid); - g_cacheLineSize = GETBYTE(cpuid[2], 0); - } - - if (!g_cacheLineSize) - g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; - - g_x86DetectionDone = true; -} - -#endif - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/cpu.h b/lib/cryptopp/cpu.h deleted file mode 100644 index 65029d338..000000000 --- a/lib/cryptopp/cpu.h +++ /dev/null @@ -1,345 +0,0 @@ -#ifndef CRYPTOPP_CPU_H -#define CRYPTOPP_CPU_H - -#ifdef CRYPTOPP_GENERATE_X64_MASM - -#define CRYPTOPP_X86_ASM_AVAILABLE -#define CRYPTOPP_BOOL_X64 1 -#define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 1 -#define NAMESPACE_END - -#else - -#include "config.h" - -#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE -#include <emmintrin.h> -#endif - -#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE -#if !defined(__GNUC__) || defined(__SSSE3__) || defined(__INTEL_COMPILER) -#include <tmmintrin.h> -#else -__inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_shuffle_epi8 (__m128i a, __m128i b) -{ - asm ("pshufb %1, %0" : "+x"(a) : "xm"(b)); - return a; -} -#endif -#if !defined(__GNUC__) || defined(__SSE4_1__) || defined(__INTEL_COMPILER) -#include <smmintrin.h> -#else -__inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_extract_epi32 (__m128i a, const int i) -{ - int r; - asm ("pextrd %2, %1, %0" : "=rm"(r) : "x"(a), "i"(i)); - return r; -} -__inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_insert_epi32 (__m128i a, int b, const int i) -{ - asm ("pinsrd %2, %1, %0" : "+x"(a) : "rm"(b), "i"(i)); - return a; -} -#endif -#if !defined(__GNUC__) || (defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) -#include <wmmintrin.h> -#else -__inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_clmulepi64_si128 (__m128i a, __m128i b, const int i) -{ - asm ("pclmulqdq %2, %1, %0" : "+x"(a) : "xm"(b), "i"(i)); - return a; -} -__inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_aeskeygenassist_si128 (__m128i a, const int i) -{ - __m128i r; - asm ("aeskeygenassist %2, %1, %0" : "=x"(r) : "xm"(a), "i"(i)); - return r; -} -__inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_aesimc_si128 (__m128i a) -{ - __m128i r; - asm ("aesimc %1, %0" : "=x"(r) : "xm"(a)); - return r; -} -__inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_aesenc_si128 (__m128i a, __m128i b) -{ - asm ("aesenc %1, %0" : "+x"(a) : "xm"(b)); - return a; -} -__inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_aesenclast_si128 (__m128i a, __m128i b) -{ - asm ("aesenclast %1, %0" : "+x"(a) : "xm"(b)); - return a; -} -__inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_aesdec_si128 (__m128i a, __m128i b) -{ - asm ("aesdec %1, %0" : "+x"(a) : "xm"(b)); - return a; -} -__inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_aesdeclast_si128 (__m128i a, __m128i b) -{ - asm ("aesdeclast %1, %0" : "+x"(a) : "xm"(b)); - return a; -} -#endif -#endif - -NAMESPACE_BEGIN(CryptoPP) - -#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64 - -#define CRYPTOPP_CPUID_AVAILABLE - -// these should not be used directly -extern CRYPTOPP_DLL bool g_x86DetectionDone; -extern CRYPTOPP_DLL bool g_hasSSSE3; -extern CRYPTOPP_DLL bool g_hasAESNI; -extern CRYPTOPP_DLL bool g_hasCLMUL; -extern CRYPTOPP_DLL bool g_isP4; -extern CRYPTOPP_DLL word32 g_cacheLineSize; -CRYPTOPP_DLL void CRYPTOPP_API DetectX86Features(); -CRYPTOPP_DLL bool CRYPTOPP_API CpuId(word32 input, word32 *output); - -#if CRYPTOPP_BOOL_X64 -inline bool HasSSE2() {return true;} -inline bool HasISSE() {return true;} -inline bool HasMMX() {return true;} -#else - -extern CRYPTOPP_DLL bool g_hasSSE2; -extern CRYPTOPP_DLL bool g_hasISSE; -extern CRYPTOPP_DLL bool g_hasMMX; - -inline bool HasSSE2() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_hasSSE2; -} - -inline bool HasISSE() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_hasISSE; -} - -inline bool HasMMX() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_hasMMX; -} - -#endif - -inline bool HasSSSE3() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_hasSSSE3; -} - -inline bool HasAESNI() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_hasAESNI; -} - -inline bool HasCLMUL() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_hasCLMUL; -} - -inline bool IsP4() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_isP4; -} - -inline int GetCacheLineSize() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_cacheLineSize; -} - -#else - -inline int GetCacheLineSize() -{ - return CRYPTOPP_L1_CACHE_LINE_SIZE; -} - -#endif - -#endif - -#ifdef CRYPTOPP_GENERATE_X64_MASM - #define AS1(x) x*newline* - #define AS2(x, y) x, y*newline* - #define AS3(x, y, z) x, y, z*newline* - #define ASS(x, y, a, b, c, d) x, y, a*64+b*16+c*4+d*newline* - #define ASL(x) label##x:*newline* - #define ASJ(x, y, z) x label##y*newline* - #define ASC(x, y) x label##y*newline* - #define AS_HEX(y) 0##y##h -#elif defined(_MSC_VER) || defined(__BORLANDC__) - #define CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY - #define AS1(x) __asm {x} - #define AS2(x, y) __asm {x, y} - #define AS3(x, y, z) __asm {x, y, z} - #define ASS(x, y, a, b, c, d) __asm {x, y, (a)*64+(b)*16+(c)*4+(d)} - #define ASL(x) __asm {label##x:} - #define ASJ(x, y, z) __asm {x label##y} - #define ASC(x, y) __asm {x label##y} - #define CRYPTOPP_NAKED __declspec(naked) - #define AS_HEX(y) 0x##y -#else - #define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY - // define these in two steps to allow arguments to be expanded - #define GNU_AS1(x) #x ";" - #define GNU_AS2(x, y) #x ", " #y ";" - #define GNU_AS3(x, y, z) #x ", " #y ", " #z ";" - #define GNU_ASL(x) "\n" #x ":" - #define GNU_ASJ(x, y, z) #x " " #y #z ";" - #define AS1(x) GNU_AS1(x) - #define AS2(x, y) GNU_AS2(x, y) - #define AS3(x, y, z) GNU_AS3(x, y, z) - #define ASS(x, y, a, b, c, d) #x ", " #y ", " #a "*64+" #b "*16+" #c "*4+" #d ";" - #define ASL(x) GNU_ASL(x) - #define ASJ(x, y, z) GNU_ASJ(x, y, z) - #define ASC(x, y) #x " " #y ";" - #define CRYPTOPP_NAKED - #define AS_HEX(y) 0x##y -#endif - -#define IF0(y) -#define IF1(y) y - -#ifdef CRYPTOPP_GENERATE_X64_MASM -#define ASM_MOD(x, y) ((x) MOD (y)) -#define XMMWORD_PTR XMMWORD PTR -#else -// GNU assembler doesn't seem to have mod operator -#define ASM_MOD(x, y) ((x)-((x)/(y))*(y)) -// GAS 2.15 doesn't support XMMWORD PTR. it seems necessary only for MASM -#define XMMWORD_PTR -#endif - -#if CRYPTOPP_BOOL_X86 - #define AS_REG_1 ecx - #define AS_REG_2 edx - #define AS_REG_3 esi - #define AS_REG_4 edi - #define AS_REG_5 eax - #define AS_REG_6 ebx - #define AS_REG_7 ebp - #define AS_REG_1d ecx - #define AS_REG_2d edx - #define AS_REG_3d esi - #define AS_REG_4d edi - #define AS_REG_5d eax - #define AS_REG_6d ebx - #define AS_REG_7d ebp - #define WORD_SZ 4 - #define WORD_REG(x) e##x - #define WORD_PTR DWORD PTR - #define AS_PUSH_IF86(x) AS1(push e##x) - #define AS_POP_IF86(x) AS1(pop e##x) - #define AS_JCXZ jecxz -#elif CRYPTOPP_BOOL_X64 - #ifdef CRYPTOPP_GENERATE_X64_MASM - #define AS_REG_1 rcx - #define AS_REG_2 rdx - #define AS_REG_3 r8 - #define AS_REG_4 r9 - #define AS_REG_5 rax - #define AS_REG_6 r10 - #define AS_REG_7 r11 - #define AS_REG_1d ecx - #define AS_REG_2d edx - #define AS_REG_3d r8d - #define AS_REG_4d r9d - #define AS_REG_5d eax - #define AS_REG_6d r10d - #define AS_REG_7d r11d - #else - #define AS_REG_1 rdi - #define AS_REG_2 rsi - #define AS_REG_3 rdx - #define AS_REG_4 rcx - #define AS_REG_5 r8 - #define AS_REG_6 r9 - #define AS_REG_7 r10 - #define AS_REG_1d edi - #define AS_REG_2d esi - #define AS_REG_3d edx - #define AS_REG_4d ecx - #define AS_REG_5d r8d - #define AS_REG_6d r9d - #define AS_REG_7d r10d - #endif - #define WORD_SZ 8 - #define WORD_REG(x) r##x - #define WORD_PTR QWORD PTR - #define AS_PUSH_IF86(x) - #define AS_POP_IF86(x) - #define AS_JCXZ jrcxz -#endif - -// helper macro for stream cipher output -#define AS_XMM_OUTPUT4(labelPrefix, inputPtr, outputPtr, x0, x1, x2, x3, t, p0, p1, p2, p3, increment)\ - AS2( test inputPtr, inputPtr)\ - ASC( jz, labelPrefix##3)\ - AS2( test inputPtr, 15)\ - ASC( jnz, labelPrefix##7)\ - AS2( pxor xmm##x0, [inputPtr+p0*16])\ - AS2( pxor xmm##x1, [inputPtr+p1*16])\ - AS2( pxor xmm##x2, [inputPtr+p2*16])\ - AS2( pxor xmm##x3, [inputPtr+p3*16])\ - AS2( add inputPtr, increment*16)\ - ASC( jmp, labelPrefix##3)\ - ASL(labelPrefix##7)\ - AS2( movdqu xmm##t, [inputPtr+p0*16])\ - AS2( pxor xmm##x0, xmm##t)\ - AS2( movdqu xmm##t, [inputPtr+p1*16])\ - AS2( pxor xmm##x1, xmm##t)\ - AS2( movdqu xmm##t, [inputPtr+p2*16])\ - AS2( pxor xmm##x2, xmm##t)\ - AS2( movdqu xmm##t, [inputPtr+p3*16])\ - AS2( pxor xmm##x3, xmm##t)\ - AS2( add inputPtr, increment*16)\ - ASL(labelPrefix##3)\ - AS2( test outputPtr, 15)\ - ASC( jnz, labelPrefix##8)\ - AS2( movdqa [outputPtr+p0*16], xmm##x0)\ - AS2( movdqa [outputPtr+p1*16], xmm##x1)\ - AS2( movdqa [outputPtr+p2*16], xmm##x2)\ - AS2( movdqa [outputPtr+p3*16], xmm##x3)\ - ASC( jmp, labelPrefix##9)\ - ASL(labelPrefix##8)\ - AS2( movdqu [outputPtr+p0*16], xmm##x0)\ - AS2( movdqu [outputPtr+p1*16], xmm##x1)\ - AS2( movdqu [outputPtr+p2*16], xmm##x2)\ - AS2( movdqu [outputPtr+p3*16], xmm##x3)\ - ASL(labelPrefix##9)\ - AS2( add outputPtr, increment*16) - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/crc.cpp b/lib/cryptopp/crc.cpp deleted file mode 100644 index 10c25c257..000000000 --- a/lib/cryptopp/crc.cpp +++ /dev/null @@ -1,160 +0,0 @@ -// crc.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "crc.h" -#include "misc.h" - -NAMESPACE_BEGIN(CryptoPP) - -/* Table of CRC-32's of all single byte values (made by makecrc.c) */ -const word32 CRC32::m_tab[] = { -#ifdef IS_LITTLE_ENDIAN - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL -#else - 0x00000000L, 0x96300777L, 0x2c610eeeL, 0xba510999L, 0x19c46d07L, - 0x8ff46a70L, 0x35a563e9L, 0xa395649eL, 0x3288db0eL, 0xa4b8dc79L, - 0x1ee9d5e0L, 0x88d9d297L, 0x2b4cb609L, 0xbd7cb17eL, 0x072db8e7L, - 0x911dbf90L, 0x6410b71dL, 0xf220b06aL, 0x4871b9f3L, 0xde41be84L, - 0x7dd4da1aL, 0xebe4dd6dL, 0x51b5d4f4L, 0xc785d383L, 0x56986c13L, - 0xc0a86b64L, 0x7af962fdL, 0xecc9658aL, 0x4f5c0114L, 0xd96c0663L, - 0x633d0ffaL, 0xf50d088dL, 0xc8206e3bL, 0x5e10694cL, 0xe44160d5L, - 0x727167a2L, 0xd1e4033cL, 0x47d4044bL, 0xfd850dd2L, 0x6bb50aa5L, - 0xfaa8b535L, 0x6c98b242L, 0xd6c9bbdbL, 0x40f9bcacL, 0xe36cd832L, - 0x755cdf45L, 0xcf0dd6dcL, 0x593dd1abL, 0xac30d926L, 0x3a00de51L, - 0x8051d7c8L, 0x1661d0bfL, 0xb5f4b421L, 0x23c4b356L, 0x9995bacfL, - 0x0fa5bdb8L, 0x9eb80228L, 0x0888055fL, 0xb2d90cc6L, 0x24e90bb1L, - 0x877c6f2fL, 0x114c6858L, 0xab1d61c1L, 0x3d2d66b6L, 0x9041dc76L, - 0x0671db01L, 0xbc20d298L, 0x2a10d5efL, 0x8985b171L, 0x1fb5b606L, - 0xa5e4bf9fL, 0x33d4b8e8L, 0xa2c90778L, 0x34f9000fL, 0x8ea80996L, - 0x18980ee1L, 0xbb0d6a7fL, 0x2d3d6d08L, 0x976c6491L, 0x015c63e6L, - 0xf4516b6bL, 0x62616c1cL, 0xd8306585L, 0x4e0062f2L, 0xed95066cL, - 0x7ba5011bL, 0xc1f40882L, 0x57c40ff5L, 0xc6d9b065L, 0x50e9b712L, - 0xeab8be8bL, 0x7c88b9fcL, 0xdf1ddd62L, 0x492dda15L, 0xf37cd38cL, - 0x654cd4fbL, 0x5861b24dL, 0xce51b53aL, 0x7400bca3L, 0xe230bbd4L, - 0x41a5df4aL, 0xd795d83dL, 0x6dc4d1a4L, 0xfbf4d6d3L, 0x6ae96943L, - 0xfcd96e34L, 0x468867adL, 0xd0b860daL, 0x732d0444L, 0xe51d0333L, - 0x5f4c0aaaL, 0xc97c0dddL, 0x3c710550L, 0xaa410227L, 0x10100bbeL, - 0x86200cc9L, 0x25b56857L, 0xb3856f20L, 0x09d466b9L, 0x9fe461ceL, - 0x0ef9de5eL, 0x98c9d929L, 0x2298d0b0L, 0xb4a8d7c7L, 0x173db359L, - 0x810db42eL, 0x3b5cbdb7L, 0xad6cbac0L, 0x2083b8edL, 0xb6b3bf9aL, - 0x0ce2b603L, 0x9ad2b174L, 0x3947d5eaL, 0xaf77d29dL, 0x1526db04L, - 0x8316dc73L, 0x120b63e3L, 0x843b6494L, 0x3e6a6d0dL, 0xa85a6a7aL, - 0x0bcf0ee4L, 0x9dff0993L, 0x27ae000aL, 0xb19e077dL, 0x44930ff0L, - 0xd2a30887L, 0x68f2011eL, 0xfec20669L, 0x5d5762f7L, 0xcb676580L, - 0x71366c19L, 0xe7066b6eL, 0x761bd4feL, 0xe02bd389L, 0x5a7ada10L, - 0xcc4add67L, 0x6fdfb9f9L, 0xf9efbe8eL, 0x43beb717L, 0xd58eb060L, - 0xe8a3d6d6L, 0x7e93d1a1L, 0xc4c2d838L, 0x52f2df4fL, 0xf167bbd1L, - 0x6757bca6L, 0xdd06b53fL, 0x4b36b248L, 0xda2b0dd8L, 0x4c1b0aafL, - 0xf64a0336L, 0x607a0441L, 0xc3ef60dfL, 0x55df67a8L, 0xef8e6e31L, - 0x79be6946L, 0x8cb361cbL, 0x1a8366bcL, 0xa0d26f25L, 0x36e26852L, - 0x95770cccL, 0x03470bbbL, 0xb9160222L, 0x2f260555L, 0xbe3bbac5L, - 0x280bbdb2L, 0x925ab42bL, 0x046ab35cL, 0xa7ffd7c2L, 0x31cfd0b5L, - 0x8b9ed92cL, 0x1daede5bL, 0xb0c2649bL, 0x26f263ecL, 0x9ca36a75L, - 0x0a936d02L, 0xa906099cL, 0x3f360eebL, 0x85670772L, 0x13570005L, - 0x824abf95L, 0x147ab8e2L, 0xae2bb17bL, 0x381bb60cL, 0x9b8ed292L, - 0x0dbed5e5L, 0xb7efdc7cL, 0x21dfdb0bL, 0xd4d2d386L, 0x42e2d4f1L, - 0xf8b3dd68L, 0x6e83da1fL, 0xcd16be81L, 0x5b26b9f6L, 0xe177b06fL, - 0x7747b718L, 0xe65a0888L, 0x706a0fffL, 0xca3b0666L, 0x5c0b0111L, - 0xff9e658fL, 0x69ae62f8L, 0xd3ff6b61L, 0x45cf6c16L, 0x78e20aa0L, - 0xeed20dd7L, 0x5483044eL, 0xc2b30339L, 0x612667a7L, 0xf71660d0L, - 0x4d476949L, 0xdb776e3eL, 0x4a6ad1aeL, 0xdc5ad6d9L, 0x660bdf40L, - 0xf03bd837L, 0x53aebca9L, 0xc59ebbdeL, 0x7fcfb247L, 0xe9ffb530L, - 0x1cf2bdbdL, 0x8ac2bacaL, 0x3093b353L, 0xa6a3b424L, 0x0536d0baL, - 0x9306d7cdL, 0x2957de54L, 0xbf67d923L, 0x2e7a66b3L, 0xb84a61c4L, - 0x021b685dL, 0x942b6f2aL, 0x37be0bb4L, 0xa18e0cc3L, 0x1bdf055aL, - 0x8def022dL -#endif -}; - -CRC32::CRC32() -{ - Reset(); -} - -void CRC32::Update(const byte *s, size_t n) -{ - word32 crc = m_crc; - - for(; !IsAligned<word32>(s) && n > 0; n--) - crc = m_tab[CRC32_INDEX(crc) ^ *s++] ^ CRC32_SHIFTED(crc); - - while (n >= 4) - { - crc ^= *(const word32 *)s; - crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc); - crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc); - crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc); - crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc); - n -= 4; - s += 4; - } - - while (n--) - crc = m_tab[CRC32_INDEX(crc) ^ *s++] ^ CRC32_SHIFTED(crc); - - m_crc = crc; -} - -void CRC32::TruncatedFinal(byte *hash, size_t size) -{ - ThrowIfInvalidTruncatedSize(size); - - m_crc ^= CRC32_NEGL; - for (size_t i=0; i<size; i++) - hash[i] = GetCrcByte(i); - - Reset(); -} - -NAMESPACE_END diff --git a/lib/cryptopp/crc.h b/lib/cryptopp/crc.h deleted file mode 100644 index f75ea384c..000000000 --- a/lib/cryptopp/crc.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef CRYPTOPP_CRC32_H -#define CRYPTOPP_CRC32_H - -#include "cryptlib.h" - -NAMESPACE_BEGIN(CryptoPP) - -const word32 CRC32_NEGL = 0xffffffffL; - -#ifdef IS_LITTLE_ENDIAN -#define CRC32_INDEX(c) (c & 0xff) -#define CRC32_SHIFTED(c) (c >> 8) -#else -#define CRC32_INDEX(c) (c >> 24) -#define CRC32_SHIFTED(c) (c << 8) -#endif - -//! CRC Checksum Calculation -class CRC32 : public HashTransformation -{ -public: - CRYPTOPP_CONSTANT(DIGESTSIZE = 4) - CRC32(); - void Update(const byte *input, size_t length); - void TruncatedFinal(byte *hash, size_t size); - unsigned int DigestSize() const {return DIGESTSIZE;} - static const char * StaticAlgorithmName() {return "CRC32";} - std::string AlgorithmName() const {return StaticAlgorithmName();} - - void UpdateByte(byte b) {m_crc = m_tab[CRC32_INDEX(m_crc) ^ b] ^ CRC32_SHIFTED(m_crc);} - byte GetCrcByte(size_t i) const {return ((byte *)&(m_crc))[i];} - -private: - void Reset() {m_crc = CRC32_NEGL;} - - static const word32 m_tab[256]; - word32 m_crc; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/cryptlib.cpp b/lib/cryptopp/cryptlib.cpp deleted file mode 100644 index df138ddb0..000000000 --- a/lib/cryptopp/cryptlib.cpp +++ /dev/null @@ -1,828 +0,0 @@ -// cryptlib.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "cryptlib.h" -#include "misc.h" -#include "filters.h" -#include "algparam.h" -#include "fips140.h" -#include "argnames.h" -#include "fltrimpl.h" -#include "trdlocal.h" -#include "osrng.h" - -#include <memory> - -NAMESPACE_BEGIN(CryptoPP) - -CRYPTOPP_COMPILE_ASSERT(sizeof(byte) == 1); -CRYPTOPP_COMPILE_ASSERT(sizeof(word16) == 2); -CRYPTOPP_COMPILE_ASSERT(sizeof(word32) == 4); -CRYPTOPP_COMPILE_ASSERT(sizeof(word64) == 8); -#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE -CRYPTOPP_COMPILE_ASSERT(sizeof(dword) == 2*sizeof(word)); -#endif - -const std::string DEFAULT_CHANNEL; -const std::string AAD_CHANNEL = "AAD"; -const std::string &BufferedTransformation::NULL_CHANNEL = DEFAULT_CHANNEL; - -class NullNameValuePairs : public NameValuePairs -{ -public: - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const {return false;} -}; - -simple_ptr<NullNameValuePairs> s_pNullNameValuePairs(new NullNameValuePairs); -const NameValuePairs &g_nullNameValuePairs = *s_pNullNameValuePairs.m_p; - -BufferedTransformation & TheBitBucket() -{ - static BitBucket bitBucket; - return bitBucket; -} - -Algorithm::Algorithm(bool checkSelfTestStatus) -{ - if (checkSelfTestStatus && FIPS_140_2_ComplianceEnabled()) - { - if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_NOT_DONE && !PowerUpSelfTestInProgressOnThisThread()) - throw SelfTestFailure("Cryptographic algorithms are disabled before the power-up self tests are performed."); - - if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_FAILED) - throw SelfTestFailure("Cryptographic algorithms are disabled after a power-up self test failed."); - } -} - -void SimpleKeyingInterface::SetKey(const byte *key, size_t length, const NameValuePairs ¶ms) -{ - this->ThrowIfInvalidKeyLength(length); - this->UncheckedSetKey(key, (unsigned int)length, params); -} - -void SimpleKeyingInterface::SetKeyWithRounds(const byte *key, size_t length, int rounds) -{ - SetKey(key, length, MakeParameters(Name::Rounds(), rounds)); -} - -void SimpleKeyingInterface::SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength) -{ - SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, ivLength))); -} - -void SimpleKeyingInterface::ThrowIfInvalidKeyLength(size_t length) -{ - if (!IsValidKeyLength(length)) - throw InvalidKeyLength(GetAlgorithm().AlgorithmName(), length); -} - -void SimpleKeyingInterface::ThrowIfResynchronizable() -{ - if (IsResynchronizable()) - throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object requires an IV"); -} - -void SimpleKeyingInterface::ThrowIfInvalidIV(const byte *iv) -{ - if (!iv && IVRequirement() == UNPREDICTABLE_RANDOM_IV) - throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object cannot use a null IV"); -} - -size_t SimpleKeyingInterface::ThrowIfInvalidIVLength(int size) -{ - if (size < 0) - return IVSize(); - else if ((size_t)size < MinIVLength()) - throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(size) + " is less than the minimum of " + IntToString(MinIVLength())); - else if ((size_t)size > MaxIVLength()) - throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(size) + " exceeds the maximum of " + IntToString(MaxIVLength())); - else - return size; -} - -const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(const NameValuePairs ¶ms, size_t &size) -{ - ConstByteArrayParameter ivWithLength; - const byte *iv; - bool found = false; - - try {found = params.GetValue(Name::IV(), ivWithLength);} - catch (const NameValuePairs::ValueTypeMismatch &) {} - - if (found) - { - iv = ivWithLength.begin(); - ThrowIfInvalidIV(iv); - size = ThrowIfInvalidIVLength((int)ivWithLength.size()); - return iv; - } - else if (params.GetValue(Name::IV(), iv)) - { - ThrowIfInvalidIV(iv); - size = IVSize(); - return iv; - } - else - { - ThrowIfResynchronizable(); - size = 0; - return NULL; - } -} - -void SimpleKeyingInterface::GetNextIV(RandomNumberGenerator &rng, byte *IV) -{ - rng.GenerateBlock(IV, IVSize()); -} - -size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const -{ - size_t blockSize = BlockSize(); - size_t inIncrement = (flags & (BT_InBlockIsCounter|BT_DontIncrementInOutPointers)) ? 0 : blockSize; - size_t xorIncrement = xorBlocks ? blockSize : 0; - size_t outIncrement = (flags & BT_DontIncrementInOutPointers) ? 0 : blockSize; - - if (flags & BT_ReverseDirection) - { - assert(length % blockSize == 0); - inBlocks += length - blockSize; - xorBlocks += length - blockSize; - outBlocks += length - blockSize; - inIncrement = 0-inIncrement; - xorIncrement = 0-xorIncrement; - outIncrement = 0-outIncrement; - } - - while (length >= blockSize) - { - if (flags & BT_XorInput) - { - xorbuf(outBlocks, xorBlocks, inBlocks, blockSize); - ProcessBlock(outBlocks); - } - else - ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks); - if (flags & BT_InBlockIsCounter) - const_cast<byte *>(inBlocks)[blockSize-1]++; - inBlocks += inIncrement; - outBlocks += outIncrement; - xorBlocks += xorIncrement; - length -= blockSize; - } - - return length; -} - -unsigned int BlockTransformation::OptimalDataAlignment() const -{ - return GetAlignmentOf<word32>(); -} - -unsigned int StreamTransformation::OptimalDataAlignment() const -{ - return GetAlignmentOf<word32>(); -} - -unsigned int HashTransformation::OptimalDataAlignment() const -{ - return GetAlignmentOf<word32>(); -} - -void StreamTransformation::ProcessLastBlock(byte *outString, const byte *inString, size_t length) -{ - assert(MinLastBlockSize() == 0); // this function should be overriden otherwise - - if (length == MandatoryBlockSize()) - ProcessData(outString, inString, length); - else if (length != 0) - throw NotImplemented(AlgorithmName() + ": this object does't support a special last block"); -} - -void AuthenticatedSymmetricCipher::SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength) -{ - if (headerLength > MaxHeaderLength()) - throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": header length " + IntToString(headerLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength())); - - if (messageLength > MaxMessageLength()) - throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": message length " + IntToString(messageLength) + " exceeds the maximum of " + IntToString(MaxMessageLength())); - - if (footerLength > MaxFooterLength()) - throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": footer length " + IntToString(footerLength) + " exceeds the maximum of " + IntToString(MaxFooterLength())); - - UncheckedSpecifyDataLengths(headerLength, messageLength, footerLength); -} - -void AuthenticatedSymmetricCipher::EncryptAndAuthenticate(byte *ciphertext, byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *header, size_t headerLength, const byte *message, size_t messageLength) -{ - Resynchronize(iv, ivLength); - SpecifyDataLengths(headerLength, messageLength); - Update(header, headerLength); - ProcessString(ciphertext, message, messageLength); - TruncatedFinal(mac, macSize); -} - -bool AuthenticatedSymmetricCipher::DecryptAndVerify(byte *message, const byte *mac, size_t macLength, const byte *iv, int ivLength, const byte *header, size_t headerLength, const byte *ciphertext, size_t ciphertextLength) -{ - Resynchronize(iv, ivLength); - SpecifyDataLengths(headerLength, ciphertextLength); - Update(header, headerLength); - ProcessString(message, ciphertext, ciphertextLength); - return TruncatedVerify(mac, macLength); -} - -unsigned int RandomNumberGenerator::GenerateBit() -{ - return GenerateByte() & 1; -} - -byte RandomNumberGenerator::GenerateByte() -{ - byte b; - GenerateBlock(&b, 1); - return b; -} - -word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max) -{ - word32 range = max-min; - const int maxBits = BitPrecision(range); - - word32 value; - - do - { - GenerateBlock((byte *)&value, sizeof(value)); - value = Crop(value, maxBits); - } while (value > range); - - return value+min; -} - -void RandomNumberGenerator::GenerateBlock(byte *output, size_t size) -{ - ArraySink s(output, size); - GenerateIntoBufferedTransformation(s, DEFAULT_CHANNEL, size); -} - -void RandomNumberGenerator::DiscardBytes(size_t n) -{ - GenerateIntoBufferedTransformation(TheBitBucket(), DEFAULT_CHANNEL, n); -} - -void RandomNumberGenerator::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length) -{ - FixedSizeSecBlock<byte, 256> buffer; - while (length) - { - size_t len = UnsignedMin(buffer.size(), length); - GenerateBlock(buffer, len); - target.ChannelPut(channel, buffer, len); - length -= len; - } -} - -//! see NullRNG() -class ClassNullRNG : public RandomNumberGenerator -{ -public: - std::string AlgorithmName() const {return "NullRNG";} - void GenerateBlock(byte *output, size_t size) {throw NotImplemented("NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes");} -}; - -RandomNumberGenerator & NullRNG() -{ - static ClassNullRNG s_nullRNG; - return s_nullRNG; -} - -bool HashTransformation::TruncatedVerify(const byte *digestIn, size_t digestLength) -{ - ThrowIfInvalidTruncatedSize(digestLength); - SecByteBlock digest(digestLength); - TruncatedFinal(digest, digestLength); - return VerifyBufsEqual(digest, digestIn, digestLength); -} - -void HashTransformation::ThrowIfInvalidTruncatedSize(size_t size) const -{ - if (size > DigestSize()) - throw InvalidArgument("HashTransformation: can't truncate a " + IntToString(DigestSize()) + " byte digest to " + IntToString(size) + " bytes"); -} - -unsigned int BufferedTransformation::GetMaxWaitObjectCount() const -{ - const BufferedTransformation *t = AttachedTransformation(); - return t ? t->GetMaxWaitObjectCount() : 0; -} - -void BufferedTransformation::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) -{ - BufferedTransformation *t = AttachedTransformation(); - if (t) - t->GetWaitObjects(container, callStack); // reduce clutter by not adding to stack here -} - -void BufferedTransformation::Initialize(const NameValuePairs ¶meters, int propagation) -{ - assert(!AttachedTransformation()); - IsolatedInitialize(parameters); -} - -bool BufferedTransformation::Flush(bool hardFlush, int propagation, bool blocking) -{ - assert(!AttachedTransformation()); - return IsolatedFlush(hardFlush, blocking); -} - -bool BufferedTransformation::MessageSeriesEnd(int propagation, bool blocking) -{ - assert(!AttachedTransformation()); - return IsolatedMessageSeriesEnd(blocking); -} - -byte * BufferedTransformation::ChannelCreatePutSpace(const std::string &channel, size_t &size) -{ - if (channel.empty()) - return CreatePutSpace(size); - else - throw NoChannelSupport(AlgorithmName()); -} - -size_t BufferedTransformation::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) -{ - if (channel.empty()) - return Put2(begin, length, messageEnd, blocking); - else - throw NoChannelSupport(AlgorithmName()); -} - -size_t BufferedTransformation::ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking) -{ - if (channel.empty()) - return PutModifiable2(begin, length, messageEnd, blocking); - else - return ChannelPut2(channel, begin, length, messageEnd, blocking); -} - -bool BufferedTransformation::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking) -{ - if (channel.empty()) - return Flush(completeFlush, propagation, blocking); - else - throw NoChannelSupport(AlgorithmName()); -} - -bool BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking) -{ - if (channel.empty()) - return MessageSeriesEnd(propagation, blocking); - else - throw NoChannelSupport(AlgorithmName()); -} - -lword BufferedTransformation::MaxRetrievable() const -{ - if (AttachedTransformation()) - return AttachedTransformation()->MaxRetrievable(); - else - return CopyTo(TheBitBucket()); -} - -bool BufferedTransformation::AnyRetrievable() const -{ - if (AttachedTransformation()) - return AttachedTransformation()->AnyRetrievable(); - else - { - byte b; - return Peek(b) != 0; - } -} - -size_t BufferedTransformation::Get(byte &outByte) -{ - if (AttachedTransformation()) - return AttachedTransformation()->Get(outByte); - else - return Get(&outByte, 1); -} - -size_t BufferedTransformation::Get(byte *outString, size_t getMax) -{ - if (AttachedTransformation()) - return AttachedTransformation()->Get(outString, getMax); - else - { - ArraySink arraySink(outString, getMax); - return (size_t)TransferTo(arraySink, getMax); - } -} - -size_t BufferedTransformation::Peek(byte &outByte) const -{ - if (AttachedTransformation()) - return AttachedTransformation()->Peek(outByte); - else - return Peek(&outByte, 1); -} - -size_t BufferedTransformation::Peek(byte *outString, size_t peekMax) const -{ - if (AttachedTransformation()) - return AttachedTransformation()->Peek(outString, peekMax); - else - { - ArraySink arraySink(outString, peekMax); - return (size_t)CopyTo(arraySink, peekMax); - } -} - -lword BufferedTransformation::Skip(lword skipMax) -{ - if (AttachedTransformation()) - return AttachedTransformation()->Skip(skipMax); - else - return TransferTo(TheBitBucket(), skipMax); -} - -lword BufferedTransformation::TotalBytesRetrievable() const -{ - if (AttachedTransformation()) - return AttachedTransformation()->TotalBytesRetrievable(); - else - return MaxRetrievable(); -} - -unsigned int BufferedTransformation::NumberOfMessages() const -{ - if (AttachedTransformation()) - return AttachedTransformation()->NumberOfMessages(); - else - return CopyMessagesTo(TheBitBucket()); -} - -bool BufferedTransformation::AnyMessages() const -{ - if (AttachedTransformation()) - return AttachedTransformation()->AnyMessages(); - else - return NumberOfMessages() != 0; -} - -bool BufferedTransformation::GetNextMessage() -{ - if (AttachedTransformation()) - return AttachedTransformation()->GetNextMessage(); - else - { - assert(!AnyMessages()); - return false; - } -} - -unsigned int BufferedTransformation::SkipMessages(unsigned int count) -{ - if (AttachedTransformation()) - return AttachedTransformation()->SkipMessages(count); - else - return TransferMessagesTo(TheBitBucket(), count); -} - -size_t BufferedTransformation::TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel, bool blocking) -{ - if (AttachedTransformation()) - return AttachedTransformation()->TransferMessagesTo2(target, messageCount, channel, blocking); - else - { - unsigned int maxMessages = messageCount; - for (messageCount=0; messageCount < maxMessages && AnyMessages(); messageCount++) - { - size_t blockedBytes; - lword transferredBytes; - - while (AnyRetrievable()) - { - transferredBytes = LWORD_MAX; - blockedBytes = TransferTo2(target, transferredBytes, channel, blocking); - if (blockedBytes > 0) - return blockedBytes; - } - - if (target.ChannelMessageEnd(channel, GetAutoSignalPropagation(), blocking)) - return 1; - - bool result = GetNextMessage(); - assert(result); - } - return 0; - } -} - -unsigned int BufferedTransformation::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const -{ - if (AttachedTransformation()) - return AttachedTransformation()->CopyMessagesTo(target, count, channel); - else - return 0; -} - -void BufferedTransformation::SkipAll() -{ - if (AttachedTransformation()) - AttachedTransformation()->SkipAll(); - else - { - while (SkipMessages()) {} - while (Skip()) {} - } -} - -size_t BufferedTransformation::TransferAllTo2(BufferedTransformation &target, const std::string &channel, bool blocking) -{ - if (AttachedTransformation()) - return AttachedTransformation()->TransferAllTo2(target, channel, blocking); - else - { - assert(!NumberOfMessageSeries()); - - unsigned int messageCount; - do - { - messageCount = UINT_MAX; - size_t blockedBytes = TransferMessagesTo2(target, messageCount, channel, blocking); - if (blockedBytes) - return blockedBytes; - } - while (messageCount != 0); - - lword byteCount; - do - { - byteCount = ULONG_MAX; - size_t blockedBytes = TransferTo2(target, byteCount, channel, blocking); - if (blockedBytes) - return blockedBytes; - } - while (byteCount != 0); - - return 0; - } -} - -void BufferedTransformation::CopyAllTo(BufferedTransformation &target, const std::string &channel) const -{ - if (AttachedTransformation()) - AttachedTransformation()->CopyAllTo(target, channel); - else - { - assert(!NumberOfMessageSeries()); - while (CopyMessagesTo(target, UINT_MAX, channel)) {} - } -} - -void BufferedTransformation::SetRetrievalChannel(const std::string &channel) -{ - if (AttachedTransformation()) - AttachedTransformation()->SetRetrievalChannel(channel); -} - -size_t BufferedTransformation::ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order, bool blocking) -{ - PutWord(false, order, m_buf, value); - return ChannelPut(channel, m_buf, 2, blocking); -} - -size_t BufferedTransformation::ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order, bool blocking) -{ - PutWord(false, order, m_buf, value); - return ChannelPut(channel, m_buf, 4, blocking); -} - -size_t BufferedTransformation::PutWord16(word16 value, ByteOrder order, bool blocking) -{ - return ChannelPutWord16(DEFAULT_CHANNEL, value, order, blocking); -} - -size_t BufferedTransformation::PutWord32(word32 value, ByteOrder order, bool blocking) -{ - return ChannelPutWord32(DEFAULT_CHANNEL, value, order, blocking); -} - -size_t BufferedTransformation::PeekWord16(word16 &value, ByteOrder order) const -{ - byte buf[2] = {0, 0}; - size_t len = Peek(buf, 2); - - if (order) - value = (buf[0] << 8) | buf[1]; - else - value = (buf[1] << 8) | buf[0]; - - return len; -} - -size_t BufferedTransformation::PeekWord32(word32 &value, ByteOrder order) const -{ - byte buf[4] = {0, 0, 0, 0}; - size_t len = Peek(buf, 4); - - if (order) - value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf [3]; - else - value = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf [0]; - - return len; -} - -size_t BufferedTransformation::GetWord16(word16 &value, ByteOrder order) -{ - return (size_t)Skip(PeekWord16(value, order)); -} - -size_t BufferedTransformation::GetWord32(word32 &value, ByteOrder order) -{ - return (size_t)Skip(PeekWord32(value, order)); -} - -void BufferedTransformation::Attach(BufferedTransformation *newOut) -{ - if (AttachedTransformation() && AttachedTransformation()->Attachable()) - AttachedTransformation()->Attach(newOut); - else - Detach(newOut); -} - -void GeneratableCryptoMaterial::GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize) -{ - GenerateRandom(rng, MakeParameters("KeySize", (int)keySize)); -} - -class PK_DefaultEncryptionFilter : public Unflushable<Filter> -{ -public: - PK_DefaultEncryptionFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment, const NameValuePairs ¶meters) - : m_rng(rng), m_encryptor(encryptor), m_parameters(parameters) - { - Detach(attachment); - } - - size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) - { - FILTER_BEGIN; - m_plaintextQueue.Put(inString, length); - - if (messageEnd) - { - { - size_t plaintextLength; - if (!SafeConvert(m_plaintextQueue.CurrentSize(), plaintextLength)) - throw InvalidArgument("PK_DefaultEncryptionFilter: plaintext too long"); - size_t ciphertextLength = m_encryptor.CiphertextLength(plaintextLength); - - SecByteBlock plaintext(plaintextLength); - m_plaintextQueue.Get(plaintext, plaintextLength); - m_ciphertext.resize(ciphertextLength); - m_encryptor.Encrypt(m_rng, plaintext, plaintextLength, m_ciphertext, m_parameters); - } - - FILTER_OUTPUT(1, m_ciphertext, m_ciphertext.size(), messageEnd); - } - FILTER_END_NO_MESSAGE_END; - } - - RandomNumberGenerator &m_rng; - const PK_Encryptor &m_encryptor; - const NameValuePairs &m_parameters; - ByteQueue m_plaintextQueue; - SecByteBlock m_ciphertext; -}; - -BufferedTransformation * PK_Encryptor::CreateEncryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs ¶meters) const -{ - return new PK_DefaultEncryptionFilter(rng, *this, attachment, parameters); -} - -class PK_DefaultDecryptionFilter : public Unflushable<Filter> -{ -public: - PK_DefaultDecryptionFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment, const NameValuePairs ¶meters) - : m_rng(rng), m_decryptor(decryptor), m_parameters(parameters) - { - Detach(attachment); - } - - size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) - { - FILTER_BEGIN; - m_ciphertextQueue.Put(inString, length); - - if (messageEnd) - { - { - size_t ciphertextLength; - if (!SafeConvert(m_ciphertextQueue.CurrentSize(), ciphertextLength)) - throw InvalidArgument("PK_DefaultDecryptionFilter: ciphertext too long"); - size_t maxPlaintextLength = m_decryptor.MaxPlaintextLength(ciphertextLength); - - SecByteBlock ciphertext(ciphertextLength); - m_ciphertextQueue.Get(ciphertext, ciphertextLength); - m_plaintext.resize(maxPlaintextLength); - m_result = m_decryptor.Decrypt(m_rng, ciphertext, ciphertextLength, m_plaintext, m_parameters); - if (!m_result.isValidCoding) - throw InvalidCiphertext(m_decryptor.AlgorithmName() + ": invalid ciphertext"); - } - - FILTER_OUTPUT(1, m_plaintext, m_result.messageLength, messageEnd); - } - FILTER_END_NO_MESSAGE_END; - } - - RandomNumberGenerator &m_rng; - const PK_Decryptor &m_decryptor; - const NameValuePairs &m_parameters; - ByteQueue m_ciphertextQueue; - SecByteBlock m_plaintext; - DecodingResult m_result; -}; - -BufferedTransformation * PK_Decryptor::CreateDecryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs ¶meters) const -{ - return new PK_DefaultDecryptionFilter(rng, *this, attachment, parameters); -} - -size_t PK_Signer::Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const -{ - std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator); - return SignAndRestart(rng, *m, signature, false); -} - -size_t PK_Signer::SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const -{ - std::auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng)); - m->Update(message, messageLen); - return SignAndRestart(rng, *m, signature, false); -} - -size_t PK_Signer::SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength, - const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const -{ - std::auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng)); - InputRecoverableMessage(*m, recoverableMessage, recoverableMessageLength); - m->Update(nonrecoverableMessage, nonrecoverableMessageLength); - return SignAndRestart(rng, *m, signature, false); -} - -bool PK_Verifier::Verify(PK_MessageAccumulator *messageAccumulator) const -{ - std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator); - return VerifyAndRestart(*m); -} - -bool PK_Verifier::VerifyMessage(const byte *message, size_t messageLen, const byte *signature, size_t signatureLength) const -{ - std::auto_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator()); - InputSignature(*m, signature, signatureLength); - m->Update(message, messageLen); - return VerifyAndRestart(*m); -} - -DecodingResult PK_Verifier::Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const -{ - std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator); - return RecoverAndRestart(recoveredMessage, *m); -} - -DecodingResult PK_Verifier::RecoverMessage(byte *recoveredMessage, - const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, - const byte *signature, size_t signatureLength) const -{ - std::auto_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator()); - InputSignature(*m, signature, signatureLength); - m->Update(nonrecoverableMessage, nonrecoverableMessageLength); - return RecoverAndRestart(recoveredMessage, *m); -} - -void SimpleKeyAgreementDomain::GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const -{ - GeneratePrivateKey(rng, privateKey); - GeneratePublicKey(rng, privateKey, publicKey); -} - -void AuthenticatedKeyAgreementDomain::GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const -{ - GenerateStaticPrivateKey(rng, privateKey); - GenerateStaticPublicKey(rng, privateKey, publicKey); -} - -void AuthenticatedKeyAgreementDomain::GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const -{ - GenerateEphemeralPrivateKey(rng, privateKey); - GenerateEphemeralPublicKey(rng, privateKey, publicKey); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/cryptlib.h b/lib/cryptopp/cryptlib.h deleted file mode 100644 index 406872232..000000000 --- a/lib/cryptopp/cryptlib.h +++ /dev/null @@ -1,1655 +0,0 @@ -// cryptlib.h - written and placed in the public domain by Wei Dai -/*! \file - This file contains the declarations for the abstract base - classes that provide a uniform interface to this library. -*/ - -/*! \mainpage Crypto++ Library 5.6.2 API Reference -<dl> -<dt>Abstract Base Classes<dd> - cryptlib.h -<dt>Authenticated Encryption<dd> - AuthenticatedSymmetricCipherDocumentation -<dt>Symmetric Ciphers<dd> - SymmetricCipherDocumentation -<dt>Hash Functions<dd> - SHA1, SHA224, SHA256, SHA384, SHA512, Tiger, Whirlpool, RIPEMD160, RIPEMD320, RIPEMD128, RIPEMD256, Weak1::MD2, Weak1::MD4, Weak1::MD5 -<dt>Non-Cryptographic Checksums<dd> - CRC32, Adler32 -<dt>Message Authentication Codes<dd> - VMAC, HMAC, CBC_MAC, CMAC, DMAC, TTMAC, GCM (GMAC) -<dt>Random Number Generators<dd> - NullRNG(), LC_RNG, RandomPool, BlockingRng, NonblockingRng, AutoSeededRandomPool, AutoSeededX917RNG, #DefaultAutoSeededRNG -<dt>Password-based Cryptography<dd> - PasswordBasedKeyDerivationFunction -<dt>Public Key Cryptosystems<dd> - DLIES, ECIES, LUCES, RSAES, RabinES, LUC_IES -<dt>Public Key Signature Schemes<dd> - DSA2, GDSA, ECDSA, NR, ECNR, LUCSS, RSASS, RSASS_ISO, RabinSS, RWSS, ESIGN -<dt>Key Agreement<dd> - #DH, DH2, #MQV, ECDH, ECMQV, XTR_DH -<dt>Algebraic Structures<dd> - Integer, PolynomialMod2, PolynomialOver, RingOfPolynomialsOver, - ModularArithmetic, MontgomeryRepresentation, GFP2_ONB, - GF2NP, GF256, GF2_32, EC2N, ECP -<dt>Secret Sharing and Information Dispersal<dd> - SecretSharing, SecretRecovery, InformationDispersal, InformationRecovery -<dt>Compression<dd> - Deflator, Inflator, Gzip, Gunzip, ZlibCompressor, ZlibDecompressor -<dt>Input Source Classes<dd> - StringSource, #ArraySource, FileSource, SocketSource, WindowsPipeSource, RandomNumberSource -<dt>Output Sink Classes<dd> - StringSinkTemplate, ArraySink, FileSink, SocketSink, WindowsPipeSink, RandomNumberSink -<dt>Filter Wrappers<dd> - StreamTransformationFilter, HashFilter, HashVerificationFilter, SignerFilter, SignatureVerificationFilter -<dt>Binary to Text Encoders and Decoders<dd> - HexEncoder, HexDecoder, Base64Encoder, Base64Decoder, Base32Encoder, Base32Decoder -<dt>Wrappers for OS features<dd> - Timer, Socket, WindowsHandle, ThreadLocalStorage, ThreadUserTimer -<dt>FIPS 140 related<dd> - fips140.h -</dl> - -In the DLL version of Crypto++, only the following implementation class are available. -<dl> -<dt>Block Ciphers<dd> - AES, DES_EDE2, DES_EDE3, SKIPJACK -<dt>Cipher Modes (replace template parameter BC with one of the block ciphers above)<dd> - ECB_Mode\<BC\>, CTR_Mode\<BC\>, CBC_Mode\<BC\>, CFB_FIPS_Mode\<BC\>, OFB_Mode\<BC\>, GCM\<AES\> -<dt>Hash Functions<dd> - SHA1, SHA224, SHA256, SHA384, SHA512 -<dt>Public Key Signature Schemes (replace template parameter H with one of the hash functions above)<dd> - RSASS\<PKCS1v15, H\>, RSASS\<PSS, H\>, RSASS_ISO\<H\>, RWSS\<P1363_EMSA2, H\>, DSA, ECDSA\<ECP, H\>, ECDSA\<EC2N, H\> -<dt>Message Authentication Codes (replace template parameter H with one of the hash functions above)<dd> - HMAC\<H\>, CBC_MAC\<DES_EDE2\>, CBC_MAC\<DES_EDE3\>, GCM\<AES\> -<dt>Random Number Generators<dd> - #DefaultAutoSeededRNG (AutoSeededX917RNG\<AES\>) -<dt>Key Agreement<dd> - #DH -<dt>Public Key Cryptosystems<dd> - RSAES\<OAEP\<SHA1\> \> -</dl> - -<p>This reference manual is a work in progress. Some classes are still lacking detailed descriptions. -<p>Click <a href="CryptoPPRef.zip">here</a> to download a zip archive containing this manual. -<p>Thanks to Ryan Phillips for providing the Doxygen configuration file -and getting me started with this manual. -*/ - -#ifndef CRYPTOPP_CRYPTLIB_H -#define CRYPTOPP_CRYPTLIB_H - -#include "config.h" -#include "stdcpp.h" - -NAMESPACE_BEGIN(CryptoPP) - -// forward declarations -class Integer; -class RandomNumberGenerator; -class BufferedTransformation; - -//! used to specify a direction for a cipher to operate in (encrypt or decrypt) -enum CipherDir {ENCRYPTION, DECRYPTION}; - -//! used to represent infinite time -const unsigned long INFINITE_TIME = ULONG_MAX; - -// VC60 workaround: using enums as template parameters causes problems -template <typename ENUM_TYPE, int VALUE> -struct EnumToType -{ - static ENUM_TYPE ToEnum() {return (ENUM_TYPE)VALUE;} -}; - -enum ByteOrder {LITTLE_ENDIAN_ORDER = 0, BIG_ENDIAN_ORDER = 1}; -typedef EnumToType<ByteOrder, LITTLE_ENDIAN_ORDER> LittleEndian; -typedef EnumToType<ByteOrder, BIG_ENDIAN_ORDER> BigEndian; - -//! base class for all exceptions thrown by Crypto++ -class CRYPTOPP_DLL Exception : public std::exception -{ -public: - //! error types - enum ErrorType { - //! a method is not implemented - NOT_IMPLEMENTED, - //! invalid function argument - INVALID_ARGUMENT, - //! BufferedTransformation received a Flush(true) signal but can't flush buffers - CANNOT_FLUSH, - //! data integerity check (such as CRC or MAC) failed - DATA_INTEGRITY_CHECK_FAILED, - //! received input data that doesn't conform to expected format - INVALID_DATA_FORMAT, - //! error reading from input device or writing to output device - IO_ERROR, - //! some error not belong to any of the above categories - OTHER_ERROR - }; - - explicit Exception(ErrorType errorType, const std::string &s) : m_errorType(errorType), m_what(s) {} - virtual ~Exception() throw() {} - const char *what() const throw() {return (m_what.c_str());} - const std::string &GetWhat() const {return m_what;} - void SetWhat(const std::string &s) {m_what = s;} - ErrorType GetErrorType() const {return m_errorType;} - void SetErrorType(ErrorType errorType) {m_errorType = errorType;} - -private: - ErrorType m_errorType; - std::string m_what; -}; - -//! exception thrown when an invalid argument is detected -class CRYPTOPP_DLL InvalidArgument : public Exception -{ -public: - explicit InvalidArgument(const std::string &s) : Exception(INVALID_ARGUMENT, s) {} -}; - -//! exception thrown when input data is received that doesn't conform to expected format -class CRYPTOPP_DLL InvalidDataFormat : public Exception -{ -public: - explicit InvalidDataFormat(const std::string &s) : Exception(INVALID_DATA_FORMAT, s) {} -}; - -//! exception thrown by decryption filters when trying to decrypt an invalid ciphertext -class CRYPTOPP_DLL InvalidCiphertext : public InvalidDataFormat -{ -public: - explicit InvalidCiphertext(const std::string &s) : InvalidDataFormat(s) {} -}; - -//! exception thrown by a class if a non-implemented method is called -class CRYPTOPP_DLL NotImplemented : public Exception -{ -public: - explicit NotImplemented(const std::string &s) : Exception(NOT_IMPLEMENTED, s) {} -}; - -//! exception thrown by a class when Flush(true) is called but it can't completely flush its buffers -class CRYPTOPP_DLL CannotFlush : public Exception -{ -public: - explicit CannotFlush(const std::string &s) : Exception(CANNOT_FLUSH, s) {} -}; - -//! error reported by the operating system -class CRYPTOPP_DLL OS_Error : public Exception -{ -public: - OS_Error(ErrorType errorType, const std::string &s, const std::string& operation, int errorCode) - : Exception(errorType, s), m_operation(operation), m_errorCode(errorCode) {} - ~OS_Error() throw() {} - - // the operating system API that reported the error - const std::string & GetOperation() const {return m_operation;} - // the error code return by the operating system - int GetErrorCode() const {return m_errorCode;} - -protected: - std::string m_operation; - int m_errorCode; -}; - -//! used to return decoding results -struct CRYPTOPP_DLL DecodingResult -{ - explicit DecodingResult() : isValidCoding(false), messageLength(0) {} - explicit DecodingResult(size_t len) : isValidCoding(true), messageLength(len) {} - - bool operator==(const DecodingResult &rhs) const {return isValidCoding == rhs.isValidCoding && messageLength == rhs.messageLength;} - bool operator!=(const DecodingResult &rhs) const {return !operator==(rhs);} - - bool isValidCoding; - size_t messageLength; - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - operator size_t() const {return isValidCoding ? messageLength : 0;} -#endif -}; - -//! interface for retrieving values given their names -/*! \note This class is used to safely pass a variable number of arbitrarily typed arguments to functions - and to read values from keys and crypto parameters. - \note To obtain an object that implements NameValuePairs for the purpose of parameter - passing, use the MakeParameters() function. - \note To get a value from NameValuePairs, you need to know the name and the type of the value. - Call GetValueNames() on a NameValuePairs object to obtain a list of value names that it supports. - Then look at the Name namespace documentation to see what the type of each value is, or - alternatively, call GetIntValue() with the value name, and if the type is not int, a - ValueTypeMismatch exception will be thrown and you can get the actual type from the exception object. -*/ -class CRYPTOPP_NO_VTABLE NameValuePairs -{ -public: - virtual ~NameValuePairs() {} - - //! exception thrown when trying to retrieve a value using a different type than expected - class CRYPTOPP_DLL ValueTypeMismatch : public InvalidArgument - { - public: - ValueTypeMismatch(const std::string &name, const std::type_info &stored, const std::type_info &retrieving) - : InvalidArgument("NameValuePairs: type mismatch for '" + name + "', stored '" + stored.name() + "', trying to retrieve '" + retrieving.name() + "'") - , m_stored(stored), m_retrieving(retrieving) {} - - const std::type_info & GetStoredTypeInfo() const {return m_stored;} - const std::type_info & GetRetrievingTypeInfo() const {return m_retrieving;} - - private: - const std::type_info &m_stored; - const std::type_info &m_retrieving; - }; - - //! get a copy of this object or a subobject of it - template <class T> - bool GetThisObject(T &object) const - { - return GetValue((std::string("ThisObject:")+typeid(T).name()).c_str(), object); - } - - //! get a pointer to this object, as a pointer to T - template <class T> - bool GetThisPointer(T *&p) const - { - return GetValue((std::string("ThisPointer:")+typeid(T).name()).c_str(), p); - } - - //! get a named value, returns true if the name exists - template <class T> - bool GetValue(const char *name, T &value) const - { - return GetVoidValue(name, typeid(T), &value); - } - - //! get a named value, returns the default if the name doesn't exist - template <class T> - T GetValueWithDefault(const char *name, T defaultValue) const - { - GetValue(name, defaultValue); - return defaultValue; - } - - //! get a list of value names that can be retrieved - CRYPTOPP_DLL std::string GetValueNames() const - {std::string result; GetValue("ValueNames", result); return result;} - - //! get a named value with type int - /*! used to ensure we don't accidentally try to get an unsigned int - or some other type when we mean int (which is the most common case) */ - CRYPTOPP_DLL bool GetIntValue(const char *name, int &value) const - {return GetValue(name, value);} - - //! get a named value with type int, with default - CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const - {return GetValueWithDefault(name, defaultValue);} - - //! used by derived classes to check for type mismatch - CRYPTOPP_DLL static void CRYPTOPP_API ThrowIfTypeMismatch(const char *name, const std::type_info &stored, const std::type_info &retrieving) - {if (stored != retrieving) throw ValueTypeMismatch(name, stored, retrieving);} - - template <class T> - void GetRequiredParameter(const char *className, const char *name, T &value) const - { - if (!GetValue(name, value)) - throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'"); - } - - CRYPTOPP_DLL void GetRequiredIntParameter(const char *className, const char *name, int &value) const - { - if (!GetIntValue(name, value)) - throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'"); - } - - //! to be implemented by derived classes, users should use one of the above functions instead - CRYPTOPP_DLL virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const =0; -}; - -//! namespace containing value name definitions -/*! value names, types and semantics: - - ThisObject:ClassName (ClassName, copy of this object or a subobject) - ThisPointer:ClassName (const ClassName *, pointer to this object or a subobject) -*/ -DOCUMENTED_NAMESPACE_BEGIN(Name) -// more names defined in argnames.h -DOCUMENTED_NAMESPACE_END - -//! empty set of name-value pairs -extern CRYPTOPP_DLL const NameValuePairs &g_nullNameValuePairs; - -// ******************************************************** - -//! interface for cloning objects, this is not implemented by most classes yet -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Clonable -{ -public: - virtual ~Clonable() {} - //! this is not implemented by most classes yet - virtual Clonable* Clone() const {throw NotImplemented("Clone() is not implemented yet.");} // TODO: make this =0 -}; - -//! interface for all crypto algorithms - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Algorithm : public Clonable -{ -public: - /*! When FIPS 140-2 compliance is enabled and checkSelfTestStatus == true, - this constructor throws SelfTestFailure if the self test hasn't been run or fails. */ - Algorithm(bool checkSelfTestStatus = true); - //! returns name of this algorithm, not universally implemented yet - virtual std::string AlgorithmName() const {return "unknown";} -}; - -//! keying interface for crypto algorithms that take byte strings as keys -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyingInterface -{ -public: - virtual ~SimpleKeyingInterface() {} - - //! returns smallest valid key length in bytes */ - virtual size_t MinKeyLength() const =0; - //! returns largest valid key length in bytes */ - virtual size_t MaxKeyLength() const =0; - //! returns default (recommended) key length in bytes */ - virtual size_t DefaultKeyLength() const =0; - - //! returns the smallest valid key length in bytes that is >= min(n, GetMaxKeyLength()) - virtual size_t GetValidKeyLength(size_t n) const =0; - - //! returns whether n is a valid key length - virtual bool IsValidKeyLength(size_t n) const - {return n == GetValidKeyLength(n);} - - //! set or reset the key of this object - /*! \param params is used to specify Rounds, BlockSize, etc. */ - virtual void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms = g_nullNameValuePairs); - - //! calls SetKey() with an NameValuePairs object that just specifies "Rounds" - void SetKeyWithRounds(const byte *key, size_t length, int rounds); - - //! calls SetKey() with an NameValuePairs object that just specifies "IV" - void SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength); - - //! calls SetKey() with an NameValuePairs object that just specifies "IV" - void SetKeyWithIV(const byte *key, size_t length, const byte *iv) - {SetKeyWithIV(key, length, iv, IVSize());} - - enum IV_Requirement {UNIQUE_IV = 0, RANDOM_IV, UNPREDICTABLE_RANDOM_IV, INTERNALLY_GENERATED_IV, NOT_RESYNCHRONIZABLE}; - //! returns the minimal requirement for secure IVs - virtual IV_Requirement IVRequirement() const =0; - - //! returns whether this object can be resynchronized (i.e. supports initialization vectors) - /*! If this function returns true, and no IV is passed to SetKey() and CanUseStructuredIVs()==true, an IV of all 0's will be assumed. */ - bool IsResynchronizable() const {return IVRequirement() < NOT_RESYNCHRONIZABLE;} - //! returns whether this object can use random IVs (in addition to ones returned by GetNextIV) - bool CanUseRandomIVs() const {return IVRequirement() <= UNPREDICTABLE_RANDOM_IV;} - //! returns whether this object can use random but possibly predictable IVs (in addition to ones returned by GetNextIV) - bool CanUsePredictableIVs() const {return IVRequirement() <= RANDOM_IV;} - //! returns whether this object can use structured IVs, for example a counter (in addition to ones returned by GetNextIV) - bool CanUseStructuredIVs() const {return IVRequirement() <= UNIQUE_IV;} - - virtual unsigned int IVSize() const {throw NotImplemented(GetAlgorithm().AlgorithmName() + ": this object doesn't support resynchronization");} - //! returns default length of IVs accepted by this object - unsigned int DefaultIVLength() const {return IVSize();} - //! returns minimal length of IVs accepted by this object - virtual unsigned int MinIVLength() const {return IVSize();} - //! returns maximal length of IVs accepted by this object - virtual unsigned int MaxIVLength() const {return IVSize();} - //! resynchronize with an IV. ivLength=-1 means use IVSize() - virtual void Resynchronize(const byte *iv, int ivLength=-1) {throw NotImplemented(GetAlgorithm().AlgorithmName() + ": this object doesn't support resynchronization");} - //! get a secure IV for the next message - /*! This method should be called after you finish encrypting one message and are ready to start the next one. - After calling it, you must call SetKey() or Resynchronize() before using this object again. - This method is not implemented on decryption objects. */ - virtual void GetNextIV(RandomNumberGenerator &rng, byte *IV); - -protected: - virtual const Algorithm & GetAlgorithm() const =0; - virtual void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) =0; - - void ThrowIfInvalidKeyLength(size_t length); - void ThrowIfResynchronizable(); // to be called when no IV is passed - void ThrowIfInvalidIV(const byte *iv); // check for NULL IV if it can't be used - size_t ThrowIfInvalidIVLength(int size); - const byte * GetIVAndThrowIfInvalid(const NameValuePairs ¶ms, size_t &size); - inline void AssertValidKeyLength(size_t length) const - {assert(IsValidKeyLength(length));} -}; - -//! interface for the data processing part of block ciphers - -/*! Classes derived from BlockTransformation are block ciphers - in ECB mode (for example the DES::Encryption class), which are stateless. - These classes should not be used directly, but only in combination with - a mode class (see CipherModeDocumentation in modes.h). -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockTransformation : public Algorithm -{ -public: - //! encrypt or decrypt inBlock, xor with xorBlock, and write to outBlock - virtual void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const =0; - - //! encrypt or decrypt one block - /*! \pre size of inBlock and outBlock == BlockSize() */ - void ProcessBlock(const byte *inBlock, byte *outBlock) const - {ProcessAndXorBlock(inBlock, NULL, outBlock);} - - //! encrypt or decrypt one block in place - void ProcessBlock(byte *inoutBlock) const - {ProcessAndXorBlock(inoutBlock, NULL, inoutBlock);} - - //! block size of the cipher in bytes - virtual unsigned int BlockSize() const =0; - - //! returns how inputs and outputs should be aligned for optimal performance - virtual unsigned int OptimalDataAlignment() const; - - //! returns true if this is a permutation (i.e. there is an inverse transformation) - virtual bool IsPermutation() const {return true;} - - //! returns true if this is an encryption object - virtual bool IsForwardTransformation() const =0; - - //! return number of blocks that can be processed in parallel, for bit-slicing implementations - virtual unsigned int OptimalNumberOfParallelBlocks() const {return 1;} - - enum {BT_InBlockIsCounter=1, BT_DontIncrementInOutPointers=2, BT_XorInput=4, BT_ReverseDirection=8, BT_AllowParallel=16} FlagsForAdvancedProcessBlocks; - - //! encrypt and xor blocks according to flags (see FlagsForAdvancedProcessBlocks) - /*! /note If BT_InBlockIsCounter is set, last byte of inBlocks may be modified. */ - virtual size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; - - inline CipherDir GetCipherDirection() const {return IsForwardTransformation() ? ENCRYPTION : DECRYPTION;} -}; - -//! interface for the data processing part of stream ciphers - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE StreamTransformation : public Algorithm -{ -public: - //! return a reference to this object, useful for passing a temporary object to a function that takes a non-const reference - StreamTransformation& Ref() {return *this;} - - //! returns block size, if input must be processed in blocks, otherwise 1 - virtual unsigned int MandatoryBlockSize() const {return 1;} - - //! returns the input block size that is most efficient for this cipher - /*! \note optimal input length is n * OptimalBlockSize() - GetOptimalBlockSizeUsed() for any n > 0 */ - virtual unsigned int OptimalBlockSize() const {return MandatoryBlockSize();} - //! returns how much of the current block is used up - virtual unsigned int GetOptimalBlockSizeUsed() const {return 0;} - - //! returns how input should be aligned for optimal performance - virtual unsigned int OptimalDataAlignment() const; - - //! encrypt or decrypt an array of bytes of specified length - /*! \note either inString == outString, or they don't overlap */ - virtual void ProcessData(byte *outString, const byte *inString, size_t length) =0; - - //! for ciphers where the last block of data is special, encrypt or decrypt the last block of data - /*! For now the only use of this function is for CBC-CTS mode. */ - virtual void ProcessLastBlock(byte *outString, const byte *inString, size_t length); - //! returns the minimum size of the last block, 0 indicating the last block is not special - virtual unsigned int MinLastBlockSize() const {return 0;} - - //! same as ProcessData(inoutString, inoutString, length) - inline void ProcessString(byte *inoutString, size_t length) - {ProcessData(inoutString, inoutString, length);} - //! same as ProcessData(outString, inString, length) - inline void ProcessString(byte *outString, const byte *inString, size_t length) - {ProcessData(outString, inString, length);} - //! implemented as {ProcessData(&input, &input, 1); return input;} - inline byte ProcessByte(byte input) - {ProcessData(&input, &input, 1); return input;} - - //! returns whether this cipher supports random access - virtual bool IsRandomAccess() const =0; - //! for random access ciphers, seek to an absolute position - virtual void Seek(lword n) - { - assert(!IsRandomAccess()); - throw NotImplemented("StreamTransformation: this object doesn't support random access"); - } - - //! returns whether this transformation is self-inverting (e.g. xor with a keystream) - virtual bool IsSelfInverting() const =0; - //! returns whether this is an encryption object - virtual bool IsForwardTransformation() const =0; -}; - -//! interface for hash functions and data processing part of MACs - -/*! HashTransformation objects are stateful. They are created in an initial state, - change state as Update() is called, and return to the initial - state when Final() is called. This interface allows a large message to - be hashed in pieces by calling Update() on each piece followed by - calling Final(). -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE HashTransformation : public Algorithm -{ -public: - //! return a reference to this object, useful for passing a temporary object to a function that takes a non-const reference - HashTransformation& Ref() {return *this;} - - //! process more input - virtual void Update(const byte *input, size_t length) =0; - - //! request space to write input into - virtual byte * CreateUpdateSpace(size_t &size) {size=0; return NULL;} - - //! compute hash for current message, then restart for a new message - /*! \pre size of digest == DigestSize(). */ - virtual void Final(byte *digest) - {TruncatedFinal(digest, DigestSize());} - - //! discard the current state, and restart with a new message - virtual void Restart() - {TruncatedFinal(NULL, 0);} - - //! size of the hash/digest/MAC returned by Final() - virtual unsigned int DigestSize() const =0; - - //! same as DigestSize() - unsigned int TagSize() const {return DigestSize();} - - - //! block size of underlying compression function, or 0 if not block based - virtual unsigned int BlockSize() const {return 0;} - - //! input to Update() should have length a multiple of this for optimal speed - virtual unsigned int OptimalBlockSize() const {return 1;} - - //! returns how input should be aligned for optimal performance - virtual unsigned int OptimalDataAlignment() const; - - //! use this if your input is in one piece and you don't want to call Update() and Final() separately - virtual void CalculateDigest(byte *digest, const byte *input, size_t length) - {Update(input, length); Final(digest);} - - //! verify that digest is a valid digest for the current message, then reinitialize the object - /*! Default implementation is to call Final() and do a bitwise comparison - between its output and digest. */ - virtual bool Verify(const byte *digest) - {return TruncatedVerify(digest, DigestSize());} - - //! use this if your input is in one piece and you don't want to call Update() and Verify() separately - virtual bool VerifyDigest(const byte *digest, const byte *input, size_t length) - {Update(input, length); return Verify(digest);} - - //! truncated version of Final() - virtual void TruncatedFinal(byte *digest, size_t digestSize) =0; - - //! truncated version of CalculateDigest() - virtual void CalculateTruncatedDigest(byte *digest, size_t digestSize, const byte *input, size_t length) - {Update(input, length); TruncatedFinal(digest, digestSize);} - - //! truncated version of Verify() - virtual bool TruncatedVerify(const byte *digest, size_t digestLength); - - //! truncated version of VerifyDigest() - virtual bool VerifyTruncatedDigest(const byte *digest, size_t digestLength, const byte *input, size_t length) - {Update(input, length); return TruncatedVerify(digest, digestLength);} - -protected: - void ThrowIfInvalidTruncatedSize(size_t size) const; -}; - -typedef HashTransformation HashFunction; - -//! interface for one direction (encryption or decryption) of a block cipher -/*! \note These objects usually should not be used directly. See BlockTransformation for more details. */ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockCipher : public SimpleKeyingInterface, public BlockTransformation -{ -protected: - const Algorithm & GetAlgorithm() const {return *this;} -}; - -//! interface for one direction (encryption or decryption) of a stream cipher or cipher mode -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SymmetricCipher : public SimpleKeyingInterface, public StreamTransformation -{ -protected: - const Algorithm & GetAlgorithm() const {return *this;} -}; - -//! interface for message authentication codes -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE MessageAuthenticationCode : public SimpleKeyingInterface, public HashTransformation -{ -protected: - const Algorithm & GetAlgorithm() const {return *this;} -}; - -//! interface for for one direction (encryption or decryption) of a stream cipher or block cipher mode with authentication -/*! The StreamTransformation part of this interface is used to encrypt/decrypt the data, and the MessageAuthenticationCode part of this - interface is used to input additional authenticated data (AAD, which is MAC'ed but not encrypted), and to generate/verify the MAC. */ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedSymmetricCipher : public MessageAuthenticationCode, public StreamTransformation -{ -public: - //! this indicates that a member function was called in the wrong state, for example trying to encrypt a message before having set the key or IV - class BadState : public Exception - { - public: - explicit BadState(const std::string &name, const char *message) : Exception(OTHER_ERROR, name + ": " + message) {} - explicit BadState(const std::string &name, const char *function, const char *state) : Exception(OTHER_ERROR, name + ": " + function + " was called before " + state) {} - }; - - //! the maximum length of AAD that can be input before the encrypted data - virtual lword MaxHeaderLength() const =0; - //! the maximum length of encrypted data - virtual lword MaxMessageLength() const =0; - //! the maximum length of AAD that can be input after the encrypted data - virtual lword MaxFooterLength() const {return 0;} - //! if this function returns true, SpecifyDataLengths() must be called before attempting to input data - /*! This is the case for some schemes, such as CCM. */ - virtual bool NeedsPrespecifiedDataLengths() const {return false;} - //! this function only needs to be called if NeedsPrespecifiedDataLengths() returns true - void SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength=0); - //! encrypt and generate MAC in one call. will truncate MAC if macSize < TagSize() - virtual void EncryptAndAuthenticate(byte *ciphertext, byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *header, size_t headerLength, const byte *message, size_t messageLength); - //! decrypt and verify MAC in one call, returning true iff MAC is valid. will assume MAC is truncated if macLength < TagSize() - virtual bool DecryptAndVerify(byte *message, const byte *mac, size_t macLength, const byte *iv, int ivLength, const byte *header, size_t headerLength, const byte *ciphertext, size_t ciphertextLength); - - // redeclare this to avoid compiler ambiguity errors - virtual std::string AlgorithmName() const =0; - -protected: - const Algorithm & GetAlgorithm() const {return *static_cast<const MessageAuthenticationCode *>(this);} - virtual void UncheckedSpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength) {} -}; - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY -typedef SymmetricCipher StreamCipher; -#endif - -//! interface for random number generators -/*! All return values are uniformly distributed over the range specified. -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomNumberGenerator : public Algorithm -{ -public: - //! update RNG state with additional unpredictable values - virtual void IncorporateEntropy(const byte *input, size_t length) {throw NotImplemented("RandomNumberGenerator: IncorporateEntropy not implemented");} - - //! returns true if IncorporateEntropy is implemented - virtual bool CanIncorporateEntropy() const {return false;} - - //! generate new random byte and return it - virtual byte GenerateByte(); - - //! generate new random bit and return it - /*! Default implementation is to call GenerateByte() and return its lowest bit. */ - virtual unsigned int GenerateBit(); - - //! generate a random 32 bit word in the range min to max, inclusive - virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL); - - //! generate random array of bytes - virtual void GenerateBlock(byte *output, size_t size); - - //! generate and discard n bytes - virtual void DiscardBytes(size_t n); - - //! generate random bytes as input to a BufferedTransformation - virtual void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length); - - //! randomly shuffle the specified array, resulting permutation is uniformly distributed - template <class IT> void Shuffle(IT begin, IT end) - { - for (; begin != end; ++begin) - std::iter_swap(begin, begin + GenerateWord32(0, end-begin-1)); - } - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - byte GetByte() {return GenerateByte();} - unsigned int GetBit() {return GenerateBit();} - word32 GetLong(word32 a=0, word32 b=0xffffffffL) {return GenerateWord32(a, b);} - word16 GetShort(word16 a=0, word16 b=0xffff) {return (word16)GenerateWord32(a, b);} - void GetBlock(byte *output, size_t size) {GenerateBlock(output, size);} -#endif -}; - -//! returns a reference that can be passed to functions that ask for a RNG but doesn't actually use it -CRYPTOPP_DLL RandomNumberGenerator & CRYPTOPP_API NullRNG(); - -class WaitObjectContainer; -class CallStack; - -//! interface for objects that you can wait for - -class CRYPTOPP_NO_VTABLE Waitable -{ -public: - virtual ~Waitable() {} - - //! maximum number of wait objects that this object can return - virtual unsigned int GetMaxWaitObjectCount() const =0; - //! put wait objects into container - /*! \param callStack is used for tracing no wait loops, example: - something.GetWaitObjects(c, CallStack("my func after X", 0)); - - or in an outer GetWaitObjects() method that itself takes a callStack parameter: - innerThing.GetWaitObjects(c, CallStack("MyClass::GetWaitObjects at X", &callStack)); */ - virtual void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) =0; - //! wait on this object - /*! same as creating an empty container, calling GetWaitObjects(), and calling Wait() on the container */ - bool Wait(unsigned long milliseconds, CallStack const& callStack); -}; - -//! the default channel for BufferedTransformation, equal to the empty string -extern CRYPTOPP_DLL const std::string DEFAULT_CHANNEL; - -//! channel for additional authenticated data, equal to "AAD" -extern CRYPTOPP_DLL const std::string AAD_CHANNEL; - -//! interface for buffered transformations - -/*! BufferedTransformation is a generalization of BlockTransformation, - StreamTransformation, and HashTransformation. - - A buffered transformation is an object that takes a stream of bytes - as input (this may be done in stages), does some computation on them, and - then places the result into an internal buffer for later retrieval. Any - partial result already in the output buffer is not modified by further - input. - - If a method takes a "blocking" parameter, and you - pass "false" for it, the method will return before all input has been processed if - the input cannot be processed without waiting (for network buffers to become available, for example). - In this case the method will return true - or a non-zero integer value. When this happens you must continue to call the method with the same - parameters until it returns false or zero, before calling any other method on it or - attached BufferedTransformation. The integer return value in this case is approximately - the number of bytes left to be processed, and can be used to implement a progress bar. - - For functions that take a "propagation" parameter, propagation != 0 means pass on the signal to attached - BufferedTransformation objects, with propagation decremented at each step until it reaches 0. - -1 means unlimited propagation. - - \nosubgrouping -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BufferedTransformation : public Algorithm, public Waitable -{ -public: - // placed up here for CW8 - static const std::string &NULL_CHANNEL; // same as DEFAULT_CHANNEL, for backwards compatibility - - BufferedTransformation() : Algorithm(false) {} - - //! return a reference to this object, useful for passing a temporary object to a function that takes a non-const reference - BufferedTransformation& Ref() {return *this;} - - //! \name INPUT - //@{ - //! input a byte for processing - size_t Put(byte inByte, bool blocking=true) - {return Put(&inByte, 1, blocking);} - //! input multiple bytes - size_t Put(const byte *inString, size_t length, bool blocking=true) - {return Put2(inString, length, 0, blocking);} - - //! input a 16-bit word - size_t PutWord16(word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); - //! input a 32-bit word - size_t PutWord32(word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); - - //! request space which can be written into by the caller, and then used as input to Put() - /*! \param size is requested size (as a hint) for input, and size of the returned space for output */ - /*! \note The purpose of this method is to help avoid doing extra memory allocations. */ - virtual byte * CreatePutSpace(size_t &size) {size=0; return NULL;} - - virtual bool CanModifyInput() const {return false;} - - //! input multiple bytes that may be modified by callee - size_t PutModifiable(byte *inString, size_t length, bool blocking=true) - {return PutModifiable2(inString, length, 0, blocking);} - - bool MessageEnd(int propagation=-1, bool blocking=true) - {return !!Put2(NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);} - size_t PutMessageEnd(const byte *inString, size_t length, int propagation=-1, bool blocking=true) - {return Put2(inString, length, propagation < 0 ? -1 : propagation+1, blocking);} - - //! input multiple bytes for blocking or non-blocking processing - /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */ - virtual size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) =0; - //! input multiple bytes that may be modified by callee for blocking or non-blocking processing - /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */ - virtual size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking) - {return Put2(inString, length, messageEnd, blocking);} - - //! thrown by objects that have not implemented nonblocking input processing - struct BlockingInputOnly : public NotImplemented - {BlockingInputOnly(const std::string &s) : NotImplemented(s + ": Nonblocking input is not implemented by this object.") {}}; - //@} - - //! \name WAITING - //@{ - unsigned int GetMaxWaitObjectCount() const; - void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); - //@} - - //! \name SIGNALS - //@{ - virtual void IsolatedInitialize(const NameValuePairs ¶meters) {throw NotImplemented("BufferedTransformation: this object can't be reinitialized");} - virtual bool IsolatedFlush(bool hardFlush, bool blocking) =0; - virtual bool IsolatedMessageSeriesEnd(bool blocking) {return false;} - - //! initialize or reinitialize this object - virtual void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1); - //! flush buffered input and/or output - /*! \param hardFlush is used to indicate whether all data should be flushed - \note Hard flushes must be used with care. It means try to process and output everything, even if - there may not be enough data to complete the action. For example, hard flushing a HexDecoder would - cause an error if you do it after inputing an odd number of hex encoded characters. - For some types of filters, for example ZlibDecompressor, hard flushes can only - be done at "synchronization points". These synchronization points are positions in the data - stream that are created by hard flushes on the corresponding reverse filters, in this - example ZlibCompressor. This is useful when zlib compressed data is moved across a - network in packets and compression state is preserved across packets, as in the ssh2 protocol. - */ - virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true); - //! mark end of a series of messages - /*! There should be a MessageEnd immediately before MessageSeriesEnd. */ - virtual bool MessageSeriesEnd(int propagation=-1, bool blocking=true); - - //! set propagation of automatically generated and transferred signals - /*! propagation == 0 means do not automaticly generate signals */ - virtual void SetAutoSignalPropagation(int propagation) {} - - //! - virtual int GetAutoSignalPropagation() const {return 0;} -public: - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - void Close() {MessageEnd();} -#endif - //@} - - //! \name RETRIEVAL OF ONE MESSAGE - //@{ - //! returns number of bytes that is currently ready for retrieval - /*! All retrieval functions return the actual number of bytes - retrieved, which is the lesser of the request number and - MaxRetrievable(). */ - virtual lword MaxRetrievable() const; - - //! returns whether any bytes are currently ready for retrieval - virtual bool AnyRetrievable() const; - - //! try to retrieve a single byte - virtual size_t Get(byte &outByte); - //! try to retrieve multiple bytes - virtual size_t Get(byte *outString, size_t getMax); - - //! peek at the next byte without removing it from the output buffer - virtual size_t Peek(byte &outByte) const; - //! peek at multiple bytes without removing them from the output buffer - virtual size_t Peek(byte *outString, size_t peekMax) const; - - //! try to retrieve a 16-bit word - size_t GetWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER); - //! try to retrieve a 32-bit word - size_t GetWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER); - - //! try to peek at a 16-bit word - size_t PeekWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER) const; - //! try to peek at a 32-bit word - size_t PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER) const; - - //! move transferMax bytes of the buffered output to target as input - lword TransferTo(BufferedTransformation &target, lword transferMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) - {TransferTo2(target, transferMax, channel); return transferMax;} - - //! discard skipMax bytes from the output buffer - virtual lword Skip(lword skipMax=LWORD_MAX); - - //! copy copyMax bytes of the buffered output to target as input - lword CopyTo(BufferedTransformation &target, lword copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const - {return CopyRangeTo(target, 0, copyMax, channel);} - - //! copy copyMax bytes of the buffered output, starting at position (relative to current position), to target as input - lword CopyRangeTo(BufferedTransformation &target, lword position, lword copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const - {lword i = position; CopyRangeTo2(target, i, i+copyMax, channel); return i-position;} - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - unsigned long MaxRetrieveable() const {return MaxRetrievable();} -#endif - //@} - - //! \name RETRIEVAL OF MULTIPLE MESSAGES - //@{ - //! - virtual lword TotalBytesRetrievable() const; - //! number of times MessageEnd() has been received minus messages retrieved or skipped - virtual unsigned int NumberOfMessages() const; - //! returns true if NumberOfMessages() > 0 - virtual bool AnyMessages() const; - //! start retrieving the next message - /*! - Returns false if no more messages exist or this message - is not completely retrieved. - */ - virtual bool GetNextMessage(); - //! skip count number of messages - virtual unsigned int SkipMessages(unsigned int count=UINT_MAX); - //! - unsigned int TransferMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) - {TransferMessagesTo2(target, count, channel); return count;} - //! - unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) const; - - //! - virtual void SkipAll(); - //! - void TransferAllTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL) - {TransferAllTo2(target, channel);} - //! - void CopyAllTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL) const; - - virtual bool GetNextMessageSeries() {return false;} - virtual unsigned int NumberOfMessagesInThisSeries() const {return NumberOfMessages();} - virtual unsigned int NumberOfMessageSeries() const {return 0;} - //@} - - //! \name NON-BLOCKING TRANSFER OF OUTPUT - //@{ - //! upon return, byteCount contains number of bytes that have finished being transfered, and returns the number of bytes left in the current transfer block - virtual size_t TransferTo2(BufferedTransformation &target, lword &byteCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) =0; - //! upon return, begin contains the start position of data yet to be finished copying, and returns the number of bytes left in the current transfer block - virtual size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const =0; - //! upon return, messageCount contains number of messages that have finished being transfered, and returns the number of bytes left in the current transfer block - size_t TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); - //! returns the number of bytes left in the current transfer block - size_t TransferAllTo2(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); - //@} - - //! \name CHANNELS - //@{ - struct NoChannelSupport : public NotImplemented - {NoChannelSupport(const std::string &name) : NotImplemented(name + ": this object doesn't support multiple channels") {}}; - struct InvalidChannelName : public InvalidArgument - {InvalidChannelName(const std::string &name, const std::string &channel) : InvalidArgument(name + ": unexpected channel name \"" + channel + "\"") {}}; - - size_t ChannelPut(const std::string &channel, byte inByte, bool blocking=true) - {return ChannelPut(channel, &inByte, 1, blocking);} - size_t ChannelPut(const std::string &channel, const byte *inString, size_t length, bool blocking=true) - {return ChannelPut2(channel, inString, length, 0, blocking);} - - size_t ChannelPutModifiable(const std::string &channel, byte *inString, size_t length, bool blocking=true) - {return ChannelPutModifiable2(channel, inString, length, 0, blocking);} - - size_t ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); - size_t ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); - - bool ChannelMessageEnd(const std::string &channel, int propagation=-1, bool blocking=true) - {return !!ChannelPut2(channel, NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);} - size_t ChannelPutMessageEnd(const std::string &channel, const byte *inString, size_t length, int propagation=-1, bool blocking=true) - {return ChannelPut2(channel, inString, length, propagation < 0 ? -1 : propagation+1, blocking);} - - virtual byte * ChannelCreatePutSpace(const std::string &channel, size_t &size); - - virtual size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking); - virtual size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking); - - virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true); - virtual bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true); - - virtual void SetRetrievalChannel(const std::string &channel); - //@} - - //! \name ATTACHMENT - /*! Some BufferedTransformation objects (e.g. Filter objects) - allow other BufferedTransformation objects to be attached. When - this is done, the first object instead of buffering its output, - sents that output to the attached object as input. The entire - attachment chain is deleted when the anchor object is destructed. - */ - //@{ - //! returns whether this object allows attachment - virtual bool Attachable() {return false;} - //! returns the object immediately attached to this object or NULL for no attachment - virtual BufferedTransformation *AttachedTransformation() {assert(!Attachable()); return 0;} - //! - virtual const BufferedTransformation *AttachedTransformation() const - {return const_cast<BufferedTransformation *>(this)->AttachedTransformation();} - //! delete the current attachment chain and replace it with newAttachment - virtual void Detach(BufferedTransformation *newAttachment = 0) - {assert(!Attachable()); throw NotImplemented("BufferedTransformation: this object is not attachable");} - //! add newAttachment to the end of attachment chain - virtual void Attach(BufferedTransformation *newAttachment); - //@} - -protected: - static int DecrementPropagation(int propagation) - {return propagation != 0 ? propagation - 1 : 0;} - -private: - byte m_buf[4]; // for ChannelPutWord16 and ChannelPutWord32, to ensure buffer isn't deallocated before non-blocking operation completes -}; - -//! returns a reference to a BufferedTransformation object that discards all input -BufferedTransformation & TheBitBucket(); - -//! interface for crypto material, such as public and private keys, and crypto parameters - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CryptoMaterial : public NameValuePairs -{ -public: - //! exception thrown when invalid crypto material is detected - class CRYPTOPP_DLL InvalidMaterial : public InvalidDataFormat - { - public: - explicit InvalidMaterial(const std::string &s) : InvalidDataFormat(s) {} - }; - - //! assign values from source to this object - /*! \note This function can be used to create a public key from a private key. */ - virtual void AssignFrom(const NameValuePairs &source) =0; - - //! check this object for errors - /*! \param level denotes the level of thoroughness: - 0 - using this object won't cause a crash or exception (rng is ignored) - 1 - this object will probably function (encrypt, sign, etc.) correctly (but may not check for weak keys and such) - 2 - make sure this object will function correctly, and do reasonable security checks - 3 - do checks that may take a long time - \return true if the tests pass */ - virtual bool Validate(RandomNumberGenerator &rng, unsigned int level) const =0; - - //! throws InvalidMaterial if this object fails Validate() test - virtual void ThrowIfInvalid(RandomNumberGenerator &rng, unsigned int level) const - {if (!Validate(rng, level)) throw InvalidMaterial("CryptoMaterial: this object contains invalid values");} - -// virtual std::vector<std::string> GetSupportedFormats(bool includeSaveOnly=false, bool includeLoadOnly=false); - - //! save key into a BufferedTransformation - virtual void Save(BufferedTransformation &bt) const - {throw NotImplemented("CryptoMaterial: this object does not support saving");} - - //! load key from a BufferedTransformation - /*! \throws KeyingErr if decode fails - \note Generally does not check that the key is valid. - Call ValidateKey() or ThrowIfInvalidKey() to check that. */ - virtual void Load(BufferedTransformation &bt) - {throw NotImplemented("CryptoMaterial: this object does not support loading");} - - //! \return whether this object supports precomputation - virtual bool SupportsPrecomputation() const {return false;} - //! do precomputation - /*! The exact semantics of Precompute() is varies, but - typically it means calculate a table of n objects - that can be used later to speed up computation. */ - virtual void Precompute(unsigned int n) - {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");} - //! retrieve previously saved precomputation - virtual void LoadPrecomputation(BufferedTransformation &storedPrecomputation) - {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");} - //! save precomputation for later use - virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const - {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");} - - // for internal library use - void DoQuickSanityCheck() const {ThrowIfInvalid(NullRNG(), 0);} - -#if (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) - // Sun Studio 11/CC 5.8 workaround: it generates incorrect code when casting to an empty virtual base class - char m_sunCCworkaround; -#endif -}; - -//! interface for generatable crypto material, such as private keys and crypto parameters - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GeneratableCryptoMaterial : virtual public CryptoMaterial -{ -public: - //! generate a random key or crypto parameters - /*! \throws KeyingErr if algorithm parameters are invalid, or if a key can't be generated - (e.g., if this is a public key object) */ - virtual void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms = g_nullNameValuePairs) - {throw NotImplemented("GeneratableCryptoMaterial: this object does not support key/parameter generation");} - - //! calls the above function with a NameValuePairs object that just specifies "KeySize" - void GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize); -}; - -//! interface for public keys - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKey : virtual public CryptoMaterial -{ -}; - -//! interface for private keys - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKey : public GeneratableCryptoMaterial -{ -}; - -//! interface for crypto prameters - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CryptoParameters : public GeneratableCryptoMaterial -{ -}; - -//! interface for asymmetric algorithms - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AsymmetricAlgorithm : public Algorithm -{ -public: - //! returns a reference to the crypto material used by this object - virtual CryptoMaterial & AccessMaterial() =0; - //! returns a const reference to the crypto material used by this object - virtual const CryptoMaterial & GetMaterial() const =0; - - //! for backwards compatibility, calls AccessMaterial().Load(bt) - void BERDecode(BufferedTransformation &bt) - {AccessMaterial().Load(bt);} - //! for backwards compatibility, calls GetMaterial().Save(bt) - void DEREncode(BufferedTransformation &bt) const - {GetMaterial().Save(bt);} -}; - -//! interface for asymmetric algorithms using public keys - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKeyAlgorithm : public AsymmetricAlgorithm -{ -public: - // VC60 workaround: no co-variant return type - CryptoMaterial & AccessMaterial() {return AccessPublicKey();} - const CryptoMaterial & GetMaterial() const {return GetPublicKey();} - - virtual PublicKey & AccessPublicKey() =0; - virtual const PublicKey & GetPublicKey() const {return const_cast<PublicKeyAlgorithm *>(this)->AccessPublicKey();} -}; - -//! interface for asymmetric algorithms using private keys - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKeyAlgorithm : public AsymmetricAlgorithm -{ -public: - CryptoMaterial & AccessMaterial() {return AccessPrivateKey();} - const CryptoMaterial & GetMaterial() const {return GetPrivateKey();} - - virtual PrivateKey & AccessPrivateKey() =0; - virtual const PrivateKey & GetPrivateKey() const {return const_cast<PrivateKeyAlgorithm *>(this)->AccessPrivateKey();} -}; - -//! interface for key agreement algorithms - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE KeyAgreementAlgorithm : public AsymmetricAlgorithm -{ -public: - CryptoMaterial & AccessMaterial() {return AccessCryptoParameters();} - const CryptoMaterial & GetMaterial() const {return GetCryptoParameters();} - - virtual CryptoParameters & AccessCryptoParameters() =0; - virtual const CryptoParameters & GetCryptoParameters() const {return const_cast<KeyAgreementAlgorithm *>(this)->AccessCryptoParameters();} -}; - -//! interface for public-key encryptors and decryptors - -/*! This class provides an interface common to encryptors and decryptors - for querying their plaintext and ciphertext lengths. -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_CryptoSystem -{ -public: - virtual ~PK_CryptoSystem() {} - - //! maximum length of plaintext for a given ciphertext length - /*! \note This function returns 0 if ciphertextLength is not valid (too long or too short). */ - virtual size_t MaxPlaintextLength(size_t ciphertextLength) const =0; - - //! calculate length of ciphertext given length of plaintext - /*! \note This function returns 0 if plaintextLength is not valid (too long). */ - virtual size_t CiphertextLength(size_t plaintextLength) const =0; - - //! this object supports the use of the parameter with the given name - /*! some possible parameter names: EncodingParameters, KeyDerivationParameters */ - virtual bool ParameterSupported(const char *name) const =0; - - //! return fixed ciphertext length, if one exists, otherwise return 0 - /*! \note "Fixed" here means length of ciphertext does not depend on length of plaintext. - It usually does depend on the key length. */ - virtual size_t FixedCiphertextLength() const {return 0;} - - //! return maximum plaintext length given the fixed ciphertext length, if one exists, otherwise return 0 - virtual size_t FixedMaxPlaintextLength() const {return 0;} - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - size_t MaxPlainTextLength(size_t cipherTextLength) const {return MaxPlaintextLength(cipherTextLength);} - size_t CipherTextLength(size_t plainTextLength) const {return CiphertextLength(plainTextLength);} -#endif -}; - -//! interface for public-key encryptors -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Encryptor : public PK_CryptoSystem, public PublicKeyAlgorithm -{ -public: - //! exception thrown when trying to encrypt plaintext of invalid length - class CRYPTOPP_DLL InvalidPlaintextLength : public Exception - { - public: - InvalidPlaintextLength() : Exception(OTHER_ERROR, "PK_Encryptor: invalid plaintext length") {} - }; - - //! encrypt a byte string - /*! \pre CiphertextLength(plaintextLength) != 0 (i.e., plaintext isn't too long) - \pre size of ciphertext == CiphertextLength(plaintextLength) - */ - virtual void Encrypt(RandomNumberGenerator &rng, - const byte *plaintext, size_t plaintextLength, - byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const =0; - - //! create a new encryption filter - /*! \note The caller is responsible for deleting the returned pointer. - \note Encoding parameters should be passed in the "EP" channel. - */ - virtual BufferedTransformation * CreateEncryptionFilter(RandomNumberGenerator &rng, - BufferedTransformation *attachment=NULL, const NameValuePairs ¶meters = g_nullNameValuePairs) const; -}; - -//! interface for public-key decryptors - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Decryptor : public PK_CryptoSystem, public PrivateKeyAlgorithm -{ -public: - //! decrypt a byte string, and return the length of plaintext - /*! \pre size of plaintext == MaxPlaintextLength(ciphertextLength) bytes. - \return the actual length of the plaintext, indication that decryption failed. - */ - virtual DecodingResult Decrypt(RandomNumberGenerator &rng, - const byte *ciphertext, size_t ciphertextLength, - byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const =0; - - //! create a new decryption filter - /*! \note caller is responsible for deleting the returned pointer - */ - virtual BufferedTransformation * CreateDecryptionFilter(RandomNumberGenerator &rng, - BufferedTransformation *attachment=NULL, const NameValuePairs ¶meters = g_nullNameValuePairs) const; - - //! decrypt a fixed size ciphertext - DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *ciphertext, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const - {return Decrypt(rng, ciphertext, FixedCiphertextLength(), plaintext, parameters);} -}; - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY -typedef PK_CryptoSystem PK_FixedLengthCryptoSystem; -typedef PK_Encryptor PK_FixedLengthEncryptor; -typedef PK_Decryptor PK_FixedLengthDecryptor; -#endif - -//! interface for public-key signers and verifiers - -/*! This class provides an interface common to signers and verifiers - for querying scheme properties. -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_SignatureScheme -{ -public: - //! invalid key exception, may be thrown by any function in this class if the private or public key has a length that can't be used - class CRYPTOPP_DLL InvalidKeyLength : public Exception - { - public: - InvalidKeyLength(const std::string &message) : Exception(OTHER_ERROR, message) {} - }; - - //! key too short exception, may be thrown by any function in this class if the private or public key is too short to sign or verify anything - class CRYPTOPP_DLL KeyTooShort : public InvalidKeyLength - { - public: - KeyTooShort() : InvalidKeyLength("PK_Signer: key too short for this signature scheme") {} - }; - - virtual ~PK_SignatureScheme() {} - - //! signature length if it only depends on the key, otherwise 0 - virtual size_t SignatureLength() const =0; - - //! maximum signature length produced for a given length of recoverable message part - virtual size_t MaxSignatureLength(size_t recoverablePartLength = 0) const {return SignatureLength();} - - //! length of longest message that can be recovered, or 0 if this signature scheme does not support message recovery - virtual size_t MaxRecoverableLength() const =0; - - //! length of longest message that can be recovered from a signature of given length, or 0 if this signature scheme does not support message recovery - virtual size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const =0; - - //! requires a random number generator to sign - /*! if this returns false, NullRNG() can be passed to functions that take RandomNumberGenerator & */ - virtual bool IsProbabilistic() const =0; - - //! whether or not a non-recoverable message part can be signed - virtual bool AllowNonrecoverablePart() const =0; - - //! if this function returns true, during verification you must input the signature before the message, otherwise you can input it at anytime */ - virtual bool SignatureUpfront() const {return false;} - - //! whether you must input the recoverable part before the non-recoverable part during signing - virtual bool RecoverablePartFirst() const =0; -}; - -//! interface for accumulating messages to be signed or verified -/*! Only Update() should be called - on this class. No other functions inherited from HashTransformation should be called. -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulator : public HashTransformation -{ -public: - //! should not be called on PK_MessageAccumulator - unsigned int DigestSize() const - {throw NotImplemented("PK_MessageAccumulator: DigestSize() should not be called");} - //! should not be called on PK_MessageAccumulator - void TruncatedFinal(byte *digest, size_t digestSize) - {throw NotImplemented("PK_MessageAccumulator: TruncatedFinal() should not be called");} -}; - -//! interface for public-key signers - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Signer : public PK_SignatureScheme, public PrivateKeyAlgorithm -{ -public: - //! create a new HashTransformation to accumulate the message to be signed - virtual PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const =0; - - virtual void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const =0; - - //! sign and delete messageAccumulator (even in case of exception thrown) - /*! \pre size of signature == MaxSignatureLength() - \return actual signature length - */ - virtual size_t Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const; - - //! sign and restart messageAccumulator - /*! \pre size of signature == MaxSignatureLength() - \return actual signature length - */ - virtual size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const =0; - - //! sign a message - /*! \pre size of signature == MaxSignatureLength() - \return actual signature length - */ - virtual size_t SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const; - - //! sign a recoverable message - /*! \pre size of signature == MaxSignatureLength(recoverableMessageLength) - \return actual signature length - */ - virtual size_t SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength, - const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const; -}; - -//! interface for public-key signature verifiers -/*! The Recover* functions throw NotImplemented if the signature scheme does not support - message recovery. - The Verify* functions throw InvalidDataFormat if the scheme does support message - recovery and the signature contains a non-empty recoverable message part. The - Recovery* functions should be used in that case. -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Verifier : public PK_SignatureScheme, public PublicKeyAlgorithm -{ -public: - //! create a new HashTransformation to accumulate the message to be verified - virtual PK_MessageAccumulator * NewVerificationAccumulator() const =0; - - //! input signature into a message accumulator - virtual void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const =0; - - //! check whether messageAccumulator contains a valid signature and message, and delete messageAccumulator (even in case of exception thrown) - virtual bool Verify(PK_MessageAccumulator *messageAccumulator) const; - - //! check whether messageAccumulator contains a valid signature and message, and restart messageAccumulator - virtual bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const =0; - - //! check whether input signature is a valid signature for input message - virtual bool VerifyMessage(const byte *message, size_t messageLen, - const byte *signature, size_t signatureLength) const; - - //! recover a message from its signature - /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength) - */ - virtual DecodingResult Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const; - - //! recover a message from its signature - /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength) - */ - virtual DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const =0; - - //! recover a message from its signature - /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength) - */ - virtual DecodingResult RecoverMessage(byte *recoveredMessage, - const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, - const byte *signature, size_t signatureLength) const; -}; - -//! interface for domains of simple key agreement protocols - -/*! A key agreement domain is a set of parameters that must be shared - by two parties in a key agreement protocol, along with the algorithms - for generating key pairs and deriving agreed values. -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyAgreementDomain : public KeyAgreementAlgorithm -{ -public: - //! return length of agreed value produced - virtual unsigned int AgreedValueLength() const =0; - //! return length of private keys in this domain - virtual unsigned int PrivateKeyLength() const =0; - //! return length of public keys in this domain - virtual unsigned int PublicKeyLength() const =0; - //! generate private key - /*! \pre size of privateKey == PrivateKeyLength() */ - virtual void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0; - //! generate public key - /*! \pre size of publicKey == PublicKeyLength() */ - virtual void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0; - //! generate private/public key pair - /*! \note equivalent to calling GeneratePrivateKey() and then GeneratePublicKey() */ - virtual void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const; - //! derive agreed value from your private key and couterparty's public key, return false in case of failure - /*! \note If you have previously validated the public key, use validateOtherPublicKey=false to save time. - \pre size of agreedValue == AgreedValueLength() - \pre length of privateKey == PrivateKeyLength() - \pre length of otherPublicKey == PublicKeyLength() - */ - virtual bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const =0; - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - bool ValidateDomainParameters(RandomNumberGenerator &rng) const - {return GetCryptoParameters().Validate(rng, 2);} -#endif -}; - -//! interface for domains of authenticated key agreement protocols - -/*! In an authenticated key agreement protocol, each party has two - key pairs. The long-lived key pair is called the static key pair, - and the short-lived key pair is called the ephemeral key pair. -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm -{ -public: - //! return length of agreed value produced - virtual unsigned int AgreedValueLength() const =0; - - //! return length of static private keys in this domain - virtual unsigned int StaticPrivateKeyLength() const =0; - //! return length of static public keys in this domain - virtual unsigned int StaticPublicKeyLength() const =0; - //! generate static private key - /*! \pre size of privateKey == PrivateStaticKeyLength() */ - virtual void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0; - //! generate static public key - /*! \pre size of publicKey == PublicStaticKeyLength() */ - virtual void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0; - //! generate private/public key pair - /*! \note equivalent to calling GenerateStaticPrivateKey() and then GenerateStaticPublicKey() */ - virtual void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const; - - //! return length of ephemeral private keys in this domain - virtual unsigned int EphemeralPrivateKeyLength() const =0; - //! return length of ephemeral public keys in this domain - virtual unsigned int EphemeralPublicKeyLength() const =0; - //! generate ephemeral private key - /*! \pre size of privateKey == PrivateEphemeralKeyLength() */ - virtual void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0; - //! generate ephemeral public key - /*! \pre size of publicKey == PublicEphemeralKeyLength() */ - virtual void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0; - //! generate private/public key pair - /*! \note equivalent to calling GenerateEphemeralPrivateKey() and then GenerateEphemeralPublicKey() */ - virtual void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const; - - //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure - /*! \note The ephemeral public key will always be validated. - If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. - \pre size of agreedValue == AgreedValueLength() - \pre length of staticPrivateKey == StaticPrivateKeyLength() - \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength() - \pre length of staticOtherPublicKey == StaticPublicKeyLength() - \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() - */ - virtual bool Agree(byte *agreedValue, - const byte *staticPrivateKey, const byte *ephemeralPrivateKey, - const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, - bool validateStaticOtherPublicKey=true) const =0; - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - bool ValidateDomainParameters(RandomNumberGenerator &rng) const - {return GetCryptoParameters().Validate(rng, 2);} -#endif -}; - -// interface for password authenticated key agreement protocols, not implemented yet -#if 0 -//! interface for protocol sessions -/*! The methods should be called in the following order: - - InitializeSession(rng, parameters); // or call initialize method in derived class - while (true) - { - if (OutgoingMessageAvailable()) - { - length = GetOutgoingMessageLength(); - GetOutgoingMessage(message); - ; // send outgoing message - } - - if (LastMessageProcessed()) - break; - - ; // receive incoming message - ProcessIncomingMessage(message); - } - ; // call methods in derived class to obtain result of protocol session -*/ -class ProtocolSession -{ -public: - //! exception thrown when an invalid protocol message is processed - class ProtocolError : public Exception - { - public: - ProtocolError(ErrorType errorType, const std::string &s) : Exception(errorType, s) {} - }; - - //! exception thrown when a function is called unexpectedly - /*! for example calling ProcessIncomingMessage() when ProcessedLastMessage() == true */ - class UnexpectedMethodCall : public Exception - { - public: - UnexpectedMethodCall(const std::string &s) : Exception(OTHER_ERROR, s) {} - }; - - ProtocolSession() : m_rng(NULL), m_throwOnProtocolError(true), m_validState(false) {} - virtual ~ProtocolSession() {} - - virtual void InitializeSession(RandomNumberGenerator &rng, const NameValuePairs ¶meters) =0; - - bool GetThrowOnProtocolError() const {return m_throwOnProtocolError;} - void SetThrowOnProtocolError(bool throwOnProtocolError) {m_throwOnProtocolError = throwOnProtocolError;} - - bool HasValidState() const {return m_validState;} - - virtual bool OutgoingMessageAvailable() const =0; - virtual unsigned int GetOutgoingMessageLength() const =0; - virtual void GetOutgoingMessage(byte *message) =0; - - virtual bool LastMessageProcessed() const =0; - virtual void ProcessIncomingMessage(const byte *message, unsigned int messageLength) =0; - -protected: - void HandleProtocolError(Exception::ErrorType errorType, const std::string &s) const; - void CheckAndHandleInvalidState() const; - void SetValidState(bool valid) {m_validState = valid;} - - RandomNumberGenerator *m_rng; - -private: - bool m_throwOnProtocolError, m_validState; -}; - -class KeyAgreementSession : public ProtocolSession -{ -public: - virtual unsigned int GetAgreedValueLength() const =0; - virtual void GetAgreedValue(byte *agreedValue) const =0; -}; - -class PasswordAuthenticatedKeyAgreementSession : public KeyAgreementSession -{ -public: - void InitializePasswordAuthenticatedKeyAgreementSession(RandomNumberGenerator &rng, - const byte *myId, unsigned int myIdLength, - const byte *counterPartyId, unsigned int counterPartyIdLength, - const byte *passwordOrVerifier, unsigned int passwordOrVerifierLength); -}; - -class PasswordAuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm -{ -public: - //! return whether the domain parameters stored in this object are valid - virtual bool ValidateDomainParameters(RandomNumberGenerator &rng) const - {return GetCryptoParameters().Validate(rng, 2);} - - virtual unsigned int GetPasswordVerifierLength(const byte *password, unsigned int passwordLength) const =0; - virtual void GeneratePasswordVerifier(RandomNumberGenerator &rng, const byte *userId, unsigned int userIdLength, const byte *password, unsigned int passwordLength, byte *verifier) const =0; - - enum RoleFlags {CLIENT=1, SERVER=2, INITIATOR=4, RESPONDER=8}; - - virtual bool IsValidRole(unsigned int role) =0; - virtual PasswordAuthenticatedKeyAgreementSession * CreateProtocolSession(unsigned int role) const =0; -}; -#endif - -//! BER Decode Exception Class, may be thrown during an ASN1 BER decode operation -class CRYPTOPP_DLL BERDecodeErr : public InvalidArgument -{ -public: - BERDecodeErr() : InvalidArgument("BER decode error") {} - BERDecodeErr(const std::string &s) : InvalidArgument(s) {} -}; - -//! interface for encoding and decoding ASN1 objects -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1Object -{ -public: - virtual ~ASN1Object() {} - //! decode this object from a BufferedTransformation, using BER (Basic Encoding Rules) - virtual void BERDecode(BufferedTransformation &bt) =0; - //! encode this object into a BufferedTransformation, using DER (Distinguished Encoding Rules) - virtual void DEREncode(BufferedTransformation &bt) const =0; - //! encode this object into a BufferedTransformation, using BER - /*! this may be useful if DEREncode() would be too inefficient */ - virtual void BEREncode(BufferedTransformation &bt) const {DEREncode(bt);} -}; - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY -typedef PK_SignatureScheme PK_SignatureSystem; -typedef SimpleKeyAgreementDomain PK_SimpleKeyAgreementDomain; -typedef AuthenticatedKeyAgreementDomain PK_AuthenticatedKeyAgreementDomain; -#endif - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/default.cpp b/lib/cryptopp/default.cpp deleted file mode 100644 index 72940784d..000000000 --- a/lib/cryptopp/default.cpp +++ /dev/null @@ -1,258 +0,0 @@ -// default.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "default.h" -#include "queue.h" -#include <time.h> -#include <memory> - -NAMESPACE_BEGIN(CryptoPP) - -static const unsigned int MASH_ITERATIONS = 200; -static const unsigned int SALTLENGTH = 8; -static const unsigned int BLOCKSIZE = Default_BlockCipher::Encryption::BLOCKSIZE; -static const unsigned int KEYLENGTH = Default_BlockCipher::Encryption::DEFAULT_KEYLENGTH; - -// The purpose of this function Mash() is to take an arbitrary length input -// string and *deterministicly* produce an arbitrary length output string such -// that (1) it looks random, (2) no information about the input is -// deducible from it, and (3) it contains as much entropy as it can hold, or -// the amount of entropy in the input string, whichever is smaller. - -static void Mash(const byte *in, size_t inLen, byte *out, size_t outLen, int iterations) -{ - if (BytePrecision(outLen) > 2) - throw InvalidArgument("Mash: output legnth too large"); - - size_t bufSize = RoundUpToMultipleOf(outLen, (size_t)DefaultHashModule::DIGESTSIZE); - byte b[2]; - SecByteBlock buf(bufSize); - SecByteBlock outBuf(bufSize); - DefaultHashModule hash; - - unsigned int i; - for(i=0; i<outLen; i+=DefaultHashModule::DIGESTSIZE) - { - b[0] = (byte) (i >> 8); - b[1] = (byte) i; - hash.Update(b, 2); - hash.Update(in, inLen); - hash.Final(outBuf+i); - } - - while (iterations-- > 1) - { - memcpy(buf, outBuf, bufSize); - for (i=0; i<bufSize; i+=DefaultHashModule::DIGESTSIZE) - { - b[0] = (byte) (i >> 8); - b[1] = (byte) i; - hash.Update(b, 2); - hash.Update(buf, bufSize); - hash.Final(outBuf+i); - } - } - - memcpy(out, outBuf, outLen); -} - -static void GenerateKeyIV(const byte *passphrase, size_t passphraseLength, const byte *salt, size_t saltLength, byte *key, byte *IV) -{ - SecByteBlock temp(passphraseLength+saltLength); - memcpy(temp, passphrase, passphraseLength); - memcpy(temp+passphraseLength, salt, saltLength); - SecByteBlock keyIV(KEYLENGTH+BLOCKSIZE); - Mash(temp, passphraseLength + saltLength, keyIV, KEYLENGTH+BLOCKSIZE, MASH_ITERATIONS); - memcpy(key, keyIV, KEYLENGTH); - memcpy(IV, keyIV+KEYLENGTH, BLOCKSIZE); -} - -// ******************************************************** - -DefaultEncryptor::DefaultEncryptor(const char *passphrase, BufferedTransformation *attachment) - : ProxyFilter(NULL, 0, 0, attachment), m_passphrase((const byte *)passphrase, strlen(passphrase)) -{ -} - -DefaultEncryptor::DefaultEncryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment) - : ProxyFilter(NULL, 0, 0, attachment), m_passphrase(passphrase, passphraseLength) -{ -} - - -void DefaultEncryptor::FirstPut(const byte *) -{ - // VC60 workaround: __LINE__ expansion bug - CRYPTOPP_COMPILE_ASSERT_INSTANCE(SALTLENGTH <= DefaultHashModule::DIGESTSIZE, 1); - CRYPTOPP_COMPILE_ASSERT_INSTANCE(BLOCKSIZE <= DefaultHashModule::DIGESTSIZE, 2); - - SecByteBlock salt(DefaultHashModule::DIGESTSIZE), keyCheck(DefaultHashModule::DIGESTSIZE); - DefaultHashModule hash; - - // use hash(passphrase | time | clock) as salt - hash.Update(m_passphrase, m_passphrase.size()); - time_t t=time(0); - hash.Update((byte *)&t, sizeof(t)); - clock_t c=clock(); - hash.Update((byte *)&c, sizeof(c)); - hash.Final(salt); - - // use hash(passphrase | salt) as key check - hash.Update(m_passphrase, m_passphrase.size()); - hash.Update(salt, SALTLENGTH); - hash.Final(keyCheck); - - AttachedTransformation()->Put(salt, SALTLENGTH); - - // mash passphrase and salt together into key and IV - SecByteBlock key(KEYLENGTH); - SecByteBlock IV(BLOCKSIZE); - GenerateKeyIV(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, key, IV); - - m_cipher.SetKeyWithIV(key, key.size(), IV); - SetFilter(new StreamTransformationFilter(m_cipher)); - - m_filter->Put(keyCheck, BLOCKSIZE); -} - -void DefaultEncryptor::LastPut(const byte *inString, size_t length) -{ - m_filter->MessageEnd(); -} - -// ******************************************************** - -DefaultDecryptor::DefaultDecryptor(const char *p, BufferedTransformation *attachment, bool throwException) - : ProxyFilter(NULL, SALTLENGTH+BLOCKSIZE, 0, attachment) - , m_state(WAITING_FOR_KEYCHECK) - , m_passphrase((const byte *)p, strlen(p)) - , m_throwException(throwException) -{ -} - -DefaultDecryptor::DefaultDecryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException) - : ProxyFilter(NULL, SALTLENGTH+BLOCKSIZE, 0, attachment) - , m_state(WAITING_FOR_KEYCHECK) - , m_passphrase(passphrase, passphraseLength) - , m_throwException(throwException) -{ -} - -void DefaultDecryptor::FirstPut(const byte *inString) -{ - CheckKey(inString, inString+SALTLENGTH); -} - -void DefaultDecryptor::LastPut(const byte *inString, size_t length) -{ - if (m_filter.get() == NULL) - { - m_state = KEY_BAD; - if (m_throwException) - throw KeyBadErr(); - } - else - { - m_filter->MessageEnd(); - m_state = WAITING_FOR_KEYCHECK; - } -} - -void DefaultDecryptor::CheckKey(const byte *salt, const byte *keyCheck) -{ - SecByteBlock check(STDMAX((unsigned int)2*BLOCKSIZE, (unsigned int)DefaultHashModule::DIGESTSIZE)); - - DefaultHashModule hash; - hash.Update(m_passphrase, m_passphrase.size()); - hash.Update(salt, SALTLENGTH); - hash.Final(check); - - SecByteBlock key(KEYLENGTH); - SecByteBlock IV(BLOCKSIZE); - GenerateKeyIV(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, key, IV); - - m_cipher.SetKeyWithIV(key, key.size(), IV); - std::auto_ptr<StreamTransformationFilter> decryptor(new StreamTransformationFilter(m_cipher)); - - decryptor->Put(keyCheck, BLOCKSIZE); - decryptor->ForceNextPut(); - decryptor->Get(check+BLOCKSIZE, BLOCKSIZE); - - SetFilter(decryptor.release()); - - if (!VerifyBufsEqual(check, check+BLOCKSIZE, BLOCKSIZE)) - { - m_state = KEY_BAD; - if (m_throwException) - throw KeyBadErr(); - } - else - m_state = KEY_GOOD; -} - -// ******************************************************** - -static DefaultMAC * NewDefaultEncryptorMAC(const byte *passphrase, size_t passphraseLength) -{ - size_t macKeyLength = DefaultMAC::StaticGetValidKeyLength(16); - SecByteBlock macKey(macKeyLength); - // since the MAC is encrypted there is no reason to mash the passphrase for many iterations - Mash(passphrase, passphraseLength, macKey, macKeyLength, 1); - return new DefaultMAC(macKey, macKeyLength); -} - -DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment) - : ProxyFilter(NULL, 0, 0, attachment) - , m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase))) -{ - SetFilter(new HashFilter(*m_mac, new DefaultEncryptor(passphrase), true)); -} - -DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment) - : ProxyFilter(NULL, 0, 0, attachment) - , m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength)) -{ - SetFilter(new HashFilter(*m_mac, new DefaultEncryptor(passphrase, passphraseLength), true)); -} - -void DefaultEncryptorWithMAC::LastPut(const byte *inString, size_t length) -{ - m_filter->MessageEnd(); -} - -// ******************************************************** - -DefaultDecryptorWithMAC::DefaultDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment, bool throwException) - : ProxyFilter(NULL, 0, 0, attachment) - , m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase))) - , m_throwException(throwException) -{ - SetFilter(new DefaultDecryptor(passphrase, m_hashVerifier=new HashVerifier(*m_mac, NULL, HashVerifier::PUT_MESSAGE), throwException)); -} - -DefaultDecryptorWithMAC::DefaultDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException) - : ProxyFilter(NULL, 0, 0, attachment) - , m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength)) - , m_throwException(throwException) -{ - SetFilter(new DefaultDecryptor(passphrase, passphraseLength, m_hashVerifier=new HashVerifier(*m_mac, NULL, HashVerifier::PUT_MESSAGE), throwException)); -} - -DefaultDecryptor::State DefaultDecryptorWithMAC::CurrentState() const -{ - return static_cast<const DefaultDecryptor *>(m_filter.get())->CurrentState(); -} - -bool DefaultDecryptorWithMAC::CheckLastMAC() const -{ - return m_hashVerifier->GetLastResult(); -} - -void DefaultDecryptorWithMAC::LastPut(const byte *inString, size_t length) -{ - m_filter->MessageEnd(); - if (m_throwException && !CheckLastMAC()) - throw MACBadErr(); -} - -NAMESPACE_END diff --git a/lib/cryptopp/default.h b/lib/cryptopp/default.h deleted file mode 100644 index fb5364152..000000000 --- a/lib/cryptopp/default.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef CRYPTOPP_DEFAULT_H -#define CRYPTOPP_DEFAULT_H - -#include "sha.h" -#include "hmac.h" -#include "des.h" -#include "filters.h" -#include "modes.h" - -NAMESPACE_BEGIN(CryptoPP) - -typedef DES_EDE2 Default_BlockCipher; -typedef SHA DefaultHashModule; -typedef HMAC<DefaultHashModule> DefaultMAC; - -//! Password-Based Encryptor using DES-EDE2 -class DefaultEncryptor : public ProxyFilter -{ -public: - DefaultEncryptor(const char *passphrase, BufferedTransformation *attachment = NULL); - DefaultEncryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL); - -protected: - void FirstPut(const byte *); - void LastPut(const byte *inString, size_t length); - -private: - SecByteBlock m_passphrase; - CBC_Mode<Default_BlockCipher>::Encryption m_cipher; -}; - -//! Password-Based Decryptor using DES-EDE2 -class DefaultDecryptor : public ProxyFilter -{ -public: - DefaultDecryptor(const char *passphrase, BufferedTransformation *attachment = NULL, bool throwException=true); - DefaultDecryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL, bool throwException=true); - - class Err : public Exception - { - public: - Err(const std::string &s) - : Exception(DATA_INTEGRITY_CHECK_FAILED, s) {} - }; - class KeyBadErr : public Err {public: KeyBadErr() : Err("DefaultDecryptor: cannot decrypt message with this passphrase") {}}; - - enum State {WAITING_FOR_KEYCHECK, KEY_GOOD, KEY_BAD}; - State CurrentState() const {return m_state;} - -protected: - void FirstPut(const byte *inString); - void LastPut(const byte *inString, size_t length); - - State m_state; - -private: - void CheckKey(const byte *salt, const byte *keyCheck); - - SecByteBlock m_passphrase; - CBC_Mode<Default_BlockCipher>::Decryption m_cipher; - member_ptr<FilterWithBufferedInput> m_decryptor; - bool m_throwException; -}; - -//! Password-Based Encryptor using DES-EDE2 and HMAC/SHA-1 -class DefaultEncryptorWithMAC : public ProxyFilter -{ -public: - DefaultEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment = NULL); - DefaultEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL); - -protected: - void FirstPut(const byte *inString) {} - void LastPut(const byte *inString, size_t length); - -private: - member_ptr<DefaultMAC> m_mac; -}; - -//! Password-Based Decryptor using DES-EDE2 and HMAC/SHA-1 -class DefaultDecryptorWithMAC : public ProxyFilter -{ -public: - class MACBadErr : public DefaultDecryptor::Err {public: MACBadErr() : DefaultDecryptor::Err("DefaultDecryptorWithMAC: MAC check failed") {}}; - - DefaultDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment = NULL, bool throwException=true); - DefaultDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL, bool throwException=true); - - DefaultDecryptor::State CurrentState() const; - bool CheckLastMAC() const; - -protected: - void FirstPut(const byte *inString) {} - void LastPut(const byte *inString, size_t length); - -private: - member_ptr<DefaultMAC> m_mac; - HashVerifier *m_hashVerifier; - bool m_throwException; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/des.cpp b/lib/cryptopp/des.cpp deleted file mode 100644 index a6e0c514d..000000000 --- a/lib/cryptopp/des.cpp +++ /dev/null @@ -1,449 +0,0 @@ -// des.cpp - modified by Wei Dai from Phil Karn's des.c -// The original code and all modifications are in the public domain. - -/* - * This is a major rewrite of my old public domain DES code written - * circa 1987, which in turn borrowed heavily from Jim Gillogly's 1977 - * public domain code. I pretty much kept my key scheduling code, but - * the actual encrypt/decrypt routines are taken from from Richard - * Outerbridge's DES code as printed in Schneier's "Applied Cryptography." - * - * This code is in the public domain. I would appreciate bug reports and - * enhancements. - * - * Phil Karn KA9Q, karn@unix.ka9q.ampr.org, August 1994. - */ - -#include "pch.h" -#include "misc.h" -#include "des.h" - -NAMESPACE_BEGIN(CryptoPP) - -typedef BlockGetAndPut<word32, BigEndian> Block; - -// Richard Outerbridge's initial permutation algorithm -/* -inline void IPERM(word32 &left, word32 &right) -{ - word32 work; - - work = ((left >> 4) ^ right) & 0x0f0f0f0f; - right ^= work; - left ^= work << 4; - work = ((left >> 16) ^ right) & 0xffff; - right ^= work; - left ^= work << 16; - work = ((right >> 2) ^ left) & 0x33333333; - left ^= work; - right ^= (work << 2); - work = ((right >> 8) ^ left) & 0xff00ff; - left ^= work; - right ^= (work << 8); - right = rotl(right, 1); - work = (left ^ right) & 0xaaaaaaaa; - left ^= work; - right ^= work; - left = rotl(left, 1); -} -inline void FPERM(word32 &left, word32 &right) -{ - word32 work; - - right = rotr(right, 1); - work = (left ^ right) & 0xaaaaaaaa; - left ^= work; - right ^= work; - left = rotr(left, 1); - work = ((left >> 8) ^ right) & 0xff00ff; - right ^= work; - left ^= work << 8; - work = ((left >> 2) ^ right) & 0x33333333; - right ^= work; - left ^= work << 2; - work = ((right >> 16) ^ left) & 0xffff; - left ^= work; - right ^= work << 16; - work = ((right >> 4) ^ left) & 0x0f0f0f0f; - left ^= work; - right ^= work << 4; -} -*/ - -// Wei Dai's modification to Richard Outerbridge's initial permutation -// algorithm, this one is faster if you have access to rotate instructions -// (like in MSVC) -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); -} - -void DES::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) -{ - AssertValidKeyLength(length); - - RawSetKey(GetCipherDirection(), userKey); -} - -#ifndef CRYPTOPP_IMPORTS - -/* Tables defined in the Data Encryption Standard documents - * Three of these tables, the initial permutation, the final - * permutation and the expansion operator, are regular enough that - * for speed, we hard-code them. They're here for reference only. - * Also, the S and P boxes are used by a separate program, gensp.c, - * to build the combined SP box, Spbox[]. They're also here just - * for reference. - */ -#ifdef notdef -/* initial permutation IP */ -static byte ip[] = { - 58, 50, 42, 34, 26, 18, 10, 2, - 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, - 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, - 63, 55, 47, 39, 31, 23, 15, 7 -}; - -/* final permutation IP^-1 */ -static byte fp[] = { - 40, 8, 48, 16, 56, 24, 64, 32, - 39, 7, 47, 15, 55, 23, 63, 31, - 38, 6, 46, 14, 54, 22, 62, 30, - 37, 5, 45, 13, 53, 21, 61, 29, - 36, 4, 44, 12, 52, 20, 60, 28, - 35, 3, 43, 11, 51, 19, 59, 27, - 34, 2, 42, 10, 50, 18, 58, 26, - 33, 1, 41, 9, 49, 17, 57, 25 -}; -/* expansion operation matrix */ -static byte ei[] = { - 32, 1, 2, 3, 4, 5, - 4, 5, 6, 7, 8, 9, - 8, 9, 10, 11, 12, 13, - 12, 13, 14, 15, 16, 17, - 16, 17, 18, 19, 20, 21, - 20, 21, 22, 23, 24, 25, - 24, 25, 26, 27, 28, 29, - 28, 29, 30, 31, 32, 1 -}; -/* The (in)famous S-boxes */ -static byte sbox[8][64] = { - /* S1 */ - 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, - 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, - 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, - 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, - - /* S2 */ - 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, - 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, - 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, - 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, - - /* S3 */ - 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, - 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, - 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, - 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, - - /* S4 */ - 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, - 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, - 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, - 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, - - /* S5 */ - 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, - 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, - 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, - 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, - - /* S6 */ - 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, - 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, - 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, - 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, - - /* S7 */ - 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, - 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, - 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, - 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, - - /* S8 */ - 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, - 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, - 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, - 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 -}; - -/* 32-bit permutation function P used on the output of the S-boxes */ -static byte p32i[] = { - 16, 7, 20, 21, - 29, 12, 28, 17, - 1, 15, 23, 26, - 5, 18, 31, 10, - 2, 8, 24, 14, - 32, 27, 3, 9, - 19, 13, 30, 6, - 22, 11, 4, 25 -}; -#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 -}; - -/* Set key (initialize key schedule array) */ -void RawDES::RawSetKey(CipherDir dir, const byte *key) -{ - SecByteBlock 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 */ - memset(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 */ - k[2*i] = ((word32)ks[0] << 24) - | ((word32)ks[2] << 16) - | ((word32)ks[4] << 8) - | ((word32)ks[6]); - k[2*i+1] = ((word32)ks[1] << 24) - | ((word32)ks[3] << 16) - | ((word32)ks[5] << 8) - | ((word32)ks[7]); - } - - if (dir==DECRYPTION) // reverse key schedule order - for (i=0; i<16; i+=2) - { - std::swap(k[i], k[32-2-i]); - std::swap(k[i+1], k[32-1-i]); - } -} - -void RawDES::RawProcessBlock(word32 &l_, word32 &r_) const -{ - word32 l = l_, r = r_; - const word32 *kptr=k; - - for (unsigned 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]; - } - - l_ = l; r_ = r; -} - -void DES_EDE2::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) -{ - AssertValidKeyLength(length); - - m_des1.RawSetKey(GetCipherDirection(), userKey); - m_des2.RawSetKey(ReverseCipherDir(GetCipherDirection()), userKey+8); -} - -void DES_EDE2::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - word32 l,r; - Block::Get(inBlock)(l)(r); - IPERM(l,r); - m_des1.RawProcessBlock(l, r); - m_des2.RawProcessBlock(r, l); - m_des1.RawProcessBlock(l, r); - FPERM(l,r); - Block::Put(xorBlock, outBlock)(r)(l); -} - -void DES_EDE3::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) -{ - AssertValidKeyLength(length); - - m_des1.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 0 : 16)); - m_des2.RawSetKey(ReverseCipherDir(GetCipherDirection()), userKey + 8); - m_des3.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 16 : 0)); -} - -void DES_EDE3::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - word32 l,r; - Block::Get(inBlock)(l)(r); - IPERM(l,r); - m_des1.RawProcessBlock(l, r); - m_des2.RawProcessBlock(r, l); - m_des3.RawProcessBlock(l, r); - FPERM(l,r); - Block::Put(xorBlock, outBlock)(r)(l); -} - -#endif // #ifndef CRYPTOPP_IMPORTS - -static inline bool CheckParity(byte b) -{ - unsigned int a = b ^ (b >> 4); - return ((a ^ (a>>1) ^ (a>>2) ^ (a>>3)) & 1) == 1; -} - -bool DES::CheckKeyParityBits(const byte *key) -{ - for (unsigned int i=0; i<8; i++) - if (!CheckParity(key[i])) - return false; - return true; -} - -void DES::CorrectKeyParityBits(byte *key) -{ - for (unsigned int i=0; i<8; i++) - if (!CheckParity(key[i])) - key[i] ^= 1; -} - -// Encrypt or decrypt a block of data in ECB mode -void DES::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - word32 l,r; - Block::Get(inBlock)(l)(r); - IPERM(l,r); - RawProcessBlock(l, r); - FPERM(l,r); - Block::Put(xorBlock, outBlock)(r)(l); -} - -void DES_XEX3::Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &) -{ - AssertValidKeyLength(length); - - if (!m_des.get()) - m_des.reset(new DES::Encryption); - - memcpy(m_x1, key + (IsForwardTransformation() ? 0 : 16), BLOCKSIZE); - m_des->RawSetKey(GetCipherDirection(), key + 8); - memcpy(m_x3, key + (IsForwardTransformation() ? 16 : 0), BLOCKSIZE); -} - -void DES_XEX3::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - xorbuf(outBlock, inBlock, m_x1, BLOCKSIZE); - m_des->ProcessAndXorBlock(outBlock, xorBlock, outBlock); - xorbuf(outBlock, m_x3, BLOCKSIZE); -} - -NAMESPACE_END diff --git a/lib/cryptopp/des.h b/lib/cryptopp/des.h deleted file mode 100644 index 62f628824..000000000 --- a/lib/cryptopp/des.h +++ /dev/null @@ -1,144 +0,0 @@ -#ifndef CRYPTOPP_DES_H -#define CRYPTOPP_DES_H - -/** \file -*/ - -#include "seckey.h" -#include "secblock.h" - -NAMESPACE_BEGIN(CryptoPP) - -class CRYPTOPP_DLL RawDES -{ -public: - void RawSetKey(CipherDir direction, const byte *userKey); - void RawProcessBlock(word32 &l, word32 &r) const; - -protected: - static const word32 Spbox[8][64]; - - FixedSizeSecBlock<word32, 32> k; -}; - -//! _ -struct DES_Info : public FixedBlockSize<8>, public FixedKeyLength<8> -{ - // disable DES in DLL version by not exporting this function - static const char * StaticAlgorithmName() {return "DES";} -}; - -/// <a href="http://www.weidai.com/scan-mirror/cs.html#DES">DES</a> -/*! The DES implementation in Crypto++ ignores the parity bits - (the least significant bits of each byte) in the key. However - you can use CheckKeyParityBits() and CorrectKeyParityBits() to - check or correct the parity bits if you wish. */ -class DES : public DES_Info, public BlockCipherDocumentation -{ - class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<DES_Info>, public RawDES - { - public: - void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - }; - -public: - //! check DES key parity bits - static bool CheckKeyParityBits(const byte *key); - //! correct DES key parity bits - static void CorrectKeyParityBits(byte *key); - - typedef BlockCipherFinal<ENCRYPTION, Base> Encryption; - typedef BlockCipherFinal<DECRYPTION, Base> Decryption; -}; - -//! _ -struct DES_EDE2_Info : public FixedBlockSize<8>, public FixedKeyLength<16> -{ - CRYPTOPP_DLL static const char * CRYPTOPP_API StaticAlgorithmName() {return "DES-EDE2";} -}; - -/// <a href="http://www.weidai.com/scan-mirror/cs.html#DESede">DES-EDE2</a> -class DES_EDE2 : public DES_EDE2_Info, public BlockCipherDocumentation -{ - class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<DES_EDE2_Info> - { - public: - void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - - protected: - RawDES m_des1, m_des2; - }; - -public: - typedef BlockCipherFinal<ENCRYPTION, Base> Encryption; - typedef BlockCipherFinal<DECRYPTION, Base> Decryption; -}; - -//! _ -struct DES_EDE3_Info : public FixedBlockSize<8>, public FixedKeyLength<24> -{ - CRYPTOPP_DLL static const char * CRYPTOPP_API StaticAlgorithmName() {return "DES-EDE3";} -}; - -/// <a href="http://www.weidai.com/scan-mirror/cs.html#DESede">DES-EDE3</a> -class DES_EDE3 : public DES_EDE3_Info, public BlockCipherDocumentation -{ - class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<DES_EDE3_Info> - { - public: - void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - - protected: - RawDES m_des1, m_des2, m_des3; - }; - -public: - typedef BlockCipherFinal<ENCRYPTION, Base> Encryption; - typedef BlockCipherFinal<DECRYPTION, Base> Decryption; -}; - -//! _ -struct DES_XEX3_Info : public FixedBlockSize<8>, public FixedKeyLength<24> -{ - static const char *StaticAlgorithmName() {return "DES-XEX3";} -}; - -/// <a href="http://www.weidai.com/scan-mirror/cs.html#DESX">DES-XEX3</a>, AKA DESX -class DES_XEX3 : public DES_XEX3_Info, public BlockCipherDocumentation -{ - class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<DES_XEX3_Info> - { - public: - void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - - protected: - FixedSizeSecBlock<byte, BLOCKSIZE> m_x1, m_x3; - // VS2005 workaround: calling modules compiled with /clr gets unresolved external symbol DES::Base::ProcessAndXorBlock - // if we use DES::Encryption here directly without value_ptr. - value_ptr<DES::Encryption> m_des; - }; - -public: - typedef BlockCipherFinal<ENCRYPTION, Base> Encryption; - typedef BlockCipherFinal<DECRYPTION, Base> Decryption; -}; - -typedef DES::Encryption DESEncryption; -typedef DES::Decryption DESDecryption; - -typedef DES_EDE2::Encryption DES_EDE2_Encryption; -typedef DES_EDE2::Decryption DES_EDE2_Decryption; - -typedef DES_EDE3::Encryption DES_EDE3_Encryption; -typedef DES_EDE3::Decryption DES_EDE3_Decryption; - -typedef DES_XEX3::Encryption DES_XEX3_Encryption; -typedef DES_XEX3::Decryption DES_XEX3_Decryption; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/dessp.cpp b/lib/cryptopp/dessp.cpp deleted file mode 100644 index 49ed1d26d..000000000 --- a/lib/cryptopp/dessp.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// This file is mostly generated by Phil Karn's gensp.c - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "des.h" - -NAMESPACE_BEGIN(CryptoPP) - -// VC60 workaround: gives a C4786 warning without this function -// when runtime lib is set to multithread debug DLL -// even though warning 4786 is disabled! -void DES_VC60Workaround() -{ -} - -const word32 RawDES::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} -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/dh.cpp b/lib/cryptopp/dh.cpp deleted file mode 100644 index 22097a051..000000000 --- a/lib/cryptopp/dh.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// dh.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "dh.h" - -NAMESPACE_BEGIN(CryptoPP) - -void DH_TestInstantiations() -{ - DH dh1; - DH dh2(NullRNG(), 10); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/dh.h b/lib/cryptopp/dh.h deleted file mode 100644 index 10e8d142e..000000000 --- a/lib/cryptopp/dh.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef CRYPTOPP_DH_H -#define CRYPTOPP_DH_H - -/** \file -*/ - -#include "gfpcrypt.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! , -template <class GROUP_PARAMETERS, class COFACTOR_OPTION = CPP_TYPENAME GROUP_PARAMETERS::DefaultCofactorOption> -class DH_Domain : public DL_SimpleKeyAgreementDomainBase<typename GROUP_PARAMETERS::Element> -{ - typedef DL_SimpleKeyAgreementDomainBase<typename GROUP_PARAMETERS::Element> Base; - -public: - typedef GROUP_PARAMETERS GroupParameters; - typedef typename GroupParameters::Element Element; - typedef DL_KeyAgreementAlgorithm_DH<Element, COFACTOR_OPTION> DH_Algorithm; - typedef DH_Domain<GROUP_PARAMETERS, COFACTOR_OPTION> Domain; - - DH_Domain() {} - - DH_Domain(const GroupParameters ¶ms) - : m_groupParameters(params) {} - - DH_Domain(BufferedTransformation &bt) - {m_groupParameters.BERDecode(bt);} - - template <class T2> - DH_Domain(RandomNumberGenerator &v1, const T2 &v2) - {m_groupParameters.Initialize(v1, v2);} - - template <class T2, class T3> - DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3) - {m_groupParameters.Initialize(v1, v2, v3);} - - template <class T2, class T3, class T4> - DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3, const T4 &v4) - {m_groupParameters.Initialize(v1, v2, v3, v4);} - - template <class T1, class T2> - DH_Domain(const T1 &v1, const T2 &v2) - {m_groupParameters.Initialize(v1, v2);} - - template <class T1, class T2, class T3> - DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3) - {m_groupParameters.Initialize(v1, v2, v3);} - - template <class T1, class T2, class T3, class T4> - DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) - {m_groupParameters.Initialize(v1, v2, v3, v4);} - - const GroupParameters & GetGroupParameters() const {return m_groupParameters;} - GroupParameters & AccessGroupParameters() {return m_groupParameters;} - - void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const - { - Base::GeneratePublicKey(rng, privateKey, publicKey); - - if (FIPS_140_2_ComplianceEnabled()) - { - SecByteBlock privateKey2(this->PrivateKeyLength()); - this->GeneratePrivateKey(rng, privateKey2); - - SecByteBlock publicKey2(this->PublicKeyLength()); - Base::GeneratePublicKey(rng, privateKey2, publicKey2); - - SecByteBlock agreedValue(this->AgreedValueLength()), agreedValue2(this->AgreedValueLength()); - bool agreed1 = this->Agree(agreedValue, privateKey, publicKey2); - bool agreed2 = this->Agree(agreedValue2, privateKey2, publicKey); - - if (!agreed1 || !agreed2 || agreedValue != agreedValue2) - throw SelfTestFailure(this->AlgorithmName() + ": pairwise consistency test failed"); - } - } - - static std::string CRYPTOPP_API StaticAlgorithmName() - {return GroupParameters::StaticAlgorithmNamePrefix() + DH_Algorithm::StaticAlgorithmName();} - std::string AlgorithmName() const {return StaticAlgorithmName();} - -private: - const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const - {return Singleton<DH_Algorithm>().Ref();} - DL_GroupParameters<Element> & AccessAbstractGroupParameters() - {return m_groupParameters;} - - GroupParameters m_groupParameters; -}; - -CRYPTOPP_DLL_TEMPLATE_CLASS DH_Domain<DL_GroupParameters_GFP_DefaultSafePrime>; - -//! <a href="http://www.weidai.com/scan-mirror/ka.html#DH">Diffie-Hellman</a> in GF(p) with key validation -typedef DH_Domain<DL_GroupParameters_GFP_DefaultSafePrime> DH; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/dh2.cpp b/lib/cryptopp/dh2.cpp deleted file mode 100644 index 98175ee28..000000000 --- a/lib/cryptopp/dh2.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// dh2.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "dh2.h" - -NAMESPACE_BEGIN(CryptoPP) - -void DH2_TestInstantiations() -{ - DH2 dh(*(SimpleKeyAgreementDomain*)NULL); -} - -bool DH2::Agree(byte *agreedValue, - const byte *staticSecretKey, const byte *ephemeralSecretKey, - const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, - bool validateStaticOtherPublicKey) const -{ - return d1.Agree(agreedValue, staticSecretKey, staticOtherPublicKey, validateStaticOtherPublicKey) - && d2.Agree(agreedValue+d1.AgreedValueLength(), ephemeralSecretKey, ephemeralOtherPublicKey, true); -} - -NAMESPACE_END diff --git a/lib/cryptopp/dh2.h b/lib/cryptopp/dh2.h deleted file mode 100644 index af9d342d6..000000000 --- a/lib/cryptopp/dh2.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef CRYPTOPP_DH2_H -#define CRYPTOPP_DH2_H - -/** \file -*/ - -#include "cryptlib.h" - -NAMESPACE_BEGIN(CryptoPP) - -/// <a href="http://www.weidai.com/scan-mirror/ka.html#DH2">Unified Diffie-Hellman</a> -class DH2 : public AuthenticatedKeyAgreementDomain -{ -public: - DH2(SimpleKeyAgreementDomain &domain) - : d1(domain), d2(domain) {} - DH2(SimpleKeyAgreementDomain &staticDomain, SimpleKeyAgreementDomain &ephemeralDomain) - : d1(staticDomain), d2(ephemeralDomain) {} - - CryptoParameters & AccessCryptoParameters() {return d1.AccessCryptoParameters();} - - unsigned int AgreedValueLength() const - {return d1.AgreedValueLength() + d2.AgreedValueLength();} - - unsigned int StaticPrivateKeyLength() const - {return d1.PrivateKeyLength();} - unsigned int StaticPublicKeyLength() const - {return d1.PublicKeyLength();} - void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const - {d1.GeneratePrivateKey(rng, privateKey);} - void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const - {d1.GeneratePublicKey(rng, privateKey, publicKey);} - void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const - {d1.GenerateKeyPair(rng, privateKey, publicKey);} - - unsigned int EphemeralPrivateKeyLength() const - {return d2.PrivateKeyLength();} - unsigned int EphemeralPublicKeyLength() const - {return d2.PublicKeyLength();} - void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const - {d2.GeneratePrivateKey(rng, privateKey);} - void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const - {d2.GeneratePublicKey(rng, privateKey, publicKey);} - void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const - {d2.GenerateKeyPair(rng, privateKey, publicKey);} - - bool Agree(byte *agreedValue, - const byte *staticPrivateKey, const byte *ephemeralPrivateKey, - const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, - bool validateStaticOtherPublicKey=true) const; - -protected: - SimpleKeyAgreementDomain &d1, &d2; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/dll.cpp b/lib/cryptopp/dll.cpp deleted file mode 100644 index 2b4ef7ade..000000000 --- a/lib/cryptopp/dll.cpp +++ /dev/null @@ -1,146 +0,0 @@ -// dll.cpp - written and placed in the public domain by Wei Dai - -#define CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES -#define CRYPTOPP_DEFAULT_NO_DLL - -#include "dll.h" -#pragma warning(default: 4660) - -#if defined(CRYPTOPP_EXPORTS) && defined(CRYPTOPP_WIN32_AVAILABLE) -#include <windows.h> -#endif - -#ifndef CRYPTOPP_IMPORTS - -NAMESPACE_BEGIN(CryptoPP) - -template<> const byte PKCS_DigestDecoration<SHA1>::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14}; -template<> const unsigned int PKCS_DigestDecoration<SHA1>::length = sizeof(PKCS_DigestDecoration<SHA1>::decoration); - -template<> const byte PKCS_DigestDecoration<SHA224>::decoration[] = {0x30,0x2d,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,0x05,0x00,0x04,0x1c}; -template<> const unsigned int PKCS_DigestDecoration<SHA224>::length = sizeof(PKCS_DigestDecoration<SHA224>::decoration); - -template<> const byte PKCS_DigestDecoration<SHA256>::decoration[] = {0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20}; -template<> const unsigned int PKCS_DigestDecoration<SHA256>::length = sizeof(PKCS_DigestDecoration<SHA256>::decoration); - -template<> const byte PKCS_DigestDecoration<SHA384>::decoration[] = {0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30}; -template<> const unsigned int PKCS_DigestDecoration<SHA384>::length = sizeof(PKCS_DigestDecoration<SHA384>::decoration); - -template<> const byte PKCS_DigestDecoration<SHA512>::decoration[] = {0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40}; -template<> const unsigned int PKCS_DigestDecoration<SHA512>::length = sizeof(PKCS_DigestDecoration<SHA512>::decoration); - -template<> const byte EMSA2HashId<SHA>::id = 0x33; -template<> const byte EMSA2HashId<SHA224>::id = 0x38; -template<> const byte EMSA2HashId<SHA256>::id = 0x34; -template<> const byte EMSA2HashId<SHA384>::id = 0x36; -template<> const byte EMSA2HashId<SHA512>::id = 0x35; - -NAMESPACE_END - -#endif - -#ifdef CRYPTOPP_EXPORTS - -USING_NAMESPACE(CryptoPP) - -#if !(defined(_MSC_VER) && (_MSC_VER < 1300)) -using std::set_new_handler; -#endif - -static PNew s_pNew = NULL; -static PDelete s_pDelete = NULL; - -static void * New (size_t size) -{ - void *p; - while (!(p = malloc(size))) - CallNewHandler(); - - return p; -} - -static void SetNewAndDeleteFunctionPointers() -{ - void *p = NULL; - HMODULE hModule = NULL; - MEMORY_BASIC_INFORMATION mbi; - - while (true) - { - VirtualQuery(p, &mbi, sizeof(mbi)); - - if (p >= (char *)mbi.BaseAddress + mbi.RegionSize) - break; - - p = (char *)mbi.BaseAddress + mbi.RegionSize; - - if (!mbi.AllocationBase || mbi.AllocationBase == hModule) - continue; - - hModule = HMODULE(mbi.AllocationBase); - - PGetNewAndDelete pGetNewAndDelete = (PGetNewAndDelete)GetProcAddress(hModule, "GetNewAndDeleteForCryptoPP"); - if (pGetNewAndDelete) - { - pGetNewAndDelete(s_pNew, s_pDelete); - return; - } - - PSetNewAndDelete pSetNewAndDelete = (PSetNewAndDelete)GetProcAddress(hModule, "SetNewAndDeleteFromCryptoPP"); - if (pSetNewAndDelete) - { - s_pNew = &New; - s_pDelete = &free; - pSetNewAndDelete(s_pNew, s_pDelete, &set_new_handler); - return; - } - } - - // try getting these directly using mangled names of new and delete operators - - hModule = GetModuleHandle("msvcrtd"); - if (!hModule) - hModule = GetModuleHandle("msvcrt"); - if (hModule) - { - // 32-bit versions - s_pNew = (PNew)GetProcAddress(hModule, "??2@YAPAXI@Z"); - s_pDelete = (PDelete)GetProcAddress(hModule, "??3@YAXPAX@Z"); - if (s_pNew && s_pDelete) - return; - - // 64-bit versions - s_pNew = (PNew)GetProcAddress(hModule, "??2@YAPEAX_K@Z"); - s_pDelete = (PDelete)GetProcAddress(hModule, "??3@YAXPEAX@Z"); - if (s_pNew && s_pDelete) - return; - } - - OutputDebugString("Crypto++ was not able to obtain new and delete function pointers.\n"); - throw 0; -} - -void * operator new (size_t size) -{ - if (!s_pNew) - SetNewAndDeleteFunctionPointers(); - - return s_pNew(size); -} - -void operator delete (void * p) -{ - s_pDelete(p); -} - -void * operator new [] (size_t size) -{ - return operator new (size); -} - -void operator delete [] (void * p) -{ - operator delete (p); -} - -#endif // #ifdef CRYPTOPP_EXPORTS diff --git a/lib/cryptopp/dll.h b/lib/cryptopp/dll.h deleted file mode 100644 index 50775e98b..000000000 --- a/lib/cryptopp/dll.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef CRYPTOPP_DLL_H -#define CRYPTOPP_DLL_H - -#if !defined(CRYPTOPP_IMPORTS) && !defined(CRYPTOPP_EXPORTS) && !defined(CRYPTOPP_DEFAULT_NO_DLL) -#ifdef CRYPTOPP_CONFIG_H -#error To use the DLL version of Crypto++, this file must be included before any other Crypto++ header files. -#endif -#define CRYPTOPP_IMPORTS -#endif - -#include "aes.h" -#include "cbcmac.h" -#include "ccm.h" -#include "cmac.h" -#include "channels.h" -#include "des.h" -#include "dh.h" -#include "dsa.h" -#include "ec2n.h" -#include "eccrypto.h" -#include "ecp.h" -#include "files.h" -#include "fips140.h" -#include "gcm.h" -#include "hex.h" -#include "hmac.h" -#include "modes.h" -#include "mqueue.h" -#include "nbtheory.h" -#include "osrng.h" -#include "pkcspad.h" -#include "pssr.h" -#include "randpool.h" -#include "rsa.h" -#include "rw.h" -#include "sha.h" -#include "trdlocal.h" - -#ifdef CRYPTOPP_IMPORTS - -#ifdef _DLL -// cause CRT DLL to be initialized before Crypto++ so that we can use malloc and free during DllMain() -#ifdef NDEBUG -#pragma comment(lib, "msvcrt") -#else -#pragma comment(lib, "msvcrtd") -#endif -#endif - -#pragma comment(lib, "cryptopp") - -#endif // #ifdef CRYPTOPP_IMPORTS - -#include <new> // for new_handler - -NAMESPACE_BEGIN(CryptoPP) - -#if !(defined(_MSC_VER) && (_MSC_VER < 1300)) -using std::new_handler; -#endif - -typedef void * (CRYPTOPP_API * PNew)(size_t); -typedef void (CRYPTOPP_API * PDelete)(void *); -typedef void (CRYPTOPP_API * PGetNewAndDelete)(PNew &, PDelete &); -typedef new_handler (CRYPTOPP_API * PSetNewHandler)(new_handler); -typedef void (CRYPTOPP_API * PSetNewAndDelete)(PNew, PDelete, PSetNewHandler); - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/dmac.h b/lib/cryptopp/dmac.h deleted file mode 100644 index 80b54ac2f..000000000 --- a/lib/cryptopp/dmac.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef CRYPTOPP_DMAC_H -#define CRYPTOPP_DMAC_H - -#include "cbcmac.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -template <class T> -class CRYPTOPP_NO_VTABLE DMAC_Base : public SameKeyLengthAs<T>, public MessageAuthenticationCode -{ -public: - static std::string StaticAlgorithmName() {return std::string("DMAC(") + T::StaticAlgorithmName() + ")";} - - CRYPTOPP_CONSTANT(DIGESTSIZE=T::BLOCKSIZE) - - DMAC_Base() {} - - void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); - void Update(const byte *input, size_t length); - void TruncatedFinal(byte *mac, size_t size); - unsigned int DigestSize() const {return DIGESTSIZE;} - -private: - byte *GenerateSubKeys(const byte *key, size_t keylength); - - size_t m_subkeylength; - SecByteBlock m_subkeys; - CBC_MAC<T> m_mac1; - typename T::Encryption m_f2; - unsigned int m_counter; -}; - -//! DMAC -/*! Based on "CBC MAC for Real-Time Data Sources" by Erez Petrank - and Charles Rackoff. T should be a class derived from BlockCipherDocumentation. -*/ -template <class T> -class DMAC : public MessageAuthenticationCodeFinal<DMAC_Base<T> > -{ -public: - DMAC() {} - DMAC(const byte *key, size_t length=DMAC_Base<T>::DEFAULT_KEYLENGTH) - {this->SetKey(key, length);} -}; - -template <class T> -void DMAC_Base<T>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) -{ - m_subkeylength = T::StaticGetValidKeyLength(T::BLOCKSIZE); - m_subkeys.resize(2*UnsignedMin((unsigned int)T::BLOCKSIZE, m_subkeylength)); - m_mac1.SetKey(GenerateSubKeys(key, length), m_subkeylength, params); - m_f2.SetKey(m_subkeys+m_subkeys.size()/2, m_subkeylength, params); - m_counter = 0; - m_subkeys.resize(0); -} - -template <class T> -void DMAC_Base<T>::Update(const byte *input, size_t length) -{ - m_mac1.Update(input, length); - m_counter = (unsigned int)((m_counter + length) % T::BLOCKSIZE); -} - -template <class T> -void DMAC_Base<T>::TruncatedFinal(byte *mac, size_t size) -{ - ThrowIfInvalidTruncatedSize(size); - - byte pad[T::BLOCKSIZE]; - byte padByte = byte(T::BLOCKSIZE-m_counter); - memset(pad, padByte, padByte); - m_mac1.Update(pad, padByte); - m_mac1.TruncatedFinal(mac, size); - m_f2.ProcessBlock(mac); - - m_counter = 0; // reset for next message -} - -template <class T> -byte *DMAC_Base<T>::GenerateSubKeys(const byte *key, size_t keylength) -{ - typename T::Encryption cipher(key, keylength); - memset(m_subkeys, 0, m_subkeys.size()); - cipher.ProcessBlock(m_subkeys); - m_subkeys[m_subkeys.size()/2 + T::BLOCKSIZE - 1] = 1; - cipher.ProcessBlock(m_subkeys+m_subkeys.size()/2); - return m_subkeys; -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/dsa.cpp b/lib/cryptopp/dsa.cpp deleted file mode 100644 index 5aace4857..000000000 --- a/lib/cryptopp/dsa.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// dsa.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "dsa.h" -#include "nbtheory.h" - -NAMESPACE_BEGIN(CryptoPP) - -size_t DSAConvertSignatureFormat(byte *buffer, size_t bufferSize, DSASignatureFormat toFormat, const byte *signature, size_t signatureLen, DSASignatureFormat fromFormat) -{ - Integer r, s; - StringStore store(signature, signatureLen); - ArraySink sink(buffer, bufferSize); - - switch (fromFormat) - { - case DSA_P1363: - r.Decode(store, signatureLen/2); - s.Decode(store, signatureLen/2); - break; - case DSA_DER: - { - BERSequenceDecoder seq(store); - r.BERDecode(seq); - s.BERDecode(seq); - seq.MessageEnd(); - break; - } - case DSA_OPENPGP: - r.OpenPGPDecode(store); - s.OpenPGPDecode(store); - break; - } - - switch (toFormat) - { - case DSA_P1363: - r.Encode(sink, bufferSize/2); - s.Encode(sink, bufferSize/2); - break; - case DSA_DER: - { - DERSequenceEncoder seq(sink); - r.DEREncode(seq); - s.DEREncode(seq); - seq.MessageEnd(); - break; - } - case DSA_OPENPGP: - r.OpenPGPEncode(sink); - s.OpenPGPEncode(sink); - break; - } - - return (size_t)sink.TotalPutLength(); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/dsa.h b/lib/cryptopp/dsa.h deleted file mode 100644 index 6ae03877c..000000000 --- a/lib/cryptopp/dsa.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef CRYPTOPP_DSA_H -#define CRYPTOPP_DSA_H - -/** \file -*/ - -#include "gfpcrypt.h" - -NAMESPACE_BEGIN(CryptoPP) - -/*! The DSA signature format used by Crypto++ is as defined by IEEE P1363. - Java uses the DER format, and OpenPGP uses the OpenPGP format. */ -enum DSASignatureFormat {DSA_P1363, DSA_DER, DSA_OPENPGP}; -/** This function converts between these formats, and returns length of signature in the target format. - If toFormat == DSA_P1363, bufferSize must equal publicKey.SignatureLength() */ -size_t DSAConvertSignatureFormat(byte *buffer, size_t bufferSize, DSASignatureFormat toFormat, - const byte *signature, size_t signatureLen, DSASignatureFormat fromFormat); - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - -typedef DSA::Signer DSAPrivateKey; -typedef DSA::Verifier DSAPublicKey; - -const int MIN_DSA_PRIME_LENGTH = DSA::MIN_PRIME_LENGTH; -const int MAX_DSA_PRIME_LENGTH = DSA::MAX_PRIME_LENGTH; -const int DSA_PRIME_LENGTH_MULTIPLE = DSA::PRIME_LENGTH_MULTIPLE; - -inline bool GenerateDSAPrimes(const byte *seed, size_t seedLength, int &counter, Integer &p, unsigned int primeLength, Integer &q) - {return DSA::GeneratePrimes(seed, seedLength, counter, p, primeLength, q);} - -#endif - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/eax.cpp b/lib/cryptopp/eax.cpp deleted file mode 100644 index 2728c9bcd..000000000 --- a/lib/cryptopp/eax.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// eax.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "eax.h" - -NAMESPACE_BEGIN(CryptoPP) - -void EAX_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms) -{ - AccessMAC().SetKey(userKey, keylength, params); - m_buffer.New(2*AccessMAC().TagSize()); -} - -void EAX_Base::Resync(const byte *iv, size_t len) -{ - MessageAuthenticationCode &mac = AccessMAC(); - unsigned int blockSize = mac.TagSize(); - - memset(m_buffer, 0, blockSize); - mac.Update(m_buffer, blockSize); - mac.CalculateDigest(m_buffer+blockSize, iv, len); - - m_buffer[blockSize-1] = 1; - mac.Update(m_buffer, blockSize); - - m_ctr.SetCipherWithIV(AccessMAC().AccessCipher(), m_buffer+blockSize, blockSize); -} - -size_t EAX_Base::AuthenticateBlocks(const byte *data, size_t len) -{ - AccessMAC().Update(data, len); - return 0; -} - -void EAX_Base::AuthenticateLastHeaderBlock() -{ - assert(m_bufferedDataLength == 0); - MessageAuthenticationCode &mac = AccessMAC(); - unsigned int blockSize = mac.TagSize(); - - mac.Final(m_buffer); - xorbuf(m_buffer+blockSize, m_buffer, blockSize); - - memset(m_buffer, 0, blockSize); - m_buffer[blockSize-1] = 2; - mac.Update(m_buffer, blockSize); -} - -void EAX_Base::AuthenticateLastFooterBlock(byte *tag, size_t macSize) -{ - assert(m_bufferedDataLength == 0); - MessageAuthenticationCode &mac = AccessMAC(); - unsigned int blockSize = mac.TagSize(); - - mac.TruncatedFinal(m_buffer, macSize); - xorbuf(tag, m_buffer, m_buffer+blockSize, macSize); -} - -NAMESPACE_END diff --git a/lib/cryptopp/eax.h b/lib/cryptopp/eax.h deleted file mode 100644 index e48ee92b5..000000000 --- a/lib/cryptopp/eax.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef CRYPTOPP_EAX_H -#define CRYPTOPP_EAX_H - -#include "authenc.h" -#include "modes.h" -#include "cmac.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! . -class CRYPTOPP_NO_VTABLE EAX_Base : public AuthenticatedSymmetricCipherBase -{ -public: - // AuthenticatedSymmetricCipher - std::string AlgorithmName() const - {return GetMAC().GetCipher().AlgorithmName() + std::string("/EAX");} - size_t MinKeyLength() const - {return GetMAC().MinKeyLength();} - size_t MaxKeyLength() const - {return GetMAC().MaxKeyLength();} - size_t DefaultKeyLength() const - {return GetMAC().DefaultKeyLength();} - size_t GetValidKeyLength(size_t n) const - {return GetMAC().GetValidKeyLength(n);} - bool IsValidKeyLength(size_t n) const - {return GetMAC().IsValidKeyLength(n);} - unsigned int OptimalDataAlignment() const - {return GetMAC().OptimalDataAlignment();} - IV_Requirement IVRequirement() const - {return UNIQUE_IV;} - unsigned int IVSize() const - {return GetMAC().TagSize();} - unsigned int MinIVLength() const - {return 0;} - unsigned int MaxIVLength() const - {return UINT_MAX;} - unsigned int DigestSize() const - {return GetMAC().TagSize();} - lword MaxHeaderLength() const - {return LWORD_MAX;} - lword MaxMessageLength() const - {return LWORD_MAX;} - -protected: - // AuthenticatedSymmetricCipherBase - bool AuthenticationIsOnPlaintext() const - {return false;} - unsigned int AuthenticationBlockSize() const - {return 1;} - void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms); - void Resync(const byte *iv, size_t len); - size_t AuthenticateBlocks(const byte *data, size_t len); - void AuthenticateLastHeaderBlock(); - void AuthenticateLastFooterBlock(byte *mac, size_t macSize); - SymmetricCipher & AccessSymmetricCipher() {return m_ctr;} - const CMAC_Base & GetMAC() const {return const_cast<EAX_Base *>(this)->AccessMAC();} - virtual CMAC_Base & AccessMAC() =0; - - CTR_Mode_ExternalCipher::Encryption m_ctr; -}; - -//! . -template <class T_BlockCipher, bool T_IsEncryption> -class EAX_Final : public EAX_Base -{ -public: - static std::string StaticAlgorithmName() - {return T_BlockCipher::StaticAlgorithmName() + std::string("/EAX");} - bool IsForwardTransformation() const - {return T_IsEncryption;} - -private: - CMAC_Base & AccessMAC() {return m_cmac;} - CMAC<T_BlockCipher> m_cmac; -}; - -#ifdef EAX // EAX is defined to 11 on GCC 3.4.3, OpenSolaris 8.11 -#undef EAX -#endif - -/// <a href="http://www.cryptolounge.org/wiki/EAX">EAX</a> -template <class T_BlockCipher> -struct EAX : public AuthenticatedSymmetricCipherDocumentation -{ - typedef EAX_Final<T_BlockCipher, true> Encryption; - typedef EAX_Final<T_BlockCipher, false> Decryption; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/ec2n.cpp b/lib/cryptopp/ec2n.cpp deleted file mode 100644 index b513b2cb8..000000000 --- a/lib/cryptopp/ec2n.cpp +++ /dev/null @@ -1,292 +0,0 @@ -// ec2n.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "ec2n.h" -#include "asn.h" - -#include "algebra.cpp" -#include "eprecomp.cpp" - -NAMESPACE_BEGIN(CryptoPP) - -EC2N::EC2N(BufferedTransformation &bt) - : m_field(BERDecodeGF2NP(bt)) -{ - BERSequenceDecoder seq(bt); - m_field->BERDecodeElement(seq, m_a); - m_field->BERDecodeElement(seq, m_b); - // skip optional seed - if (!seq.EndReached()) - { - SecByteBlock seed; - unsigned int unused; - BERDecodeBitString(seq, seed, unused); - } - seq.MessageEnd(); -} - -void EC2N::DEREncode(BufferedTransformation &bt) const -{ - m_field->DEREncode(bt); - DERSequenceEncoder seq(bt); - m_field->DEREncodeElement(seq, m_a); - m_field->DEREncodeElement(seq, m_b); - seq.MessageEnd(); -} - -bool EC2N::DecodePoint(EC2N::Point &P, const byte *encodedPoint, size_t encodedPointLen) const -{ - StringStore store(encodedPoint, encodedPointLen); - return DecodePoint(P, store, encodedPointLen); -} - -bool EC2N::DecodePoint(EC2N::Point &P, BufferedTransformation &bt, size_t encodedPointLen) const -{ - byte type; - if (encodedPointLen < 1 || !bt.Get(type)) - return false; - - switch (type) - { - case 0: - P.identity = true; - return true; - case 2: - case 3: - { - if (encodedPointLen != EncodedPointSize(true)) - return false; - - P.identity = false; - P.x.Decode(bt, m_field->MaxElementByteLength()); - - if (P.x.IsZero()) - { - P.y = m_field->SquareRoot(m_b); - return true; - } - - FieldElement z = m_field->Square(P.x); - assert(P.x == m_field->SquareRoot(z)); - P.y = m_field->Divide(m_field->Add(m_field->Multiply(z, m_field->Add(P.x, m_a)), m_b), z); - assert(P.x == m_field->Subtract(m_field->Divide(m_field->Subtract(m_field->Multiply(P.y, z), m_b), z), m_a)); - z = m_field->SolveQuadraticEquation(P.y); - assert(m_field->Add(m_field->Square(z), z) == P.y); - z.SetCoefficient(0, type & 1); - - P.y = m_field->Multiply(z, P.x); - return true; - } - case 4: - { - if (encodedPointLen != EncodedPointSize(false)) - return false; - - unsigned int len = m_field->MaxElementByteLength(); - P.identity = false; - P.x.Decode(bt, len); - P.y.Decode(bt, len); - return true; - } - default: - return false; - } -} - -void EC2N::EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const -{ - if (P.identity) - NullStore().TransferTo(bt, EncodedPointSize(compressed)); - else if (compressed) - { - bt.Put(2 + (!P.x ? 0 : m_field->Divide(P.y, P.x).GetBit(0))); - P.x.Encode(bt, m_field->MaxElementByteLength()); - } - else - { - unsigned int len = m_field->MaxElementByteLength(); - bt.Put(4); // uncompressed - P.x.Encode(bt, len); - P.y.Encode(bt, len); - } -} - -void EC2N::EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const -{ - ArraySink sink(encodedPoint, EncodedPointSize(compressed)); - EncodePoint(sink, P, compressed); - assert(sink.TotalPutLength() == EncodedPointSize(compressed)); -} - -EC2N::Point EC2N::BERDecodePoint(BufferedTransformation &bt) const -{ - SecByteBlock str; - BERDecodeOctetString(bt, str); - Point P; - if (!DecodePoint(P, str, str.size())) - BERDecodeError(); - return P; -} - -void EC2N::DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const -{ - SecByteBlock str(EncodedPointSize(compressed)); - EncodePoint(str, P, compressed); - DEREncodeOctetString(bt, str); -} - -bool EC2N::ValidateParameters(RandomNumberGenerator &rng, unsigned int level) const -{ - bool pass = !!m_b; - pass = pass && m_a.CoefficientCount() <= m_field->MaxElementBitLength(); - pass = pass && m_b.CoefficientCount() <= m_field->MaxElementBitLength(); - - if (level >= 1) - pass = pass && m_field->GetModulus().IsIrreducible(); - - return pass; -} - -bool EC2N::VerifyPoint(const Point &P) const -{ - const FieldElement &x = P.x, &y = P.y; - return P.identity || - (x.CoefficientCount() <= m_field->MaxElementBitLength() - && y.CoefficientCount() <= m_field->MaxElementBitLength() - && !(((x+m_a)*x*x+m_b-(x+y)*y)%m_field->GetModulus())); -} - -bool EC2N::Equal(const Point &P, const Point &Q) const -{ - if (P.identity && Q.identity) - return true; - - if (P.identity && !Q.identity) - return false; - - if (!P.identity && Q.identity) - return false; - - return (m_field->Equal(P.x,Q.x) && m_field->Equal(P.y,Q.y)); -} - -const EC2N::Point& EC2N::Identity() const -{ - return Singleton<Point>().Ref(); -} - -const EC2N::Point& EC2N::Inverse(const Point &P) const -{ - if (P.identity) - return P; - else - { - m_R.identity = false; - m_R.y = m_field->Add(P.x, P.y); - m_R.x = P.x; - return m_R; - } -} - -const EC2N::Point& EC2N::Add(const Point &P, const Point &Q) const -{ - if (P.identity) return Q; - if (Q.identity) return P; - if (Equal(P, Q)) return Double(P); - if (m_field->Equal(P.x, Q.x) && m_field->Equal(P.y, m_field->Add(Q.x, Q.y))) return Identity(); - - FieldElement t = m_field->Add(P.y, Q.y); - t = m_field->Divide(t, m_field->Add(P.x, Q.x)); - FieldElement x = m_field->Square(t); - m_field->Accumulate(x, t); - m_field->Accumulate(x, Q.x); - m_field->Accumulate(x, m_a); - m_R.y = m_field->Add(P.y, m_field->Multiply(t, x)); - m_field->Accumulate(x, P.x); - m_field->Accumulate(m_R.y, x); - - m_R.x.swap(x); - m_R.identity = false; - return m_R; -} - -const EC2N::Point& EC2N::Double(const Point &P) const -{ - if (P.identity) return P; - if (!m_field->IsUnit(P.x)) return Identity(); - - FieldElement t = m_field->Divide(P.y, P.x); - m_field->Accumulate(t, P.x); - m_R.y = m_field->Square(P.x); - m_R.x = m_field->Square(t); - m_field->Accumulate(m_R.x, t); - m_field->Accumulate(m_R.x, m_a); - m_field->Accumulate(m_R.y, m_field->Multiply(t, m_R.x)); - m_field->Accumulate(m_R.y, m_R.x); - - m_R.identity = false; - return m_R; -} - -// ******************************************************** - -/* -EcPrecomputation<EC2N>& EcPrecomputation<EC2N>::operator=(const EcPrecomputation<EC2N> &rhs) -{ - m_ec = rhs.m_ec; - m_ep = rhs.m_ep; - m_ep.m_group = m_ec.get(); - return *this; -} - -void EcPrecomputation<EC2N>::SetCurveAndBase(const EC2N &ec, const EC2N::Point &base) -{ - m_ec.reset(new EC2N(ec)); - m_ep.SetGroupAndBase(*m_ec, base); -} - -void EcPrecomputation<EC2N>::Precompute(unsigned int maxExpBits, unsigned int storage) -{ - m_ep.Precompute(maxExpBits, storage); -} - -void EcPrecomputation<EC2N>::Load(BufferedTransformation &bt) -{ - BERSequenceDecoder seq(bt); - word32 version; - BERDecodeUnsigned<word32>(seq, version, INTEGER, 1, 1); - m_ep.m_exponentBase.BERDecode(seq); - m_ep.m_windowSize = m_ep.m_exponentBase.BitCount() - 1; - m_ep.m_bases.clear(); - while (!seq.EndReached()) - m_ep.m_bases.push_back(m_ec->BERDecodePoint(seq)); - seq.MessageEnd(); -} - -void EcPrecomputation<EC2N>::Save(BufferedTransformation &bt) const -{ - DERSequenceEncoder seq(bt); - DEREncodeUnsigned<word32>(seq, 1); // version - m_ep.m_exponentBase.DEREncode(seq); - for (unsigned i=0; i<m_ep.m_bases.size(); i++) - m_ec->DEREncodePoint(seq, m_ep.m_bases[i]); - seq.MessageEnd(); -} - -EC2N::Point EcPrecomputation<EC2N>::Exponentiate(const Integer &exponent) const -{ - return m_ep.Exponentiate(exponent); -} - -EC2N::Point EcPrecomputation<EC2N>::CascadeExponentiate(const Integer &exponent, const DL_FixedBasePrecomputation<Element> &pc2, const Integer &exponent2) const -{ - return m_ep.CascadeExponentiate(exponent, static_cast<const EcPrecomputation<EC2N> &>(pc2).m_ep, exponent2); -} -*/ - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/ec2n.h b/lib/cryptopp/ec2n.h deleted file mode 100644 index ae4007cd6..000000000 --- a/lib/cryptopp/ec2n.h +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef CRYPTOPP_EC2N_H -#define CRYPTOPP_EC2N_H - -#include "gf2n.h" -#include "eprecomp.h" -#include "smartptr.h" -#include "pubkey.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! Elliptic Curve Point -struct CRYPTOPP_DLL EC2NPoint -{ - EC2NPoint() : identity(true) {} - EC2NPoint(const PolynomialMod2 &x, const PolynomialMod2 &y) - : identity(false), x(x), y(y) {} - - bool operator==(const EC2NPoint &t) const - {return (identity && t.identity) || (!identity && !t.identity && x==t.x && y==t.y);} - bool operator< (const EC2NPoint &t) const - {return identity ? !t.identity : (!t.identity && (x<t.x || (x==t.x && y<t.y)));} - - bool identity; - PolynomialMod2 x, y; -}; - -CRYPTOPP_DLL_TEMPLATE_CLASS AbstractGroup<EC2NPoint>; - -//! Elliptic Curve over GF(2^n) -class CRYPTOPP_DLL EC2N : public AbstractGroup<EC2NPoint> -{ -public: - typedef GF2NP Field; - typedef Field::Element FieldElement; - typedef EC2NPoint Point; - - EC2N() {} - EC2N(const Field &field, const Field::Element &a, const Field::Element &b) - : m_field(field), m_a(a), m_b(b) {} - // construct from BER encoded parameters - // this constructor will decode and extract the the fields fieldID and curve of the sequence ECParameters - EC2N(BufferedTransformation &bt); - - // encode the fields fieldID and curve of the sequence ECParameters - void DEREncode(BufferedTransformation &bt) const; - - bool Equal(const Point &P, const Point &Q) const; - const Point& Identity() const; - const Point& Inverse(const Point &P) const; - bool InversionIsFast() const {return true;} - const Point& Add(const Point &P, const Point &Q) const; - const Point& Double(const Point &P) const; - - Point Multiply(const Integer &k, const Point &P) const - {return ScalarMultiply(P, k);} - Point CascadeMultiply(const Integer &k1, const Point &P, const Integer &k2, const Point &Q) const - {return CascadeScalarMultiply(P, k1, Q, k2);} - - bool ValidateParameters(RandomNumberGenerator &rng, unsigned int level=3) const; - bool VerifyPoint(const Point &P) const; - - unsigned int EncodedPointSize(bool compressed = false) const - {return 1 + (compressed?1:2)*m_field->MaxElementByteLength();} - // returns false if point is compressed and not valid (doesn't check if uncompressed) - bool DecodePoint(Point &P, BufferedTransformation &bt, size_t len) const; - bool DecodePoint(Point &P, const byte *encodedPoint, size_t len) const; - void EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const; - void EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const; - - Point BERDecodePoint(BufferedTransformation &bt) const; - void DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const; - - Integer FieldSize() const {return Integer::Power2(m_field->MaxElementBitLength());} - const Field & GetField() const {return *m_field;} - const FieldElement & GetA() const {return m_a;} - const FieldElement & GetB() const {return m_b;} - - bool operator==(const EC2N &rhs) const - {return GetField() == rhs.GetField() && m_a == rhs.m_a && m_b == rhs.m_b;} - -private: - clonable_ptr<Field> m_field; - FieldElement m_a, m_b; - mutable Point m_R; -}; - -CRYPTOPP_DLL_TEMPLATE_CLASS DL_FixedBasePrecomputationImpl<EC2N::Point>; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupPrecomputation<EC2N::Point>; - -template <class T> class EcPrecomputation; - -//! EC2N precomputation -template<> class EcPrecomputation<EC2N> : public DL_GroupPrecomputation<EC2N::Point> -{ -public: - typedef EC2N EllipticCurve; - - // DL_GroupPrecomputation - const AbstractGroup<Element> & GetGroup() const {return m_ec;} - Element BERDecodeElement(BufferedTransformation &bt) const {return m_ec.BERDecodePoint(bt);} - void DEREncodeElement(BufferedTransformation &bt, const Element &v) const {m_ec.DEREncodePoint(bt, v, false);} - - // non-inherited - void SetCurve(const EC2N &ec) {m_ec = ec;} - const EC2N & GetCurve() const {return m_ec;} - -private: - EC2N m_ec; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/eccrypto.cpp b/lib/cryptopp/eccrypto.cpp deleted file mode 100644 index 922104c4d..000000000 --- a/lib/cryptopp/eccrypto.cpp +++ /dev/null @@ -1,694 +0,0 @@ -// eccrypto.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "eccrypto.h" -#include "nbtheory.h" -#include "oids.h" -#include "hex.h" -#include "argnames.h" -#include "ec2n.h" - -NAMESPACE_BEGIN(CryptoPP) - -#if 0 -static void ECDSA_TestInstantiations() -{ - ECDSA<EC2N>::Signer t1; - ECDSA<EC2N>::Verifier t2(t1); - ECNR<ECP>::Signer t3; - ECNR<ECP>::Verifier t4(t3); - ECIES<ECP>::Encryptor t5; - ECIES<EC2N>::Decryptor t6; - ECDH<ECP>::Domain t7; - ECMQV<ECP>::Domain t8; -} -#endif - -// VC60 workaround: complains when these functions are put into an anonymous namespace -static Integer ConvertToInteger(const PolynomialMod2 &x) -{ - unsigned int l = x.ByteCount(); - SecByteBlock temp(l); - x.Encode(temp, l); - return Integer(temp, l); -} - -static inline Integer ConvertToInteger(const Integer &x) -{ - return x; -} - -static bool CheckMOVCondition(const Integer &q, const Integer &r) -{ - // see "Updated standards for validating elliptic curves", http://eprint.iacr.org/2007/343 - Integer t = 1; - unsigned int n = q.IsEven() ? 1 : q.BitCount(), m = r.BitCount(); - - for (unsigned int i=n; DiscreteLogWorkFactor(i)<m/2; i+=n) - { - if (q.IsEven()) - t = (t+t)%r; - else - t = (t*q)%r; - if (t == 1) - return false; - } - return true; -} - -// ****************************************************************** - -template <class T> struct EcRecommendedParameters; - -template<> struct EcRecommendedParameters<EC2N> -{ - EcRecommendedParameters(const OID &oid, unsigned int t2, unsigned int t3, unsigned int t4, const char *a, const char *b, const char *g, const char *n, unsigned int h) - : oid(oid), t0(0), t1(0), t2(t2), t3(t3), t4(t4), a(a), b(b), g(g), n(n), h(h) {} - EcRecommendedParameters(const OID &oid, unsigned int t0, unsigned int t1, unsigned int t2, unsigned int t3, unsigned int t4, const char *a, const char *b, const char *g, const char *n, unsigned int h) - : oid(oid), t0(t0), t1(t1), t2(t2), t3(t3), t4(t4), a(a), b(b), g(g), n(n), h(h) {} - EC2N *NewEC() const - { - StringSource ssA(a, true, new HexDecoder); - StringSource ssB(b, true, new HexDecoder); - if (t0 == 0) - return new EC2N(GF2NT(t2, t3, t4), EC2N::FieldElement(ssA, (size_t)ssA.MaxRetrievable()), EC2N::FieldElement(ssB, (size_t)ssB.MaxRetrievable())); - else - return new EC2N(GF2NPP(t0, t1, t2, t3, t4), EC2N::FieldElement(ssA, (size_t)ssA.MaxRetrievable()), EC2N::FieldElement(ssB, (size_t)ssB.MaxRetrievable())); - }; - - OID oid; - unsigned int t0, t1, t2, t3, t4; - const char *a, *b, *g, *n; - unsigned int h; -}; - -template<> struct EcRecommendedParameters<ECP> -{ - EcRecommendedParameters(const OID &oid, const char *p, const char *a, const char *b, const char *g, const char *n, unsigned int h) - : oid(oid), p(p), a(a), b(b), g(g), n(n), h(h) {} - ECP *NewEC() const - { - StringSource ssP(p, true, new HexDecoder); - StringSource ssA(a, true, new HexDecoder); - StringSource ssB(b, true, new HexDecoder); - return new ECP(Integer(ssP, (size_t)ssP.MaxRetrievable()), ECP::FieldElement(ssA, (size_t)ssA.MaxRetrievable()), ECP::FieldElement(ssB, (size_t)ssB.MaxRetrievable())); - }; - - OID oid; - const char *p; - const char *a, *b, *g, *n; - unsigned int h; -}; - -struct OIDLessThan -{ - template <typename T> - inline bool operator()(const EcRecommendedParameters<T>& a, const OID& b) {return a.oid < b;} - template <typename T> - inline bool operator()(const OID& a, const EcRecommendedParameters<T>& b) {return a < b.oid;} - template <typename T> - inline bool operator()(const EcRecommendedParameters<T>& a, const EcRecommendedParameters<T>& b) {return a.oid < b.oid;} -}; - -static void GetRecommendedParameters(const EcRecommendedParameters<EC2N> *&begin, const EcRecommendedParameters<EC2N> *&end) -{ - // this array must be sorted by OID - static const EcRecommendedParameters<EC2N> rec[] = { - EcRecommendedParameters<EC2N>(ASN1::sect163k1(), - 163, 7, 6, 3, 0, - "000000000000000000000000000000000000000001", - "000000000000000000000000000000000000000001", - "0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9", - "04000000000000000000020108A2E0CC0D99F8A5EF", - 2), - EcRecommendedParameters<EC2N>(ASN1::sect163r1(), - 163, 7, 6, 3, 0, - "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2", - "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9", - "040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883", - "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", - 2), - EcRecommendedParameters<EC2N>(ASN1::sect239k1(), - 239, 158, 0, - "000000000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000000001", - "0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA", - "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", - 4), - EcRecommendedParameters<EC2N>(ASN1::sect113r1(), - 113, 9, 0, - "003088250CA6E7C7FE649CE85820F7", - "00E8BEE4D3E2260744188BE0E9C723", - "04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886", - "0100000000000000D9CCEC8A39E56F", - 2), - EcRecommendedParameters<EC2N>(ASN1::sect113r2(), - 113, 9, 0, - "00689918DBEC7E5A0DD6DFC0AA55C7", - "0095E9A9EC9B297BD4BF36E059184F", - "0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D", - "010000000000000108789B2496AF93", - 2), - EcRecommendedParameters<EC2N>(ASN1::sect163r2(), - 163, 7, 6, 3, 0, - "000000000000000000000000000000000000000001", - "020A601907B8C953CA1481EB10512F78744A3205FD", - "0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", - "040000000000000000000292FE77E70C12A4234C33", - 2), - EcRecommendedParameters<EC2N>(ASN1::sect283k1(), - 283, 12, 7, 5, 0, - "000000000000000000000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000000000000000000001", - "040503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC245849283601CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259", - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", - 4), - EcRecommendedParameters<EC2N>(ASN1::sect283r1(), - 283, 12, 7, 5, 0, - "000000000000000000000000000000000000000000000000000000000000000000000001", - "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5", - "0405F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B1205303676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4", - "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", - 2), - EcRecommendedParameters<EC2N>(ASN1::sect131r1(), - 131, 8, 3, 2, 0, - "07A11B09A76B562144418FF3FF8C2570B8", - "0217C05610884B63B9C6C7291678F9D341", - "040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150", - "0400000000000000023123953A9464B54D", - 2), - EcRecommendedParameters<EC2N>(ASN1::sect131r2(), - 131, 8, 3, 2, 0, - "03E5A88919D7CAFCBF415F07C2176573B2", - "04B8266A46C55657AC734CE38F018F2192", - "040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F", - "0400000000000000016954A233049BA98F", - 2), - EcRecommendedParameters<EC2N>(ASN1::sect193r1(), - 193, 15, 0, - "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01", - "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814", - "0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05", - "01000000000000000000000000C7F34A778F443ACC920EBA49", - 2), - EcRecommendedParameters<EC2N>(ASN1::sect193r2(), - 193, 15, 0, - "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B", - "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE", - "0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C", - "010000000000000000000000015AAB561B005413CCD4EE99D5", - 2), - EcRecommendedParameters<EC2N>(ASN1::sect233k1(), - 233, 74, 0, - "000000000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000000001", - "04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3", - "8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", - 4), - EcRecommendedParameters<EC2N>(ASN1::sect233r1(), - 233, 74, 0, - "000000000000000000000000000000000000000000000000000000000001", - "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD", - "0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052", - "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", - 2), - EcRecommendedParameters<EC2N>(ASN1::sect409k1(), - 409, 87, 0, - "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "040060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE902374601E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B", - "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", - 4), - EcRecommendedParameters<EC2N>(ASN1::sect409r1(), - 409, 87, 0, - "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F", - "04015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A70061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706", - "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", - 2), - EcRecommendedParameters<EC2N>(ASN1::sect571k1(), - 571, 10, 5, 2, 0, - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "04026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C89720349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3", - "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", - 4), - EcRecommendedParameters<EC2N>(ASN1::sect571r1(), - 571, 10, 5, 2, 0, - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A", - "040303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B", - "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", - 2), - }; - begin = rec; - end = rec + sizeof(rec)/sizeof(rec[0]); -} - -static void GetRecommendedParameters(const EcRecommendedParameters<ECP> *&begin, const EcRecommendedParameters<ECP> *&end) -{ - // this array must be sorted by OID - static const EcRecommendedParameters<ECP> rec[] = { - EcRecommendedParameters<ECP>(ASN1::secp192r1(), - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", - "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", - "04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811", - "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", - 1), - EcRecommendedParameters<ECP>(ASN1::secp256r1(), - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", - "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", - "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", - "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", - 1), - EcRecommendedParameters<ECP>(ASN1::brainpoolP160r1(), - "E95E4A5F737059DC60DFC7AD95B3D8139515620F", - "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", - "1E589A8595423412134FAA2DBDEC95C8D8675E58", - "04BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC31667CB477A1A8EC338F94741669C976316DA6321", - "E95E4A5F737059DC60DF5991D45029409E60FC09", - 1), - EcRecommendedParameters<ECP>(ASN1::brainpoolP192r1(), - "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", - "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", - "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", - "04C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD614B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", - "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", - 1), - EcRecommendedParameters<ECP>(ASN1::brainpoolP224r1(), - "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", - "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", - "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", - "040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", - "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", - 1), - EcRecommendedParameters<ECP>(ASN1::brainpoolP256r1(), - "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", - "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", - "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", - "048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", - "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", - 1), - EcRecommendedParameters<ECP>(ASN1::brainpoolP320r1(), - "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", - "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", - "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", - "0443BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E2061114FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", - "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", - 1), - EcRecommendedParameters<ECP>(ASN1::brainpoolP384r1(), - "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", - "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", - "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", - "041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", - "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", - 1), - EcRecommendedParameters<ECP>(ASN1::brainpoolP512r1(), - "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", - "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", - "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", - "0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", - "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", - 1), - EcRecommendedParameters<ECP>(ASN1::secp112r1(), - "DB7C2ABF62E35E668076BEAD208B", - "DB7C2ABF62E35E668076BEAD2088", - "659EF8BA043916EEDE8911702B22", - "0409487239995A5EE76B55F9C2F098A89CE5AF8724C0A23E0E0FF77500", - "DB7C2ABF62E35E7628DFAC6561C5", - 1), - EcRecommendedParameters<ECP>(ASN1::secp112r2(), - "DB7C2ABF62E35E668076BEAD208B", - "6127C24C05F38A0AAAF65C0EF02C", - "51DEF1815DB5ED74FCC34C85D709", - "044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97", - "36DF0AAFD8B8D7597CA10520D04B", - 4), - EcRecommendedParameters<ECP>(ASN1::secp160r1(), - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", - "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", - "044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32", - "0100000000000000000001F4C8F927AED3CA752257", - 1), - EcRecommendedParameters<ECP>(ASN1::secp160k1(), - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", - "0000000000000000000000000000000000000000", - "0000000000000000000000000000000000000007", - "043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE", - "0100000000000000000001B8FA16DFAB9ACA16B6B3", - 1), - EcRecommendedParameters<ECP>(ASN1::secp256k1(), - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000007", - "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", - 1), - EcRecommendedParameters<ECP>(ASN1::secp128r1(), - "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", - "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", - "E87579C11079F43DD824993C2CEE5ED3", - "04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83", - "FFFFFFFE0000000075A30D1B9038A115", - 1), - EcRecommendedParameters<ECP>(ASN1::secp128r2(), - "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", - "D6031998D1B3BBFEBF59CC9BBFF9AEE1", - "5EEEFCA380D02919DC2C6558BB6D8A5D", - "047B6AA5D85E572983E6FB32A7CDEBC14027B6916A894D3AEE7106FE805FC34B44", - "3FFFFFFF7FFFFFFFBE0024720613B5A3", - 4), - EcRecommendedParameters<ECP>(ASN1::secp160r2(), - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", - "B4E134D3FB59EB8BAB57274904664D5AF50388BA", - "0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", - "0100000000000000000000351EE786A818F3A1A16B", - 1), - EcRecommendedParameters<ECP>(ASN1::secp192k1(), - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", - "000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000003", - "04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", - "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", - 1), - EcRecommendedParameters<ECP>(ASN1::secp224k1(), - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", - "00000000000000000000000000000000000000000000000000000000", - "00000000000000000000000000000000000000000000000000000005", - "04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", - "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", - 1), - EcRecommendedParameters<ECP>(ASN1::secp224r1(), - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", - "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", - "04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", - 1), - EcRecommendedParameters<ECP>(ASN1::secp384r1(), - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", - "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", - "04AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB73617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", - 1), - EcRecommendedParameters<ECP>(ASN1::secp521r1(), - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", - "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", - "0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", - 1), - }; - begin = rec; - end = rec + sizeof(rec)/sizeof(rec[0]); -} - -template <class EC> OID DL_GroupParameters_EC<EC>::GetNextRecommendedParametersOID(const OID &oid) -{ - const EcRecommendedParameters<EllipticCurve> *begin, *end; - GetRecommendedParameters(begin, end); - const EcRecommendedParameters<EllipticCurve> *it = std::upper_bound(begin, end, oid, OIDLessThan()); - return (it == end ? OID() : it->oid); -} - -template <class EC> void DL_GroupParameters_EC<EC>::Initialize(const OID &oid) -{ - const EcRecommendedParameters<EllipticCurve> *begin, *end; - GetRecommendedParameters(begin, end); - const EcRecommendedParameters<EllipticCurve> *it = std::lower_bound(begin, end, oid, OIDLessThan()); - if (it == end || it->oid != oid) - throw UnknownOID(); - - const EcRecommendedParameters<EllipticCurve> ¶m = *it; - m_oid = oid; - std::auto_ptr<EllipticCurve> ec(param.NewEC()); - this->m_groupPrecomputation.SetCurve(*ec); - - StringSource ssG(param.g, true, new HexDecoder); - Element G; - bool result = GetCurve().DecodePoint(G, ssG, (size_t)ssG.MaxRetrievable()); - this->SetSubgroupGenerator(G); - assert(result); - - StringSource ssN(param.n, true, new HexDecoder); - m_n.Decode(ssN, (size_t)ssN.MaxRetrievable()); - m_k = param.h; -} - -template <class EC> -bool DL_GroupParameters_EC<EC>::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const -{ - if (strcmp(name, Name::GroupOID()) == 0) - { - if (m_oid.m_values.empty()) - return false; - - this->ThrowIfTypeMismatch(name, typeid(OID), valueType); - *reinterpret_cast<OID *>(pValue) = m_oid; - return true; - } - else - return GetValueHelper<DL_GroupParameters<Element> >(this, name, valueType, pValue).Assignable() - CRYPTOPP_GET_FUNCTION_ENTRY(Curve); -} - -template <class EC> -void DL_GroupParameters_EC<EC>::AssignFrom(const NameValuePairs &source) -{ - OID oid; - if (source.GetValue(Name::GroupOID(), oid)) - Initialize(oid); - else - { - EllipticCurve ec; - Point G; - Integer n; - - source.GetRequiredParameter("DL_GroupParameters_EC<EC>", Name::Curve(), ec); - source.GetRequiredParameter("DL_GroupParameters_EC<EC>", Name::SubgroupGenerator(), G); - source.GetRequiredParameter("DL_GroupParameters_EC<EC>", Name::SubgroupOrder(), n); - Integer k = source.GetValueWithDefault(Name::Cofactor(), Integer::Zero()); - - Initialize(ec, G, n, k); - } -} - -template <class EC> -void DL_GroupParameters_EC<EC>::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) -{ - try - { - AssignFrom(alg); - } - catch (InvalidArgument &) - { - throw NotImplemented("DL_GroupParameters_EC<EC>: curve generation is not implemented yet"); - } -} - -template <class EC> -void DL_GroupParameters_EC<EC>::BERDecode(BufferedTransformation &bt) -{ - byte b; - if (!bt.Peek(b)) - BERDecodeError(); - if (b == OBJECT_IDENTIFIER) - Initialize(OID(bt)); - else - { - BERSequenceDecoder seq(bt); - word32 version; - BERDecodeUnsigned<word32>(seq, version, INTEGER, 1, 1); // check version - EllipticCurve ec(seq); - Point G = ec.BERDecodePoint(seq); - Integer n(seq); - Integer k; - bool cofactorPresent = !seq.EndReached(); - if (cofactorPresent) - k.BERDecode(seq); - else - k = Integer::Zero(); - seq.MessageEnd(); - - Initialize(ec, G, n, k); - } -} - -template <class EC> -void DL_GroupParameters_EC<EC>::DEREncode(BufferedTransformation &bt) const -{ - if (m_encodeAsOID && !m_oid.m_values.empty()) - m_oid.DEREncode(bt); - else - { - DERSequenceEncoder seq(bt); - DEREncodeUnsigned<word32>(seq, 1); // version - GetCurve().DEREncode(seq); - GetCurve().DEREncodePoint(seq, this->GetSubgroupGenerator(), m_compress); - m_n.DEREncode(seq); - if (m_k.NotZero()) - m_k.DEREncode(seq); - seq.MessageEnd(); - } -} - -template <class EC> -Integer DL_GroupParameters_EC<EC>::GetCofactor() const -{ - if (!m_k) - { - Integer q = GetCurve().FieldSize(); - Integer qSqrt = q.SquareRoot(); - m_k = (q+2*qSqrt+1)/m_n; - } - - return m_k; -} - -template <class EC> -Integer DL_GroupParameters_EC<EC>::ConvertElementToInteger(const Element &element) const -{ - return ConvertToInteger(element.x); -}; - -template <class EC> -bool DL_GroupParameters_EC<EC>::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const -{ - bool pass = GetCurve().ValidateParameters(rng, level); - - Integer q = GetCurve().FieldSize(); - pass = pass && m_n!=q; - - if (level >= 2) - { - Integer qSqrt = q.SquareRoot(); - pass = pass && m_n>4*qSqrt; - pass = pass && VerifyPrime(rng, m_n, level-2); - pass = pass && (m_k.IsZero() || m_k == (q+2*qSqrt+1)/m_n); - pass = pass && CheckMOVCondition(q, m_n); - } - - return pass; -} - -template <class EC> -bool DL_GroupParameters_EC<EC>::ValidateElement(unsigned int level, const Element &g, const DL_FixedBasePrecomputation<Element> *gpc) const -{ - bool pass = !IsIdentity(g) && GetCurve().VerifyPoint(g); - if (level >= 1) - { - if (gpc) - pass = pass && gpc->Exponentiate(this->GetGroupPrecomputation(), Integer::One()) == g; - } - if (level >= 2 && pass) - { - const Integer &q = GetSubgroupOrder(); - Element gq = gpc ? gpc->Exponentiate(this->GetGroupPrecomputation(), q) : this->ExponentiateElement(g, q); - pass = pass && IsIdentity(gq); - } - return pass; -} - -template <class EC> -void DL_GroupParameters_EC<EC>::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const -{ - GetCurve().SimultaneousMultiply(results, base, exponents, exponentsCount); -} - -template <class EC> -CPP_TYPENAME DL_GroupParameters_EC<EC>::Element DL_GroupParameters_EC<EC>::MultiplyElements(const Element &a, const Element &b) const -{ - return GetCurve().Add(a, b); -} - -template <class EC> -CPP_TYPENAME DL_GroupParameters_EC<EC>::Element DL_GroupParameters_EC<EC>::CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const -{ - return GetCurve().CascadeMultiply(exponent1, element1, exponent2, element2); -} - -template <class EC> -OID DL_GroupParameters_EC<EC>::GetAlgorithmID() const -{ - return ASN1::id_ecPublicKey(); -} - -// ****************************************************************** - -template <class EC> -void DL_PublicKey_EC<EC>::BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size) -{ - typename EC::Point P; - if (!this->GetGroupParameters().GetCurve().DecodePoint(P, bt, size)) - BERDecodeError(); - this->SetPublicElement(P); -} - -template <class EC> -void DL_PublicKey_EC<EC>::DEREncodePublicKey(BufferedTransformation &bt) const -{ - this->GetGroupParameters().GetCurve().EncodePoint(bt, this->GetPublicElement(), this->GetGroupParameters().GetPointCompression()); -} - -// ****************************************************************** - -template <class EC> -void DL_PrivateKey_EC<EC>::BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size) -{ - BERSequenceDecoder seq(bt); - word32 version; - BERDecodeUnsigned<word32>(seq, version, INTEGER, 1, 1); // check version - - BERGeneralDecoder dec(seq, OCTET_STRING); - if (!dec.IsDefiniteLength()) - BERDecodeError(); - Integer x; - x.Decode(dec, (size_t)dec.RemainingLength()); - dec.MessageEnd(); - if (!parametersPresent && seq.PeekByte() != (CONTEXT_SPECIFIC | CONSTRUCTED | 0)) - BERDecodeError(); - if (!seq.EndReached() && seq.PeekByte() == (CONTEXT_SPECIFIC | CONSTRUCTED | 0)) - { - BERGeneralDecoder parameters(seq, CONTEXT_SPECIFIC | CONSTRUCTED | 0); - this->AccessGroupParameters().BERDecode(parameters); - parameters.MessageEnd(); - } - if (!seq.EndReached()) - { - // skip over the public element - SecByteBlock subjectPublicKey; - unsigned int unusedBits; - BERGeneralDecoder publicKey(seq, CONTEXT_SPECIFIC | CONSTRUCTED | 1); - BERDecodeBitString(publicKey, subjectPublicKey, unusedBits); - publicKey.MessageEnd(); - Element Q; - if (!(unusedBits == 0 && this->GetGroupParameters().GetCurve().DecodePoint(Q, subjectPublicKey, subjectPublicKey.size()))) - BERDecodeError(); - } - seq.MessageEnd(); - - this->SetPrivateExponent(x); -} - -template <class EC> -void DL_PrivateKey_EC<EC>::DEREncodePrivateKey(BufferedTransformation &bt) const -{ - DERSequenceEncoder privateKey(bt); - DEREncodeUnsigned<word32>(privateKey, 1); // version - // SEC 1 ver 1.0 says privateKey (m_d) has the same length as order of the curve - // this will be changed to order of base point in a future version - this->GetPrivateExponent().DEREncodeAsOctetString(privateKey, this->GetGroupParameters().GetSubgroupOrder().ByteCount()); - privateKey.MessageEnd(); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/eccrypto.h b/lib/cryptopp/eccrypto.h deleted file mode 100644 index 3530455a3..000000000 --- a/lib/cryptopp/eccrypto.h +++ /dev/null @@ -1,280 +0,0 @@ -#ifndef CRYPTOPP_ECCRYPTO_H -#define CRYPTOPP_ECCRYPTO_H - -/*! \file -*/ - -#include "pubkey.h" -#include "integer.h" -#include "asn.h" -#include "hmac.h" -#include "sha.h" -#include "gfpcrypt.h" -#include "dh.h" -#include "mqv.h" -#include "ecp.h" -#include "ec2n.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! Elliptic Curve Parameters -/*! This class corresponds to the ASN.1 sequence of the same name - in ANSI X9.62 (also SEC 1). -*/ -template <class EC> -class DL_GroupParameters_EC : public DL_GroupParametersImpl<EcPrecomputation<EC> > -{ - typedef DL_GroupParameters_EC<EC> ThisClass; - -public: - typedef EC EllipticCurve; - typedef typename EllipticCurve::Point Point; - typedef Point Element; - typedef IncompatibleCofactorMultiplication DefaultCofactorOption; - - DL_GroupParameters_EC() : m_compress(false), m_encodeAsOID(false) {} - DL_GroupParameters_EC(const OID &oid) - : m_compress(false), m_encodeAsOID(false) {Initialize(oid);} - DL_GroupParameters_EC(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero()) - : m_compress(false), m_encodeAsOID(false) {Initialize(ec, G, n, k);} - DL_GroupParameters_EC(BufferedTransformation &bt) - : m_compress(false), m_encodeAsOID(false) {BERDecode(bt);} - - void Initialize(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero()) - { - this->m_groupPrecomputation.SetCurve(ec); - this->SetSubgroupGenerator(G); - m_n = n; - m_k = k; - } - void Initialize(const OID &oid); - - // NameValuePairs - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; - void AssignFrom(const NameValuePairs &source); - - // GeneratibleCryptoMaterial interface - //! this implementation doesn't actually generate a curve, it just initializes the parameters with existing values - /*! parameters: (Curve, SubgroupGenerator, SubgroupOrder, Cofactor (optional)), or (GroupOID) */ - void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); - - // DL_GroupParameters - const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return this->m_gpc;} - DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return this->m_gpc;} - const Integer & GetSubgroupOrder() const {return m_n;} - Integer GetCofactor() const; - bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; - bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const; - bool FastSubgroupCheckAvailable() const {return false;} - void EncodeElement(bool reversible, const Element &element, byte *encoded) const - { - if (reversible) - GetCurve().EncodePoint(encoded, element, m_compress); - else - element.x.Encode(encoded, GetEncodedElementSize(false)); - } - unsigned int GetEncodedElementSize(bool reversible) const - { - if (reversible) - return GetCurve().EncodedPointSize(m_compress); - else - return GetCurve().GetField().MaxElementByteLength(); - } - Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const - { - Point result; - if (!GetCurve().DecodePoint(result, encoded, GetEncodedElementSize(true))) - throw DL_BadElement(); - if (checkForGroupMembership && !ValidateElement(1, result, NULL)) - throw DL_BadElement(); - return result; - } - Integer ConvertElementToInteger(const Element &element) const; - Integer GetMaxExponent() const {return GetSubgroupOrder()-1;} - bool IsIdentity(const Element &element) const {return element.identity;} - void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; - static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "EC";} - - // ASN1Key - OID GetAlgorithmID() const; - - // used by MQV - Element MultiplyElements(const Element &a, const Element &b) const; - Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const; - - // non-inherited - - // enumerate OIDs for recommended parameters, use OID() to get first one - static OID CRYPTOPP_API GetNextRecommendedParametersOID(const OID &oid); - - void BERDecode(BufferedTransformation &bt); - void DEREncode(BufferedTransformation &bt) const; - - void SetPointCompression(bool compress) {m_compress = compress;} - bool GetPointCompression() const {return m_compress;} - - void SetEncodeAsOID(bool encodeAsOID) {m_encodeAsOID = encodeAsOID;} - bool GetEncodeAsOID() const {return m_encodeAsOID;} - - const EllipticCurve& GetCurve() const {return this->m_groupPrecomputation.GetCurve();} - - bool operator==(const ThisClass &rhs) const - {return this->m_groupPrecomputation.GetCurve() == rhs.m_groupPrecomputation.GetCurve() && this->m_gpc.GetBase(this->m_groupPrecomputation) == rhs.m_gpc.GetBase(rhs.m_groupPrecomputation);} - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - const Point& GetBasePoint() const {return GetSubgroupGenerator();} - const Integer& GetBasePointOrder() const {return GetSubgroupOrder();} - void LoadRecommendedParameters(const OID &oid) {Initialize(oid);} -#endif - -protected: - unsigned int FieldElementLength() const {return GetCurve().GetField().MaxElementByteLength();} - unsigned int ExponentLength() const {return m_n.ByteCount();} - - OID m_oid; // set if parameters loaded from a recommended curve - Integer m_n; // order of base point - bool m_compress, m_encodeAsOID; - mutable Integer m_k; // cofactor -}; - -//! EC public key -template <class EC> -class DL_PublicKey_EC : public DL_PublicKeyImpl<DL_GroupParameters_EC<EC> > -{ -public: - typedef typename EC::Point Element; - - void Initialize(const DL_GroupParameters_EC<EC> ¶ms, const Element &Q) - {this->AccessGroupParameters() = params; this->SetPublicElement(Q);} - void Initialize(const EC &ec, const Element &G, const Integer &n, const Element &Q) - {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPublicElement(Q);} - - // X509PublicKey - void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size); - void DEREncodePublicKey(BufferedTransformation &bt) const; -}; - -//! EC private key -template <class EC> -class DL_PrivateKey_EC : public DL_PrivateKeyImpl<DL_GroupParameters_EC<EC> > -{ -public: - typedef typename EC::Point Element; - - void Initialize(const DL_GroupParameters_EC<EC> ¶ms, const Integer &x) - {this->AccessGroupParameters() = params; this->SetPrivateExponent(x);} - void Initialize(const EC &ec, const Element &G, const Integer &n, const Integer &x) - {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPrivateExponent(x);} - void Initialize(RandomNumberGenerator &rng, const DL_GroupParameters_EC<EC> ¶ms) - {this->GenerateRandom(rng, params);} - void Initialize(RandomNumberGenerator &rng, const EC &ec, const Element &G, const Integer &n) - {this->GenerateRandom(rng, DL_GroupParameters_EC<EC>(ec, G, n));} - - // PKCS8PrivateKey - void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size); - void DEREncodePrivateKey(BufferedTransformation &bt) const; -}; - -//! Elliptic Curve Diffie-Hellman, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#ECDH">ECDH</a> -template <class EC, class COFACTOR_OPTION = CPP_TYPENAME DL_GroupParameters_EC<EC>::DefaultCofactorOption> -struct ECDH -{ - typedef DH_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION> Domain; -}; - -/// Elliptic Curve Menezes-Qu-Vanstone, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#ECMQV">ECMQV</a> -template <class EC, class COFACTOR_OPTION = CPP_TYPENAME DL_GroupParameters_EC<EC>::DefaultCofactorOption> -struct ECMQV -{ - typedef MQV_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION> Domain; -}; - -//! EC keys -template <class EC> -struct DL_Keys_EC -{ - typedef DL_PublicKey_EC<EC> PublicKey; - typedef DL_PrivateKey_EC<EC> PrivateKey; -}; - -template <class EC, class H> -struct ECDSA; - -//! ECDSA keys -template <class EC> -struct DL_Keys_ECDSA -{ - typedef DL_PublicKey_EC<EC> PublicKey; - typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<EC>, ECDSA<EC, SHA256> > PrivateKey; -}; - -//! ECDSA algorithm -template <class EC> -class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA<typename EC::Point> -{ -public: - static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";} -}; - -//! ECNR algorithm -template <class EC> -class DL_Algorithm_ECNR : public DL_Algorithm_NR<typename EC::Point> -{ -public: - static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECNR";} -}; - -//! <a href="http://www.weidai.com/scan-mirror/sig.html#ECDSA">ECDSA</a> -template <class EC, class H> -struct ECDSA : public DL_SS<DL_Keys_ECDSA<EC>, DL_Algorithm_ECDSA<EC>, DL_SignatureMessageEncodingMethod_DSA, H> -{ -}; - -//! ECNR -template <class EC, class H = SHA> -struct ECNR : public DL_SS<DL_Keys_EC<EC>, DL_Algorithm_ECNR<EC>, DL_SignatureMessageEncodingMethod_NR, H> -{ -}; - -//! Elliptic Curve Integrated Encryption Scheme, AKA <a href="http://www.weidai.com/scan-mirror/ca.html#ECIES">ECIES</a> -/*! Default to (NoCofactorMultiplication and DHAES_MODE = false) for compatibilty with SEC1 and Crypto++ 4.2. - The combination of (IncompatibleCofactorMultiplication and DHAES_MODE = true) is recommended for best - efficiency and security. */ -template <class EC, class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = false> -struct ECIES - : public DL_ES< - DL_Keys_EC<EC>, - DL_KeyAgreementAlgorithm_DH<typename EC::Point, COFACTOR_OPTION>, - DL_KeyDerivationAlgorithm_P1363<typename EC::Point, DHAES_MODE, P1363_KDF2<SHA1> >, - DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>, - ECIES<EC> > -{ - static std::string CRYPTOPP_API StaticAlgorithmName() {return "ECIES";} // TODO: fix this after name is standardized -}; - -NAMESPACE_END - -#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES -#include "eccrypto.cpp" -#endif - -NAMESPACE_BEGIN(CryptoPP) - -CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC<ECP>; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC<EC2N>; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl<DL_GroupParameters_EC<ECP> >; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl<DL_GroupParameters_EC<EC2N> >; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC<ECP>; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC<EC2N>; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<ECP> >; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<EC2N> >; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<ECP>; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<EC2N>; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<ECP::Point>; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<EC2N::Point>; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<ECP>, ECDSA<ECP, SHA256> >; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<EC2N>, ECDSA<EC2N, SHA256> >; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/ecp.cpp b/lib/cryptopp/ecp.cpp deleted file mode 100644 index 55a7cc15b..000000000 --- a/lib/cryptopp/ecp.cpp +++ /dev/null @@ -1,473 +0,0 @@ -// ecp.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "ecp.h" -#include "asn.h" -#include "nbtheory.h" - -#include "algebra.cpp" - -NAMESPACE_BEGIN(CryptoPP) - -ANONYMOUS_NAMESPACE_BEGIN -static inline ECP::Point ToMontgomery(const ModularArithmetic &mr, const ECP::Point &P) -{ - return P.identity ? P : ECP::Point(mr.ConvertIn(P.x), mr.ConvertIn(P.y)); -} - -static inline ECP::Point FromMontgomery(const ModularArithmetic &mr, const ECP::Point &P) -{ - return P.identity ? P : ECP::Point(mr.ConvertOut(P.x), mr.ConvertOut(P.y)); -} -NAMESPACE_END - -ECP::ECP(const ECP &ecp, bool convertToMontgomeryRepresentation) -{ - if (convertToMontgomeryRepresentation && !ecp.GetField().IsMontgomeryRepresentation()) - { - m_fieldPtr.reset(new MontgomeryRepresentation(ecp.GetField().GetModulus())); - m_a = GetField().ConvertIn(ecp.m_a); - m_b = GetField().ConvertIn(ecp.m_b); - } - else - operator=(ecp); -} - -ECP::ECP(BufferedTransformation &bt) - : m_fieldPtr(new Field(bt)) -{ - BERSequenceDecoder seq(bt); - GetField().BERDecodeElement(seq, m_a); - GetField().BERDecodeElement(seq, m_b); - // skip optional seed - if (!seq.EndReached()) - { - SecByteBlock seed; - unsigned int unused; - BERDecodeBitString(seq, seed, unused); - } - seq.MessageEnd(); -} - -void ECP::DEREncode(BufferedTransformation &bt) const -{ - GetField().DEREncode(bt); - DERSequenceEncoder seq(bt); - GetField().DEREncodeElement(seq, m_a); - GetField().DEREncodeElement(seq, m_b); - seq.MessageEnd(); -} - -bool ECP::DecodePoint(ECP::Point &P, const byte *encodedPoint, size_t encodedPointLen) const -{ - StringStore store(encodedPoint, encodedPointLen); - return DecodePoint(P, store, encodedPointLen); -} - -bool ECP::DecodePoint(ECP::Point &P, BufferedTransformation &bt, size_t encodedPointLen) const -{ - byte type; - if (encodedPointLen < 1 || !bt.Get(type)) - return false; - - switch (type) - { - case 0: - P.identity = true; - return true; - case 2: - case 3: - { - if (encodedPointLen != EncodedPointSize(true)) - return false; - - Integer p = FieldSize(); - - P.identity = false; - P.x.Decode(bt, GetField().MaxElementByteLength()); - P.y = ((P.x*P.x+m_a)*P.x+m_b) % p; - - if (Jacobi(P.y, p) !=1) - return false; - - P.y = ModularSquareRoot(P.y, p); - - if ((type & 1) != P.y.GetBit(0)) - P.y = p-P.y; - - return true; - } - case 4: - { - if (encodedPointLen != EncodedPointSize(false)) - return false; - - unsigned int len = GetField().MaxElementByteLength(); - P.identity = false; - P.x.Decode(bt, len); - P.y.Decode(bt, len); - return true; - } - default: - return false; - } -} - -void ECP::EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const -{ - if (P.identity) - NullStore().TransferTo(bt, EncodedPointSize(compressed)); - else if (compressed) - { - bt.Put(2 + P.y.GetBit(0)); - P.x.Encode(bt, GetField().MaxElementByteLength()); - } - else - { - unsigned int len = GetField().MaxElementByteLength(); - bt.Put(4); // uncompressed - P.x.Encode(bt, len); - P.y.Encode(bt, len); - } -} - -void ECP::EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const -{ - ArraySink sink(encodedPoint, EncodedPointSize(compressed)); - EncodePoint(sink, P, compressed); - assert(sink.TotalPutLength() == EncodedPointSize(compressed)); -} - -ECP::Point ECP::BERDecodePoint(BufferedTransformation &bt) const -{ - SecByteBlock str; - BERDecodeOctetString(bt, str); - Point P; - if (!DecodePoint(P, str, str.size())) - BERDecodeError(); - return P; -} - -void ECP::DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const -{ - SecByteBlock str(EncodedPointSize(compressed)); - EncodePoint(str, P, compressed); - DEREncodeOctetString(bt, str); -} - -bool ECP::ValidateParameters(RandomNumberGenerator &rng, unsigned int level) const -{ - Integer p = FieldSize(); - - bool pass = p.IsOdd(); - pass = pass && !m_a.IsNegative() && m_a<p && !m_b.IsNegative() && m_b<p; - - if (level >= 1) - pass = pass && ((4*m_a*m_a*m_a+27*m_b*m_b)%p).IsPositive(); - - if (level >= 2) - pass = pass && VerifyPrime(rng, p); - - return pass; -} - -bool ECP::VerifyPoint(const Point &P) const -{ - const FieldElement &x = P.x, &y = P.y; - Integer p = FieldSize(); - return P.identity || - (!x.IsNegative() && x<p && !y.IsNegative() && y<p - && !(((x*x+m_a)*x+m_b-y*y)%p)); -} - -bool ECP::Equal(const Point &P, const Point &Q) const -{ - if (P.identity && Q.identity) - return true; - - if (P.identity && !Q.identity) - return false; - - if (!P.identity && Q.identity) - return false; - - return (GetField().Equal(P.x,Q.x) && GetField().Equal(P.y,Q.y)); -} - -const ECP::Point& ECP::Identity() const -{ - return Singleton<Point>().Ref(); -} - -const ECP::Point& ECP::Inverse(const Point &P) const -{ - if (P.identity) - return P; - else - { - m_R.identity = false; - m_R.x = P.x; - m_R.y = GetField().Inverse(P.y); - return m_R; - } -} - -const ECP::Point& ECP::Add(const Point &P, const Point &Q) const -{ - if (P.identity) return Q; - if (Q.identity) return P; - if (GetField().Equal(P.x, Q.x)) - return GetField().Equal(P.y, Q.y) ? Double(P) : Identity(); - - FieldElement t = GetField().Subtract(Q.y, P.y); - t = GetField().Divide(t, GetField().Subtract(Q.x, P.x)); - FieldElement x = GetField().Subtract(GetField().Subtract(GetField().Square(t), P.x), Q.x); - m_R.y = GetField().Subtract(GetField().Multiply(t, GetField().Subtract(P.x, x)), P.y); - - m_R.x.swap(x); - m_R.identity = false; - return m_R; -} - -const ECP::Point& ECP::Double(const Point &P) const -{ - if (P.identity || P.y==GetField().Identity()) return Identity(); - - FieldElement t = GetField().Square(P.x); - t = GetField().Add(GetField().Add(GetField().Double(t), t), m_a); - t = GetField().Divide(t, GetField().Double(P.y)); - FieldElement x = GetField().Subtract(GetField().Subtract(GetField().Square(t), P.x), P.x); - m_R.y = GetField().Subtract(GetField().Multiply(t, GetField().Subtract(P.x, x)), P.y); - - m_R.x.swap(x); - m_R.identity = false; - return m_R; -} - -template <class T, class Iterator> void ParallelInvert(const AbstractRing<T> &ring, Iterator begin, Iterator end) -{ - size_t n = end-begin; - if (n == 1) - *begin = ring.MultiplicativeInverse(*begin); - else if (n > 1) - { - std::vector<T> vec((n+1)/2); - unsigned int i; - Iterator it; - - for (i=0, it=begin; i<n/2; i++, it+=2) - vec[i] = ring.Multiply(*it, *(it+1)); - if (n%2 == 1) - vec[n/2] = *it; - - ParallelInvert(ring, vec.begin(), vec.end()); - - for (i=0, it=begin; i<n/2; i++, it+=2) - { - if (!vec[i]) - { - *it = ring.MultiplicativeInverse(*it); - *(it+1) = ring.MultiplicativeInverse(*(it+1)); - } - else - { - std::swap(*it, *(it+1)); - *it = ring.Multiply(*it, vec[i]); - *(it+1) = ring.Multiply(*(it+1), vec[i]); - } - } - if (n%2 == 1) - *it = vec[n/2]; - } -} - -struct ProjectivePoint -{ - ProjectivePoint() {} - ProjectivePoint(const Integer &x, const Integer &y, const Integer &z) - : x(x), y(y), z(z) {} - - Integer x,y,z; -}; - -class ProjectiveDoubling -{ -public: - ProjectiveDoubling(const ModularArithmetic &mr, const Integer &m_a, const Integer &m_b, const ECPPoint &Q) - : mr(mr), firstDoubling(true), negated(false) - { - if (Q.identity) - { - sixteenY4 = P.x = P.y = mr.MultiplicativeIdentity(); - aZ4 = P.z = mr.Identity(); - } - else - { - P.x = Q.x; - P.y = Q.y; - sixteenY4 = P.z = mr.MultiplicativeIdentity(); - aZ4 = m_a; - } - } - - void Double() - { - twoY = mr.Double(P.y); - P.z = mr.Multiply(P.z, twoY); - fourY2 = mr.Square(twoY); - S = mr.Multiply(fourY2, P.x); - aZ4 = mr.Multiply(aZ4, sixteenY4); - M = mr.Square(P.x); - M = mr.Add(mr.Add(mr.Double(M), M), aZ4); - P.x = mr.Square(M); - mr.Reduce(P.x, S); - mr.Reduce(P.x, S); - mr.Reduce(S, P.x); - P.y = mr.Multiply(M, S); - sixteenY4 = mr.Square(fourY2); - mr.Reduce(P.y, mr.Half(sixteenY4)); - } - - const ModularArithmetic &mr; - ProjectivePoint P; - bool firstDoubling, negated; - Integer sixteenY4, aZ4, twoY, fourY2, S, M; -}; - -struct ZIterator -{ - ZIterator() {} - ZIterator(std::vector<ProjectivePoint>::iterator it) : it(it) {} - Integer& operator*() {return it->z;} - int operator-(ZIterator it2) {return int(it-it2.it);} - ZIterator operator+(int i) {return ZIterator(it+i);} - ZIterator& operator+=(int i) {it+=i; return *this;} - std::vector<ProjectivePoint>::iterator it; -}; - -ECP::Point ECP::ScalarMultiply(const Point &P, const Integer &k) const -{ - Element result; - if (k.BitCount() <= 5) - AbstractGroup<ECPPoint>::SimultaneousMultiply(&result, P, &k, 1); - else - ECP::SimultaneousMultiply(&result, P, &k, 1); - return result; -} - -void ECP::SimultaneousMultiply(ECP::Point *results, const ECP::Point &P, const Integer *expBegin, unsigned int expCount) const -{ - if (!GetField().IsMontgomeryRepresentation()) - { - ECP ecpmr(*this, true); - const ModularArithmetic &mr = ecpmr.GetField(); - ecpmr.SimultaneousMultiply(results, ToMontgomery(mr, P), expBegin, expCount); - for (unsigned int i=0; i<expCount; i++) - results[i] = FromMontgomery(mr, results[i]); - return; - } - - ProjectiveDoubling rd(GetField(), m_a, m_b, P); - std::vector<ProjectivePoint> bases; - std::vector<WindowSlider> exponents; - exponents.reserve(expCount); - std::vector<std::vector<word32> > baseIndices(expCount); - std::vector<std::vector<bool> > negateBase(expCount); - std::vector<std::vector<word32> > exponentWindows(expCount); - unsigned int i; - - for (i=0; i<expCount; i++) - { - assert(expBegin->NotNegative()); - exponents.push_back(WindowSlider(*expBegin++, InversionIsFast(), 5)); - exponents[i].FindNextWindow(); - } - - unsigned int expBitPosition = 0; - bool notDone = true; - - while (notDone) - { - notDone = false; - bool baseAdded = false; - for (i=0; i<expCount; i++) - { - if (!exponents[i].finished && expBitPosition == exponents[i].windowBegin) - { - if (!baseAdded) - { - bases.push_back(rd.P); - baseAdded =true; - } - - exponentWindows[i].push_back(exponents[i].expWindow); - baseIndices[i].push_back((word32)bases.size()-1); - negateBase[i].push_back(exponents[i].negateNext); - - exponents[i].FindNextWindow(); - } - notDone = notDone || !exponents[i].finished; - } - - if (notDone) - { - rd.Double(); - expBitPosition++; - } - } - - // convert from projective to affine coordinates - ParallelInvert(GetField(), ZIterator(bases.begin()), ZIterator(bases.end())); - for (i=0; i<bases.size(); i++) - { - if (bases[i].z.NotZero()) - { - bases[i].y = GetField().Multiply(bases[i].y, bases[i].z); - bases[i].z = GetField().Square(bases[i].z); - bases[i].x = GetField().Multiply(bases[i].x, bases[i].z); - bases[i].y = GetField().Multiply(bases[i].y, bases[i].z); - } - } - - std::vector<BaseAndExponent<Point, Integer> > finalCascade; - for (i=0; i<expCount; i++) - { - finalCascade.resize(baseIndices[i].size()); - for (unsigned int j=0; j<baseIndices[i].size(); j++) - { - ProjectivePoint &base = bases[baseIndices[i][j]]; - if (base.z.IsZero()) - finalCascade[j].base.identity = true; - else - { - finalCascade[j].base.identity = false; - finalCascade[j].base.x = base.x; - if (negateBase[i][j]) - finalCascade[j].base.y = GetField().Inverse(base.y); - else - finalCascade[j].base.y = base.y; - } - finalCascade[j].exponent = Integer(Integer::POSITIVE, 0, exponentWindows[i][j]); - } - results[i] = GeneralCascadeMultiplication(*this, finalCascade.begin(), finalCascade.end()); - } -} - -ECP::Point ECP::CascadeScalarMultiply(const Point &P, const Integer &k1, const Point &Q, const Integer &k2) const -{ - if (!GetField().IsMontgomeryRepresentation()) - { - ECP ecpmr(*this, true); - const ModularArithmetic &mr = ecpmr.GetField(); - return FromMontgomery(mr, ecpmr.CascadeScalarMultiply(ToMontgomery(mr, P), k1, ToMontgomery(mr, Q), k2)); - } - else - return AbstractGroup<Point>::CascadeScalarMultiply(P, k1, Q, k2); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/ecp.h b/lib/cryptopp/ecp.h deleted file mode 100644 index d946be63a..000000000 --- a/lib/cryptopp/ecp.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef CRYPTOPP_ECP_H -#define CRYPTOPP_ECP_H - -#include "modarith.h" -#include "eprecomp.h" -#include "smartptr.h" -#include "pubkey.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! Elliptical Curve Point -struct CRYPTOPP_DLL ECPPoint -{ - ECPPoint() : identity(true) {} - ECPPoint(const Integer &x, const Integer &y) - : identity(false), x(x), y(y) {} - - bool operator==(const ECPPoint &t) const - {return (identity && t.identity) || (!identity && !t.identity && x==t.x && y==t.y);} - bool operator< (const ECPPoint &t) const - {return identity ? !t.identity : (!t.identity && (x<t.x || (x==t.x && y<t.y)));} - - bool identity; - Integer x, y; -}; - -CRYPTOPP_DLL_TEMPLATE_CLASS AbstractGroup<ECPPoint>; - -//! Elliptic Curve over GF(p), where p is prime -class CRYPTOPP_DLL ECP : public AbstractGroup<ECPPoint> -{ -public: - typedef ModularArithmetic Field; - typedef Integer FieldElement; - typedef ECPPoint Point; - - ECP() {} - ECP(const ECP &ecp, bool convertToMontgomeryRepresentation = false); - ECP(const Integer &modulus, const FieldElement &a, const FieldElement &b) - : m_fieldPtr(new Field(modulus)), m_a(a.IsNegative() ? modulus+a : a), m_b(b) {} - // construct from BER encoded parameters - // this constructor will decode and extract the the fields fieldID and curve of the sequence ECParameters - ECP(BufferedTransformation &bt); - - // encode the fields fieldID and curve of the sequence ECParameters - void DEREncode(BufferedTransformation &bt) const; - - bool Equal(const Point &P, const Point &Q) const; - const Point& Identity() const; - const Point& Inverse(const Point &P) const; - bool InversionIsFast() const {return true;} - const Point& Add(const Point &P, const Point &Q) const; - const Point& Double(const Point &P) const; - Point ScalarMultiply(const Point &P, const Integer &k) const; - Point CascadeScalarMultiply(const Point &P, const Integer &k1, const Point &Q, const Integer &k2) const; - void SimultaneousMultiply(Point *results, const Point &base, const Integer *exponents, unsigned int exponentsCount) const; - - Point Multiply(const Integer &k, const Point &P) const - {return ScalarMultiply(P, k);} - Point CascadeMultiply(const Integer &k1, const Point &P, const Integer &k2, const Point &Q) const - {return CascadeScalarMultiply(P, k1, Q, k2);} - - bool ValidateParameters(RandomNumberGenerator &rng, unsigned int level=3) const; - bool VerifyPoint(const Point &P) const; - - unsigned int EncodedPointSize(bool compressed = false) const - {return 1 + (compressed?1:2)*GetField().MaxElementByteLength();} - // returns false if point is compressed and not valid (doesn't check if uncompressed) - bool DecodePoint(Point &P, BufferedTransformation &bt, size_t len) const; - bool DecodePoint(Point &P, const byte *encodedPoint, size_t len) const; - void EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const; - void EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const; - - Point BERDecodePoint(BufferedTransformation &bt) const; - void DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const; - - Integer FieldSize() const {return GetField().GetModulus();} - const Field & GetField() const {return *m_fieldPtr;} - const FieldElement & GetA() const {return m_a;} - const FieldElement & GetB() const {return m_b;} - - bool operator==(const ECP &rhs) const - {return GetField() == rhs.GetField() && m_a == rhs.m_a && m_b == rhs.m_b;} - -private: - clonable_ptr<Field> m_fieldPtr; - FieldElement m_a, m_b; - mutable Point m_R; -}; - -CRYPTOPP_DLL_TEMPLATE_CLASS DL_FixedBasePrecomputationImpl<ECP::Point>; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupPrecomputation<ECP::Point>; - -template <class T> class EcPrecomputation; - -//! ECP precomputation -template<> class EcPrecomputation<ECP> : public DL_GroupPrecomputation<ECP::Point> -{ -public: - typedef ECP EllipticCurve; - - // DL_GroupPrecomputation - bool NeedConversions() const {return true;} - Element ConvertIn(const Element &P) const - {return P.identity ? P : ECP::Point(m_ec->GetField().ConvertIn(P.x), m_ec->GetField().ConvertIn(P.y));}; - Element ConvertOut(const Element &P) const - {return P.identity ? P : ECP::Point(m_ec->GetField().ConvertOut(P.x), m_ec->GetField().ConvertOut(P.y));} - const AbstractGroup<Element> & GetGroup() const {return *m_ec;} - Element BERDecodeElement(BufferedTransformation &bt) const {return m_ec->BERDecodePoint(bt);} - void DEREncodeElement(BufferedTransformation &bt, const Element &v) const {m_ec->DEREncodePoint(bt, v, false);} - - // non-inherited - void SetCurve(const ECP &ec) - { - m_ec.reset(new ECP(ec, true)); - m_ecOriginal = ec; - } - const ECP & GetCurve() const {return *m_ecOriginal;} - -private: - value_ptr<ECP> m_ec, m_ecOriginal; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/elgamal.cpp b/lib/cryptopp/elgamal.cpp deleted file mode 100644 index b58fe7c06..000000000 --- a/lib/cryptopp/elgamal.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// elgamal.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "elgamal.h" -#include "asn.h" -#include "nbtheory.h" - -NAMESPACE_BEGIN(CryptoPP) - -void ElGamal_TestInstantiations() -{ - ElGamalEncryptor test1(1, 1, 1); - ElGamalDecryptor test2(NullRNG(), 123); - ElGamalEncryptor test3(test2); -} - -NAMESPACE_END diff --git a/lib/cryptopp/elgamal.h b/lib/cryptopp/elgamal.h deleted file mode 100644 index 9afc30eee..000000000 --- a/lib/cryptopp/elgamal.h +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef CRYPTOPP_ELGAMAL_H -#define CRYPTOPP_ELGAMAL_H - -#include "modexppc.h" -#include "dsa.h" - -NAMESPACE_BEGIN(CryptoPP) - -class CRYPTOPP_NO_VTABLE ElGamalBase : public DL_KeyAgreementAlgorithm_DH<Integer, NoCofactorMultiplication>, - public DL_KeyDerivationAlgorithm<Integer>, - public DL_SymmetricEncryptionAlgorithm -{ -public: - void Derive(const DL_GroupParameters<Integer> &groupParams, byte *derivedKey, size_t derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey, const NameValuePairs &derivationParams) const - { - agreedElement.Encode(derivedKey, derivedLength); - } - - size_t GetSymmetricKeyLength(size_t plainTextLength) const - { - return GetGroupParameters().GetModulus().ByteCount(); - } - - size_t GetSymmetricCiphertextLength(size_t plainTextLength) const - { - unsigned int len = GetGroupParameters().GetModulus().ByteCount(); - if (plainTextLength <= GetMaxSymmetricPlaintextLength(len)) - return len; - else - return 0; - } - - size_t GetMaxSymmetricPlaintextLength(size_t cipherTextLength) const - { - unsigned int len = GetGroupParameters().GetModulus().ByteCount(); - if (cipherTextLength == len) - return STDMIN(255U, len-3); - else - return 0; - } - - void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plainText, size_t plainTextLength, byte *cipherText, const NameValuePairs ¶meters) const - { - const Integer &p = GetGroupParameters().GetModulus(); - unsigned int modulusLen = p.ByteCount(); - - SecByteBlock block(modulusLen-1); - rng.GenerateBlock(block, modulusLen-2-plainTextLength); - memcpy(block+modulusLen-2-plainTextLength, plainText, plainTextLength); - block[modulusLen-2] = (byte)plainTextLength; - - a_times_b_mod_c(Integer(key, modulusLen), Integer(block, modulusLen-1), p).Encode(cipherText, modulusLen); - } - - DecodingResult SymmetricDecrypt(const byte *key, const byte *cipherText, size_t cipherTextLength, byte *plainText, const NameValuePairs ¶meters) const - { - const Integer &p = GetGroupParameters().GetModulus(); - unsigned int modulusLen = p.ByteCount(); - - if (cipherTextLength != modulusLen) - return DecodingResult(); - - Integer m = a_times_b_mod_c(Integer(cipherText, modulusLen), Integer(key, modulusLen).InverseMod(p), p); - - m.Encode(plainText, 1); - unsigned int plainTextLength = plainText[0]; - if (plainTextLength > GetMaxSymmetricPlaintextLength(modulusLen)) - return DecodingResult(); - m >>= 8; - m.Encode(plainText, plainTextLength); - return DecodingResult(plainTextLength); - } - - virtual const DL_GroupParameters_GFP & GetGroupParameters() const =0; -}; - -template <class BASE, class SCHEME_OPTIONS, class KEY> -class ElGamalObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>, public ElGamalBase -{ -public: - size_t FixedMaxPlaintextLength() const {return this->MaxPlaintextLength(FixedCiphertextLength());} - size_t FixedCiphertextLength() const {return this->CiphertextLength(0);} - - const DL_GroupParameters_GFP & GetGroupParameters() const {return this->GetKey().GetGroupParameters();} - - DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *cipherText, byte *plainText) const - {return Decrypt(rng, cipherText, FixedCiphertextLength(), plainText);} - -protected: - const DL_KeyAgreementAlgorithm<Integer> & GetKeyAgreementAlgorithm() const {return *this;} - const DL_KeyDerivationAlgorithm<Integer> & GetKeyDerivationAlgorithm() const {return *this;} - const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const {return *this;} -}; - -struct ElGamalKeys -{ - typedef DL_CryptoKeys_GFP::GroupParameters GroupParameters; - typedef DL_PrivateKey_GFP_OldFormat<DL_CryptoKeys_GFP::PrivateKey> PrivateKey; - typedef DL_PublicKey_GFP_OldFormat<DL_CryptoKeys_GFP::PublicKey> PublicKey; -}; - -//! ElGamal encryption scheme with non-standard padding -struct ElGamal -{ - typedef DL_CryptoSchemeOptions<ElGamal, ElGamalKeys, int, int, int> SchemeOptions; - - static const char * StaticAlgorithmName() {return "ElgamalEnc/Crypto++Padding";} - - typedef SchemeOptions::GroupParameters GroupParameters; - //! implements PK_Encryptor interface - typedef PK_FinalTemplate<ElGamalObjectImpl<DL_EncryptorBase<Integer>, SchemeOptions, SchemeOptions::PublicKey> > Encryptor; - //! implements PK_Decryptor interface - typedef PK_FinalTemplate<ElGamalObjectImpl<DL_DecryptorBase<Integer>, SchemeOptions, SchemeOptions::PrivateKey> > Decryptor; -}; - -typedef ElGamal::Encryptor ElGamalEncryptor; -typedef ElGamal::Decryptor ElGamalDecryptor; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/emsa2.cpp b/lib/cryptopp/emsa2.cpp deleted file mode 100644 index 3dbb7e8c0..000000000 --- a/lib/cryptopp/emsa2.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// emsa2.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "emsa2.h" - -#ifndef CRYPTOPP_IMPORTS - -NAMESPACE_BEGIN(CryptoPP) - -void EMSA2Pad::ComputeMessageRepresentative(RandomNumberGenerator &rng, - const byte *recoverableMessage, size_t recoverableMessageLength, - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const -{ - assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize())); - - if (representativeBitLength % 8 != 7) - throw PK_SignatureScheme::InvalidKeyLength("EMSA2: EMSA2 requires a key length that is a multiple of 8"); - - size_t digestSize = hash.DigestSize(); - size_t representativeByteLength = BitsToBytes(representativeBitLength); - - representative[0] = messageEmpty ? 0x4b : 0x6b; - memset(representative+1, 0xbb, representativeByteLength-digestSize-4); // pad with 0xbb - byte *afterP2 = representative+representativeByteLength-digestSize-3; - afterP2[0] = 0xba; - hash.Final(afterP2+1); - representative[representativeByteLength-2] = *hashIdentifier.first; - representative[representativeByteLength-1] = 0xcc; -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/emsa2.h b/lib/cryptopp/emsa2.h deleted file mode 100644 index 49109e6db..000000000 --- a/lib/cryptopp/emsa2.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef CRYPTOPP_EMSA2_H -#define CRYPTOPP_EMSA2_H - -/** \file - This file contains various padding schemes for public key algorithms. -*/ - -#include "cryptlib.h" -#include "pubkey.h" - -#ifdef CRYPTOPP_IS_DLL -#include "sha.h" -#endif - -NAMESPACE_BEGIN(CryptoPP) - -template <class H> class EMSA2HashId -{ -public: - static const byte id; -}; - -template <class BASE> -class EMSA2HashIdLookup : public BASE -{ -public: - struct HashIdentifierLookup - { - template <class H> struct HashIdentifierLookup2 - { - static HashIdentifier Lookup() - { - return HashIdentifier(&EMSA2HashId<H>::id, 1); - } - }; - }; -}; - -// EMSA2HashId can be instantiated with the following classes. -class SHA1; -class RIPEMD160; -class RIPEMD128; -class SHA256; -class SHA384; -class SHA512; -class Whirlpool; -class SHA224; -// end of list - -#ifdef CRYPTOPP_IS_DLL -CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId<SHA1>; -CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId<SHA224>; -CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId<SHA256>; -CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId<SHA384>; -CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId<SHA512>; -#endif - -//! _ -class CRYPTOPP_DLL EMSA2Pad : public EMSA2HashIdLookup<PK_DeterministicSignatureMessageEncodingMethod> -{ -public: - static const char * CRYPTOPP_API StaticAlgorithmName() {return "EMSA2";} - - size_t MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const - {return 8*digestLength + 31;} - - void ComputeMessageRepresentative(RandomNumberGenerator &rng, - const byte *recoverableMessage, size_t recoverableMessageLength, - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const; -}; - -//! EMSA2, for use with RWSS and RSA_ISO -/*! Only the following hash functions are supported by this signature standard: - \dontinclude emsa2.h - \skip EMSA2HashId can be instantiated - \until end of list -*/ -struct P1363_EMSA2 : public SignatureStandard -{ - typedef EMSA2Pad SignatureMessageEncodingMethod; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/eprecomp.cpp b/lib/cryptopp/eprecomp.cpp deleted file mode 100644 index a061cf6cd..000000000 --- a/lib/cryptopp/eprecomp.cpp +++ /dev/null @@ -1,112 +0,0 @@ -// eprecomp.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "eprecomp.h" -#include "asn.h" - -NAMESPACE_BEGIN(CryptoPP) - -template <class T> void DL_FixedBasePrecomputationImpl<T>::SetBase(const DL_GroupPrecomputation<Element> &group, const Element &i_base) -{ - m_base = group.NeedConversions() ? group.ConvertIn(i_base) : i_base; - - if (m_bases.empty() || !(m_base == m_bases[0])) - { - m_bases.resize(1); - m_bases[0] = m_base; - } - - if (group.NeedConversions()) - m_base = i_base; -} - -template <class T> void DL_FixedBasePrecomputationImpl<T>::Precompute(const DL_GroupPrecomputation<Element> &group, unsigned int maxExpBits, unsigned int storage) -{ - assert(m_bases.size() > 0); - assert(storage <= maxExpBits); - - if (storage > 1) - { - m_windowSize = (maxExpBits+storage-1)/storage; - m_exponentBase = Integer::Power2(m_windowSize); - } - - m_bases.resize(storage); - for (unsigned i=1; i<storage; i++) - m_bases[i] = group.GetGroup().ScalarMultiply(m_bases[i-1], m_exponentBase); -} - -template <class T> void DL_FixedBasePrecomputationImpl<T>::Load(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &bt) -{ - BERSequenceDecoder seq(bt); - word32 version; - BERDecodeUnsigned<word32>(seq, version, INTEGER, 1, 1); - m_exponentBase.BERDecode(seq); - m_windowSize = m_exponentBase.BitCount() - 1; - m_bases.clear(); - while (!seq.EndReached()) - m_bases.push_back(group.BERDecodeElement(seq)); - if (!m_bases.empty() && group.NeedConversions()) - m_base = group.ConvertOut(m_bases[0]); - seq.MessageEnd(); -} - -template <class T> void DL_FixedBasePrecomputationImpl<T>::Save(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &bt) const -{ - DERSequenceEncoder seq(bt); - DEREncodeUnsigned<word32>(seq, 1); // version - m_exponentBase.DEREncode(seq); - for (unsigned i=0; i<m_bases.size(); i++) - group.DEREncodeElement(seq, m_bases[i]); - seq.MessageEnd(); -} - -template <class T> void DL_FixedBasePrecomputationImpl<T>::PrepareCascade(const DL_GroupPrecomputation<Element> &i_group, std::vector<BaseAndExponent<Element> > &eb, const Integer &exponent) const -{ - const AbstractGroup<T> &group = i_group.GetGroup(); - - Integer r, q, e = exponent; - bool fastNegate = group.InversionIsFast() && m_windowSize > 1; - unsigned int i; - - for (i=0; i+1<m_bases.size(); i++) - { - Integer::DivideByPowerOf2(r, q, e, m_windowSize); - std::swap(q, e); - if (fastNegate && r.GetBit(m_windowSize-1)) - { - ++e; - eb.push_back(BaseAndExponent<Element>(group.Inverse(m_bases[i]), m_exponentBase - r)); - } - else - eb.push_back(BaseAndExponent<Element>(m_bases[i], r)); - } - eb.push_back(BaseAndExponent<Element>(m_bases[i], e)); -} - -template <class T> T DL_FixedBasePrecomputationImpl<T>::Exponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent) const -{ - std::vector<BaseAndExponent<Element> > eb; // array of segments of the exponent and precalculated bases - eb.reserve(m_bases.size()); - PrepareCascade(group, eb, exponent); - return group.ConvertOut(GeneralCascadeMultiplication<Element>(group.GetGroup(), eb.begin(), eb.end())); -} - -template <class T> T - DL_FixedBasePrecomputationImpl<T>::CascadeExponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent, - const DL_FixedBasePrecomputation<T> &i_pc2, const Integer &exponent2) const -{ - std::vector<BaseAndExponent<Element> > eb; // array of segments of the exponent and precalculated bases - const DL_FixedBasePrecomputationImpl<T> &pc2 = static_cast<const DL_FixedBasePrecomputationImpl<T> &>(i_pc2); - eb.reserve(m_bases.size() + pc2.m_bases.size()); - PrepareCascade(group, eb, exponent); - pc2.PrepareCascade(group, eb, exponent2); - return group.ConvertOut(GeneralCascadeMultiplication<Element>(group.GetGroup(), eb.begin(), eb.end())); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/eprecomp.h b/lib/cryptopp/eprecomp.h deleted file mode 100644 index 1f3256766..000000000 --- a/lib/cryptopp/eprecomp.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef CRYPTOPP_EPRECOMP_H -#define CRYPTOPP_EPRECOMP_H - -#include "integer.h" -#include "algebra.h" -#include <vector> - -NAMESPACE_BEGIN(CryptoPP) - -template <class T> -class DL_GroupPrecomputation -{ -public: - typedef T Element; - - virtual bool NeedConversions() const {return false;} - virtual Element ConvertIn(const Element &v) const {return v;} - virtual Element ConvertOut(const Element &v) const {return v;} - virtual const AbstractGroup<Element> & GetGroup() const =0; - virtual Element BERDecodeElement(BufferedTransformation &bt) const =0; - virtual void DEREncodeElement(BufferedTransformation &bt, const Element &P) const =0; -}; - -template <class T> -class DL_FixedBasePrecomputation -{ -public: - typedef T Element; - - virtual bool IsInitialized() const =0; - virtual void SetBase(const DL_GroupPrecomputation<Element> &group, const Element &base) =0; - virtual const Element & GetBase(const DL_GroupPrecomputation<Element> &group) const =0; - virtual void Precompute(const DL_GroupPrecomputation<Element> &group, unsigned int maxExpBits, unsigned int storage) =0; - virtual void Load(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &storedPrecomputation) =0; - virtual void Save(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &storedPrecomputation) const =0; - virtual Element Exponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent) const =0; - virtual Element CascadeExponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent, const DL_FixedBasePrecomputation<Element> &pc2, const Integer &exponent2) const =0; -}; - -template <class T> -class DL_FixedBasePrecomputationImpl : public DL_FixedBasePrecomputation<T> -{ -public: - typedef T Element; - - DL_FixedBasePrecomputationImpl() : m_windowSize(0) {} - - // DL_FixedBasePrecomputation - bool IsInitialized() const - {return !m_bases.empty();} - void SetBase(const DL_GroupPrecomputation<Element> &group, const Element &base); - const Element & GetBase(const DL_GroupPrecomputation<Element> &group) const - {return group.NeedConversions() ? m_base : m_bases[0];} - void Precompute(const DL_GroupPrecomputation<Element> &group, unsigned int maxExpBits, unsigned int storage); - void Load(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &storedPrecomputation); - void Save(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &storedPrecomputation) const; - Element Exponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent) const; - Element CascadeExponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent, const DL_FixedBasePrecomputation<Element> &pc2, const Integer &exponent2) const; - -private: - void PrepareCascade(const DL_GroupPrecomputation<Element> &group, std::vector<BaseAndExponent<Element> > &eb, const Integer &exponent) const; - - Element m_base; - unsigned int m_windowSize; - Integer m_exponentBase; // what base to represent the exponent in - std::vector<Element> m_bases; // precalculated bases -}; - -NAMESPACE_END - -#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES -#include "eprecomp.cpp" -#endif - -#endif diff --git a/lib/cryptopp/esign.cpp b/lib/cryptopp/esign.cpp deleted file mode 100644 index 8b42c1fa4..000000000 --- a/lib/cryptopp/esign.cpp +++ /dev/null @@ -1,210 +0,0 @@ -// esign.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "esign.h" -#include "asn.h" -#include "modarith.h" -#include "nbtheory.h" -#include "sha.h" -#include "algparam.h" - -NAMESPACE_BEGIN(CryptoPP) - -void ESIGN_TestInstantiations() -{ - ESIGN<SHA>::Verifier x1(1, 1); - ESIGN<SHA>::Signer x2(NullRNG(), 1); - ESIGN<SHA>::Verifier x3(x2); - ESIGN<SHA>::Verifier x4(x2.GetKey()); - ESIGN<SHA>::Verifier x5(x3); - ESIGN<SHA>::Signer x6 = x2; - - x6 = x2; - x3 = ESIGN<SHA>::Verifier(x2); - x4 = x2.GetKey(); -} - -void ESIGNFunction::BERDecode(BufferedTransformation &bt) -{ - BERSequenceDecoder seq(bt); - m_n.BERDecode(seq); - m_e.BERDecode(seq); - seq.MessageEnd(); -} - -void ESIGNFunction::DEREncode(BufferedTransformation &bt) const -{ - DERSequenceEncoder seq(bt); - m_n.DEREncode(seq); - m_e.DEREncode(seq); - seq.MessageEnd(); -} - -Integer ESIGNFunction::ApplyFunction(const Integer &x) const -{ - DoQuickSanityCheck(); - return STDMIN(a_exp_b_mod_c(x, m_e, m_n) >> (2*GetK()+2), MaxImage()); -} - -bool ESIGNFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const -{ - bool pass = true; - pass = pass && m_n > Integer::One() && m_n.IsOdd(); - pass = pass && m_e >= 8 && m_e < m_n; - return pass; -} - -bool ESIGNFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const -{ - return GetValueHelper(this, name, valueType, pValue).Assignable() - CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) - CRYPTOPP_GET_FUNCTION_ENTRY(PublicExponent) - ; -} - -void ESIGNFunction::AssignFrom(const NameValuePairs &source) -{ - AssignFromHelper(this, source) - CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) - CRYPTOPP_SET_FUNCTION_ENTRY(PublicExponent) - ; -} - -// ***************************************************************************** - -void InvertibleESIGNFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶m) -{ - int modulusSize = 1023*2; - param.GetIntValue("ModulusSize", modulusSize) || param.GetIntValue("KeySize", modulusSize); - - if (modulusSize < 24) - throw InvalidArgument("InvertibleESIGNFunction: specified modulus size is too small"); - - if (modulusSize % 3 != 0) - throw InvalidArgument("InvertibleESIGNFunction: modulus size must be divisible by 3"); - - m_e = param.GetValueWithDefault("PublicExponent", Integer(32)); - - if (m_e < 8) - throw InvalidArgument("InvertibleESIGNFunction: public exponents less than 8 may not be secure"); - - // VC70 workaround: putting these after primeParam causes overlapped stack allocation - ConstByteArrayParameter seedParam; - SecByteBlock seed; - - const Integer minP = Integer(204) << (modulusSize/3-8); - const Integer maxP = Integer::Power2(modulusSize/3)-1; - AlgorithmParameters primeParam = MakeParameters("Min", minP)("Max", maxP)("RandomNumberType", Integer::PRIME); - - if (param.GetValue("Seed", seedParam)) - { - seed.resize(seedParam.size() + 4); - memcpy(seed + 4, seedParam.begin(), seedParam.size()); - - PutWord(false, BIG_ENDIAN_ORDER, seed, (word32)0); - m_p.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("Seed", ConstByteArrayParameter(seed)))); - PutWord(false, BIG_ENDIAN_ORDER, seed, (word32)1); - m_q.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("Seed", ConstByteArrayParameter(seed)))); - } - else - { - m_p.GenerateRandom(rng, primeParam); - m_q.GenerateRandom(rng, primeParam); - } - - m_n = m_p * m_p * m_q; - - assert(m_n.BitCount() == modulusSize); -} - -void InvertibleESIGNFunction::BERDecode(BufferedTransformation &bt) -{ - BERSequenceDecoder privateKey(bt); - m_n.BERDecode(privateKey); - m_e.BERDecode(privateKey); - m_p.BERDecode(privateKey); - m_q.BERDecode(privateKey); - privateKey.MessageEnd(); -} - -void InvertibleESIGNFunction::DEREncode(BufferedTransformation &bt) const -{ - DERSequenceEncoder privateKey(bt); - m_n.DEREncode(privateKey); - m_e.DEREncode(privateKey); - m_p.DEREncode(privateKey); - m_q.DEREncode(privateKey); - privateKey.MessageEnd(); -} - -Integer InvertibleESIGNFunction::CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const -{ - DoQuickSanityCheck(); - - Integer pq = m_p * m_q; - Integer p2 = m_p * m_p; - Integer r, z, re, a, w0, w1; - - do - { - r.Randomize(rng, Integer::Zero(), pq); - z = x << (2*GetK()+2); - re = a_exp_b_mod_c(r, m_e, m_n); - a = (z - re) % m_n; - Integer::Divide(w1, w0, a, pq); - if (w1.NotZero()) - { - ++w0; - w1 = pq - w1; - } - } - while ((w1 >> 2*GetK()+1).IsPositive()); - - ModularArithmetic modp(m_p); - Integer t = modp.Divide(w0 * r % m_p, m_e * re % m_p); - Integer s = r + t*pq; - assert(s < m_n); -/* - using namespace std; - cout << "f = " << x << endl; - cout << "r = " << r << endl; - cout << "z = " << z << endl; - cout << "a = " << a << endl; - cout << "w0 = " << w0 << endl; - cout << "w1 = " << w1 << endl; - cout << "t = " << t << endl; - cout << "s = " << s << endl; -*/ - return s; -} - -bool InvertibleESIGNFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const -{ - bool pass = ESIGNFunction::Validate(rng, level); - pass = pass && m_p > Integer::One() && m_p.IsOdd() && m_p < m_n; - pass = pass && m_q > Integer::One() && m_q.IsOdd() && m_q < m_n; - pass = pass && m_p.BitCount() == m_q.BitCount(); - if (level >= 1) - pass = pass && m_p * m_p * m_q == m_n; - if (level >= 2) - pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); - return pass; -} - -bool InvertibleESIGNFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const -{ - return GetValueHelper<ESIGNFunction>(this, name, valueType, pValue).Assignable() - CRYPTOPP_GET_FUNCTION_ENTRY(Prime1) - CRYPTOPP_GET_FUNCTION_ENTRY(Prime2) - ; -} - -void InvertibleESIGNFunction::AssignFrom(const NameValuePairs &source) -{ - AssignFromHelper<ESIGNFunction>(this, source) - CRYPTOPP_SET_FUNCTION_ENTRY(Prime1) - CRYPTOPP_SET_FUNCTION_ENTRY(Prime2) - ; -} - -NAMESPACE_END diff --git a/lib/cryptopp/esign.h b/lib/cryptopp/esign.h deleted file mode 100644 index 8eecbc5a1..000000000 --- a/lib/cryptopp/esign.h +++ /dev/null @@ -1,128 +0,0 @@ -#ifndef CRYPTOPP_ESIGN_H -#define CRYPTOPP_ESIGN_H - -/** \file - This file contains classes that implement the - ESIGN signature schemes as defined in IEEE P1363a. -*/ - -#include "pubkey.h" -#include "integer.h" -#include "asn.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -class ESIGNFunction : public TrapdoorFunction, public ASN1CryptoMaterial<PublicKey> -{ - typedef ESIGNFunction ThisClass; - -public: - void Initialize(const Integer &n, const Integer &e) - {m_n = n; m_e = e;} - - // PublicKey - void BERDecode(BufferedTransformation &bt); - void DEREncode(BufferedTransformation &bt) const; - - // CryptoMaterial - bool Validate(RandomNumberGenerator &rng, unsigned int level) const; - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; - void AssignFrom(const NameValuePairs &source); - - // TrapdoorFunction - Integer ApplyFunction(const Integer &x) const; - Integer PreimageBound() const {return m_n;} - Integer ImageBound() const {return Integer::Power2(GetK());} - - // non-derived - const Integer & GetModulus() const {return m_n;} - const Integer & GetPublicExponent() const {return m_e;} - - void SetModulus(const Integer &n) {m_n = n;} - void SetPublicExponent(const Integer &e) {m_e = e;} - -protected: - unsigned int GetK() const {return m_n.BitCount()/3-1;} - - Integer m_n, m_e; -}; - -//! _ -class InvertibleESIGNFunction : public ESIGNFunction, public RandomizedTrapdoorFunctionInverse, public PrivateKey -{ - typedef InvertibleESIGNFunction ThisClass; - -public: - void Initialize(const Integer &n, const Integer &e, const Integer &p, const Integer &q) - {m_n = n; m_e = e; m_p = p; m_q = q;} - // generate a random private key - void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits) - {GenerateRandomWithKeySize(rng, modulusBits);} - - void BERDecode(BufferedTransformation &bt); - void DEREncode(BufferedTransformation &bt) const; - - Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const; - - // GeneratibleCryptoMaterial - bool Validate(RandomNumberGenerator &rng, unsigned int level) const; - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; - void AssignFrom(const NameValuePairs &source); - /*! parameters: (ModulusSize) */ - void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); - - const Integer& GetPrime1() const {return m_p;} - const Integer& GetPrime2() const {return m_q;} - - void SetPrime1(const Integer &p) {m_p = p;} - void SetPrime2(const Integer &q) {m_q = q;} - -protected: - Integer m_p, m_q; -}; - -//! _ -template <class T> -class EMSA5Pad : public PK_DeterministicSignatureMessageEncodingMethod -{ -public: - static const char *StaticAlgorithmName() {return "EMSA5";} - - void ComputeMessageRepresentative(RandomNumberGenerator &rng, - const byte *recoverableMessage, size_t recoverableMessageLength, - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const - { - SecByteBlock digest(hash.DigestSize()); - hash.Final(digest); - size_t representativeByteLength = BitsToBytes(representativeBitLength); - T mgf; - mgf.GenerateAndMask(hash, representative, representativeByteLength, digest, digest.size(), false); - if (representativeBitLength % 8 != 0) - representative[0] = (byte)Crop(representative[0], representativeBitLength % 8); - } -}; - -//! EMSA5, for use with ESIGN -struct P1363_EMSA5 : public SignatureStandard -{ - typedef EMSA5Pad<P1363_MGF1> SignatureMessageEncodingMethod; -}; - -struct ESIGN_Keys -{ - static std::string StaticAlgorithmName() {return "ESIGN";} - typedef ESIGNFunction PublicKey; - typedef InvertibleESIGNFunction PrivateKey; -}; - -//! ESIGN, as defined in IEEE P1363a -template <class H, class STANDARD = P1363_EMSA5> -struct ESIGN : public TF_SS<STANDARD, H, ESIGN_Keys> -{ -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/factory.h b/lib/cryptopp/factory.h deleted file mode 100644 index 5b65db3da..000000000 --- a/lib/cryptopp/factory.h +++ /dev/null @@ -1,136 +0,0 @@ -#ifndef CRYPTOPP_OBJFACT_H -#define CRYPTOPP_OBJFACT_H - -#include "cryptlib.h" -#include <map> -#include <vector> - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -template <class AbstractClass> -class ObjectFactory -{ -public: - virtual ~ObjectFactory () {} - virtual AbstractClass * CreateObject() const =0; -}; - -//! _ -template <class AbstractClass, class ConcreteClass> -class DefaultObjectFactory : public ObjectFactory<AbstractClass> -{ -public: - AbstractClass * CreateObject() const - { - return new ConcreteClass; - } - -}; - -//! _ -template <class AbstractClass, int instance=0> -class ObjectFactoryRegistry -{ -public: - class FactoryNotFound : public Exception - { - public: - FactoryNotFound(const char *name) : Exception(OTHER_ERROR, std::string("ObjectFactoryRegistry: could not find factory for algorithm ") + name) {} - }; - - ~ObjectFactoryRegistry() - { - for (CPP_TYPENAME Map::iterator i = m_map.begin(); i != m_map.end(); ++i) - { - delete (ObjectFactory<AbstractClass> *)i->second; - i->second = NULL; - } - } - - void RegisterFactory(const std::string &name, ObjectFactory<AbstractClass> *factory) - { - m_map[name] = factory; - } - - const ObjectFactory<AbstractClass> * GetFactory(const char *name) const - { - CPP_TYPENAME Map::const_iterator i = m_map.find(name); - return i == m_map.end() ? NULL : (ObjectFactory<AbstractClass> *)i->second; - } - - AbstractClass *CreateObject(const char *name) const - { - const ObjectFactory<AbstractClass> *factory = GetFactory(name); - if (!factory) - throw FactoryNotFound(name); - return factory->CreateObject(); - } - - // Return a vector containing the factory names. This is easier than returning an iterator. - // from Andrew Pitonyak - std::vector<std::string> GetFactoryNames() const - { - std::vector<std::string> names; - CPP_TYPENAME Map::const_iterator iter; - for (iter = m_map.begin(); iter != m_map.end(); ++iter) - names.push_back(iter->first); - return names; - } - - CRYPTOPP_NOINLINE static ObjectFactoryRegistry<AbstractClass, instance> & Registry(CRYPTOPP_NOINLINE_DOTDOTDOT); - -private: - // use void * instead of ObjectFactory<AbstractClass> * to save code size - typedef std::map<std::string, void *> Map; - Map m_map; -}; - -template <class AbstractClass, int instance> -ObjectFactoryRegistry<AbstractClass, instance> & ObjectFactoryRegistry<AbstractClass, instance>::Registry(CRYPTOPP_NOINLINE_DOTDOTDOT) -{ - static ObjectFactoryRegistry<AbstractClass, instance> s_registry; - return s_registry; -} - -template <class AbstractClass, class ConcreteClass, int instance = 0> -struct RegisterDefaultFactoryFor { -RegisterDefaultFactoryFor(const char *name=NULL) -{ - // BCB2006 workaround - std::string n = name ? std::string(name) : std::string(ConcreteClass::StaticAlgorithmName()); - ObjectFactoryRegistry<AbstractClass, instance>::Registry(). - RegisterFactory(n, new DefaultObjectFactory<AbstractClass, ConcreteClass>); -}}; - -template <class SchemeClass> -void RegisterAsymmetricCipherDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL) -{ - RegisterDefaultFactoryFor<PK_Encryptor, CPP_TYPENAME SchemeClass::Encryptor>((const char *)name); - RegisterDefaultFactoryFor<PK_Decryptor, CPP_TYPENAME SchemeClass::Decryptor>((const char *)name); -} - -template <class SchemeClass> -void RegisterSignatureSchemeDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL) -{ - RegisterDefaultFactoryFor<PK_Signer, CPP_TYPENAME SchemeClass::Signer>((const char *)name); - RegisterDefaultFactoryFor<PK_Verifier, CPP_TYPENAME SchemeClass::Verifier>((const char *)name); -} - -template <class SchemeClass> -void RegisterSymmetricCipherDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL) -{ - RegisterDefaultFactoryFor<SymmetricCipher, CPP_TYPENAME SchemeClass::Encryption, ENCRYPTION>((const char *)name); - RegisterDefaultFactoryFor<SymmetricCipher, CPP_TYPENAME SchemeClass::Decryption, DECRYPTION>((const char *)name); -} - -template <class SchemeClass> -void RegisterAuthenticatedSymmetricCipherDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL) -{ - RegisterDefaultFactoryFor<AuthenticatedSymmetricCipher, CPP_TYPENAME SchemeClass::Encryption, ENCRYPTION>((const char *)name); - RegisterDefaultFactoryFor<AuthenticatedSymmetricCipher, CPP_TYPENAME SchemeClass::Decryption, DECRYPTION>((const char *)name); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/files.cpp b/lib/cryptopp/files.cpp deleted file mode 100644 index 453b56248..000000000 --- a/lib/cryptopp/files.cpp +++ /dev/null @@ -1,259 +0,0 @@ -// files.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "files.h" - -#include <limits> - -NAMESPACE_BEGIN(CryptoPP) - -using namespace std; - -#ifndef NDEBUG -void Files_TestInstantiations() -{ - FileStore f0; - FileSource f1; - FileSink f2; -} -#endif - -void FileStore::StoreInitialize(const NameValuePairs ¶meters) -{ - m_waiting = false; - m_stream = NULL; - m_file.release(); - - const char *fileName = NULL; -#if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400 - const wchar_t *fileNameWide = NULL; - if (!parameters.GetValue(Name::InputFileNameWide(), fileNameWide)) -#endif - if (!parameters.GetValue(Name::InputFileName(), fileName)) - { - parameters.GetValue(Name::InputStreamPointer(), m_stream); - return; - } - - ios::openmode binary = parameters.GetValueWithDefault(Name::InputBinaryMode(), true) ? ios::binary : ios::openmode(0); - m_file.reset(new std::ifstream); -#ifdef CRYPTOPP_UNIX_AVAILABLE - std::string narrowed; - if (fileNameWide) - fileName = (narrowed = StringNarrow(fileNameWide)).c_str(); -#endif -#if _MSC_VER >= 1400 - if (fileNameWide) - { - m_file->open(fileNameWide, ios::in | binary); - if (!*m_file) - throw OpenErr(StringNarrow(fileNameWide, false)); - } -#endif - if (fileName) - { - m_file->open(fileName, ios::in | binary); - if (!*m_file) - throw OpenErr(fileName); - } - m_stream = m_file.get(); -} - -lword FileStore::MaxRetrievable() const -{ - if (!m_stream) - return 0; - - streampos current = m_stream->tellg(); - streampos end = m_stream->seekg(0, ios::end).tellg(); - m_stream->seekg(current); - return end-current; -} - -size_t FileStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) -{ - if (!m_stream) - { - transferBytes = 0; - return 0; - } - - lword size=transferBytes; - transferBytes = 0; - - if (m_waiting) - goto output; - - while (size && m_stream->good()) - { - { - size_t spaceSize = 1024; - m_space = HelpCreatePutSpace(target, channel, 1, UnsignedMin(size_t(0)-1, size), spaceSize); - - m_stream->read((char *)m_space, (unsigned int)STDMIN(size, (lword)spaceSize)); - } - m_len = (size_t)m_stream->gcount(); - size_t blockedBytes; -output: - blockedBytes = target.ChannelPutModifiable2(channel, m_space, m_len, 0, blocking); - m_waiting = blockedBytes > 0; - if (m_waiting) - return blockedBytes; - size -= m_len; - transferBytes += m_len; - } - - if (!m_stream->good() && !m_stream->eof()) - throw ReadErr(); - - return 0; -} - -size_t FileStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const -{ - if (!m_stream) - return 0; - - if (begin == 0 && end == 1) - { - int result = m_stream->peek(); - if (result == char_traits<char>::eof()) - return 0; - else - { - size_t blockedBytes = target.ChannelPut(channel, byte(result), blocking); - begin += 1-blockedBytes; - return blockedBytes; - } - } - - // TODO: figure out what happens on cin - streampos current = m_stream->tellg(); - streampos endPosition = m_stream->seekg(0, ios::end).tellg(); - streampos newPosition = current + (streamoff)begin; - - if (newPosition >= endPosition) - { - m_stream->seekg(current); - return 0; // don't try to seek beyond the end of file - } - m_stream->seekg(newPosition); - try - { - assert(!m_waiting); - lword copyMax = end-begin; - size_t blockedBytes = const_cast<FileStore *>(this)->TransferTo2(target, copyMax, channel, blocking); - begin += copyMax; - if (blockedBytes) - { - const_cast<FileStore *>(this)->m_waiting = false; - return blockedBytes; - } - } - catch(...) - { - m_stream->clear(); - m_stream->seekg(current); - throw; - } - m_stream->clear(); - m_stream->seekg(current); - - return 0; -} - -lword FileStore::Skip(lword skipMax) -{ - if (!m_stream) - return 0; - - lword oldPos = m_stream->tellg(); - std::istream::off_type offset; - if (!SafeConvert(skipMax, offset)) - throw InvalidArgument("FileStore: maximum seek offset exceeded"); - m_stream->seekg(offset, ios::cur); - return (lword)m_stream->tellg() - oldPos; -} - -void FileSink::IsolatedInitialize(const NameValuePairs ¶meters) -{ - m_stream = NULL; - m_file.release(); - - const char *fileName = NULL; -#if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400 - const wchar_t *fileNameWide = NULL; - if (!parameters.GetValue(Name::OutputFileNameWide(), fileNameWide)) -#endif - if (!parameters.GetValue(Name::OutputFileName(), fileName)) - { - parameters.GetValue(Name::OutputStreamPointer(), m_stream); - return; - } - - ios::openmode binary = parameters.GetValueWithDefault(Name::OutputBinaryMode(), true) ? ios::binary : ios::openmode(0); - m_file.reset(new std::ofstream); -#ifdef CRYPTOPP_UNIX_AVAILABLE - std::string narrowed; - if (fileNameWide) - fileName = (narrowed = StringNarrow(fileNameWide)).c_str(); -#endif -#if _MSC_VER >= 1400 - if (fileNameWide) - { - m_file->open(fileNameWide, ios::out | ios::trunc | binary); - if (!*m_file) - throw OpenErr(StringNarrow(fileNameWide, false)); - } -#endif - if (fileName) - { - m_file->open(fileName, ios::out | ios::trunc | binary); - if (!*m_file) - throw OpenErr(fileName); - } - m_stream = m_file.get(); -} - -bool FileSink::IsolatedFlush(bool hardFlush, bool blocking) -{ - if (!m_stream) - throw Err("FileSink: output stream not opened"); - - m_stream->flush(); - if (!m_stream->good()) - throw WriteErr(); - - return false; -} - -size_t FileSink::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) -{ - if (!m_stream) - throw Err("FileSink: output stream not opened"); - - while (length > 0) - { - std::streamsize size; - if (!SafeConvert(length, size)) - size = numeric_limits<std::streamsize>::max(); - m_stream->write((const char *)inString, size); - inString += size; - length -= (size_t)size; - } - - if (messageEnd) - m_stream->flush(); - - if (!m_stream->good()) - throw WriteErr(); - - return 0; -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/files.h b/lib/cryptopp/files.h deleted file mode 100644 index a47e856bf..000000000 --- a/lib/cryptopp/files.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef CRYPTOPP_FILES_H -#define CRYPTOPP_FILES_H - -#include "cryptlib.h" -#include "filters.h" -#include "argnames.h" - -#include <iostream> -#include <fstream> - -NAMESPACE_BEGIN(CryptoPP) - -//! file-based implementation of Store interface -class CRYPTOPP_DLL FileStore : public Store, private FilterPutSpaceHelper, public NotCopyable -{ -public: - class Err : public Exception - { - public: - Err(const std::string &s) : Exception(IO_ERROR, s) {} - }; - class OpenErr : public Err {public: OpenErr(const std::string &filename) : Err("FileStore: error opening file for reading: " + filename) {}}; - class ReadErr : public Err {public: ReadErr() : Err("FileStore: error reading file") {}}; - - FileStore() : m_stream(NULL) {} - FileStore(std::istream &in) - {StoreInitialize(MakeParameters(Name::InputStreamPointer(), &in));} - FileStore(const char *filename) - {StoreInitialize(MakeParameters(Name::InputFileName(), filename));} -#if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400 - //! specify file with Unicode name. On non-Windows OS, this function assumes that setlocale() has been called. - FileStore(const wchar_t *filename) - {StoreInitialize(MakeParameters(Name::InputFileNameWide(), filename));} -#endif - - std::istream* GetStream() {return m_stream;} - - lword MaxRetrievable() const; - size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); - size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; - lword Skip(lword skipMax=ULONG_MAX); - -private: - void StoreInitialize(const NameValuePairs ¶meters); - - member_ptr<std::ifstream> m_file; - std::istream *m_stream; - byte *m_space; - size_t m_len; - bool m_waiting; -}; - -//! file-based implementation of Source interface -class CRYPTOPP_DLL FileSource : public SourceTemplate<FileStore> -{ -public: - typedef FileStore::Err Err; - typedef FileStore::OpenErr OpenErr; - typedef FileStore::ReadErr ReadErr; - - FileSource(BufferedTransformation *attachment = NULL) - : SourceTemplate<FileStore>(attachment) {} - FileSource(std::istream &in, bool pumpAll, BufferedTransformation *attachment = NULL) - : SourceTemplate<FileStore>(attachment) {SourceInitialize(pumpAll, MakeParameters(Name::InputStreamPointer(), &in));} - FileSource(const char *filename, bool pumpAll, BufferedTransformation *attachment = NULL, bool binary=true) - : SourceTemplate<FileStore>(attachment) {SourceInitialize(pumpAll, MakeParameters(Name::InputFileName(), filename)(Name::InputBinaryMode(), binary));} -#if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400 - //! specify file with Unicode name. On non-Windows OS, this function assumes that setlocale() has been called. - FileSource(const wchar_t *filename, bool pumpAll, BufferedTransformation *attachment = NULL, bool binary=true) - : SourceTemplate<FileStore>(attachment) {SourceInitialize(pumpAll, MakeParameters(Name::InputFileNameWide(), filename)(Name::InputBinaryMode(), binary));} -#endif - - std::istream* GetStream() {return m_store.GetStream();} -}; - -//! file-based implementation of Sink interface -class CRYPTOPP_DLL FileSink : public Sink, public NotCopyable -{ -public: - class Err : public Exception - { - public: - Err(const std::string &s) : Exception(IO_ERROR, s) {} - }; - class OpenErr : public Err {public: OpenErr(const std::string &filename) : Err("FileSink: error opening file for writing: " + filename) {}}; - class WriteErr : public Err {public: WriteErr() : Err("FileSink: error writing file") {}}; - - FileSink() : m_stream(NULL) {} - FileSink(std::ostream &out) - {IsolatedInitialize(MakeParameters(Name::OutputStreamPointer(), &out));} - FileSink(const char *filename, bool binary=true) - {IsolatedInitialize(MakeParameters(Name::OutputFileName(), filename)(Name::OutputBinaryMode(), binary));} -#if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400 - //! specify file with Unicode name. On non-Windows OS, this function assumes that setlocale() has been called. - FileSink(const wchar_t *filename, bool binary=true) - {IsolatedInitialize(MakeParameters(Name::OutputFileNameWide(), filename)(Name::OutputBinaryMode(), binary));} -#endif - - std::ostream* GetStream() {return m_stream;} - - void IsolatedInitialize(const NameValuePairs ¶meters); - size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); - bool IsolatedFlush(bool hardFlush, bool blocking); - -private: - member_ptr<std::ofstream> m_file; - std::ostream *m_stream; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/filters.cpp b/lib/cryptopp/filters.cpp deleted file mode 100644 index 083dfd361..000000000 --- a/lib/cryptopp/filters.cpp +++ /dev/null @@ -1,1120 +0,0 @@ -// filters.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "filters.h" -#include "mqueue.h" -#include "fltrimpl.h" -#include "argnames.h" -#include <memory> -#include <functional> - -NAMESPACE_BEGIN(CryptoPP) - -Filter::Filter(BufferedTransformation *attachment) - : m_attachment(attachment), m_continueAt(0) -{ -} - -BufferedTransformation * Filter::NewDefaultAttachment() const -{ - return new MessageQueue; -} - -BufferedTransformation * Filter::AttachedTransformation() -{ - if (m_attachment.get() == NULL) - m_attachment.reset(NewDefaultAttachment()); - return m_attachment.get(); -} - -const BufferedTransformation *Filter::AttachedTransformation() const -{ - if (m_attachment.get() == NULL) - const_cast<Filter *>(this)->m_attachment.reset(NewDefaultAttachment()); - return m_attachment.get(); -} - -void Filter::Detach(BufferedTransformation *newOut) -{ - m_attachment.reset(newOut); -} - -void Filter::Insert(Filter *filter) -{ - filter->m_attachment.reset(m_attachment.release()); - m_attachment.reset(filter); -} - -size_t Filter::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const -{ - return AttachedTransformation()->CopyRangeTo2(target, begin, end, channel, blocking); -} - -size_t Filter::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) -{ - return AttachedTransformation()->TransferTo2(target, transferBytes, channel, blocking); -} - -void Filter::Initialize(const NameValuePairs ¶meters, int propagation) -{ - m_continueAt = 0; - IsolatedInitialize(parameters); - PropagateInitialize(parameters, propagation); -} - -bool Filter::Flush(bool hardFlush, int propagation, bool blocking) -{ - switch (m_continueAt) - { - case 0: - if (IsolatedFlush(hardFlush, blocking)) - return true; - case 1: - if (OutputFlush(1, hardFlush, propagation, blocking)) - return true; - } - return false; -} - -bool Filter::MessageSeriesEnd(int propagation, bool blocking) -{ - switch (m_continueAt) - { - case 0: - if (IsolatedMessageSeriesEnd(blocking)) - return true; - case 1: - if (ShouldPropagateMessageSeriesEnd() && OutputMessageSeriesEnd(1, propagation, blocking)) - return true; - } - return false; -} - -void Filter::PropagateInitialize(const NameValuePairs ¶meters, int propagation) -{ - if (propagation) - AttachedTransformation()->Initialize(parameters, propagation-1); -} - -size_t Filter::OutputModifiable(int outputSite, byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel) -{ - if (messageEnd) - messageEnd--; - size_t result = AttachedTransformation()->ChannelPutModifiable2(channel, inString, length, messageEnd, blocking); - m_continueAt = result ? outputSite : 0; - return result; -} - -size_t Filter::Output(int outputSite, const byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel) -{ - if (messageEnd) - messageEnd--; - size_t result = AttachedTransformation()->ChannelPut2(channel, inString, length, messageEnd, blocking); - m_continueAt = result ? outputSite : 0; - return result; -} - -bool Filter::OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel) -{ - if (propagation && AttachedTransformation()->ChannelFlush(channel, hardFlush, propagation-1, blocking)) - { - m_continueAt = outputSite; - return true; - } - m_continueAt = 0; - return false; -} - -bool Filter::OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel) -{ - if (propagation && AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation-1, blocking)) - { - m_continueAt = outputSite; - return true; - } - m_continueAt = 0; - return false; -} - -// ************************************************************* - -void MeterFilter::ResetMeter() -{ - m_currentMessageBytes = m_totalBytes = m_currentSeriesMessages = m_totalMessages = m_totalMessageSeries = 0; - m_rangesToSkip.clear(); -} - -void MeterFilter::AddRangeToSkip(unsigned int message, lword position, lword size, bool sortNow) -{ - MessageRange r = {message, position, size}; - m_rangesToSkip.push_back(r); - if (sortNow) - std::sort(m_rangesToSkip.begin(), m_rangesToSkip.end()); -} - -size_t MeterFilter::PutMaybeModifiable(byte *begin, size_t length, int messageEnd, bool blocking, bool modifiable) -{ - if (!m_transparent) - return 0; - - size_t t; - FILTER_BEGIN; - - m_begin = begin; - m_length = length; - - while (m_length > 0 || messageEnd) - { - if (m_length > 0 && !m_rangesToSkip.empty() && m_rangesToSkip.front().message == m_totalMessages && m_currentMessageBytes + m_length > m_rangesToSkip.front().position) - { - FILTER_OUTPUT_MAYBE_MODIFIABLE(1, m_begin, t = (size_t)SaturatingSubtract(m_rangesToSkip.front().position, m_currentMessageBytes), false, modifiable); - - assert(t < m_length); - m_begin += t; - m_length -= t; - m_currentMessageBytes += t; - m_totalBytes += t; - - if (m_currentMessageBytes + m_length < m_rangesToSkip.front().position + m_rangesToSkip.front().size) - t = m_length; - else - { - t = (size_t)SaturatingSubtract(m_rangesToSkip.front().position + m_rangesToSkip.front().size, m_currentMessageBytes); - assert(t <= m_length); - m_rangesToSkip.pop_front(); - } - - m_begin += t; - m_length -= t; - m_currentMessageBytes += t; - m_totalBytes += t; - } - else - { - FILTER_OUTPUT_MAYBE_MODIFIABLE(2, m_begin, m_length, messageEnd, modifiable); - - m_currentMessageBytes += m_length; - m_totalBytes += m_length; - m_length = 0; - - if (messageEnd) - { - m_currentMessageBytes = 0; - m_currentSeriesMessages++; - m_totalMessages++; - messageEnd = false; - } - } - } - - FILTER_END_NO_MESSAGE_END; -} - -size_t MeterFilter::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) -{ - return PutMaybeModifiable(const_cast<byte *>(begin), length, messageEnd, blocking, false); -} - -size_t MeterFilter::PutModifiable2(byte *begin, size_t length, int messageEnd, bool blocking) -{ - return PutMaybeModifiable(begin, length, messageEnd, blocking, true); -} - -bool MeterFilter::IsolatedMessageSeriesEnd(bool blocking) -{ - m_currentMessageBytes = 0; - m_currentSeriesMessages = 0; - m_totalMessageSeries++; - return false; -} - -// ************************************************************* - -void FilterWithBufferedInput::BlockQueue::ResetQueue(size_t blockSize, size_t maxBlocks) -{ - m_buffer.New(blockSize * maxBlocks); - m_blockSize = blockSize; - m_maxBlocks = maxBlocks; - m_size = 0; - m_begin = m_buffer; -} - -byte *FilterWithBufferedInput::BlockQueue::GetBlock() -{ - if (m_size >= m_blockSize) - { - byte *ptr = m_begin; - if ((m_begin+=m_blockSize) == m_buffer.end()) - m_begin = m_buffer; - m_size -= m_blockSize; - return ptr; - } - else - return NULL; -} - -byte *FilterWithBufferedInput::BlockQueue::GetContigousBlocks(size_t &numberOfBytes) -{ - numberOfBytes = STDMIN(numberOfBytes, STDMIN(size_t(m_buffer.end()-m_begin), m_size)); - byte *ptr = m_begin; - m_begin += numberOfBytes; - m_size -= numberOfBytes; - if (m_size == 0 || m_begin == m_buffer.end()) - m_begin = m_buffer; - return ptr; -} - -size_t FilterWithBufferedInput::BlockQueue::GetAll(byte *outString) -{ - size_t size = m_size; - size_t numberOfBytes = m_maxBlocks*m_blockSize; - const byte *ptr = GetContigousBlocks(numberOfBytes); - memcpy(outString, ptr, numberOfBytes); - memcpy(outString+numberOfBytes, m_begin, m_size); - m_size = 0; - return size; -} - -void FilterWithBufferedInput::BlockQueue::Put(const byte *inString, size_t length) -{ - assert(m_size + length <= m_buffer.size()); - byte *end = (m_size < size_t(m_buffer.end()-m_begin)) ? m_begin + m_size : m_begin + m_size - m_buffer.size(); - size_t len = STDMIN(length, size_t(m_buffer.end()-end)); - memcpy(end, inString, len); - if (len < length) - memcpy(m_buffer, inString+len, length-len); - m_size += length; -} - -FilterWithBufferedInput::FilterWithBufferedInput(BufferedTransformation *attachment) - : Filter(attachment) -{ -} - -FilterWithBufferedInput::FilterWithBufferedInput(size_t firstSize, size_t blockSize, size_t lastSize, BufferedTransformation *attachment) - : Filter(attachment), m_firstSize(firstSize), m_blockSize(blockSize), m_lastSize(lastSize) - , m_firstInputDone(false) -{ - if (m_firstSize < 0 || m_blockSize < 1 || m_lastSize < 0) - throw InvalidArgument("FilterWithBufferedInput: invalid buffer size"); - - m_queue.ResetQueue(1, m_firstSize); -} - -void FilterWithBufferedInput::IsolatedInitialize(const NameValuePairs ¶meters) -{ - InitializeDerivedAndReturnNewSizes(parameters, m_firstSize, m_blockSize, m_lastSize); - if (m_firstSize < 0 || m_blockSize < 1 || m_lastSize < 0) - throw InvalidArgument("FilterWithBufferedInput: invalid buffer size"); - m_queue.ResetQueue(1, m_firstSize); - m_firstInputDone = false; -} - -bool FilterWithBufferedInput::IsolatedFlush(bool hardFlush, bool blocking) -{ - if (!blocking) - throw BlockingInputOnly("FilterWithBufferedInput"); - - if (hardFlush) - ForceNextPut(); - FlushDerived(); - - return false; -} - -size_t FilterWithBufferedInput::PutMaybeModifiable(byte *inString, size_t length, int messageEnd, bool blocking, bool modifiable) -{ - if (!blocking) - throw BlockingInputOnly("FilterWithBufferedInput"); - - if (length != 0) - { - size_t newLength = m_queue.CurrentSize() + length; - - if (!m_firstInputDone && newLength >= m_firstSize) - { - size_t len = m_firstSize - m_queue.CurrentSize(); - m_queue.Put(inString, len); - FirstPut(m_queue.GetContigousBlocks(m_firstSize)); - assert(m_queue.CurrentSize() == 0); - m_queue.ResetQueue(m_blockSize, (2*m_blockSize+m_lastSize-2)/m_blockSize); - - inString += len; - newLength -= m_firstSize; - m_firstInputDone = true; - } - - if (m_firstInputDone) - { - if (m_blockSize == 1) - { - while (newLength > m_lastSize && m_queue.CurrentSize() > 0) - { - size_t len = newLength - m_lastSize; - byte *ptr = m_queue.GetContigousBlocks(len); - NextPutModifiable(ptr, len); - newLength -= len; - } - - if (newLength > m_lastSize) - { - size_t len = newLength - m_lastSize; - NextPutMaybeModifiable(inString, len, modifiable); - inString += len; - newLength -= len; - } - } - else - { - while (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() >= m_blockSize) - { - NextPutModifiable(m_queue.GetBlock(), m_blockSize); - newLength -= m_blockSize; - } - - if (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() > 0) - { - assert(m_queue.CurrentSize() < m_blockSize); - size_t len = m_blockSize - m_queue.CurrentSize(); - m_queue.Put(inString, len); - inString += len; - NextPutModifiable(m_queue.GetBlock(), m_blockSize); - newLength -= m_blockSize; - } - - if (newLength >= m_blockSize + m_lastSize) - { - size_t len = RoundDownToMultipleOf(newLength - m_lastSize, m_blockSize); - NextPutMaybeModifiable(inString, len, modifiable); - inString += len; - newLength -= len; - } - } - } - - m_queue.Put(inString, newLength - m_queue.CurrentSize()); - } - - if (messageEnd) - { - if (!m_firstInputDone && m_firstSize==0) - FirstPut(NULL); - - SecByteBlock temp(m_queue.CurrentSize()); - m_queue.GetAll(temp); - LastPut(temp, temp.size()); - - m_firstInputDone = false; - m_queue.ResetQueue(1, m_firstSize); - - Output(1, NULL, 0, messageEnd, blocking); - } - return 0; -} - -void FilterWithBufferedInput::ForceNextPut() -{ - if (!m_firstInputDone) - return; - - if (m_blockSize > 1) - { - while (m_queue.CurrentSize() >= m_blockSize) - NextPutModifiable(m_queue.GetBlock(), m_blockSize); - } - else - { - size_t len; - while ((len = m_queue.CurrentSize()) > 0) - NextPutModifiable(m_queue.GetContigousBlocks(len), len); - } -} - -void FilterWithBufferedInput::NextPutMultiple(const byte *inString, size_t length) -{ - assert(m_blockSize > 1); // m_blockSize = 1 should always override this function - while (length > 0) - { - assert(length >= m_blockSize); - NextPutSingle(inString); - inString += m_blockSize; - length -= m_blockSize; - } -} - -// ************************************************************* - -void Redirector::Initialize(const NameValuePairs ¶meters, int propagation) -{ - m_target = parameters.GetValueWithDefault("RedirectionTargetPointer", (BufferedTransformation*)NULL); - m_behavior = parameters.GetIntValueWithDefault("RedirectionBehavior", PASS_EVERYTHING); - - if (m_target && GetPassSignals()) - m_target->Initialize(parameters, propagation); -} - -// ************************************************************* - -ProxyFilter::ProxyFilter(BufferedTransformation *filter, size_t firstSize, size_t lastSize, BufferedTransformation *attachment) - : FilterWithBufferedInput(firstSize, 1, lastSize, attachment), m_filter(filter) -{ - if (m_filter.get()) - m_filter->Attach(new OutputProxy(*this, false)); -} - -bool ProxyFilter::IsolatedFlush(bool hardFlush, bool blocking) -{ - return m_filter.get() ? m_filter->Flush(hardFlush, -1, blocking) : false; -} - -void ProxyFilter::SetFilter(Filter *filter) -{ - m_filter.reset(filter); - if (filter) - { - OutputProxy *proxy; - std::auto_ptr<OutputProxy> temp(proxy = new OutputProxy(*this, false)); - m_filter->TransferAllTo(*proxy); - m_filter->Attach(temp.release()); - } -} - -void ProxyFilter::NextPutMultiple(const byte *s, size_t len) -{ - if (m_filter.get()) - m_filter->Put(s, len); -} - -void ProxyFilter::NextPutModifiable(byte *s, size_t len) -{ - if (m_filter.get()) - m_filter->PutModifiable(s, len); -} - -// ************************************************************* - -void RandomNumberSink::IsolatedInitialize(const NameValuePairs ¶meters) -{ - parameters.GetRequiredParameter("RandomNumberSink", "RandomNumberGeneratorPointer", m_rng); -} - -size_t RandomNumberSink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) -{ - m_rng->IncorporateEntropy(begin, length); - return 0; -} - -size_t ArraySink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) -{ - if (m_buf+m_total != begin) - memcpy(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total))); - m_total += length; - return 0; -} - -byte * ArraySink::CreatePutSpace(size_t &size) -{ - size = SaturatingSubtract(m_size, m_total); - return m_buf + m_total; -} - -void ArraySink::IsolatedInitialize(const NameValuePairs ¶meters) -{ - ByteArrayParameter array; - if (!parameters.GetValue(Name::OutputBuffer(), array)) - throw InvalidArgument("ArraySink: missing OutputBuffer argument"); - m_buf = array.begin(); - m_size = array.size(); - m_total = 0; -} - -size_t ArrayXorSink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) -{ - xorbuf(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total))); - m_total += length; - return 0; -} - -// ************************************************************* - -StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding, bool allowAuthenticatedSymmetricCipher) - : FilterWithBufferedInput(attachment) - , m_cipher(c) -{ - assert(c.MinLastBlockSize() == 0 || c.MinLastBlockSize() > c.MandatoryBlockSize()); - - if (!allowAuthenticatedSymmetricCipher && dynamic_cast<AuthenticatedSymmetricCipher *>(&c) != 0) - throw InvalidArgument("StreamTransformationFilter: please use AuthenticatedEncryptionFilter and AuthenticatedDecryptionFilter for AuthenticatedSymmetricCipher"); - - IsolatedInitialize(MakeParameters(Name::BlockPaddingScheme(), padding)); -} - -size_t StreamTransformationFilter::LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding) -{ - if (c.MinLastBlockSize() > 0) - return c.MinLastBlockSize(); - else if (c.MandatoryBlockSize() > 1 && !c.IsForwardTransformation() && padding != NO_PADDING && padding != ZEROS_PADDING) - return c.MandatoryBlockSize(); - else - return 0; -} - -void StreamTransformationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize) -{ - BlockPaddingScheme padding = parameters.GetValueWithDefault(Name::BlockPaddingScheme(), DEFAULT_PADDING); - bool isBlockCipher = (m_cipher.MandatoryBlockSize() > 1 && m_cipher.MinLastBlockSize() == 0); - - if (padding == DEFAULT_PADDING) - m_padding = isBlockCipher ? PKCS_PADDING : NO_PADDING; - else - m_padding = padding; - - if (!isBlockCipher && (m_padding == PKCS_PADDING || m_padding == ONE_AND_ZEROS_PADDING)) - throw InvalidArgument("StreamTransformationFilter: PKCS_PADDING and ONE_AND_ZEROS_PADDING cannot be used with " + m_cipher.AlgorithmName()); - - firstSize = 0; - blockSize = m_cipher.MandatoryBlockSize(); - lastSize = LastBlockSize(m_cipher, m_padding); -} - -void StreamTransformationFilter::FirstPut(const byte *inString) -{ - m_optimalBufferSize = m_cipher.OptimalBlockSize(); - m_optimalBufferSize = (unsigned int)STDMAX(m_optimalBufferSize, RoundDownToMultipleOf(4096U, m_optimalBufferSize)); -} - -void StreamTransformationFilter::NextPutMultiple(const byte *inString, size_t length) -{ - if (!length) - return; - - size_t s = m_cipher.MandatoryBlockSize(); - - do - { - size_t len = m_optimalBufferSize; - byte *space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, s, length, len); - if (len < length) - { - if (len == m_optimalBufferSize) - len -= m_cipher.GetOptimalBlockSizeUsed(); - len = RoundDownToMultipleOf(len, s); - } - else - len = length; - m_cipher.ProcessString(space, inString, len); - AttachedTransformation()->PutModifiable(space, len); - inString += len; - length -= len; - } - while (length > 0); -} - -void StreamTransformationFilter::NextPutModifiable(byte *inString, size_t length) -{ - m_cipher.ProcessString(inString, length); - AttachedTransformation()->PutModifiable(inString, length); -} - -void StreamTransformationFilter::LastPut(const byte *inString, size_t length) -{ - byte *space = NULL; - - switch (m_padding) - { - case NO_PADDING: - case ZEROS_PADDING: - if (length > 0) - { - size_t minLastBlockSize = m_cipher.MinLastBlockSize(); - bool isForwardTransformation = m_cipher.IsForwardTransformation(); - - if (isForwardTransformation && m_padding == ZEROS_PADDING && (minLastBlockSize == 0 || length < minLastBlockSize)) - { - // do padding - size_t blockSize = STDMAX(minLastBlockSize, (size_t)m_cipher.MandatoryBlockSize()); - space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, blockSize); - memcpy(space, inString, length); - memset(space + length, 0, blockSize - length); - m_cipher.ProcessLastBlock(space, space, blockSize); - AttachedTransformation()->Put(space, blockSize); - } - else - { - if (minLastBlockSize == 0) - { - if (isForwardTransformation) - throw InvalidDataFormat("StreamTransformationFilter: plaintext length is not a multiple of block size and NO_PADDING is specified"); - else - throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size"); - } - - space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, length, m_optimalBufferSize); - m_cipher.ProcessLastBlock(space, inString, length); - AttachedTransformation()->Put(space, length); - } - } - break; - - case PKCS_PADDING: - case ONE_AND_ZEROS_PADDING: - unsigned int s; - s = m_cipher.MandatoryBlockSize(); - assert(s > 1); - space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, s, m_optimalBufferSize); - if (m_cipher.IsForwardTransformation()) - { - assert(length < s); - memcpy(space, inString, length); - if (m_padding == PKCS_PADDING) - { - assert(s < 256); - byte pad = byte(s-length); - memset(space+length, pad, s-length); - } - else - { - space[length] = 0x80; - memset(space+length+1, 0, s-length-1); - } - m_cipher.ProcessData(space, space, s); - AttachedTransformation()->Put(space, s); - } - else - { - if (length != s) - throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size"); - m_cipher.ProcessData(space, inString, s); - if (m_padding == PKCS_PADDING) - { - byte pad = space[s-1]; - if (pad < 1 || pad > s || std::find_if(space+s-pad, space+s, std::bind2nd(std::not_equal_to<byte>(), pad)) != space+s) - throw InvalidCiphertext("StreamTransformationFilter: invalid PKCS #7 block padding found"); - length = s-pad; - } - else - { - while (length > 1 && space[length-1] == 0) - --length; - if (space[--length] != 0x80) - throw InvalidCiphertext("StreamTransformationFilter: invalid ones-and-zeros padding found"); - } - AttachedTransformation()->Put(space, length); - } - break; - - default: - assert(false); - } -} - -// ************************************************************* - -HashFilter::HashFilter(HashTransformation &hm, BufferedTransformation *attachment, bool putMessage, int truncatedDigestSize, const std::string &messagePutChannel, const std::string &hashPutChannel) - : m_hashModule(hm), m_putMessage(putMessage), m_messagePutChannel(messagePutChannel), m_hashPutChannel(hashPutChannel) -{ - m_digestSize = truncatedDigestSize < 0 ? m_hashModule.DigestSize() : truncatedDigestSize; - Detach(attachment); -} - -void HashFilter::IsolatedInitialize(const NameValuePairs ¶meters) -{ - m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false); - int s = parameters.GetIntValueWithDefault(Name::TruncatedDigestSize(), -1); - m_digestSize = s < 0 ? m_hashModule.DigestSize() : s; -} - -size_t HashFilter::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) -{ - FILTER_BEGIN; - if (m_putMessage) - FILTER_OUTPUT3(1, 0, inString, length, 0, m_messagePutChannel); - m_hashModule.Update(inString, length); - if (messageEnd) - { - { - size_t size; - m_space = HelpCreatePutSpace(*AttachedTransformation(), m_hashPutChannel, m_digestSize, m_digestSize, size = m_digestSize); - m_hashModule.TruncatedFinal(m_space, m_digestSize); - } - FILTER_OUTPUT3(2, 0, m_space, m_digestSize, messageEnd, m_hashPutChannel); - } - FILTER_END_NO_MESSAGE_END; -} - -// ************************************************************* - -HashVerificationFilter::HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment, word32 flags, int truncatedDigestSize) - : FilterWithBufferedInput(attachment) - , m_hashModule(hm) -{ - IsolatedInitialize(MakeParameters(Name::HashVerificationFilterFlags(), flags)(Name::TruncatedDigestSize(), truncatedDigestSize)); -} - -void HashVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize) -{ - m_flags = parameters.GetValueWithDefault(Name::HashVerificationFilterFlags(), (word32)DEFAULT_FLAGS); - int s = parameters.GetIntValueWithDefault(Name::TruncatedDigestSize(), -1); - m_digestSize = s < 0 ? m_hashModule.DigestSize() : s; - m_verified = false; - firstSize = m_flags & HASH_AT_BEGIN ? m_digestSize : 0; - blockSize = 1; - lastSize = m_flags & HASH_AT_BEGIN ? 0 : m_digestSize; -} - -void HashVerificationFilter::FirstPut(const byte *inString) -{ - if (m_flags & HASH_AT_BEGIN) - { - m_expectedHash.New(m_digestSize); - memcpy(m_expectedHash, inString, m_expectedHash.size()); - if (m_flags & PUT_HASH) - AttachedTransformation()->Put(inString, m_expectedHash.size()); - } -} - -void HashVerificationFilter::NextPutMultiple(const byte *inString, size_t length) -{ - m_hashModule.Update(inString, length); - if (m_flags & PUT_MESSAGE) - AttachedTransformation()->Put(inString, length); -} - -void HashVerificationFilter::LastPut(const byte *inString, size_t length) -{ - if (m_flags & HASH_AT_BEGIN) - { - assert(length == 0); - m_verified = m_hashModule.TruncatedVerify(m_expectedHash, m_digestSize); - } - else - { - m_verified = (length==m_digestSize && m_hashModule.TruncatedVerify(inString, length)); - if (m_flags & PUT_HASH) - AttachedTransformation()->Put(inString, length); - } - - if (m_flags & PUT_RESULT) - AttachedTransformation()->Put(m_verified); - - if ((m_flags & THROW_EXCEPTION) && !m_verified) - throw HashVerificationFailed(); -} - -// ************************************************************* - -AuthenticatedEncryptionFilter::AuthenticatedEncryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment, - bool putAAD, int truncatedDigestSize, const std::string &macChannel, BlockPaddingScheme padding) - : StreamTransformationFilter(c, attachment, padding, true) - , m_hf(c, new OutputProxy(*this, false), putAAD, truncatedDigestSize, AAD_CHANNEL, macChannel) -{ - assert(c.IsForwardTransformation()); -} - -void AuthenticatedEncryptionFilter::IsolatedInitialize(const NameValuePairs ¶meters) -{ - m_hf.IsolatedInitialize(parameters); - StreamTransformationFilter::IsolatedInitialize(parameters); -} - -byte * AuthenticatedEncryptionFilter::ChannelCreatePutSpace(const std::string &channel, size_t &size) -{ - if (channel.empty()) - return StreamTransformationFilter::CreatePutSpace(size); - - if (channel == AAD_CHANNEL) - return m_hf.CreatePutSpace(size); - - throw InvalidChannelName("AuthenticatedEncryptionFilter", channel); -} - -size_t AuthenticatedEncryptionFilter::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) -{ - if (channel.empty()) - return StreamTransformationFilter::Put2(begin, length, messageEnd, blocking); - - if (channel == AAD_CHANNEL) - return m_hf.Put2(begin, length, 0, blocking); - - throw InvalidChannelName("AuthenticatedEncryptionFilter", channel); -} - -void AuthenticatedEncryptionFilter::LastPut(const byte *inString, size_t length) -{ - StreamTransformationFilter::LastPut(inString, length); - m_hf.MessageEnd(); -} - -// ************************************************************* - -AuthenticatedDecryptionFilter::AuthenticatedDecryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment, word32 flags, int truncatedDigestSize, BlockPaddingScheme padding) - : FilterWithBufferedInput(attachment) - , m_hashVerifier(c, new OutputProxy(*this, false)) - , m_streamFilter(c, new OutputProxy(*this, false), padding, true) -{ - assert(!c.IsForwardTransformation() || c.IsSelfInverting()); - IsolatedInitialize(MakeParameters(Name::BlockPaddingScheme(), padding)(Name::AuthenticatedDecryptionFilterFlags(), flags)(Name::TruncatedDigestSize(), truncatedDigestSize)); -} - -void AuthenticatedDecryptionFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize) -{ - word32 flags = parameters.GetValueWithDefault(Name::AuthenticatedDecryptionFilterFlags(), (word32)DEFAULT_FLAGS); - - m_hashVerifier.Initialize(CombinedNameValuePairs(parameters, MakeParameters(Name::HashVerificationFilterFlags(), flags))); - m_streamFilter.Initialize(parameters); - - firstSize = m_hashVerifier.m_firstSize; - blockSize = 1; - lastSize = m_hashVerifier.m_lastSize; -} - -byte * AuthenticatedDecryptionFilter::ChannelCreatePutSpace(const std::string &channel, size_t &size) -{ - if (channel.empty()) - return m_streamFilter.CreatePutSpace(size); - - if (channel == AAD_CHANNEL) - return m_hashVerifier.CreatePutSpace(size); - - throw InvalidChannelName("AuthenticatedDecryptionFilter", channel); -} - -size_t AuthenticatedDecryptionFilter::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) -{ - if (channel.empty()) - { - if (m_lastSize > 0) - m_hashVerifier.ForceNextPut(); - return FilterWithBufferedInput::Put2(begin, length, messageEnd, blocking); - } - - if (channel == AAD_CHANNEL) - return m_hashVerifier.Put2(begin, length, 0, blocking); - - throw InvalidChannelName("AuthenticatedDecryptionFilter", channel); -} - -void AuthenticatedDecryptionFilter::FirstPut(const byte *inString) -{ - m_hashVerifier.Put(inString, m_firstSize); -} - -void AuthenticatedDecryptionFilter::NextPutMultiple(const byte *inString, size_t length) -{ - m_streamFilter.Put(inString, length); -} - -void AuthenticatedDecryptionFilter::LastPut(const byte *inString, size_t length) -{ - m_streamFilter.MessageEnd(); - m_hashVerifier.PutMessageEnd(inString, length); -} - -// ************************************************************* - -void SignerFilter::IsolatedInitialize(const NameValuePairs ¶meters) -{ - m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false); - m_messageAccumulator.reset(m_signer.NewSignatureAccumulator(m_rng)); -} - -size_t SignerFilter::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) -{ - FILTER_BEGIN; - m_messageAccumulator->Update(inString, length); - if (m_putMessage) - FILTER_OUTPUT(1, inString, length, 0); - if (messageEnd) - { - m_buf.New(m_signer.SignatureLength()); - m_signer.Sign(m_rng, m_messageAccumulator.release(), m_buf); - FILTER_OUTPUT(2, m_buf, m_buf.size(), messageEnd); - m_messageAccumulator.reset(m_signer.NewSignatureAccumulator(m_rng)); - } - FILTER_END_NO_MESSAGE_END; -} - -SignatureVerificationFilter::SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment, word32 flags) - : FilterWithBufferedInput(attachment) - , m_verifier(verifier) -{ - IsolatedInitialize(MakeParameters(Name::SignatureVerificationFilterFlags(), flags)); -} - -void SignatureVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize) -{ - m_flags = parameters.GetValueWithDefault(Name::SignatureVerificationFilterFlags(), (word32)DEFAULT_FLAGS); - m_messageAccumulator.reset(m_verifier.NewVerificationAccumulator()); - size_t size = m_verifier.SignatureLength(); - assert(size != 0); // TODO: handle recoverable signature scheme - m_verified = false; - firstSize = m_flags & SIGNATURE_AT_BEGIN ? size : 0; - blockSize = 1; - lastSize = m_flags & SIGNATURE_AT_BEGIN ? 0 : size; -} - -void SignatureVerificationFilter::FirstPut(const byte *inString) -{ - if (m_flags & SIGNATURE_AT_BEGIN) - { - if (m_verifier.SignatureUpfront()) - m_verifier.InputSignature(*m_messageAccumulator, inString, m_verifier.SignatureLength()); - else - { - m_signature.New(m_verifier.SignatureLength()); - memcpy(m_signature, inString, m_signature.size()); - } - - if (m_flags & PUT_SIGNATURE) - AttachedTransformation()->Put(inString, m_signature.size()); - } - else - { - assert(!m_verifier.SignatureUpfront()); - } -} - -void SignatureVerificationFilter::NextPutMultiple(const byte *inString, size_t length) -{ - m_messageAccumulator->Update(inString, length); - if (m_flags & PUT_MESSAGE) - AttachedTransformation()->Put(inString, length); -} - -void SignatureVerificationFilter::LastPut(const byte *inString, size_t length) -{ - if (m_flags & SIGNATURE_AT_BEGIN) - { - assert(length == 0); - m_verifier.InputSignature(*m_messageAccumulator, m_signature, m_signature.size()); - m_verified = m_verifier.VerifyAndRestart(*m_messageAccumulator); - } - else - { - m_verifier.InputSignature(*m_messageAccumulator, inString, length); - m_verified = m_verifier.VerifyAndRestart(*m_messageAccumulator); - if (m_flags & PUT_SIGNATURE) - AttachedTransformation()->Put(inString, length); - } - - if (m_flags & PUT_RESULT) - AttachedTransformation()->Put(m_verified); - - if ((m_flags & THROW_EXCEPTION) && !m_verified) - throw SignatureVerificationFailed(); -} - -// ************************************************************* - -size_t Source::PumpAll2(bool blocking) -{ - unsigned int messageCount = UINT_MAX; - do { - RETURN_IF_NONZERO(PumpMessages2(messageCount, blocking)); - } while(messageCount == UINT_MAX); - - return 0; -} - -bool Store::GetNextMessage() -{ - if (!m_messageEnd && !AnyRetrievable()) - { - m_messageEnd=true; - return true; - } - else - return false; -} - -unsigned int Store::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const -{ - if (m_messageEnd || count == 0) - return 0; - else - { - CopyTo(target, ULONG_MAX, channel); - if (GetAutoSignalPropagation()) - target.ChannelMessageEnd(channel, GetAutoSignalPropagation()-1); - return 1; - } -} - -void StringStore::StoreInitialize(const NameValuePairs ¶meters) -{ - ConstByteArrayParameter array; - if (!parameters.GetValue(Name::InputBuffer(), array)) - throw InvalidArgument("StringStore: missing InputBuffer argument"); - m_store = array.begin(); - m_length = array.size(); - m_count = 0; -} - -size_t StringStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) -{ - lword position = 0; - size_t blockedBytes = CopyRangeTo2(target, position, transferBytes, channel, blocking); - m_count += (size_t)position; - transferBytes = position; - return blockedBytes; -} - -size_t StringStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const -{ - size_t i = UnsignedMin(m_length, m_count+begin); - size_t len = UnsignedMin(m_length-i, end-begin); - size_t blockedBytes = target.ChannelPut2(channel, m_store+i, len, 0, blocking); - if (!blockedBytes) - begin += len; - return blockedBytes; -} - -void RandomNumberStore::StoreInitialize(const NameValuePairs ¶meters) -{ - parameters.GetRequiredParameter("RandomNumberStore", "RandomNumberGeneratorPointer", m_rng); - int length; - parameters.GetRequiredIntParameter("RandomNumberStore", "RandomNumberStoreSize", length); - m_length = length; -} - -size_t RandomNumberStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) -{ - if (!blocking) - throw NotImplemented("RandomNumberStore: nonblocking transfer is not implemented by this object"); - - transferBytes = UnsignedMin(transferBytes, m_length - m_count); - m_rng->GenerateIntoBufferedTransformation(target, channel, transferBytes); - m_count += transferBytes; - - return 0; -} - -size_t NullStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const -{ - static const byte nullBytes[128] = {0}; - while (begin < end) - { - size_t len = (size_t)STDMIN(end-begin, lword(128)); - size_t blockedBytes = target.ChannelPut2(channel, nullBytes, len, 0, blocking); - if (blockedBytes) - return blockedBytes; - begin += len; - } - return 0; -} - -size_t NullStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) -{ - lword begin = 0; - size_t blockedBytes = NullStore::CopyRangeTo2(target, begin, transferBytes, channel, blocking); - transferBytes = begin; - m_size -= begin; - return blockedBytes; -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/filters.h b/lib/cryptopp/filters.h deleted file mode 100644 index c72a4ece3..000000000 --- a/lib/cryptopp/filters.h +++ /dev/null @@ -1,810 +0,0 @@ -#ifndef CRYPTOPP_FILTERS_H -#define CRYPTOPP_FILTERS_H - -//! \file - -#include "simple.h" -#include "secblock.h" -#include "misc.h" -#include "smartptr.h" -#include "queue.h" -#include "algparam.h" -#include <deque> - -NAMESPACE_BEGIN(CryptoPP) - -/// provides an implementation of BufferedTransformation's attachment interface -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Filter : public BufferedTransformation, public NotCopyable -{ -public: - Filter(BufferedTransformation *attachment = NULL); - - bool Attachable() {return true;} - BufferedTransformation *AttachedTransformation(); - const BufferedTransformation *AttachedTransformation() const; - void Detach(BufferedTransformation *newAttachment = NULL); - - size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); - size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; - - void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1); - bool Flush(bool hardFlush, int propagation=-1, bool blocking=true); - bool MessageSeriesEnd(int propagation=-1, bool blocking=true); - -protected: - virtual BufferedTransformation * NewDefaultAttachment() const; - void Insert(Filter *nextFilter); // insert filter after this one - - virtual bool ShouldPropagateMessageEnd() const {return true;} - virtual bool ShouldPropagateMessageSeriesEnd() const {return true;} - - void PropagateInitialize(const NameValuePairs ¶meters, int propagation); - - size_t Output(int outputSite, const byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel=DEFAULT_CHANNEL); - size_t OutputModifiable(int outputSite, byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel=DEFAULT_CHANNEL); - bool OutputMessageEnd(int outputSite, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL); - bool OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL); - bool OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL); - -private: - member_ptr<BufferedTransformation> m_attachment; - -protected: - size_t m_inputPosition; - int m_continueAt; -}; - -struct CRYPTOPP_DLL FilterPutSpaceHelper -{ - // desiredSize is how much to ask target, bufferSize is how much to allocate in m_tempSpace - byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, size_t minSize, size_t desiredSize, size_t &bufferSize) - { - assert(desiredSize >= minSize && bufferSize >= minSize); - if (m_tempSpace.size() < minSize) - { - byte *result = target.ChannelCreatePutSpace(channel, desiredSize); - if (desiredSize >= minSize) - { - bufferSize = desiredSize; - return result; - } - m_tempSpace.New(bufferSize); - } - - bufferSize = m_tempSpace.size(); - return m_tempSpace.begin(); - } - byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, size_t minSize) - {return HelpCreatePutSpace(target, channel, minSize, minSize, minSize);} - byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, size_t minSize, size_t bufferSize) - {return HelpCreatePutSpace(target, channel, minSize, minSize, bufferSize);} - SecByteBlock m_tempSpace; -}; - -//! measure how many byte and messages pass through, also serves as valve -class CRYPTOPP_DLL MeterFilter : public Bufferless<Filter> -{ -public: - MeterFilter(BufferedTransformation *attachment=NULL, bool transparent=true) - : m_transparent(transparent) {Detach(attachment); ResetMeter();} - - void SetTransparent(bool transparent) {m_transparent = transparent;} - void AddRangeToSkip(unsigned int message, lword position, lword size, bool sortNow = true); - void ResetMeter(); - void IsolatedInitialize(const NameValuePairs ¶meters) {ResetMeter();} - - lword GetCurrentMessageBytes() const {return m_currentMessageBytes;} - lword GetTotalBytes() {return m_totalBytes;} - unsigned int GetCurrentSeriesMessages() {return m_currentSeriesMessages;} - unsigned int GetTotalMessages() {return m_totalMessages;} - unsigned int GetTotalMessageSeries() {return m_totalMessageSeries;} - - byte * CreatePutSpace(size_t &size) - {return AttachedTransformation()->CreatePutSpace(size);} - size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); - size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking); - bool IsolatedMessageSeriesEnd(bool blocking); - -private: - size_t PutMaybeModifiable(byte *inString, size_t length, int messageEnd, bool blocking, bool modifiable); - bool ShouldPropagateMessageEnd() const {return m_transparent;} - bool ShouldPropagateMessageSeriesEnd() const {return m_transparent;} - - struct MessageRange - { - inline bool operator<(const MessageRange &b) const // BCB2006 workaround: this has to be a member function - {return message < b.message || (message == b.message && position < b.position);} - unsigned int message; lword position; lword size; - }; - - bool m_transparent; - lword m_currentMessageBytes, m_totalBytes; - unsigned int m_currentSeriesMessages, m_totalMessages, m_totalMessageSeries; - std::deque<MessageRange> m_rangesToSkip; - byte *m_begin; - size_t m_length; -}; - -//! _ -class CRYPTOPP_DLL TransparentFilter : public MeterFilter -{ -public: - TransparentFilter(BufferedTransformation *attachment=NULL) : MeterFilter(attachment, true) {} -}; - -//! _ -class CRYPTOPP_DLL OpaqueFilter : public MeterFilter -{ -public: - OpaqueFilter(BufferedTransformation *attachment=NULL) : MeterFilter(attachment, false) {} -}; - -/*! FilterWithBufferedInput divides up the input stream into - a first block, a number of middle blocks, and a last block. - First and last blocks are optional, and middle blocks may - be a stream instead (i.e. blockSize == 1). -*/ -class CRYPTOPP_DLL FilterWithBufferedInput : public Filter -{ -public: - FilterWithBufferedInput(BufferedTransformation *attachment); - //! firstSize and lastSize may be 0, blockSize must be at least 1 - FilterWithBufferedInput(size_t firstSize, size_t blockSize, size_t lastSize, BufferedTransformation *attachment); - - void IsolatedInitialize(const NameValuePairs ¶meters); - size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) - { - return PutMaybeModifiable(const_cast<byte *>(inString), length, messageEnd, blocking, false); - } - size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking) - { - return PutMaybeModifiable(inString, length, messageEnd, blocking, true); - } - /*! calls ForceNextPut() if hardFlush is true */ - bool IsolatedFlush(bool hardFlush, bool blocking); - - /*! The input buffer may contain more than blockSize bytes if lastSize != 0. - ForceNextPut() forces a call to NextPut() if this is the case. - */ - void ForceNextPut(); - -protected: - bool DidFirstPut() {return m_firstInputDone;} - - virtual void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize) - {InitializeDerived(parameters);} - virtual void InitializeDerived(const NameValuePairs ¶meters) {} - // FirstPut() is called if (firstSize != 0 and totalLength >= firstSize) - // or (firstSize == 0 and (totalLength > 0 or a MessageEnd() is received)) - virtual void FirstPut(const byte *inString) =0; - // NextPut() is called if totalLength >= firstSize+blockSize+lastSize - virtual void NextPutSingle(const byte *inString) {assert(false);} - // Same as NextPut() except length can be a multiple of blockSize - // Either NextPut() or NextPutMultiple() must be overriden - virtual void NextPutMultiple(const byte *inString, size_t length); - // Same as NextPutMultiple(), but inString can be modified - virtual void NextPutModifiable(byte *inString, size_t length) - {NextPutMultiple(inString, length);} - // LastPut() is always called - // if totalLength < firstSize then length == totalLength - // else if totalLength <= firstSize+lastSize then length == totalLength-firstSize - // else lastSize <= length < lastSize+blockSize - virtual void LastPut(const byte *inString, size_t length) =0; - virtual void FlushDerived() {} - -protected: - size_t PutMaybeModifiable(byte *begin, size_t length, int messageEnd, bool blocking, bool modifiable); - void NextPutMaybeModifiable(byte *inString, size_t length, bool modifiable) - { - if (modifiable) NextPutModifiable(inString, length); - else NextPutMultiple(inString, length); - } - - // This function should no longer be used, put this here to cause a compiler error - // if someone tries to override NextPut(). - virtual int NextPut(const byte *inString, size_t length) {assert(false); return 0;} - - class BlockQueue - { - public: - void ResetQueue(size_t blockSize, size_t maxBlocks); - byte *GetBlock(); - byte *GetContigousBlocks(size_t &numberOfBytes); - size_t GetAll(byte *outString); - void Put(const byte *inString, size_t length); - size_t CurrentSize() const {return m_size;} - size_t MaxSize() const {return m_buffer.size();} - - private: - SecByteBlock m_buffer; - size_t m_blockSize, m_maxBlocks, m_size; - byte *m_begin; - }; - - size_t m_firstSize, m_blockSize, m_lastSize; - bool m_firstInputDone; - BlockQueue m_queue; -}; - -//! _ -class CRYPTOPP_DLL FilterWithInputQueue : public Filter -{ -public: - FilterWithInputQueue(BufferedTransformation *attachment=NULL) : Filter(attachment) {} - - size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) - { - if (!blocking) - throw BlockingInputOnly("FilterWithInputQueue"); - - m_inQueue.Put(inString, length); - if (messageEnd) - { - IsolatedMessageEnd(blocking); - Output(0, NULL, 0, messageEnd, blocking); - } - return 0; - } - -protected: - virtual bool IsolatedMessageEnd(bool blocking) =0; - void IsolatedInitialize(const NameValuePairs ¶meters) {m_inQueue.Clear();} - - ByteQueue m_inQueue; -}; - -struct BlockPaddingSchemeDef -{ - enum BlockPaddingScheme {NO_PADDING, ZEROS_PADDING, PKCS_PADDING, ONE_AND_ZEROS_PADDING, DEFAULT_PADDING}; -}; - -//! Filter Wrapper for StreamTransformation, optionally handling padding/unpadding when needed -class CRYPTOPP_DLL StreamTransformationFilter : public FilterWithBufferedInput, public BlockPaddingSchemeDef, private FilterPutSpaceHelper -{ -public: - /*! DEFAULT_PADDING means PKCS_PADDING if c.MandatoryBlockSize() > 1 && c.MinLastBlockSize() == 0 (e.g. ECB or CBC mode), - otherwise NO_PADDING (OFB, CFB, CTR, CBC-CTS modes). - See http://www.weidai.com/scan-mirror/csp.html for details of the padding schemes. */ - StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment = NULL, BlockPaddingScheme padding = DEFAULT_PADDING, bool allowAuthenticatedSymmetricCipher = false); - - std::string AlgorithmName() const {return m_cipher.AlgorithmName();} - -protected: - void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize); - void FirstPut(const byte *inString); - void NextPutMultiple(const byte *inString, size_t length); - void NextPutModifiable(byte *inString, size_t length); - void LastPut(const byte *inString, size_t length); - - static size_t LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding); - - StreamTransformation &m_cipher; - BlockPaddingScheme m_padding; - unsigned int m_optimalBufferSize; -}; - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY -typedef StreamTransformationFilter StreamCipherFilter; -#endif - -//! Filter Wrapper for HashTransformation -class CRYPTOPP_DLL HashFilter : public Bufferless<Filter>, private FilterPutSpaceHelper -{ -public: - HashFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, bool putMessage=false, int truncatedDigestSize=-1, const std::string &messagePutChannel=DEFAULT_CHANNEL, const std::string &hashPutChannel=DEFAULT_CHANNEL); - - std::string AlgorithmName() const {return m_hashModule.AlgorithmName();} - void IsolatedInitialize(const NameValuePairs ¶meters); - size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); - byte * CreatePutSpace(size_t &size) {return m_hashModule.CreateUpdateSpace(size);} - -private: - HashTransformation &m_hashModule; - bool m_putMessage; - unsigned int m_digestSize; - byte *m_space; - std::string m_messagePutChannel, m_hashPutChannel; -}; - -//! Filter Wrapper for HashTransformation -class CRYPTOPP_DLL HashVerificationFilter : public FilterWithBufferedInput -{ -public: - class HashVerificationFailed : public Exception - { - public: - HashVerificationFailed() - : Exception(DATA_INTEGRITY_CHECK_FAILED, "HashVerificationFilter: message hash or MAC not valid") {} - }; - - enum Flags {HASH_AT_END=0, HASH_AT_BEGIN=1, PUT_MESSAGE=2, PUT_HASH=4, PUT_RESULT=8, THROW_EXCEPTION=16, DEFAULT_FLAGS = HASH_AT_BEGIN | PUT_RESULT}; - HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, word32 flags = DEFAULT_FLAGS, int truncatedDigestSize=-1); - - std::string AlgorithmName() const {return m_hashModule.AlgorithmName();} - bool GetLastResult() const {return m_verified;} - -protected: - void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize); - void FirstPut(const byte *inString); - void NextPutMultiple(const byte *inString, size_t length); - void LastPut(const byte *inString, size_t length); - -private: - friend class AuthenticatedDecryptionFilter; - - HashTransformation &m_hashModule; - word32 m_flags; - unsigned int m_digestSize; - bool m_verified; - SecByteBlock m_expectedHash; -}; - -typedef HashVerificationFilter HashVerifier; // for backwards compatibility - -//! Filter wrapper for encrypting with AuthenticatedSymmetricCipher, optionally handling padding/unpadding when needed -/*! Additional authenticated data should be given in channel "AAD". If putAAD is true, AAD will be Put() to the attached BufferedTransformation in channel "AAD". */ -class CRYPTOPP_DLL AuthenticatedEncryptionFilter : public StreamTransformationFilter -{ -public: - /*! See StreamTransformationFilter for documentation on BlockPaddingScheme */ - AuthenticatedEncryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment = NULL, bool putAAD=false, int truncatedDigestSize=-1, const std::string &macChannel=DEFAULT_CHANNEL, BlockPaddingScheme padding = DEFAULT_PADDING); - - void IsolatedInitialize(const NameValuePairs ¶meters); - byte * ChannelCreatePutSpace(const std::string &channel, size_t &size); - size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking); - void LastPut(const byte *inString, size_t length); - -protected: - HashFilter m_hf; -}; - -//! Filter wrapper for decrypting with AuthenticatedSymmetricCipher, optionally handling padding/unpadding when needed -/*! Additional authenticated data should be given in channel "AAD". */ -class CRYPTOPP_DLL AuthenticatedDecryptionFilter : public FilterWithBufferedInput, public BlockPaddingSchemeDef -{ -public: - enum Flags {MAC_AT_END=0, MAC_AT_BEGIN=1, THROW_EXCEPTION=16, DEFAULT_FLAGS = THROW_EXCEPTION}; - - /*! See StreamTransformationFilter for documentation on BlockPaddingScheme */ - AuthenticatedDecryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment = NULL, word32 flags = DEFAULT_FLAGS, int truncatedDigestSize=-1, BlockPaddingScheme padding = DEFAULT_PADDING); - - std::string AlgorithmName() const {return m_hashVerifier.AlgorithmName();} - byte * ChannelCreatePutSpace(const std::string &channel, size_t &size); - size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking); - bool GetLastResult() const {return m_hashVerifier.GetLastResult();} - -protected: - void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize); - void FirstPut(const byte *inString); - void NextPutMultiple(const byte *inString, size_t length); - void LastPut(const byte *inString, size_t length); - - HashVerificationFilter m_hashVerifier; - StreamTransformationFilter m_streamFilter; -}; - -//! Filter Wrapper for PK_Signer -class CRYPTOPP_DLL SignerFilter : public Unflushable<Filter> -{ -public: - SignerFilter(RandomNumberGenerator &rng, const PK_Signer &signer, BufferedTransformation *attachment = NULL, bool putMessage=false) - : m_rng(rng), m_signer(signer), m_messageAccumulator(signer.NewSignatureAccumulator(rng)), m_putMessage(putMessage) {Detach(attachment);} - - std::string AlgorithmName() const {return m_signer.AlgorithmName();} - - void IsolatedInitialize(const NameValuePairs ¶meters); - size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); - -private: - RandomNumberGenerator &m_rng; - const PK_Signer &m_signer; - member_ptr<PK_MessageAccumulator> m_messageAccumulator; - bool m_putMessage; - SecByteBlock m_buf; -}; - -//! Filter Wrapper for PK_Verifier -class CRYPTOPP_DLL SignatureVerificationFilter : public FilterWithBufferedInput -{ -public: - class SignatureVerificationFailed : public Exception - { - public: - SignatureVerificationFailed() - : Exception(DATA_INTEGRITY_CHECK_FAILED, "VerifierFilter: digital signature not valid") {} - }; - - enum Flags {SIGNATURE_AT_END=0, SIGNATURE_AT_BEGIN=1, PUT_MESSAGE=2, PUT_SIGNATURE=4, PUT_RESULT=8, THROW_EXCEPTION=16, DEFAULT_FLAGS = SIGNATURE_AT_BEGIN | PUT_RESULT}; - SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment = NULL, word32 flags = DEFAULT_FLAGS); - - std::string AlgorithmName() const {return m_verifier.AlgorithmName();} - - bool GetLastResult() const {return m_verified;} - -protected: - void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize); - void FirstPut(const byte *inString); - void NextPutMultiple(const byte *inString, size_t length); - void LastPut(const byte *inString, size_t length); - -private: - const PK_Verifier &m_verifier; - member_ptr<PK_MessageAccumulator> m_messageAccumulator; - word32 m_flags; - SecByteBlock m_signature; - bool m_verified; -}; - -typedef SignatureVerificationFilter VerifierFilter; // for backwards compatibility - -//! Redirect input to another BufferedTransformation without owning it -class CRYPTOPP_DLL Redirector : public CustomSignalPropagation<Sink> -{ -public: - enum Behavior - { - DATA_ONLY = 0x00, - PASS_SIGNALS = 0x01, - PASS_WAIT_OBJECTS = 0x02, - PASS_EVERYTHING = PASS_SIGNALS | PASS_WAIT_OBJECTS - }; - - Redirector() : m_target(NULL), m_behavior(PASS_EVERYTHING) {} - Redirector(BufferedTransformation &target, Behavior behavior=PASS_EVERYTHING) - : m_target(&target), m_behavior(behavior) {} - - void Redirect(BufferedTransformation &target) {m_target = ⌖} - void StopRedirection() {m_target = NULL;} - - Behavior GetBehavior() {return (Behavior) m_behavior;} - void SetBehavior(Behavior behavior) {m_behavior=behavior;} - bool GetPassSignals() const {return (m_behavior & PASS_SIGNALS) != 0;} - void SetPassSignals(bool pass) { if (pass) m_behavior |= PASS_SIGNALS; else m_behavior &= ~(word32) PASS_SIGNALS; } - bool GetPassWaitObjects() const {return (m_behavior & PASS_WAIT_OBJECTS) != 0;} - void SetPassWaitObjects(bool pass) { if (pass) m_behavior |= PASS_WAIT_OBJECTS; else m_behavior &= ~(word32) PASS_WAIT_OBJECTS; } - - bool CanModifyInput() const - {return m_target ? m_target->CanModifyInput() : false;} - - void Initialize(const NameValuePairs ¶meters, int propagation); - byte * CreatePutSpace(size_t &size) - {return m_target ? m_target->CreatePutSpace(size) : (byte *)(size=0, NULL);} - size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) - {return m_target ? m_target->Put2(begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;} - bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) - {return m_target && GetPassSignals() ? m_target->Flush(hardFlush, propagation, blocking) : false;} - bool MessageSeriesEnd(int propagation=-1, bool blocking=true) - {return m_target && GetPassSignals() ? m_target->MessageSeriesEnd(propagation, blocking) : false;} - - byte * ChannelCreatePutSpace(const std::string &channel, size_t &size) - {return m_target ? m_target->ChannelCreatePutSpace(channel, size) : (byte *)(size=0, NULL);} - size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) - {return m_target ? m_target->ChannelPut2(channel, begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;} - size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking) - {return m_target ? m_target->ChannelPutModifiable2(channel, begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;} - bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true) - {return m_target && GetPassSignals() ? m_target->ChannelFlush(channel, completeFlush, propagation, blocking) : false;} - bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true) - {return m_target && GetPassSignals() ? m_target->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;} - - unsigned int GetMaxWaitObjectCount() const - { return m_target && GetPassWaitObjects() ? m_target->GetMaxWaitObjectCount() : 0; } - void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) - { if (m_target && GetPassWaitObjects()) m_target->GetWaitObjects(container, callStack); } - -private: - BufferedTransformation *m_target; - word32 m_behavior; -}; - -// Used By ProxyFilter -class CRYPTOPP_DLL OutputProxy : public CustomSignalPropagation<Sink> -{ -public: - OutputProxy(BufferedTransformation &owner, bool passSignal) : m_owner(owner), m_passSignal(passSignal) {} - - bool GetPassSignal() const {return m_passSignal;} - void SetPassSignal(bool passSignal) {m_passSignal = passSignal;} - - byte * CreatePutSpace(size_t &size) - {return m_owner.AttachedTransformation()->CreatePutSpace(size);} - size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) - {return m_owner.AttachedTransformation()->Put2(begin, length, m_passSignal ? messageEnd : 0, blocking);} - size_t PutModifiable2(byte *begin, size_t length, int messageEnd, bool blocking) - {return m_owner.AttachedTransformation()->PutModifiable2(begin, length, m_passSignal ? messageEnd : 0, blocking);} - void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1) - {if (m_passSignal) m_owner.AttachedTransformation()->Initialize(parameters, propagation);} - bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) - {return m_passSignal ? m_owner.AttachedTransformation()->Flush(hardFlush, propagation, blocking) : false;} - bool MessageSeriesEnd(int propagation=-1, bool blocking=true) - {return m_passSignal ? m_owner.AttachedTransformation()->MessageSeriesEnd(propagation, blocking) : false;} - - byte * ChannelCreatePutSpace(const std::string &channel, size_t &size) - {return m_owner.AttachedTransformation()->ChannelCreatePutSpace(channel, size);} - size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) - {return m_owner.AttachedTransformation()->ChannelPut2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);} - size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking) - {return m_owner.AttachedTransformation()->ChannelPutModifiable2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);} - bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true) - {return m_passSignal ? m_owner.AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation, blocking) : false;} - bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true) - {return m_passSignal ? m_owner.AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;} - -private: - BufferedTransformation &m_owner; - bool m_passSignal; -}; - -//! Base class for Filter classes that are proxies for a chain of other filters. -class CRYPTOPP_DLL ProxyFilter : public FilterWithBufferedInput -{ -public: - ProxyFilter(BufferedTransformation *filter, size_t firstSize, size_t lastSize, BufferedTransformation *attachment); - - bool IsolatedFlush(bool hardFlush, bool blocking); - - void SetFilter(Filter *filter); - void NextPutMultiple(const byte *s, size_t len); - void NextPutModifiable(byte *inString, size_t length); - -protected: - member_ptr<BufferedTransformation> m_filter; -}; - -//! simple proxy filter that doesn't modify the underlying filter's input or output -class CRYPTOPP_DLL SimpleProxyFilter : public ProxyFilter -{ -public: - SimpleProxyFilter(BufferedTransformation *filter, BufferedTransformation *attachment) - : ProxyFilter(filter, 0, 0, attachment) {} - - void FirstPut(const byte *) {} - void LastPut(const byte *, size_t) {m_filter->MessageEnd();} -}; - -//! proxy for the filter created by PK_Encryptor::CreateEncryptionFilter -/*! This class is here just to provide symmetry with VerifierFilter. */ -class CRYPTOPP_DLL PK_EncryptorFilter : public SimpleProxyFilter -{ -public: - PK_EncryptorFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment = NULL) - : SimpleProxyFilter(encryptor.CreateEncryptionFilter(rng), attachment) {} -}; - -//! proxy for the filter created by PK_Decryptor::CreateDecryptionFilter -/*! This class is here just to provide symmetry with SignerFilter. */ -class CRYPTOPP_DLL PK_DecryptorFilter : public SimpleProxyFilter -{ -public: - PK_DecryptorFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment = NULL) - : SimpleProxyFilter(decryptor.CreateDecryptionFilter(rng), attachment) {} -}; - -//! Append input to a string object -template <class T> -class StringSinkTemplate : public Bufferless<Sink> -{ -public: - // VC60 workaround: no T::char_type - typedef typename T::traits_type::char_type char_type; - - StringSinkTemplate(T &output) - : m_output(&output) {assert(sizeof(output[0])==1);} - - void IsolatedInitialize(const NameValuePairs ¶meters) - {if (!parameters.GetValue("OutputStringPointer", m_output)) throw InvalidArgument("StringSink: OutputStringPointer not specified");} - - size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) - { - if (length > 0) - { - typename T::size_type size = m_output->size(); - if (length < size && size + length > m_output->capacity()) - m_output->reserve(2*size); - m_output->append((const char_type *)begin, (const char_type *)begin+length); - } - return 0; - } - -private: - T *m_output; -}; - -//! Append input to an std::string -CRYPTOPP_DLL_TEMPLATE_CLASS StringSinkTemplate<std::string>; -typedef StringSinkTemplate<std::string> StringSink; - -//! incorporates input into RNG as additional entropy -class RandomNumberSink : public Bufferless<Sink> -{ -public: - RandomNumberSink() - : m_rng(NULL) {} - - RandomNumberSink(RandomNumberGenerator &rng) - : m_rng(&rng) {} - - void IsolatedInitialize(const NameValuePairs ¶meters); - size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); - -private: - RandomNumberGenerator *m_rng; -}; - -//! Copy input to a memory buffer -class CRYPTOPP_DLL ArraySink : public Bufferless<Sink> -{ -public: - ArraySink(const NameValuePairs ¶meters = g_nullNameValuePairs) {IsolatedInitialize(parameters);} - ArraySink(byte *buf, size_t size) : m_buf(buf), m_size(size), m_total(0) {} - - size_t AvailableSize() {return SaturatingSubtract(m_size, m_total);} - lword TotalPutLength() {return m_total;} - - void IsolatedInitialize(const NameValuePairs ¶meters); - byte * CreatePutSpace(size_t &size); - size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); - -protected: - byte *m_buf; - size_t m_size; - lword m_total; -}; - -//! Xor input to a memory buffer -class CRYPTOPP_DLL ArrayXorSink : public ArraySink -{ -public: - ArrayXorSink(byte *buf, size_t size) - : ArraySink(buf, size) {} - - size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); - byte * CreatePutSpace(size_t &size) {return BufferedTransformation::CreatePutSpace(size);} -}; - -//! string-based implementation of Store interface -class StringStore : public Store -{ -public: - StringStore(const char *string = NULL) - {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));} - StringStore(const byte *string, size_t length) - {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));} - template <class T> StringStore(const T &string) - {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));} - - CRYPTOPP_DLL size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); - CRYPTOPP_DLL size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; - -private: - CRYPTOPP_DLL void StoreInitialize(const NameValuePairs ¶meters); - - const byte *m_store; - size_t m_length, m_count; -}; - -//! RNG-based implementation of Source interface -class CRYPTOPP_DLL RandomNumberStore : public Store -{ -public: - RandomNumberStore() - : m_rng(NULL), m_length(0), m_count(0) {} - - RandomNumberStore(RandomNumberGenerator &rng, lword length) - : m_rng(&rng), m_length(length), m_count(0) {} - - bool AnyRetrievable() const {return MaxRetrievable() != 0;} - lword MaxRetrievable() const {return m_length-m_count;} - - size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); - size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const - { - throw NotImplemented("RandomNumberStore: CopyRangeTo2() is not supported by this store"); - } - -private: - void StoreInitialize(const NameValuePairs ¶meters); - - RandomNumberGenerator *m_rng; - lword m_length, m_count; -}; - -//! empty store -class CRYPTOPP_DLL NullStore : public Store -{ -public: - NullStore(lword size = ULONG_MAX) : m_size(size) {} - void StoreInitialize(const NameValuePairs ¶meters) {} - lword MaxRetrievable() const {return m_size;} - size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); - size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; - -private: - lword m_size; -}; - -//! A Filter that pumps data into its attachment as input -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Source : public InputRejecting<Filter> -{ -public: - Source(BufferedTransformation *attachment = NULL) - {Source::Detach(attachment);} - - lword Pump(lword pumpMax=size_t(0)-1) - {Pump2(pumpMax); return pumpMax;} - unsigned int PumpMessages(unsigned int count=UINT_MAX) - {PumpMessages2(count); return count;} - void PumpAll() - {PumpAll2();} - virtual size_t Pump2(lword &byteCount, bool blocking=true) =0; - virtual size_t PumpMessages2(unsigned int &messageCount, bool blocking=true) =0; - virtual size_t PumpAll2(bool blocking=true); - virtual bool SourceExhausted() const =0; - -protected: - void SourceInitialize(bool pumpAll, const NameValuePairs ¶meters) - { - IsolatedInitialize(parameters); - if (pumpAll) - PumpAll(); - } -}; - -//! Turn a Store into a Source -template <class T> -class SourceTemplate : public Source -{ -public: - SourceTemplate<T>(BufferedTransformation *attachment) - : Source(attachment) {} - void IsolatedInitialize(const NameValuePairs ¶meters) - {m_store.IsolatedInitialize(parameters);} - size_t Pump2(lword &byteCount, bool blocking=true) - {return m_store.TransferTo2(*AttachedTransformation(), byteCount, DEFAULT_CHANNEL, blocking);} - size_t PumpMessages2(unsigned int &messageCount, bool blocking=true) - {return m_store.TransferMessagesTo2(*AttachedTransformation(), messageCount, DEFAULT_CHANNEL, blocking);} - size_t PumpAll2(bool blocking=true) - {return m_store.TransferAllTo2(*AttachedTransformation(), DEFAULT_CHANNEL, blocking);} - bool SourceExhausted() const - {return !m_store.AnyRetrievable() && !m_store.AnyMessages();} - void SetAutoSignalPropagation(int propagation) - {m_store.SetAutoSignalPropagation(propagation);} - int GetAutoSignalPropagation() const - {return m_store.GetAutoSignalPropagation();} - -protected: - T m_store; -}; - -//! string-based implementation of Source interface -class CRYPTOPP_DLL StringSource : public SourceTemplate<StringStore> -{ -public: - StringSource(BufferedTransformation *attachment = NULL) - : SourceTemplate<StringStore>(attachment) {} - //! zero terminated string as source - StringSource(const char *string, bool pumpAll, BufferedTransformation *attachment = NULL) - : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));} - //! binary byte array as source - StringSource(const byte *string, size_t length, bool pumpAll, BufferedTransformation *attachment = NULL) - : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));} - //! std::string as source - StringSource(const std::string &string, bool pumpAll, BufferedTransformation *attachment = NULL) - : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));} -}; - -//! use the third constructor for an array source -typedef StringSource ArraySource; - -//! RNG-based implementation of Source interface -class CRYPTOPP_DLL RandomNumberSource : public SourceTemplate<RandomNumberStore> -{ -public: - RandomNumberSource(RandomNumberGenerator &rng, int length, bool pumpAll, BufferedTransformation *attachment = NULL) - : SourceTemplate<RandomNumberStore>(attachment) - {SourceInitialize(pumpAll, MakeParameters("RandomNumberGeneratorPointer", &rng)("RandomNumberStoreSize", length));} -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/fips140.cpp b/lib/cryptopp/fips140.cpp deleted file mode 100644 index 1fcf59014..000000000 --- a/lib/cryptopp/fips140.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// fips140.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "fips140.h" -#include "trdlocal.h" // needs to be included last for cygwin - -NAMESPACE_BEGIN(CryptoPP) - -// Define this to 1 to turn on FIPS 140-2 compliance features, including additional tests during -// startup, random number generation, and key generation. These tests may affect performance. -#ifndef CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 -#define CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 0 -#endif - -#if (CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 && !defined(THREADS_AVAILABLE)) -#error FIPS 140-2 compliance requires the availability of thread local storage. -#endif - -#if (CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 && !defined(OS_RNG_AVAILABLE)) -#error FIPS 140-2 compliance requires the availability of OS provided RNG. -#endif - -PowerUpSelfTestStatus g_powerUpSelfTestStatus = POWER_UP_SELF_TEST_NOT_DONE; - -bool FIPS_140_2_ComplianceEnabled() -{ - return CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2; -} - -void SimulatePowerUpSelfTestFailure() -{ - g_powerUpSelfTestStatus = POWER_UP_SELF_TEST_FAILED; -} - -PowerUpSelfTestStatus CRYPTOPP_API GetPowerUpSelfTestStatus() -{ - return g_powerUpSelfTestStatus; -} - -#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 -ThreadLocalStorage & AccessPowerUpSelfTestInProgress() -{ - static ThreadLocalStorage selfTestInProgress; - return selfTestInProgress; -} -#endif - -bool PowerUpSelfTestInProgressOnThisThread() -{ -#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 - return AccessPowerUpSelfTestInProgress().GetValue() != NULL; -#else - assert(false); // should not be called - return false; -#endif -} - -void SetPowerUpSelfTestInProgressOnThisThread(bool inProgress) -{ -#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 - AccessPowerUpSelfTestInProgress().SetValue((void *)inProgress); -#endif -} - -void EncryptionPairwiseConsistencyTest_FIPS_140_Only(const PK_Encryptor &encryptor, const PK_Decryptor &decryptor) -{ -#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 - EncryptionPairwiseConsistencyTest(encryptor, decryptor); -#endif -} - -void SignaturePairwiseConsistencyTest_FIPS_140_Only(const PK_Signer &signer, const PK_Verifier &verifier) -{ -#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 - SignaturePairwiseConsistencyTest(signer, verifier); -#endif -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/fips140.h b/lib/cryptopp/fips140.h deleted file mode 100644 index a3e538613..000000000 --- a/lib/cryptopp/fips140.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef CRYPTOPP_FIPS140_H -#define CRYPTOPP_FIPS140_H - -/*! \file - FIPS 140 related functions and classes. -*/ - -#include "cryptlib.h" -#include "secblock.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! exception thrown when a crypto algorithm is used after a self test fails -class CRYPTOPP_DLL SelfTestFailure : public Exception -{ -public: - explicit SelfTestFailure(const std::string &s) : Exception(OTHER_ERROR, s) {} -}; - -//! returns whether FIPS 140-2 compliance features were enabled at compile time -CRYPTOPP_DLL bool CRYPTOPP_API FIPS_140_2_ComplianceEnabled(); - -//! enum values representing status of the power-up self test -enum PowerUpSelfTestStatus {POWER_UP_SELF_TEST_NOT_DONE, POWER_UP_SELF_TEST_FAILED, POWER_UP_SELF_TEST_PASSED}; - -//! perform the power-up self test, and set the self test status -CRYPTOPP_DLL void CRYPTOPP_API DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleMac); - -//! perform the power-up self test using the filename of this DLL and the embedded module MAC -CRYPTOPP_DLL void CRYPTOPP_API DoDllPowerUpSelfTest(); - -//! set the power-up self test status to POWER_UP_SELF_TEST_FAILED -CRYPTOPP_DLL void CRYPTOPP_API SimulatePowerUpSelfTestFailure(); - -//! return the current power-up self test status -CRYPTOPP_DLL PowerUpSelfTestStatus CRYPTOPP_API GetPowerUpSelfTestStatus(); - -typedef PowerUpSelfTestStatus (CRYPTOPP_API * PGetPowerUpSelfTestStatus)(); - -CRYPTOPP_DLL MessageAuthenticationCode * CRYPTOPP_API NewIntegrityCheckingMAC(); - -CRYPTOPP_DLL bool CRYPTOPP_API IntegrityCheckModule(const char *moduleFilename, const byte *expectedModuleMac, SecByteBlock *pActualMac = NULL, unsigned long *pMacFileLocation = NULL); - -// this is used by Algorithm constructor to allow Algorithm objects to be constructed for the self test -bool PowerUpSelfTestInProgressOnThisThread(); - -void SetPowerUpSelfTestInProgressOnThisThread(bool inProgress); - -void SignaturePairwiseConsistencyTest(const PK_Signer &signer, const PK_Verifier &verifier); -void EncryptionPairwiseConsistencyTest(const PK_Encryptor &encryptor, const PK_Decryptor &decryptor); - -void SignaturePairwiseConsistencyTest_FIPS_140_Only(const PK_Signer &signer, const PK_Verifier &verifier); -void EncryptionPairwiseConsistencyTest_FIPS_140_Only(const PK_Encryptor &encryptor, const PK_Decryptor &decryptor); - -#define CRYPTOPP_DUMMY_DLL_MAC "MAC_51f34b8db820ae8" - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/fltrimpl.h b/lib/cryptopp/fltrimpl.h deleted file mode 100644 index 4087d7d9f..000000000 --- a/lib/cryptopp/fltrimpl.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef CRYPTOPP_FLTRIMPL_H -#define CRYPTOPP_FLTRIMPL_H - -#define FILTER_BEGIN \ - switch (m_continueAt) \ - { \ - case 0: \ - m_inputPosition = 0; - -#define FILTER_END_NO_MESSAGE_END_NO_RETURN \ - break; \ - default: \ - assert(false); \ - } - -#define FILTER_END_NO_MESSAGE_END \ - FILTER_END_NO_MESSAGE_END_NO_RETURN \ - return 0; - -/* -#define FILTER_END \ - case -1: \ - if (messageEnd && Output(-1, NULL, 0, messageEnd, blocking)) \ - return 1; \ - FILTER_END_NO_MESSAGE_END -*/ - -#define FILTER_OUTPUT3(site, statement, output, length, messageEnd, channel) \ - {\ - case site: \ - statement; \ - if (Output(site, output, length, messageEnd, blocking, channel)) \ - return STDMAX(size_t(1), length-m_inputPosition);\ - } - -#define FILTER_OUTPUT2(site, statement, output, length, messageEnd) \ - FILTER_OUTPUT3(site, statement, output, length, messageEnd, DEFAULT_CHANNEL) - -#define FILTER_OUTPUT(site, output, length, messageEnd) \ - FILTER_OUTPUT2(site, 0, output, length, messageEnd) - -#define FILTER_OUTPUT_BYTE(site, output) \ - FILTER_OUTPUT(site, &(const byte &)(byte)output, 1, 0) - -#define FILTER_OUTPUT2_MODIFIABLE(site, statement, output, length, messageEnd) \ - {\ - case site: \ - statement; \ - if (OutputModifiable(site, output, length, messageEnd, blocking)) \ - return STDMAX(size_t(1), length-m_inputPosition);\ - } - -#define FILTER_OUTPUT_MODIFIABLE(site, output, length, messageEnd) \ - FILTER_OUTPUT2_MODIFIABLE(site, 0, output, length, messageEnd) - -#define FILTER_OUTPUT2_MAYBE_MODIFIABLE(site, statement, output, length, messageEnd, modifiable) \ - {\ - case site: \ - statement; \ - if (modifiable ? OutputModifiable(site, output, length, messageEnd, blocking) : Output(site, output, length, messageEnd, blocking)) \ - return STDMAX(size_t(1), length-m_inputPosition);\ - } - -#define FILTER_OUTPUT_MAYBE_MODIFIABLE(site, output, length, messageEnd, modifiable) \ - FILTER_OUTPUT2_MAYBE_MODIFIABLE(site, 0, output, length, messageEnd, modifiable) - -#endif diff --git a/lib/cryptopp/gcm.cpp b/lib/cryptopp/gcm.cpp deleted file mode 100644 index 2304f96d8..000000000 --- a/lib/cryptopp/gcm.cpp +++ /dev/null @@ -1,828 +0,0 @@ -// gcm.cpp - written and placed in the public domain by Wei Dai - -// use "cl /EP /P /DCRYPTOPP_GENERATE_X64_MASM gcm.cpp" to generate MASM code - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS -#ifndef CRYPTOPP_GENERATE_X64_MASM - -#include "gcm.h" -#include "cpu.h" - -NAMESPACE_BEGIN(CryptoPP) - -word16 GCM_Base::s_reductionTable[256]; -volatile bool GCM_Base::s_reductionTableInitialized = false; - -void GCM_Base::GCTR::IncrementCounterBy256() -{ - IncrementCounterByOne(m_counterArray+BlockSize()-4, 3); -} - -#if 0 -// preserved for testing -void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c) -{ - word64 Z0=0, Z1=0, V0, V1; - - typedef BlockGetAndPut<word64, BigEndian> Block; - Block::Get(a)(V0)(V1); - - for (int i=0; i<16; i++) - { - for (int j=0x80; j!=0; j>>=1) - { - int x = b[i] & j; - Z0 ^= x ? V0 : 0; - Z1 ^= x ? V1 : 0; - x = (int)V1 & 1; - V1 = (V1>>1) | (V0<<63); - V0 = (V0>>1) ^ (x ? W64LIT(0xe1) << 56 : 0); - } - } - Block::Put(NULL, c)(Z0)(Z1); -} - -__m128i _mm_clmulepi64_si128(const __m128i &a, const __m128i &b, int i) -{ - word64 A[1] = {ByteReverse(((word64*)&a)[i&1])}; - word64 B[1] = {ByteReverse(((word64*)&b)[i>>4])}; - - PolynomialMod2 pa((byte *)A, 8); - PolynomialMod2 pb((byte *)B, 8); - PolynomialMod2 c = pa*pb; - - __m128i output; - for (int i=0; i<16; i++) - ((byte *)&output)[i] = c.GetByte(i); - return output; -} -#endif - -#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE -inline static void SSE2_Xor16(byte *a, const byte *b, const byte *c) -{ -#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE - *(__m128i *)a = _mm_xor_si128(*(__m128i *)b, *(__m128i *)c); -#else - asm ("movdqa %1, %%xmm0; pxor %2, %%xmm0; movdqa %%xmm0, %0;" : "=m" (a[0]) : "m"(b[0]), "m"(c[0])); -#endif -} -#endif - -inline static void Xor16(byte *a, const byte *b, const byte *c) -{ - ((word64 *)a)[0] = ((word64 *)b)[0] ^ ((word64 *)c)[0]; - ((word64 *)a)[1] = ((word64 *)b)[1] ^ ((word64 *)c)[1]; -} - -#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE -static CRYPTOPP_ALIGN_DATA(16) const word64 s_clmulConstants64[] = { - W64LIT(0xe100000000000000), W64LIT(0xc200000000000000), - W64LIT(0x08090a0b0c0d0e0f), W64LIT(0x0001020304050607), - W64LIT(0x0001020304050607), W64LIT(0x08090a0b0c0d0e0f)}; -static const __m128i *s_clmulConstants = (const __m128i *)s_clmulConstants64; -static const unsigned int s_clmulTableSizeInBlocks = 8; - -inline __m128i CLMUL_Reduce(__m128i c0, __m128i c1, __m128i c2, const __m128i &r) -{ - /* - The polynomial to be reduced is c0 * x^128 + c1 * x^64 + c2. c0t below refers to the most - significant half of c0 as a polynomial, which, due to GCM's bit reflection, are in the - rightmost bit positions, and the lowest byte addresses. - - c1 ^= c0t * 0xc200000000000000 - c2t ^= c0t - t = shift (c1t ^ c0b) left 1 bit - c2 ^= t * 0xe100000000000000 - c2t ^= c1b - shift c2 left 1 bit and xor in lowest bit of c1t - */ -#if 0 // MSVC 2010 workaround: see http://connect.microsoft.com/VisualStudio/feedback/details/575301 - c2 = _mm_xor_si128(c2, _mm_move_epi64(c0)); -#else - c1 = _mm_xor_si128(c1, _mm_slli_si128(c0, 8)); -#endif - c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(c0, r, 0x10)); - c0 = _mm_srli_si128(c0, 8); - c0 = _mm_xor_si128(c0, c1); - c0 = _mm_slli_epi64(c0, 1); - c0 = _mm_clmulepi64_si128(c0, r, 0); - c2 = _mm_xor_si128(c2, c0); - c2 = _mm_xor_si128(c2, _mm_srli_si128(c1, 8)); - c1 = _mm_unpacklo_epi64(c1, c2); - c1 = _mm_srli_epi64(c1, 63); - c2 = _mm_slli_epi64(c2, 1); - return _mm_xor_si128(c2, c1); -} - -inline __m128i CLMUL_GF_Mul(const __m128i &x, const __m128i &h, const __m128i &r) -{ - __m128i c0 = _mm_clmulepi64_si128(x,h,0); - __m128i c1 = _mm_xor_si128(_mm_clmulepi64_si128(x,h,1), _mm_clmulepi64_si128(x,h,0x10)); - __m128i c2 = _mm_clmulepi64_si128(x,h,0x11); - - return CLMUL_Reduce(c0, c1, c2, r); -} -#endif - -void GCM_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms) -{ - BlockCipher &blockCipher = AccessBlockCipher(); - blockCipher.SetKey(userKey, keylength, params); - - if (blockCipher.BlockSize() != REQUIRED_BLOCKSIZE) - throw InvalidArgument(AlgorithmName() + ": block size of underlying block cipher is not 16"); - - int tableSize, i, j, k; - -#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE - if (HasCLMUL()) - { - params.GetIntValue(Name::TableSize(), tableSize); // avoid "parameter not used" error - tableSize = s_clmulTableSizeInBlocks * REQUIRED_BLOCKSIZE; - } - else -#endif - { - if (params.GetIntValue(Name::TableSize(), tableSize)) - tableSize = (tableSize >= 64*1024) ? 64*1024 : 2*1024; - else - tableSize = (GetTablesOption() == GCM_64K_Tables) ? 64*1024 : 2*1024; - -#if defined(_MSC_VER) && (_MSC_VER >= 1300 && _MSC_VER < 1400) - // VC 2003 workaround: compiler generates bad code for 64K tables - tableSize = 2*1024; -#endif - } - - m_buffer.resize(3*REQUIRED_BLOCKSIZE + tableSize); - byte *table = MulTable(); - byte *hashKey = HashKey(); - memset(hashKey, 0, REQUIRED_BLOCKSIZE); - blockCipher.ProcessBlock(hashKey); - -#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE - if (HasCLMUL()) - { - const __m128i r = s_clmulConstants[0]; - __m128i h0 = _mm_shuffle_epi8(_mm_load_si128((__m128i *)hashKey), s_clmulConstants[1]); - __m128i h = h0; - - for (i=0; i<tableSize; i+=32) - { - __m128i h1 = CLMUL_GF_Mul(h, h0, r); - _mm_storel_epi64((__m128i *)(table+i), h); - _mm_storeu_si128((__m128i *)(table+i+16), h1); - _mm_storeu_si128((__m128i *)(table+i+8), h); - _mm_storel_epi64((__m128i *)(table+i+8), h1); - h = CLMUL_GF_Mul(h1, h0, r); - } - - return; - } -#endif - - word64 V0, V1; - typedef BlockGetAndPut<word64, BigEndian> Block; - Block::Get(hashKey)(V0)(V1); - - if (tableSize == 64*1024) - { - for (i=0; i<128; i++) - { - k = i%8; - Block::Put(NULL, table+(i/8)*256*16+(size_t(1)<<(11-k)))(V0)(V1); - - int x = (int)V1 & 1; - V1 = (V1>>1) | (V0<<63); - V0 = (V0>>1) ^ (x ? W64LIT(0xe1) << 56 : 0); - } - - for (i=0; i<16; i++) - { - memset(table+i*256*16, 0, 16); -#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - if (HasSSE2()) - for (j=2; j<=0x80; j*=2) - for (k=1; k<j; k++) - SSE2_Xor16(table+i*256*16+(j+k)*16, table+i*256*16+j*16, table+i*256*16+k*16); - else -#endif - for (j=2; j<=0x80; j*=2) - for (k=1; k<j; k++) - Xor16(table+i*256*16+(j+k)*16, table+i*256*16+j*16, table+i*256*16+k*16); - } - } - else - { - if (!s_reductionTableInitialized) - { - s_reductionTable[0] = 0; - word16 x = 0x01c2; - s_reductionTable[1] = ByteReverse(x); - for (int i=2; i<=0x80; i*=2) - { - x <<= 1; - s_reductionTable[i] = ByteReverse(x); - for (int j=1; j<i; j++) - s_reductionTable[i+j] = s_reductionTable[i] ^ s_reductionTable[j]; - } - s_reductionTableInitialized = true; - } - - for (i=0; i<128-24; i++) - { - k = i%32; - if (k < 4) - Block::Put(NULL, table+1024+(i/32)*256+(size_t(1)<<(7-k)))(V0)(V1); - else if (k < 8) - Block::Put(NULL, table+(i/32)*256+(size_t(1)<<(11-k)))(V0)(V1); - - int x = (int)V1 & 1; - V1 = (V1>>1) | (V0<<63); - V0 = (V0>>1) ^ (x ? W64LIT(0xe1) << 56 : 0); - } - - for (i=0; i<4; i++) - { - memset(table+i*256, 0, 16); - memset(table+1024+i*256, 0, 16); -#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - if (HasSSE2()) - for (j=2; j<=8; j*=2) - for (k=1; k<j; k++) - { - SSE2_Xor16(table+i*256+(j+k)*16, table+i*256+j*16, table+i*256+k*16); - SSE2_Xor16(table+1024+i*256+(j+k)*16, table+1024+i*256+j*16, table+1024+i*256+k*16); - } - else -#endif - for (j=2; j<=8; j*=2) - for (k=1; k<j; k++) - { - Xor16(table+i*256+(j+k)*16, table+i*256+j*16, table+i*256+k*16); - Xor16(table+1024+i*256+(j+k)*16, table+1024+i*256+j*16, table+1024+i*256+k*16); - } - } - } -} - -inline void GCM_Base::ReverseHashBufferIfNeeded() -{ -#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE - if (HasCLMUL()) - { - __m128i &x = *(__m128i *)HashBuffer(); - x = _mm_shuffle_epi8(x, s_clmulConstants[1]); - } -#endif -} - -void GCM_Base::Resync(const byte *iv, size_t len) -{ - BlockCipher &cipher = AccessBlockCipher(); - byte *hashBuffer = HashBuffer(); - - if (len == 12) - { - memcpy(hashBuffer, iv, len); - memset(hashBuffer+len, 0, 3); - hashBuffer[len+3] = 1; - } - else - { - size_t origLen = len; - memset(hashBuffer, 0, HASH_BLOCKSIZE); - - if (len >= HASH_BLOCKSIZE) - { - len = GCM_Base::AuthenticateBlocks(iv, len); - iv += (origLen - len); - } - - if (len > 0) - { - memcpy(m_buffer, iv, len); - memset(m_buffer+len, 0, HASH_BLOCKSIZE-len); - GCM_Base::AuthenticateBlocks(m_buffer, HASH_BLOCKSIZE); - } - - PutBlock<word64, BigEndian, true>(NULL, m_buffer)(0)(origLen*8); - GCM_Base::AuthenticateBlocks(m_buffer, HASH_BLOCKSIZE); - - ReverseHashBufferIfNeeded(); - } - - if (m_state >= State_IVSet) - m_ctr.Resynchronize(hashBuffer, REQUIRED_BLOCKSIZE); - else - m_ctr.SetCipherWithIV(cipher, hashBuffer); - - m_ctr.Seek(HASH_BLOCKSIZE); - - memset(hashBuffer, 0, HASH_BLOCKSIZE); -} - -unsigned int GCM_Base::OptimalDataAlignment() const -{ - return -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) - HasSSE2() ? 16 : -#endif - GetBlockCipher().OptimalDataAlignment(); -} - -#pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code - -#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM - -#ifdef CRYPTOPP_X64_MASM_AVAILABLE -extern "C" { -void GCM_AuthenticateBlocks_2K(const byte *data, size_t blocks, word64 *hashBuffer, const word16 *reductionTable); -void GCM_AuthenticateBlocks_64K(const byte *data, size_t blocks, word64 *hashBuffer); -} -#endif - -#ifndef CRYPTOPP_GENERATE_X64_MASM - -size_t GCM_Base::AuthenticateBlocks(const byte *data, size_t len) -{ -#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE - if (HasCLMUL()) - { - const __m128i *table = (const __m128i *)MulTable(); - __m128i x = _mm_load_si128((__m128i *)HashBuffer()); - const __m128i r = s_clmulConstants[0], bswapMask = s_clmulConstants[1], bswapMask2 = s_clmulConstants[2]; - - while (len >= 16) - { - size_t s = UnsignedMin(len/16, s_clmulTableSizeInBlocks), i=0; - __m128i d, d2 = _mm_shuffle_epi8(_mm_loadu_si128((const __m128i *)(data+(s-1)*16)), bswapMask2);; - __m128i c0 = _mm_setzero_si128(); - __m128i c1 = _mm_setzero_si128(); - __m128i c2 = _mm_setzero_si128(); - - while (true) - { - __m128i h0 = _mm_load_si128(table+i); - __m128i h1 = _mm_load_si128(table+i+1); - __m128i h01 = _mm_xor_si128(h0, h1); - - if (++i == s) - { - d = _mm_shuffle_epi8(_mm_loadu_si128((const __m128i *)data), bswapMask); - d = _mm_xor_si128(d, x); - c0 = _mm_xor_si128(c0, _mm_clmulepi64_si128(d, h0, 0)); - c2 = _mm_xor_si128(c2, _mm_clmulepi64_si128(d, h1, 1)); - d = _mm_xor_si128(d, _mm_shuffle_epi32(d, _MM_SHUFFLE(1, 0, 3, 2))); - c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(d, h01, 0)); - break; - } - - d = _mm_shuffle_epi8(_mm_loadu_si128((const __m128i *)(data+(s-i)*16-8)), bswapMask2); - c0 = _mm_xor_si128(c0, _mm_clmulepi64_si128(d2, h0, 1)); - c2 = _mm_xor_si128(c2, _mm_clmulepi64_si128(d, h1, 1)); - d2 = _mm_xor_si128(d2, d); - c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(d2, h01, 1)); - - if (++i == s) - { - d = _mm_shuffle_epi8(_mm_loadu_si128((const __m128i *)data), bswapMask); - d = _mm_xor_si128(d, x); - c0 = _mm_xor_si128(c0, _mm_clmulepi64_si128(d, h0, 0x10)); - c2 = _mm_xor_si128(c2, _mm_clmulepi64_si128(d, h1, 0x11)); - d = _mm_xor_si128(d, _mm_shuffle_epi32(d, _MM_SHUFFLE(1, 0, 3, 2))); - c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(d, h01, 0x10)); - break; - } - - d2 = _mm_shuffle_epi8(_mm_loadu_si128((const __m128i *)(data+(s-i)*16-8)), bswapMask); - c0 = _mm_xor_si128(c0, _mm_clmulepi64_si128(d, h0, 0x10)); - c2 = _mm_xor_si128(c2, _mm_clmulepi64_si128(d2, h1, 0x10)); - d = _mm_xor_si128(d, d2); - c1 = _mm_xor_si128(c1, _mm_clmulepi64_si128(d, h01, 0x10)); - } - data += s*16; - len -= s*16; - - c1 = _mm_xor_si128(_mm_xor_si128(c1, c0), c2); - x = CLMUL_Reduce(c0, c1, c2, r); - } - - _mm_store_si128((__m128i *)HashBuffer(), x); - return len; - } -#endif - - typedef BlockGetAndPut<word64, NativeByteOrder> Block; - word64 *hashBuffer = (word64 *)HashBuffer(); - - switch (2*(m_buffer.size()>=64*1024) -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) - + HasSSE2() -#endif - ) - { - case 0: // non-SSE2 and 2K tables - { - byte *table = MulTable(); - word64 x0 = hashBuffer[0], x1 = hashBuffer[1]; - - do - { - word64 y0, y1, a0, a1, b0, b1, c0, c1, d0, d1; - Block::Get(data)(y0)(y1); - x0 ^= y0; - x1 ^= y1; - - data += HASH_BLOCKSIZE; - len -= HASH_BLOCKSIZE; - - #define READ_TABLE_WORD64_COMMON(a, b, c, d) *(word64 *)(table+(a*1024)+(b*256)+c+d*8) - - #ifdef IS_LITTLE_ENDIAN - #if CRYPTOPP_BOOL_SLOW_WORD64 - word32 z0 = (word32)x0; - word32 z1 = (word32)(x0>>32); - word32 z2 = (word32)x1; - word32 z3 = (word32)(x1>>32); - #define READ_TABLE_WORD64(a, b, c, d, e) READ_TABLE_WORD64_COMMON((d%2), c, (d?(z##c>>((d?d-1:0)*4))&0xf0:(z##c&0xf)<<4), e) - #else - #define READ_TABLE_WORD64(a, b, c, d, e) READ_TABLE_WORD64_COMMON((d%2), c, ((d+8*b)?(x##a>>(((d+8*b)?(d+8*b)-1:1)*4))&0xf0:(x##a&0xf)<<4), e) - #endif - #define GF_MOST_SIG_8BITS(a) (a##1 >> 7*8) - #define GF_SHIFT_8(a) a##1 = (a##1 << 8) ^ (a##0 >> 7*8); a##0 <<= 8; - #else - #define READ_TABLE_WORD64(a, b, c, d, e) READ_TABLE_WORD64_COMMON((1-d%2), c, ((15-d-8*b)?(x##a>>(((15-d-8*b)?(15-d-8*b)-1:0)*4))&0xf0:(x##a&0xf)<<4), e) - #define GF_MOST_SIG_8BITS(a) (a##1 & 0xff) - #define GF_SHIFT_8(a) a##1 = (a##1 >> 8) ^ (a##0 << 7*8); a##0 >>= 8; - #endif - - #define GF_MUL_32BY128(op, a, b, c) \ - a0 op READ_TABLE_WORD64(a, b, c, 0, 0) ^ READ_TABLE_WORD64(a, b, c, 1, 0);\ - a1 op READ_TABLE_WORD64(a, b, c, 0, 1) ^ READ_TABLE_WORD64(a, b, c, 1, 1);\ - b0 op READ_TABLE_WORD64(a, b, c, 2, 0) ^ READ_TABLE_WORD64(a, b, c, 3, 0);\ - b1 op READ_TABLE_WORD64(a, b, c, 2, 1) ^ READ_TABLE_WORD64(a, b, c, 3, 1);\ - c0 op READ_TABLE_WORD64(a, b, c, 4, 0) ^ READ_TABLE_WORD64(a, b, c, 5, 0);\ - c1 op READ_TABLE_WORD64(a, b, c, 4, 1) ^ READ_TABLE_WORD64(a, b, c, 5, 1);\ - d0 op READ_TABLE_WORD64(a, b, c, 6, 0) ^ READ_TABLE_WORD64(a, b, c, 7, 0);\ - d1 op READ_TABLE_WORD64(a, b, c, 6, 1) ^ READ_TABLE_WORD64(a, b, c, 7, 1);\ - - GF_MUL_32BY128(=, 0, 0, 0) - GF_MUL_32BY128(^=, 0, 1, 1) - GF_MUL_32BY128(^=, 1, 0, 2) - GF_MUL_32BY128(^=, 1, 1, 3) - - word32 r = (word32)s_reductionTable[GF_MOST_SIG_8BITS(d)] << 16; - GF_SHIFT_8(d) - c0 ^= d0; c1 ^= d1; - r ^= (word32)s_reductionTable[GF_MOST_SIG_8BITS(c)] << 8; - GF_SHIFT_8(c) - b0 ^= c0; b1 ^= c1; - r ^= s_reductionTable[GF_MOST_SIG_8BITS(b)]; - GF_SHIFT_8(b) - a0 ^= b0; a1 ^= b1; - a0 ^= ConditionalByteReverse<word64>(LITTLE_ENDIAN_ORDER, r); - x0 = a0; x1 = a1; - } - while (len >= HASH_BLOCKSIZE); - - hashBuffer[0] = x0; hashBuffer[1] = x1; - return len; - } - - case 2: // non-SSE2 and 64K tables - { - byte *table = MulTable(); - word64 x0 = hashBuffer[0], x1 = hashBuffer[1]; - - do - { - word64 y0, y1, a0, a1; - Block::Get(data)(y0)(y1); - x0 ^= y0; - x1 ^= y1; - - data += HASH_BLOCKSIZE; - len -= HASH_BLOCKSIZE; - - #undef READ_TABLE_WORD64_COMMON - #undef READ_TABLE_WORD64 - - #define READ_TABLE_WORD64_COMMON(a, c, d) *(word64 *)(table+(a)*256*16+(c)+(d)*8) - - #ifdef IS_LITTLE_ENDIAN - #if CRYPTOPP_BOOL_SLOW_WORD64 - word32 z0 = (word32)x0; - word32 z1 = (word32)(x0>>32); - word32 z2 = (word32)x1; - word32 z3 = (word32)(x1>>32); - #define READ_TABLE_WORD64(b, c, d, e) READ_TABLE_WORD64_COMMON(c*4+d, (d?(z##c>>((d?d:1)*8-4))&0xff0:(z##c&0xff)<<4), e) - #else - #define READ_TABLE_WORD64(b, c, d, e) READ_TABLE_WORD64_COMMON(c*4+d, ((d+4*(c%2))?(x##b>>(((d+4*(c%2))?(d+4*(c%2)):1)*8-4))&0xff0:(x##b&0xff)<<4), e) - #endif - #else - #define READ_TABLE_WORD64(b, c, d, e) READ_TABLE_WORD64_COMMON(c*4+d, ((7-d-4*(c%2))?(x##b>>(((7-d-4*(c%2))?(7-d-4*(c%2)):1)*8-4))&0xff0:(x##b&0xff)<<4), e) - #endif - - #define GF_MUL_8BY128(op, b, c, d) \ - a0 op READ_TABLE_WORD64(b, c, d, 0);\ - a1 op READ_TABLE_WORD64(b, c, d, 1);\ - - GF_MUL_8BY128(=, 0, 0, 0) - GF_MUL_8BY128(^=, 0, 0, 1) - GF_MUL_8BY128(^=, 0, 0, 2) - GF_MUL_8BY128(^=, 0, 0, 3) - GF_MUL_8BY128(^=, 0, 1, 0) - GF_MUL_8BY128(^=, 0, 1, 1) - GF_MUL_8BY128(^=, 0, 1, 2) - GF_MUL_8BY128(^=, 0, 1, 3) - GF_MUL_8BY128(^=, 1, 2, 0) - GF_MUL_8BY128(^=, 1, 2, 1) - GF_MUL_8BY128(^=, 1, 2, 2) - GF_MUL_8BY128(^=, 1, 2, 3) - GF_MUL_8BY128(^=, 1, 3, 0) - GF_MUL_8BY128(^=, 1, 3, 1) - GF_MUL_8BY128(^=, 1, 3, 2) - GF_MUL_8BY128(^=, 1, 3, 3) - - x0 = a0; x1 = a1; - } - while (len >= HASH_BLOCKSIZE); - - hashBuffer[0] = x0; hashBuffer[1] = x1; - return len; - } -#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM - -#ifdef CRYPTOPP_X64_MASM_AVAILABLE - case 1: // SSE2 and 2K tables - GCM_AuthenticateBlocks_2K(data, len/16, hashBuffer, s_reductionTable); - return len % 16; - case 3: // SSE2 and 64K tables - GCM_AuthenticateBlocks_64K(data, len/16, hashBuffer); - return len % 16; -#endif - -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - case 1: // SSE2 and 2K tables - { - #ifdef __GNUC__ - __asm__ __volatile__ - ( - ".intel_syntax noprefix;" - #elif defined(CRYPTOPP_GENERATE_X64_MASM) - ALIGN 8 - GCM_AuthenticateBlocks_2K PROC FRAME - rex_push_reg rsi - push_reg rdi - push_reg rbx - .endprolog - mov rsi, r8 - mov r11, r9 - #else - AS2( mov WORD_REG(cx), data ) - AS2( mov WORD_REG(dx), len ) - AS2( mov WORD_REG(si), hashBuffer ) - AS2( shr WORD_REG(dx), 4 ) - #endif - - AS_PUSH_IF86( bx) - AS_PUSH_IF86( bp) - - #ifdef __GNUC__ - AS2( mov AS_REG_7, WORD_REG(di)) - #elif CRYPTOPP_BOOL_X86 - AS2( lea AS_REG_7, s_reductionTable) - #endif - - AS2( movdqa xmm0, [WORD_REG(si)] ) - - #define MUL_TABLE_0 WORD_REG(si) + 32 - #define MUL_TABLE_1 WORD_REG(si) + 32 + 1024 - #define RED_TABLE AS_REG_7 - - ASL(0) - AS2( movdqu xmm4, [WORD_REG(cx)] ) - AS2( pxor xmm0, xmm4 ) - - AS2( movd ebx, xmm0 ) - AS2( mov eax, AS_HEX(f0f0f0f0) ) - AS2( and eax, ebx ) - AS2( shl ebx, 4 ) - AS2( and ebx, AS_HEX(f0f0f0f0) ) - AS2( movzx edi, ah ) - AS2( movdqa xmm5, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] ) - AS2( movzx edi, al ) - AS2( movdqa xmm4, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] ) - AS2( shr eax, 16 ) - AS2( movzx edi, ah ) - AS2( movdqa xmm3, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] ) - AS2( movzx edi, al ) - AS2( movdqa xmm2, XMMWORD_PTR [MUL_TABLE_1 + WORD_REG(di)] ) - - #define SSE2_MUL_32BITS(i) \ - AS2( psrldq xmm0, 4 )\ - AS2( movd eax, xmm0 )\ - AS2( and eax, AS_HEX(f0f0f0f0) )\ - AS2( movzx edi, bh )\ - AS2( pxor xmm5, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\ - AS2( movzx edi, bl )\ - AS2( pxor xmm4, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\ - AS2( shr ebx, 16 )\ - AS2( movzx edi, bh )\ - AS2( pxor xmm3, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\ - AS2( movzx edi, bl )\ - AS2( pxor xmm2, XMMWORD_PTR [MUL_TABLE_0 + (i-1)*256 + WORD_REG(di)] )\ - AS2( movd ebx, xmm0 )\ - AS2( shl ebx, 4 )\ - AS2( and ebx, AS_HEX(f0f0f0f0) )\ - AS2( movzx edi, ah )\ - AS2( pxor xmm5, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\ - AS2( movzx edi, al )\ - AS2( pxor xmm4, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\ - AS2( shr eax, 16 )\ - AS2( movzx edi, ah )\ - AS2( pxor xmm3, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\ - AS2( movzx edi, al )\ - AS2( pxor xmm2, XMMWORD_PTR [MUL_TABLE_1 + i*256 + WORD_REG(di)] )\ - - SSE2_MUL_32BITS(1) - SSE2_MUL_32BITS(2) - SSE2_MUL_32BITS(3) - - AS2( movzx edi, bh ) - AS2( pxor xmm5, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] ) - AS2( movzx edi, bl ) - AS2( pxor xmm4, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] ) - AS2( shr ebx, 16 ) - AS2( movzx edi, bh ) - AS2( pxor xmm3, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] ) - AS2( movzx edi, bl ) - AS2( pxor xmm2, XMMWORD_PTR [MUL_TABLE_0 + 3*256 + WORD_REG(di)] ) - - AS2( movdqa xmm0, xmm3 ) - AS2( pslldq xmm3, 1 ) - AS2( pxor xmm2, xmm3 ) - AS2( movdqa xmm1, xmm2 ) - AS2( pslldq xmm2, 1 ) - AS2( pxor xmm5, xmm2 ) - - AS2( psrldq xmm0, 15 ) - AS2( movd WORD_REG(di), xmm0 ) - AS2( movzx eax, WORD PTR [RED_TABLE + WORD_REG(di)*2] ) - AS2( shl eax, 8 ) - - AS2( movdqa xmm0, xmm5 ) - AS2( pslldq xmm5, 1 ) - AS2( pxor xmm4, xmm5 ) - - AS2( psrldq xmm1, 15 ) - AS2( movd WORD_REG(di), xmm1 ) - AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] ) - AS2( shl eax, 8 ) - - AS2( psrldq xmm0, 15 ) - AS2( movd WORD_REG(di), xmm0 ) - AS2( xor ax, WORD PTR [RED_TABLE + WORD_REG(di)*2] ) - - AS2( movd xmm0, eax ) - AS2( pxor xmm0, xmm4 ) - - AS2( add WORD_REG(cx), 16 ) - AS2( sub WORD_REG(dx), 1 ) - ASJ( jnz, 0, b ) - AS2( movdqa [WORD_REG(si)], xmm0 ) - - AS_POP_IF86( bp) - AS_POP_IF86( bx) - - #ifdef __GNUC__ - ".att_syntax prefix;" - : - : "c" (data), "d" (len/16), "S" (hashBuffer), "D" (s_reductionTable) - : "memory", "cc", "%eax" - #if CRYPTOPP_BOOL_X64 - , "%ebx", "%r11" - #endif - ); - #elif defined(CRYPTOPP_GENERATE_X64_MASM) - pop rbx - pop rdi - pop rsi - ret - GCM_AuthenticateBlocks_2K ENDP - #endif - - return len%16; - } - case 3: // SSE2 and 64K tables - { - #ifdef __GNUC__ - __asm__ __volatile__ - ( - ".intel_syntax noprefix;" - #elif defined(CRYPTOPP_GENERATE_X64_MASM) - ALIGN 8 - GCM_AuthenticateBlocks_64K PROC FRAME - rex_push_reg rsi - push_reg rdi - .endprolog - mov rsi, r8 - #else - AS2( mov WORD_REG(cx), data ) - AS2( mov WORD_REG(dx), len ) - AS2( mov WORD_REG(si), hashBuffer ) - AS2( shr WORD_REG(dx), 4 ) - #endif - - AS2( movdqa xmm0, [WORD_REG(si)] ) - - #undef MUL_TABLE - #define MUL_TABLE(i,j) WORD_REG(si) + 32 + (i*4+j)*256*16 - - ASL(1) - AS2( movdqu xmm1, [WORD_REG(cx)] ) - AS2( pxor xmm1, xmm0 ) - AS2( pxor xmm0, xmm0 ) - - #undef SSE2_MUL_32BITS - #define SSE2_MUL_32BITS(i) \ - AS2( movd eax, xmm1 )\ - AS2( psrldq xmm1, 4 )\ - AS2( movzx edi, al )\ - AS2( add WORD_REG(di), WORD_REG(di) )\ - AS2( pxor xmm0, [MUL_TABLE(i,0) + WORD_REG(di)*8] )\ - AS2( movzx edi, ah )\ - AS2( add WORD_REG(di), WORD_REG(di) )\ - AS2( pxor xmm0, [MUL_TABLE(i,1) + WORD_REG(di)*8] )\ - AS2( shr eax, 16 )\ - AS2( movzx edi, al )\ - AS2( add WORD_REG(di), WORD_REG(di) )\ - AS2( pxor xmm0, [MUL_TABLE(i,2) + WORD_REG(di)*8] )\ - AS2( movzx edi, ah )\ - AS2( add WORD_REG(di), WORD_REG(di) )\ - AS2( pxor xmm0, [MUL_TABLE(i,3) + WORD_REG(di)*8] )\ - - SSE2_MUL_32BITS(0) - SSE2_MUL_32BITS(1) - SSE2_MUL_32BITS(2) - SSE2_MUL_32BITS(3) - - AS2( add WORD_REG(cx), 16 ) - AS2( sub WORD_REG(dx), 1 ) - ASJ( jnz, 1, b ) - AS2( movdqa [WORD_REG(si)], xmm0 ) - - #ifdef __GNUC__ - ".att_syntax prefix;" - : - : "c" (data), "d" (len/16), "S" (hashBuffer) - : "memory", "cc", "%edi", "%eax" - ); - #elif defined(CRYPTOPP_GENERATE_X64_MASM) - pop rdi - pop rsi - ret - GCM_AuthenticateBlocks_64K ENDP - #endif - - return len%16; - } -#endif -#ifndef CRYPTOPP_GENERATE_X64_MASM - } - - return len%16; -} - -void GCM_Base::AuthenticateLastHeaderBlock() -{ - if (m_bufferedDataLength > 0) - { - memset(m_buffer+m_bufferedDataLength, 0, HASH_BLOCKSIZE-m_bufferedDataLength); - m_bufferedDataLength = 0; - GCM_Base::AuthenticateBlocks(m_buffer, HASH_BLOCKSIZE); - } -} - -void GCM_Base::AuthenticateLastConfidentialBlock() -{ - GCM_Base::AuthenticateLastHeaderBlock(); - PutBlock<word64, BigEndian, true>(NULL, m_buffer)(m_totalHeaderLength*8)(m_totalMessageLength*8); - GCM_Base::AuthenticateBlocks(m_buffer, HASH_BLOCKSIZE); -} - -void GCM_Base::AuthenticateLastFooterBlock(byte *mac, size_t macSize) -{ - m_ctr.Seek(0); - ReverseHashBufferIfNeeded(); - m_ctr.ProcessData(mac, HashBuffer(), macSize); -} - -NAMESPACE_END - -#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM -#endif diff --git a/lib/cryptopp/gcm.h b/lib/cryptopp/gcm.h deleted file mode 100644 index 272a51c9c..000000000 --- a/lib/cryptopp/gcm.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef CRYPTOPP_GCM_H -#define CRYPTOPP_GCM_H - -#include "authenc.h" -#include "modes.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! . -enum GCM_TablesOption {GCM_2K_Tables, GCM_64K_Tables}; - -//! . -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GCM_Base : public AuthenticatedSymmetricCipherBase -{ -public: - // AuthenticatedSymmetricCipher - std::string AlgorithmName() const - {return GetBlockCipher().AlgorithmName() + std::string("/GCM");} - size_t MinKeyLength() const - {return GetBlockCipher().MinKeyLength();} - size_t MaxKeyLength() const - {return GetBlockCipher().MaxKeyLength();} - size_t DefaultKeyLength() const - {return GetBlockCipher().DefaultKeyLength();} - size_t GetValidKeyLength(size_t n) const - {return GetBlockCipher().GetValidKeyLength(n);} - bool IsValidKeyLength(size_t n) const - {return GetBlockCipher().IsValidKeyLength(n);} - unsigned int OptimalDataAlignment() const; - IV_Requirement IVRequirement() const - {return UNIQUE_IV;} - unsigned int IVSize() const - {return 12;} - unsigned int MinIVLength() const - {return 1;} - unsigned int MaxIVLength() const - {return UINT_MAX;} // (W64LIT(1)<<61)-1 in the standard - unsigned int DigestSize() const - {return 16;} - lword MaxHeaderLength() const - {return (W64LIT(1)<<61)-1;} - lword MaxMessageLength() const - {return ((W64LIT(1)<<39)-256)/8;} - -protected: - // AuthenticatedSymmetricCipherBase - bool AuthenticationIsOnPlaintext() const - {return false;} - unsigned int AuthenticationBlockSize() const - {return HASH_BLOCKSIZE;} - void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms); - void Resync(const byte *iv, size_t len); - size_t AuthenticateBlocks(const byte *data, size_t len); - void AuthenticateLastHeaderBlock(); - void AuthenticateLastConfidentialBlock(); - void AuthenticateLastFooterBlock(byte *mac, size_t macSize); - SymmetricCipher & AccessSymmetricCipher() {return m_ctr;} - - virtual BlockCipher & AccessBlockCipher() =0; - virtual GCM_TablesOption GetTablesOption() const =0; - - const BlockCipher & GetBlockCipher() const {return const_cast<GCM_Base *>(this)->AccessBlockCipher();}; - byte *HashBuffer() {return m_buffer+REQUIRED_BLOCKSIZE;} - byte *HashKey() {return m_buffer+2*REQUIRED_BLOCKSIZE;} - byte *MulTable() {return m_buffer+3*REQUIRED_BLOCKSIZE;} - inline void ReverseHashBufferIfNeeded(); - - class CRYPTOPP_DLL GCTR : public CTR_Mode_ExternalCipher::Encryption - { - protected: - void IncrementCounterBy256(); - }; - - GCTR m_ctr; - static word16 s_reductionTable[256]; - static volatile bool s_reductionTableInitialized; - enum {REQUIRED_BLOCKSIZE = 16, HASH_BLOCKSIZE = 16}; -}; - -//! . -template <class T_BlockCipher, GCM_TablesOption T_TablesOption, bool T_IsEncryption> -class GCM_Final : public GCM_Base -{ -public: - static std::string StaticAlgorithmName() - {return T_BlockCipher::StaticAlgorithmName() + std::string("/GCM");} - bool IsForwardTransformation() const - {return T_IsEncryption;} - -private: - GCM_TablesOption GetTablesOption() const {return T_TablesOption;} - BlockCipher & AccessBlockCipher() {return m_cipher;} - typename T_BlockCipher::Encryption m_cipher; -}; - -//! <a href="http://www.cryptolounge.org/wiki/GCM">GCM</a> -template <class T_BlockCipher, GCM_TablesOption T_TablesOption=GCM_2K_Tables> -struct GCM : public AuthenticatedSymmetricCipherDocumentation -{ - typedef GCM_Final<T_BlockCipher, T_TablesOption, true> Encryption; - typedef GCM_Final<T_BlockCipher, T_TablesOption, false> Decryption; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/gf256.cpp b/lib/cryptopp/gf256.cpp deleted file mode 100644 index 72026d1e1..000000000 --- a/lib/cryptopp/gf256.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// gf256.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "gf256.h" - -NAMESPACE_BEGIN(CryptoPP) - -GF256::Element GF256::Multiply(Element a, Element b) const -{ - word result = 0, t = b; - - for (unsigned int i=0; i<8; i++) - { - result <<= 1; - if (result & 0x100) - result ^= m_modulus; - - t <<= 1; - if (t & 0x100) - result ^= a; - } - - return (GF256::Element) result; -} - -GF256::Element GF256::MultiplicativeInverse(Element a) const -{ - Element result = a; - for (int i=1; i<7; i++) - result = Multiply(Square(result), a); - return Square(result); -} - -NAMESPACE_END diff --git a/lib/cryptopp/gf256.h b/lib/cryptopp/gf256.h deleted file mode 100644 index e0ea74826..000000000 --- a/lib/cryptopp/gf256.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef CRYPTOPP_GF256_H -#define CRYPTOPP_GF256_H - -#include "cryptlib.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! GF(256) with polynomial basis -class GF256 -{ -public: - typedef byte Element; - typedef int RandomizationParameter; - - GF256(byte modulus) : m_modulus(modulus) {} - - Element RandomElement(RandomNumberGenerator &rng, int ignored = 0) const - {return rng.GenerateByte();} - - bool Equal(Element a, Element b) const - {return a==b;} - - Element Zero() const - {return 0;} - - Element Add(Element a, Element b) const - {return a^b;} - - Element& Accumulate(Element &a, Element b) const - {return a^=b;} - - Element Inverse(Element a) const - {return a;} - - Element Subtract(Element a, Element b) const - {return a^b;} - - Element& Reduce(Element &a, Element b) const - {return a^=b;} - - Element Double(Element a) const - {return 0;} - - Element One() const - {return 1;} - - Element Multiply(Element a, Element b) const; - - Element Square(Element a) const - {return Multiply(a, a);} - - bool IsUnit(Element a) const - {return a != 0;} - - Element MultiplicativeInverse(Element a) const; - - Element Divide(Element a, Element b) const - {return Multiply(a, MultiplicativeInverse(b));} - -private: - word m_modulus; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/gf2_32.cpp b/lib/cryptopp/gf2_32.cpp deleted file mode 100644 index ae4874a40..000000000 --- a/lib/cryptopp/gf2_32.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// gf2_32.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "misc.h" -#include "gf2_32.h" - -NAMESPACE_BEGIN(CryptoPP) - -GF2_32::Element GF2_32::Multiply(Element a, Element b) const -{ - word32 table[4]; - table[0] = 0; - table[1] = m_modulus; - if (a & 0x80000000) - { - table[2] = m_modulus ^ (a<<1); - table[3] = a<<1; - } - else - { - table[2] = a<<1; - table[3] = m_modulus ^ (a<<1); - } - -#if CRYPTOPP_FAST_ROTATE(32) - b = rotrFixed(b, 30U); - word32 result = table[b&2]; - - for (int i=29; i>=0; --i) - { - b = rotlFixed(b, 1U); - result = (result<<1) ^ table[(b&2) + (result>>31)]; - } - - return (b&1) ? result ^ a : result; -#else - word32 result = table[(b>>30) & 2]; - - for (int i=29; i>=0; --i) - result = (result<<1) ^ table[((b>>i)&2) + (result>>31)]; - - return (b&1) ? result ^ a : result; -#endif -} - -GF2_32::Element GF2_32::MultiplicativeInverse(Element a) const -{ - if (a <= 1) // 1 is a special case - return a; - - // warning - don't try to adapt this algorithm for another situation - word32 g0=m_modulus, g1=a, g2=a; - word32 v0=0, v1=1, v2=1; - - assert(g1); - - while (!(g2 & 0x80000000)) - { - g2 <<= 1; - v2 <<= 1; - } - - g2 <<= 1; - v2 <<= 1; - - g0 ^= g2; - v0 ^= v2; - - while (g0 != 1) - { - if (g1 < g0 || ((g0^g1) < g0 && (g0^g1) < g1)) - { - assert(BitPrecision(g1) <= BitPrecision(g0)); - g2 = g1; - v2 = v1; - } - else - { - assert(BitPrecision(g1) > BitPrecision(g0)); - g2 = g0; g0 = g1; g1 = g2; - v2 = v0; v0 = v1; v1 = v2; - } - - while ((g0^g2) >= g2) - { - assert(BitPrecision(g0) > BitPrecision(g2)); - g2 <<= 1; - v2 <<= 1; - } - - assert(BitPrecision(g0) == BitPrecision(g2)); - g0 ^= g2; - v0 ^= v2; - } - - return v0; -} - -NAMESPACE_END diff --git a/lib/cryptopp/gf2_32.h b/lib/cryptopp/gf2_32.h deleted file mode 100644 index 31713f4c0..000000000 --- a/lib/cryptopp/gf2_32.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef CRYPTOPP_GF2_32_H -#define CRYPTOPP_GF2_32_H - -#include "cryptlib.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! GF(2^32) with polynomial basis -class GF2_32 -{ -public: - typedef word32 Element; - typedef int RandomizationParameter; - - GF2_32(word32 modulus=0x0000008D) : m_modulus(modulus) {} - - Element RandomElement(RandomNumberGenerator &rng, int ignored = 0) const - {return rng.GenerateWord32();} - - bool Equal(Element a, Element b) const - {return a==b;} - - Element Identity() const - {return 0;} - - Element Add(Element a, Element b) const - {return a^b;} - - Element& Accumulate(Element &a, Element b) const - {return a^=b;} - - Element Inverse(Element a) const - {return a;} - - Element Subtract(Element a, Element b) const - {return a^b;} - - Element& Reduce(Element &a, Element b) const - {return a^=b;} - - Element Double(Element a) const - {return 0;} - - Element MultiplicativeIdentity() const - {return 1;} - - Element Multiply(Element a, Element b) const; - - Element Square(Element a) const - {return Multiply(a, a);} - - bool IsUnit(Element a) const - {return a != 0;} - - Element MultiplicativeInverse(Element a) const; - - Element Divide(Element a, Element b) const - {return Multiply(a, MultiplicativeInverse(b));} - -private: - word32 m_modulus; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/gf2n.cpp b/lib/cryptopp/gf2n.cpp deleted file mode 100644 index bcc56071a..000000000 --- a/lib/cryptopp/gf2n.cpp +++ /dev/null @@ -1,882 +0,0 @@ -// gf2n.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "gf2n.h" -#include "algebra.h" -#include "words.h" -#include "randpool.h" -#include "asn.h" -#include "oids.h" - -#include <iostream> - -NAMESPACE_BEGIN(CryptoPP) - -PolynomialMod2::PolynomialMod2() -{ -} - -PolynomialMod2::PolynomialMod2(word value, size_t bitLength) - : reg(BitsToWords(bitLength)) -{ - assert(value==0 || reg.size()>0); - - if (reg.size() > 0) - { - reg[0] = value; - SetWords(reg+1, 0, reg.size()-1); - } -} - -PolynomialMod2::PolynomialMod2(const PolynomialMod2& t) - : reg(t.reg.size()) -{ - CopyWords(reg, t.reg, reg.size()); -} - -void PolynomialMod2::Randomize(RandomNumberGenerator &rng, size_t nbits) -{ - const size_t nbytes = nbits/8 + 1; - SecByteBlock buf(nbytes); - rng.GenerateBlock(buf, nbytes); - buf[0] = (byte)Crop(buf[0], nbits % 8); - Decode(buf, nbytes); -} - -PolynomialMod2 PolynomialMod2::AllOnes(size_t bitLength) -{ - PolynomialMod2 result((word)0, bitLength); - SetWords(result.reg, ~(word)0, result.reg.size()); - if (bitLength%WORD_BITS) - result.reg[result.reg.size()-1] = (word)Crop(result.reg[result.reg.size()-1], bitLength%WORD_BITS); - return result; -} - -void PolynomialMod2::SetBit(size_t n, int value) -{ - if (value) - { - reg.CleanGrow(n/WORD_BITS + 1); - reg[n/WORD_BITS] |= (word(1) << (n%WORD_BITS)); - } - else - { - if (n/WORD_BITS < reg.size()) - reg[n/WORD_BITS] &= ~(word(1) << (n%WORD_BITS)); - } -} - -byte PolynomialMod2::GetByte(size_t n) const -{ - if (n/WORD_SIZE >= reg.size()) - return 0; - else - return byte(reg[n/WORD_SIZE] >> ((n%WORD_SIZE)*8)); -} - -void PolynomialMod2::SetByte(size_t n, byte value) -{ - reg.CleanGrow(BytesToWords(n+1)); - reg[n/WORD_SIZE] &= ~(word(0xff) << 8*(n%WORD_SIZE)); - reg[n/WORD_SIZE] |= (word(value) << 8*(n%WORD_SIZE)); -} - -PolynomialMod2 PolynomialMod2::Monomial(size_t i) -{ - PolynomialMod2 r((word)0, i+1); - r.SetBit(i); - return r; -} - -PolynomialMod2 PolynomialMod2::Trinomial(size_t t0, size_t t1, size_t t2) -{ - PolynomialMod2 r((word)0, t0+1); - r.SetBit(t0); - r.SetBit(t1); - r.SetBit(t2); - return r; -} - -PolynomialMod2 PolynomialMod2::Pentanomial(size_t t0, size_t t1, size_t t2, size_t t3, size_t t4) -{ - PolynomialMod2 r((word)0, t0+1); - r.SetBit(t0); - r.SetBit(t1); - r.SetBit(t2); - r.SetBit(t3); - r.SetBit(t4); - return r; -} - -template <word i> -struct NewPolynomialMod2 -{ - PolynomialMod2 * operator()() const - { - return new PolynomialMod2(i); - } -}; - -const PolynomialMod2 &PolynomialMod2::Zero() -{ - return Singleton<PolynomialMod2>().Ref(); -} - -const PolynomialMod2 &PolynomialMod2::One() -{ - return Singleton<PolynomialMod2, NewPolynomialMod2<1> >().Ref(); -} - -void PolynomialMod2::Decode(const byte *input, size_t inputLen) -{ - StringStore store(input, inputLen); - Decode(store, inputLen); -} - -void PolynomialMod2::Encode(byte *output, size_t outputLen) const -{ - ArraySink sink(output, outputLen); - Encode(sink, outputLen); -} - -void PolynomialMod2::Decode(BufferedTransformation &bt, size_t inputLen) -{ - reg.CleanNew(BytesToWords(inputLen)); - - for (size_t i=inputLen; i > 0; i--) - { - byte b; - bt.Get(b); - reg[(i-1)/WORD_SIZE] |= word(b) << ((i-1)%WORD_SIZE)*8; - } -} - -void PolynomialMod2::Encode(BufferedTransformation &bt, size_t outputLen) const -{ - for (size_t i=outputLen; i > 0; i--) - bt.Put(GetByte(i-1)); -} - -void PolynomialMod2::DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const -{ - DERGeneralEncoder enc(bt, OCTET_STRING); - Encode(enc, length); - enc.MessageEnd(); -} - -void PolynomialMod2::BERDecodeAsOctetString(BufferedTransformation &bt, size_t length) -{ - BERGeneralDecoder dec(bt, OCTET_STRING); - if (!dec.IsDefiniteLength() || dec.RemainingLength() != length) - BERDecodeError(); - Decode(dec, length); - dec.MessageEnd(); -} - -unsigned int PolynomialMod2::WordCount() const -{ - return (unsigned int)CountWords(reg, reg.size()); -} - -unsigned int PolynomialMod2::ByteCount() const -{ - unsigned wordCount = WordCount(); - if (wordCount) - return (wordCount-1)*WORD_SIZE + BytePrecision(reg[wordCount-1]); - else - return 0; -} - -unsigned int PolynomialMod2::BitCount() const -{ - unsigned wordCount = WordCount(); - if (wordCount) - return (wordCount-1)*WORD_BITS + BitPrecision(reg[wordCount-1]); - else - return 0; -} - -unsigned int PolynomialMod2::Parity() const -{ - unsigned i; - word temp=0; - for (i=0; i<reg.size(); i++) - temp ^= reg[i]; - return CryptoPP::Parity(temp); -} - -PolynomialMod2& PolynomialMod2::operator=(const PolynomialMod2& t) -{ - reg.Assign(t.reg); - return *this; -} - -PolynomialMod2& PolynomialMod2::operator^=(const PolynomialMod2& t) -{ - reg.CleanGrow(t.reg.size()); - XorWords(reg, t.reg, t.reg.size()); - return *this; -} - -PolynomialMod2 PolynomialMod2::Xor(const PolynomialMod2 &b) const -{ - if (b.reg.size() >= reg.size()) - { - PolynomialMod2 result((word)0, b.reg.size()*WORD_BITS); - XorWords(result.reg, reg, b.reg, reg.size()); - CopyWords(result.reg+reg.size(), b.reg+reg.size(), b.reg.size()-reg.size()); - return result; - } - else - { - PolynomialMod2 result((word)0, reg.size()*WORD_BITS); - XorWords(result.reg, reg, b.reg, b.reg.size()); - CopyWords(result.reg+b.reg.size(), reg+b.reg.size(), reg.size()-b.reg.size()); - return result; - } -} - -PolynomialMod2 PolynomialMod2::And(const PolynomialMod2 &b) const -{ - PolynomialMod2 result((word)0, WORD_BITS*STDMIN(reg.size(), b.reg.size())); - AndWords(result.reg, reg, b.reg, result.reg.size()); - return result; -} - -PolynomialMod2 PolynomialMod2::Times(const PolynomialMod2 &b) const -{ - PolynomialMod2 result((word)0, BitCount() + b.BitCount()); - - for (int i=b.Degree(); i>=0; i--) - { - result <<= 1; - if (b[i]) - XorWords(result.reg, reg, reg.size()); - } - return result; -} - -PolynomialMod2 PolynomialMod2::Squared() const -{ - static const word map[16] = {0, 1, 4, 5, 16, 17, 20, 21, 64, 65, 68, 69, 80, 81, 84, 85}; - - PolynomialMod2 result((word)0, 2*reg.size()*WORD_BITS); - - for (unsigned i=0; i<reg.size(); i++) - { - unsigned j; - - for (j=0; j<WORD_BITS; j+=8) - result.reg[2*i] |= map[(reg[i] >> (j/2)) % 16] << j; - - for (j=0; j<WORD_BITS; j+=8) - result.reg[2*i+1] |= map[(reg[i] >> (j/2 + WORD_BITS/2)) % 16] << j; - } - - return result; -} - -void PolynomialMod2::Divide(PolynomialMod2 &remainder, PolynomialMod2 "ient, - const PolynomialMod2 ÷nd, const PolynomialMod2 &divisor) -{ - if (!divisor) - throw PolynomialMod2::DivideByZero(); - - int degree = divisor.Degree(); - remainder.reg.CleanNew(BitsToWords(degree+1)); - if (dividend.BitCount() >= divisor.BitCount()) - quotient.reg.CleanNew(BitsToWords(dividend.BitCount() - divisor.BitCount() + 1)); - else - quotient.reg.CleanNew(0); - - for (int i=dividend.Degree(); i>=0; i--) - { - remainder <<= 1; - remainder.reg[0] |= dividend[i]; - if (remainder[degree]) - { - remainder -= divisor; - quotient.SetBit(i); - } - } -} - -PolynomialMod2 PolynomialMod2::DividedBy(const PolynomialMod2 &b) const -{ - PolynomialMod2 remainder, quotient; - PolynomialMod2::Divide(remainder, quotient, *this, b); - return quotient; -} - -PolynomialMod2 PolynomialMod2::Modulo(const PolynomialMod2 &b) const -{ - PolynomialMod2 remainder, quotient; - PolynomialMod2::Divide(remainder, quotient, *this, b); - return remainder; -} - -PolynomialMod2& PolynomialMod2::operator<<=(unsigned int n) -{ - if (!reg.size()) - return *this; - - int i; - word u; - word carry=0; - word *r=reg; - - if (n==1) // special case code for most frequent case - { - i = (int)reg.size(); - while (i--) - { - u = *r; - *r = (u << 1) | carry; - carry = u >> (WORD_BITS-1); - r++; - } - - if (carry) - { - reg.Grow(reg.size()+1); - reg[reg.size()-1] = carry; - } - - return *this; - } - - int shiftWords = n / WORD_BITS; - int shiftBits = n % WORD_BITS; - - if (shiftBits) - { - i = (int)reg.size(); - while (i--) - { - u = *r; - *r = (u << shiftBits) | carry; - carry = u >> (WORD_BITS-shiftBits); - r++; - } - } - - if (carry) - { - reg.Grow(reg.size()+shiftWords+1); - reg[reg.size()-1] = carry; - } - else - reg.Grow(reg.size()+shiftWords); - - if (shiftWords) - { - for (i = (int)reg.size()-1; i>=shiftWords; i--) - reg[i] = reg[i-shiftWords]; - for (; i>=0; i--) - reg[i] = 0; - } - - return *this; -} - -PolynomialMod2& PolynomialMod2::operator>>=(unsigned int n) -{ - if (!reg.size()) - return *this; - - int shiftWords = n / WORD_BITS; - int shiftBits = n % WORD_BITS; - - size_t i; - word u; - word carry=0; - word *r=reg+reg.size()-1; - - if (shiftBits) - { - i = reg.size(); - while (i--) - { - u = *r; - *r = (u >> shiftBits) | carry; - carry = u << (WORD_BITS-shiftBits); - r--; - } - } - - if (shiftWords) - { - for (i=0; i<reg.size()-shiftWords; i++) - reg[i] = reg[i+shiftWords]; - for (; i<reg.size(); i++) - reg[i] = 0; - } - - return *this; -} - -PolynomialMod2 PolynomialMod2::operator<<(unsigned int n) const -{ - PolynomialMod2 result(*this); - return result<<=n; -} - -PolynomialMod2 PolynomialMod2::operator>>(unsigned int n) const -{ - PolynomialMod2 result(*this); - return result>>=n; -} - -bool PolynomialMod2::operator!() const -{ - for (unsigned i=0; i<reg.size(); i++) - if (reg[i]) return false; - return true; -} - -bool PolynomialMod2::Equals(const PolynomialMod2 &rhs) const -{ - size_t i, smallerSize = STDMIN(reg.size(), rhs.reg.size()); - - for (i=0; i<smallerSize; i++) - if (reg[i] != rhs.reg[i]) return false; - - for (i=smallerSize; i<reg.size(); i++) - if (reg[i] != 0) return false; - - for (i=smallerSize; i<rhs.reg.size(); i++) - if (rhs.reg[i] != 0) return false; - - return true; -} - -std::ostream& operator<<(std::ostream& out, const PolynomialMod2 &a) -{ - // Get relevant conversion specifications from ostream. - long f = out.flags() & std::ios::basefield; // Get base digits. - int bits, block; - char suffix; - switch(f) - { - case std::ios::oct : - bits = 3; - block = 4; - suffix = 'o'; - break; - case std::ios::hex : - bits = 4; - block = 2; - suffix = 'h'; - break; - default : - bits = 1; - block = 8; - suffix = 'b'; - } - - if (!a) - return out << '0' << suffix; - - SecBlock<char> s(a.BitCount()/bits+1); - unsigned i; - - static const char upper[]="0123456789ABCDEF"; - static const char lower[]="0123456789abcdef"; - const char* vec = (out.flags() & std::ios::uppercase) ? upper : lower; - - for (i=0; i*bits < a.BitCount(); i++) - { - int digit=0; - for (int j=0; j<bits; j++) - digit |= a[i*bits+j] << j; - s[i]=vec[digit]; - } - - while (i--) - { - out << s[i]; - if (i && (i%block)==0) - out << ','; - } - - return out << suffix; -} - -PolynomialMod2 PolynomialMod2::Gcd(const PolynomialMod2 &a, const PolynomialMod2 &b) -{ - return EuclideanDomainOf<PolynomialMod2>().Gcd(a, b); -} - -PolynomialMod2 PolynomialMod2::InverseMod(const PolynomialMod2 &modulus) const -{ - typedef EuclideanDomainOf<PolynomialMod2> Domain; - return QuotientRing<Domain>(Domain(), modulus).MultiplicativeInverse(*this); -} - -bool PolynomialMod2::IsIrreducible() const -{ - signed int d = Degree(); - if (d <= 0) - return false; - - PolynomialMod2 t(2), u(t); - for (int i=1; i<=d/2; i++) - { - u = u.Squared()%(*this); - if (!Gcd(u+t, *this).IsUnit()) - return false; - } - return true; -} - -// ******************************************************** - -GF2NP::GF2NP(const PolynomialMod2 &modulus) - : QuotientRing<EuclideanDomainOf<PolynomialMod2> >(EuclideanDomainOf<PolynomialMod2>(), modulus), m(modulus.Degree()) -{ -} - -GF2NP::Element GF2NP::SquareRoot(const Element &a) const -{ - Element r = a; - for (unsigned int i=1; i<m; i++) - r = Square(r); - return r; -} - -GF2NP::Element GF2NP::HalfTrace(const Element &a) const -{ - assert(m%2 == 1); - Element h = a; - for (unsigned int i=1; i<=(m-1)/2; i++) - h = Add(Square(Square(h)), a); - return h; -} - -GF2NP::Element GF2NP::SolveQuadraticEquation(const Element &a) const -{ - if (m%2 == 0) - { - Element z, w; - RandomPool rng; - do - { - Element p((RandomNumberGenerator &)rng, m); - z = PolynomialMod2::Zero(); - w = p; - for (unsigned int i=1; i<=m-1; i++) - { - w = Square(w); - z = Square(z); - Accumulate(z, Multiply(w, a)); - Accumulate(w, p); - } - } while (w.IsZero()); - return z; - } - else - return HalfTrace(a); -} - -// ******************************************************** - -GF2NT::GF2NT(unsigned int t0, unsigned int t1, unsigned int t2) - : GF2NP(PolynomialMod2::Trinomial(t0, t1, t2)) - , t0(t0), t1(t1) - , result((word)0, m) -{ - assert(t0 > t1 && t1 > t2 && t2==0); -} - -const GF2NT::Element& GF2NT::MultiplicativeInverse(const Element &a) const -{ - if (t0-t1 < WORD_BITS) - return GF2NP::MultiplicativeInverse(a); - - SecWordBlock T(m_modulus.reg.size() * 4); - word *b = T; - word *c = T+m_modulus.reg.size(); - word *f = T+2*m_modulus.reg.size(); - word *g = T+3*m_modulus.reg.size(); - size_t bcLen=1, fgLen=m_modulus.reg.size(); - unsigned int k=0; - - SetWords(T, 0, 3*m_modulus.reg.size()); - b[0]=1; - assert(a.reg.size() <= m_modulus.reg.size()); - CopyWords(f, a.reg, a.reg.size()); - CopyWords(g, m_modulus.reg, m_modulus.reg.size()); - - while (1) - { - word t=f[0]; - while (!t) - { - ShiftWordsRightByWords(f, fgLen, 1); - if (c[bcLen-1]) - bcLen++; - assert(bcLen <= m_modulus.reg.size()); - ShiftWordsLeftByWords(c, bcLen, 1); - k+=WORD_BITS; - t=f[0]; - } - - unsigned int i=0; - while (t%2 == 0) - { - t>>=1; - i++; - } - k+=i; - - if (t==1 && CountWords(f, fgLen)==1) - break; - - if (i==1) - { - ShiftWordsRightByBits(f, fgLen, 1); - t=ShiftWordsLeftByBits(c, bcLen, 1); - } - else - { - ShiftWordsRightByBits(f, fgLen, i); - t=ShiftWordsLeftByBits(c, bcLen, i); - } - if (t) - { - c[bcLen] = t; - bcLen++; - assert(bcLen <= m_modulus.reg.size()); - } - - if (f[fgLen-1]==0 && g[fgLen-1]==0) - fgLen--; - - if (f[fgLen-1] < g[fgLen-1]) - { - std::swap(f, g); - std::swap(b, c); - } - - XorWords(f, g, fgLen); - XorWords(b, c, bcLen); - } - - while (k >= WORD_BITS) - { - word temp = b[0]; - // right shift b - for (unsigned i=0; i+1<BitsToWords(m); i++) - b[i] = b[i+1]; - b[BitsToWords(m)-1] = 0; - - if (t1 < WORD_BITS) - for (unsigned int j=0; j<WORD_BITS-t1; j++) - temp ^= ((temp >> j) & 1) << (t1 + j); - else - b[t1/WORD_BITS-1] ^= temp << t1%WORD_BITS; - - if (t1 % WORD_BITS) - b[t1/WORD_BITS] ^= temp >> (WORD_BITS - t1%WORD_BITS); - - if (t0%WORD_BITS) - { - b[t0/WORD_BITS-1] ^= temp << t0%WORD_BITS; - b[t0/WORD_BITS] ^= temp >> (WORD_BITS - t0%WORD_BITS); - } - else - b[t0/WORD_BITS-1] ^= temp; - - k -= WORD_BITS; - } - - if (k) - { - word temp = b[0] << (WORD_BITS - k); - ShiftWordsRightByBits(b, BitsToWords(m), k); - - if (t1 < WORD_BITS) - for (unsigned int j=0; j<WORD_BITS-t1; j++) - temp ^= ((temp >> j) & 1) << (t1 + j); - else - b[t1/WORD_BITS-1] ^= temp << t1%WORD_BITS; - - if (t1 % WORD_BITS) - b[t1/WORD_BITS] ^= temp >> (WORD_BITS - t1%WORD_BITS); - - if (t0%WORD_BITS) - { - b[t0/WORD_BITS-1] ^= temp << t0%WORD_BITS; - b[t0/WORD_BITS] ^= temp >> (WORD_BITS - t0%WORD_BITS); - } - else - b[t0/WORD_BITS-1] ^= temp; - } - - CopyWords(result.reg.begin(), b, result.reg.size()); - return result; -} - -const GF2NT::Element& GF2NT::Multiply(const Element &a, const Element &b) const -{ - size_t aSize = STDMIN(a.reg.size(), result.reg.size()); - Element r((word)0, m); - - for (int i=m-1; i>=0; i--) - { - if (r[m-1]) - { - ShiftWordsLeftByBits(r.reg.begin(), r.reg.size(), 1); - XorWords(r.reg.begin(), m_modulus.reg, r.reg.size()); - } - else - ShiftWordsLeftByBits(r.reg.begin(), r.reg.size(), 1); - - if (b[i]) - XorWords(r.reg.begin(), a.reg, aSize); - } - - if (m%WORD_BITS) - r.reg.begin()[r.reg.size()-1] = (word)Crop(r.reg[r.reg.size()-1], m%WORD_BITS); - - CopyWords(result.reg.begin(), r.reg.begin(), result.reg.size()); - return result; -} - -const GF2NT::Element& GF2NT::Reduced(const Element &a) const -{ - if (t0-t1 < WORD_BITS) - return m_domain.Mod(a, m_modulus); - - SecWordBlock b(a.reg); - - size_t i; - for (i=b.size()-1; i>=BitsToWords(t0); i--) - { - word temp = b[i]; - - if (t0%WORD_BITS) - { - b[i-t0/WORD_BITS] ^= temp >> t0%WORD_BITS; - b[i-t0/WORD_BITS-1] ^= temp << (WORD_BITS - t0%WORD_BITS); - } - else - b[i-t0/WORD_BITS] ^= temp; - - if ((t0-t1)%WORD_BITS) - { - b[i-(t0-t1)/WORD_BITS] ^= temp >> (t0-t1)%WORD_BITS; - b[i-(t0-t1)/WORD_BITS-1] ^= temp << (WORD_BITS - (t0-t1)%WORD_BITS); - } - else - b[i-(t0-t1)/WORD_BITS] ^= temp; - } - - if (i==BitsToWords(t0)-1 && t0%WORD_BITS) - { - word mask = ((word)1<<(t0%WORD_BITS))-1; - word temp = b[i] & ~mask; - b[i] &= mask; - - b[i-t0/WORD_BITS] ^= temp >> t0%WORD_BITS; - - if ((t0-t1)%WORD_BITS) - { - b[i-(t0-t1)/WORD_BITS] ^= temp >> (t0-t1)%WORD_BITS; - if ((t0-t1)%WORD_BITS > t0%WORD_BITS) - b[i-(t0-t1)/WORD_BITS-1] ^= temp << (WORD_BITS - (t0-t1)%WORD_BITS); - else - assert(temp << (WORD_BITS - (t0-t1)%WORD_BITS) == 0); - } - else - b[i-(t0-t1)/WORD_BITS] ^= temp; - } - - SetWords(result.reg.begin(), 0, result.reg.size()); - CopyWords(result.reg.begin(), b, STDMIN(b.size(), result.reg.size())); - return result; -} - -void GF2NP::DEREncodeElement(BufferedTransformation &out, const Element &a) const -{ - a.DEREncodeAsOctetString(out, MaxElementByteLength()); -} - -void GF2NP::BERDecodeElement(BufferedTransformation &in, Element &a) const -{ - a.BERDecodeAsOctetString(in, MaxElementByteLength()); -} - -void GF2NT::DEREncode(BufferedTransformation &bt) const -{ - DERSequenceEncoder seq(bt); - ASN1::characteristic_two_field().DEREncode(seq); - DERSequenceEncoder parameters(seq); - DEREncodeUnsigned(parameters, m); - ASN1::tpBasis().DEREncode(parameters); - DEREncodeUnsigned(parameters, t1); - parameters.MessageEnd(); - seq.MessageEnd(); -} - -void GF2NPP::DEREncode(BufferedTransformation &bt) const -{ - DERSequenceEncoder seq(bt); - ASN1::characteristic_two_field().DEREncode(seq); - DERSequenceEncoder parameters(seq); - DEREncodeUnsigned(parameters, m); - ASN1::ppBasis().DEREncode(parameters); - DERSequenceEncoder pentanomial(parameters); - DEREncodeUnsigned(pentanomial, t3); - DEREncodeUnsigned(pentanomial, t2); - DEREncodeUnsigned(pentanomial, t1); - pentanomial.MessageEnd(); - parameters.MessageEnd(); - seq.MessageEnd(); -} - -GF2NP * BERDecodeGF2NP(BufferedTransformation &bt) -{ - // VC60 workaround: auto_ptr lacks reset() - member_ptr<GF2NP> result; - - BERSequenceDecoder seq(bt); - if (OID(seq) != ASN1::characteristic_two_field()) - BERDecodeError(); - BERSequenceDecoder parameters(seq); - unsigned int m; - BERDecodeUnsigned(parameters, m); - OID oid(parameters); - if (oid == ASN1::tpBasis()) - { - unsigned int t1; - BERDecodeUnsigned(parameters, t1); - result.reset(new GF2NT(m, t1, 0)); - } - else if (oid == ASN1::ppBasis()) - { - unsigned int t1, t2, t3; - BERSequenceDecoder pentanomial(parameters); - BERDecodeUnsigned(pentanomial, t3); - BERDecodeUnsigned(pentanomial, t2); - BERDecodeUnsigned(pentanomial, t1); - pentanomial.MessageEnd(); - result.reset(new GF2NPP(m, t3, t2, t1, 0)); - } - else - { - BERDecodeError(); - return NULL; - } - parameters.MessageEnd(); - seq.MessageEnd(); - - return result.release(); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/gf2n.h b/lib/cryptopp/gf2n.h deleted file mode 100644 index 67ade641e..000000000 --- a/lib/cryptopp/gf2n.h +++ /dev/null @@ -1,369 +0,0 @@ -#ifndef CRYPTOPP_GF2N_H -#define CRYPTOPP_GF2N_H - -/*! \file */ - -#include "cryptlib.h" -#include "secblock.h" -#include "misc.h" -#include "algebra.h" - -#include <iosfwd> - -NAMESPACE_BEGIN(CryptoPP) - -//! Polynomial with Coefficients in GF(2) -/*! \nosubgrouping */ -class CRYPTOPP_DLL PolynomialMod2 -{ -public: - //! \name ENUMS, EXCEPTIONS, and TYPEDEFS - //@{ - //! divide by zero exception - class DivideByZero : public Exception - { - public: - DivideByZero() : Exception(OTHER_ERROR, "PolynomialMod2: division by zero") {} - }; - - typedef unsigned int RandomizationParameter; - //@} - - //! \name CREATORS - //@{ - //! creates the zero polynomial - PolynomialMod2(); - //! copy constructor - PolynomialMod2(const PolynomialMod2& t); - - //! convert from word - /*! value should be encoded with the least significant bit as coefficient to x^0 - and most significant bit as coefficient to x^(WORD_BITS-1) - bitLength denotes how much memory to allocate initially - */ - PolynomialMod2(word value, size_t bitLength=WORD_BITS); - - //! convert from big-endian byte array - PolynomialMod2(const byte *encodedPoly, size_t byteCount) - {Decode(encodedPoly, byteCount);} - - //! convert from big-endian form stored in a BufferedTransformation - PolynomialMod2(BufferedTransformation &encodedPoly, size_t byteCount) - {Decode(encodedPoly, byteCount);} - - //! create a random polynomial uniformly distributed over all polynomials with degree less than bitcount - PolynomialMod2(RandomNumberGenerator &rng, size_t bitcount) - {Randomize(rng, bitcount);} - - //! return x^i - static PolynomialMod2 CRYPTOPP_API Monomial(size_t i); - //! return x^t0 + x^t1 + x^t2 - static PolynomialMod2 CRYPTOPP_API Trinomial(size_t t0, size_t t1, size_t t2); - //! return x^t0 + x^t1 + x^t2 + x^t3 + x^t4 - static PolynomialMod2 CRYPTOPP_API Pentanomial(size_t t0, size_t t1, size_t t2, size_t t3, size_t t4); - //! return x^(n-1) + ... + x + 1 - static PolynomialMod2 CRYPTOPP_API AllOnes(size_t n); - - //! - static const PolynomialMod2 & CRYPTOPP_API Zero(); - //! - static const PolynomialMod2 & CRYPTOPP_API One(); - //@} - - //! \name ENCODE/DECODE - //@{ - //! minimum number of bytes to encode this polynomial - /*! MinEncodedSize of 0 is 1 */ - unsigned int MinEncodedSize() const {return STDMAX(1U, ByteCount());} - - //! encode in big-endian format - /*! if outputLen < MinEncodedSize, the most significant bytes will be dropped - if outputLen > MinEncodedSize, the most significant bytes will be padded - */ - void Encode(byte *output, size_t outputLen) const; - //! - void Encode(BufferedTransformation &bt, size_t outputLen) const; - - //! - void Decode(const byte *input, size_t inputLen); - //! - //* Precondition: bt.MaxRetrievable() >= inputLen - void Decode(BufferedTransformation &bt, size_t inputLen); - - //! encode value as big-endian octet string - void DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const; - //! decode value as big-endian octet string - void BERDecodeAsOctetString(BufferedTransformation &bt, size_t length); - //@} - - //! \name ACCESSORS - //@{ - //! number of significant bits = Degree() + 1 - unsigned int BitCount() const; - //! number of significant bytes = ceiling(BitCount()/8) - unsigned int ByteCount() const; - //! number of significant words = ceiling(ByteCount()/sizeof(word)) - unsigned int WordCount() const; - - //! return the n-th bit, n=0 being the least significant bit - bool GetBit(size_t n) const {return GetCoefficient(n)!=0;} - //! return the n-th byte - byte GetByte(size_t n) const; - - //! the zero polynomial will return a degree of -1 - signed int Degree() const {return BitCount()-1;} - //! degree + 1 - unsigned int CoefficientCount() const {return BitCount();} - //! return coefficient for x^i - int GetCoefficient(size_t i) const - {return (i/WORD_BITS < reg.size()) ? int(reg[i/WORD_BITS] >> (i % WORD_BITS)) & 1 : 0;} - //! return coefficient for x^i - int operator[](unsigned int i) const {return GetCoefficient(i);} - - //! - bool IsZero() const {return !*this;} - //! - bool Equals(const PolynomialMod2 &rhs) const; - //@} - - //! \name MANIPULATORS - //@{ - //! - PolynomialMod2& operator=(const PolynomialMod2& t); - //! - PolynomialMod2& operator&=(const PolynomialMod2& t); - //! - PolynomialMod2& operator^=(const PolynomialMod2& t); - //! - PolynomialMod2& operator+=(const PolynomialMod2& t) {return *this ^= t;} - //! - PolynomialMod2& operator-=(const PolynomialMod2& t) {return *this ^= t;} - //! - PolynomialMod2& operator*=(const PolynomialMod2& t); - //! - PolynomialMod2& operator/=(const PolynomialMod2& t); - //! - PolynomialMod2& operator%=(const PolynomialMod2& t); - //! - PolynomialMod2& operator<<=(unsigned int); - //! - PolynomialMod2& operator>>=(unsigned int); - - //! - void Randomize(RandomNumberGenerator &rng, size_t bitcount); - - //! - void SetBit(size_t i, int value = 1); - //! set the n-th byte to value - void SetByte(size_t n, byte value); - - //! - void SetCoefficient(size_t i, int value) {SetBit(i, value);} - - //! - void swap(PolynomialMod2 &a) {reg.swap(a.reg);} - //@} - - //! \name UNARY OPERATORS - //@{ - //! - bool operator!() const; - //! - PolynomialMod2 operator+() const {return *this;} - //! - PolynomialMod2 operator-() const {return *this;} - //@} - - //! \name BINARY OPERATORS - //@{ - //! - PolynomialMod2 And(const PolynomialMod2 &b) const; - //! - PolynomialMod2 Xor(const PolynomialMod2 &b) const; - //! - PolynomialMod2 Plus(const PolynomialMod2 &b) const {return Xor(b);} - //! - PolynomialMod2 Minus(const PolynomialMod2 &b) const {return Xor(b);} - //! - PolynomialMod2 Times(const PolynomialMod2 &b) const; - //! - PolynomialMod2 DividedBy(const PolynomialMod2 &b) const; - //! - PolynomialMod2 Modulo(const PolynomialMod2 &b) const; - - //! - PolynomialMod2 operator>>(unsigned int n) const; - //! - PolynomialMod2 operator<<(unsigned int n) const; - //@} - - //! \name OTHER ARITHMETIC FUNCTIONS - //@{ - //! sum modulo 2 of all coefficients - unsigned int Parity() const; - - //! check for irreducibility - bool IsIrreducible() const; - - //! is always zero since we're working modulo 2 - PolynomialMod2 Doubled() const {return Zero();} - //! - PolynomialMod2 Squared() const; - - //! only 1 is a unit - bool IsUnit() const {return Equals(One());} - //! return inverse if *this is a unit, otherwise return 0 - PolynomialMod2 MultiplicativeInverse() const {return IsUnit() ? One() : Zero();} - - //! greatest common divisor - static PolynomialMod2 CRYPTOPP_API Gcd(const PolynomialMod2 &a, const PolynomialMod2 &n); - //! calculate multiplicative inverse of *this mod n - PolynomialMod2 InverseMod(const PolynomialMod2 &) const; - - //! calculate r and q such that (a == d*q + r) && (deg(r) < deg(d)) - static void CRYPTOPP_API Divide(PolynomialMod2 &r, PolynomialMod2 &q, const PolynomialMod2 &a, const PolynomialMod2 &d); - //@} - - //! \name INPUT/OUTPUT - //@{ - //! - friend std::ostream& operator<<(std::ostream& out, const PolynomialMod2 &a); - //@} - -private: - friend class GF2NT; - - SecWordBlock reg; -}; - -//! -inline bool operator==(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) -{return a.Equals(b);} -//! -inline bool operator!=(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) -{return !(a==b);} -//! compares degree -inline bool operator> (const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) -{return a.Degree() > b.Degree();} -//! compares degree -inline bool operator>=(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) -{return a.Degree() >= b.Degree();} -//! compares degree -inline bool operator< (const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) -{return a.Degree() < b.Degree();} -//! compares degree -inline bool operator<=(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) -{return a.Degree() <= b.Degree();} -//! -inline CryptoPP::PolynomialMod2 operator&(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.And(b);} -//! -inline CryptoPP::PolynomialMod2 operator^(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.Xor(b);} -//! -inline CryptoPP::PolynomialMod2 operator+(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.Plus(b);} -//! -inline CryptoPP::PolynomialMod2 operator-(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.Minus(b);} -//! -inline CryptoPP::PolynomialMod2 operator*(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.Times(b);} -//! -inline CryptoPP::PolynomialMod2 operator/(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.DividedBy(b);} -//! -inline CryptoPP::PolynomialMod2 operator%(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.Modulo(b);} - -// CodeWarrior 8 workaround: put these template instantiations after overloaded operator declarations, -// but before the use of QuotientRing<EuclideanDomainOf<PolynomialMod2> > for VC .NET 2003 -CRYPTOPP_DLL_TEMPLATE_CLASS AbstractGroup<PolynomialMod2>; -CRYPTOPP_DLL_TEMPLATE_CLASS AbstractRing<PolynomialMod2>; -CRYPTOPP_DLL_TEMPLATE_CLASS AbstractEuclideanDomain<PolynomialMod2>; -CRYPTOPP_DLL_TEMPLATE_CLASS EuclideanDomainOf<PolynomialMod2>; -CRYPTOPP_DLL_TEMPLATE_CLASS QuotientRing<EuclideanDomainOf<PolynomialMod2> >; - -//! GF(2^n) with Polynomial Basis -class CRYPTOPP_DLL GF2NP : public QuotientRing<EuclideanDomainOf<PolynomialMod2> > -{ -public: - GF2NP(const PolynomialMod2 &modulus); - - virtual GF2NP * Clone() const {return new GF2NP(*this);} - virtual void DEREncode(BufferedTransformation &bt) const - {assert(false);} // no ASN.1 syntax yet for general polynomial basis - - void DEREncodeElement(BufferedTransformation &out, const Element &a) const; - void BERDecodeElement(BufferedTransformation &in, Element &a) const; - - bool Equal(const Element &a, const Element &b) const - {assert(a.Degree() < m_modulus.Degree() && b.Degree() < m_modulus.Degree()); return a.Equals(b);} - - bool IsUnit(const Element &a) const - {assert(a.Degree() < m_modulus.Degree()); return !!a;} - - unsigned int MaxElementBitLength() const - {return m;} - - unsigned int MaxElementByteLength() const - {return (unsigned int)BitsToBytes(MaxElementBitLength());} - - Element SquareRoot(const Element &a) const; - - Element HalfTrace(const Element &a) const; - - // returns z such that z^2 + z == a - Element SolveQuadraticEquation(const Element &a) const; - -protected: - unsigned int m; -}; - -//! GF(2^n) with Trinomial Basis -class CRYPTOPP_DLL GF2NT : public GF2NP -{ -public: - // polynomial modulus = x^t0 + x^t1 + x^t2, t0 > t1 > t2 - GF2NT(unsigned int t0, unsigned int t1, unsigned int t2); - - GF2NP * Clone() const {return new GF2NT(*this);} - void DEREncode(BufferedTransformation &bt) const; - - const Element& Multiply(const Element &a, const Element &b) const; - - const Element& Square(const Element &a) const - {return Reduced(a.Squared());} - - const Element& MultiplicativeInverse(const Element &a) const; - -private: - const Element& Reduced(const Element &a) const; - - unsigned int t0, t1; - mutable PolynomialMod2 result; -}; - -//! GF(2^n) with Pentanomial Basis -class CRYPTOPP_DLL GF2NPP : public GF2NP -{ -public: - // polynomial modulus = x^t0 + x^t1 + x^t2 + x^t3 + x^t4, t0 > t1 > t2 > t3 > t4 - GF2NPP(unsigned int t0, unsigned int t1, unsigned int t2, unsigned int t3, unsigned int t4) - : GF2NP(PolynomialMod2::Pentanomial(t0, t1, t2, t3, t4)), t0(t0), t1(t1), t2(t2), t3(t3) {} - - GF2NP * Clone() const {return new GF2NPP(*this);} - void DEREncode(BufferedTransformation &bt) const; - -private: - unsigned int t0, t1, t2, t3; -}; - -// construct new GF2NP from the ASN.1 sequence Characteristic-two -CRYPTOPP_DLL GF2NP * CRYPTOPP_API BERDecodeGF2NP(BufferedTransformation &bt); - -NAMESPACE_END - -#ifndef __BORLANDC__ -NAMESPACE_BEGIN(std) -template<> inline void swap(CryptoPP::PolynomialMod2 &a, CryptoPP::PolynomialMod2 &b) -{ - a.swap(b); -} -NAMESPACE_END -#endif - -#endif diff --git a/lib/cryptopp/gfpcrypt.cpp b/lib/cryptopp/gfpcrypt.cpp deleted file mode 100644 index e293fc598..000000000 --- a/lib/cryptopp/gfpcrypt.cpp +++ /dev/null @@ -1,273 +0,0 @@ -// dsa.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "gfpcrypt.h" -#include "asn.h" -#include "oids.h" -#include "nbtheory.h" - -NAMESPACE_BEGIN(CryptoPP) - -void TestInstantiations_gfpcrypt() -{ - GDSA<SHA>::Signer test; - GDSA<SHA>::Verifier test1; - DSA::Signer test5(NullRNG(), 100); - DSA::Signer test2(test5); - NR<SHA>::Signer test3; - NR<SHA>::Verifier test4; - DLIES<>::Encryptor test6; - DLIES<>::Decryptor test7; -} - -void DL_GroupParameters_DSA::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) -{ - Integer p, q, g; - - if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g)) - { - q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2); - Initialize(p, q, g); - } - else - { - int modulusSize = 1024, defaultSubgroupOrderSize; - alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize); - - switch (modulusSize) - { - case 1024: - defaultSubgroupOrderSize = 160; - break; - case 2048: - defaultSubgroupOrderSize = 224; - break; - case 3072: - defaultSubgroupOrderSize = 256; - break; - default: - throw InvalidArgument("DSA: not a valid prime length"); - } - - DL_GroupParameters_GFP::GenerateRandom(rng, CombinedNameValuePairs(alg, MakeParameters(Name::SubgroupOrderSize(), defaultSubgroupOrderSize, false))); - } -} - -bool DL_GroupParameters_DSA::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const -{ - bool pass = DL_GroupParameters_GFP::ValidateGroup(rng, level); - int pSize = GetModulus().BitCount(), qSize = GetSubgroupOrder().BitCount(); - pass = pass && ((pSize==1024 && qSize==160) || (pSize==2048 && qSize==224) || (pSize==2048 && qSize==256) || (pSize==3072 && qSize==256)); - return pass; -} - -void DL_SignatureMessageEncodingMethod_DSA::ComputeMessageRepresentative(RandomNumberGenerator &rng, - const byte *recoverableMessage, size_t recoverableMessageLength, - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const -{ - assert(recoverableMessageLength == 0); - assert(hashIdentifier.second == 0); - const size_t representativeByteLength = BitsToBytes(representativeBitLength); - const size_t digestSize = hash.DigestSize(); - const size_t paddingLength = SaturatingSubtract(representativeByteLength, digestSize); - - memset(representative, 0, paddingLength); - hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize)); - - if (digestSize*8 > representativeBitLength) - { - Integer h(representative, representativeByteLength); - h >>= representativeByteLength*8 - representativeBitLength; - h.Encode(representative, representativeByteLength); - } -} - -void DL_SignatureMessageEncodingMethod_NR::ComputeMessageRepresentative(RandomNumberGenerator &rng, - const byte *recoverableMessage, size_t recoverableMessageLength, - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const -{ - assert(recoverableMessageLength == 0); - assert(hashIdentifier.second == 0); - const size_t representativeByteLength = BitsToBytes(representativeBitLength); - const size_t digestSize = hash.DigestSize(); - const size_t paddingLength = SaturatingSubtract(representativeByteLength, digestSize); - - memset(representative, 0, paddingLength); - hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize)); - - if (digestSize*8 >= representativeBitLength) - { - Integer h(representative, representativeByteLength); - h >>= representativeByteLength*8 - representativeBitLength + 1; - h.Encode(representative, representativeByteLength); - } -} - -bool DL_GroupParameters_IntegerBased::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const -{ - const Integer &p = GetModulus(), &q = GetSubgroupOrder(); - - bool pass = true; - pass = pass && p > Integer::One() && p.IsOdd(); - pass = pass && q > Integer::One() && q.IsOdd(); - - if (level >= 1) - pass = pass && GetCofactor() > Integer::One() && GetGroupOrder() % q == Integer::Zero(); - if (level >= 2) - pass = pass && VerifyPrime(rng, q, level-2) && VerifyPrime(rng, p, level-2); - - return pass; -} - -bool DL_GroupParameters_IntegerBased::ValidateElement(unsigned int level, const Integer &g, const DL_FixedBasePrecomputation<Integer> *gpc) const -{ - const Integer &p = GetModulus(), &q = GetSubgroupOrder(); - - bool pass = true; - pass = pass && GetFieldType() == 1 ? g.IsPositive() : g.NotNegative(); - pass = pass && g < p && !IsIdentity(g); - - if (level >= 1) - { - if (gpc) - pass = pass && gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g; - } - if (level >= 2) - { - if (GetFieldType() == 2) - pass = pass && Jacobi(g*g-4, p)==-1; - - // verifying that Lucas((p+1)/2, w, p)==2 is omitted because it's too costly - // and at most 1 bit is leaked if it's false - bool fullValidate = (GetFieldType() == 2 && level >= 3) || !FastSubgroupCheckAvailable(); - - if (fullValidate && pass) - { - Integer gp = gpc ? gpc->Exponentiate(GetGroupPrecomputation(), q) : ExponentiateElement(g, q); - pass = pass && IsIdentity(gp); - } - else if (GetFieldType() == 1) - pass = pass && Jacobi(g, p) == 1; - } - - return pass; -} - -void DL_GroupParameters_IntegerBased::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) -{ - Integer p, q, g; - - if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g)) - { - q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2); - } - else - { - int modulusSize, subgroupOrderSize; - - if (!alg.GetIntValue("ModulusSize", modulusSize)) - modulusSize = alg.GetIntValueWithDefault("KeySize", 2048); - - if (!alg.GetIntValue("SubgroupOrderSize", subgroupOrderSize)) - subgroupOrderSize = GetDefaultSubgroupOrderSize(modulusSize); - - PrimeAndGenerator pg; - pg.Generate(GetFieldType() == 1 ? 1 : -1, rng, modulusSize, subgroupOrderSize); - p = pg.Prime(); - q = pg.SubPrime(); - g = pg.Generator(); - } - - Initialize(p, q, g); -} - -Integer DL_GroupParameters_IntegerBased::DecodeElement(const byte *encoded, bool checkForGroupMembership) const -{ - Integer g(encoded, GetModulus().ByteCount()); - if (!ValidateElement(1, g, NULL)) - throw DL_BadElement(); - return g; -} - -void DL_GroupParameters_IntegerBased::BERDecode(BufferedTransformation &bt) -{ - BERSequenceDecoder parameters(bt); - Integer p(parameters); - Integer q(parameters); - Integer g; - if (parameters.EndReached()) - { - g = q; - q = ComputeGroupOrder(p) / 2; - } - else - g.BERDecode(parameters); - parameters.MessageEnd(); - - SetModulusAndSubgroupGenerator(p, g); - SetSubgroupOrder(q); -} - -void DL_GroupParameters_IntegerBased::DEREncode(BufferedTransformation &bt) const -{ - DERSequenceEncoder parameters(bt); - GetModulus().DEREncode(parameters); - m_q.DEREncode(parameters); - GetSubgroupGenerator().DEREncode(parameters); - parameters.MessageEnd(); -} - -bool DL_GroupParameters_IntegerBased::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const -{ - return GetValueHelper<DL_GroupParameters<Element> >(this, name, valueType, pValue) - CRYPTOPP_GET_FUNCTION_ENTRY(Modulus); -} - -void DL_GroupParameters_IntegerBased::AssignFrom(const NameValuePairs &source) -{ - AssignFromHelper(this, source) - CRYPTOPP_SET_FUNCTION_ENTRY2(Modulus, SubgroupGenerator) - CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder) - ; -} - -OID DL_GroupParameters_IntegerBased::GetAlgorithmID() const -{ - return ASN1::id_dsa(); -} - -void DL_GroupParameters_GFP::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const -{ - ModularArithmetic ma(GetModulus()); - ma.SimultaneousExponentiate(results, base, exponents, exponentsCount); -} - -DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::MultiplyElements(const Element &a, const Element &b) const -{ - return a_times_b_mod_c(a, b, GetModulus()); -} - -DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const -{ - ModularArithmetic ma(GetModulus()); - return ma.CascadeExponentiate(element1, exponent1, element2, exponent2); -} - -Integer DL_GroupParameters_IntegerBased::GetMaxExponent() const -{ - return STDMIN(GetSubgroupOrder()-1, Integer::Power2(2*DiscreteLogWorkFactor(GetFieldType()*GetModulus().BitCount()))); -} - -unsigned int DL_GroupParameters_IntegerBased::GetDefaultSubgroupOrderSize(unsigned int modulusSize) const -{ - return 2*DiscreteLogWorkFactor(GetFieldType()*modulusSize); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/gfpcrypt.h b/lib/cryptopp/gfpcrypt.h deleted file mode 100644 index 7af993fb3..000000000 --- a/lib/cryptopp/gfpcrypt.h +++ /dev/null @@ -1,528 +0,0 @@ -#ifndef CRYPTOPP_GFPCRYPT_H -#define CRYPTOPP_GFPCRYPT_H - -/** \file - Implementation of schemes based on DL over GF(p) -*/ - -#include "pubkey.h" -#include "modexppc.h" -#include "sha.h" -#include "algparam.h" -#include "asn.h" -#include "smartptr.h" -#include "hmac.h" - -#include <limits.h> - -NAMESPACE_BEGIN(CryptoPP) - -CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters<Integer>; - -//! _ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBased : public ASN1CryptoMaterial<DL_GroupParameters<Integer> > -{ - typedef DL_GroupParameters_IntegerBased ThisClass; - -public: - void Initialize(const DL_GroupParameters_IntegerBased ¶ms) - {Initialize(params.GetModulus(), params.GetSubgroupOrder(), params.GetSubgroupGenerator());} - void Initialize(RandomNumberGenerator &rng, unsigned int pbits) - {GenerateRandom(rng, MakeParameters("ModulusSize", (int)pbits));} - void Initialize(const Integer &p, const Integer &g) - {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(ComputeGroupOrder(p)/2);} - void Initialize(const Integer &p, const Integer &q, const Integer &g) - {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(q);} - - // ASN1Object interface - void BERDecode(BufferedTransformation &bt); - void DEREncode(BufferedTransformation &bt) const; - - // GeneratibleCryptoMaterial interface - /*! parameters: (ModulusSize, SubgroupOrderSize (optional)) */ - void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; - void AssignFrom(const NameValuePairs &source); - - // DL_GroupParameters - const Integer & GetSubgroupOrder() const {return m_q;} - Integer GetGroupOrder() const {return GetFieldType() == 1 ? GetModulus()-Integer::One() : GetModulus()+Integer::One();} - bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; - bool ValidateElement(unsigned int level, const Integer &element, const DL_FixedBasePrecomputation<Integer> *precomp) const; - bool FastSubgroupCheckAvailable() const {return GetCofactor() == 2;} - void EncodeElement(bool reversible, const Element &element, byte *encoded) const - {element.Encode(encoded, GetModulus().ByteCount());} - unsigned int GetEncodedElementSize(bool reversible) const {return GetModulus().ByteCount();} - Integer DecodeElement(const byte *encoded, bool checkForGroupMembership) const; - Integer ConvertElementToInteger(const Element &element) const - {return element;} - Integer GetMaxExponent() const; - static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "";} - - OID GetAlgorithmID() const; - - virtual const Integer & GetModulus() const =0; - virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) =0; - - void SetSubgroupOrder(const Integer &q) - {m_q = q; ParametersChanged();} - -protected: - Integer ComputeGroupOrder(const Integer &modulus) const - {return modulus-(GetFieldType() == 1 ? 1 : -1);} - - // GF(p) = 1, GF(p^2) = 2 - virtual int GetFieldType() const =0; - virtual unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const; - -private: - Integer m_q; -}; - -//! _ -template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<CPP_TYPENAME GROUP_PRECOMP::Element> > -class CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBasedImpl : public DL_GroupParametersImpl<GROUP_PRECOMP, BASE_PRECOMP, DL_GroupParameters_IntegerBased> -{ - typedef DL_GroupParameters_IntegerBasedImpl<GROUP_PRECOMP, BASE_PRECOMP> ThisClass; - -public: - typedef typename GROUP_PRECOMP::Element Element; - - // GeneratibleCryptoMaterial interface - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const - {return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable();} - - void AssignFrom(const NameValuePairs &source) - {AssignFromHelper<DL_GroupParameters_IntegerBased>(this, source);} - - // DL_GroupParameters - const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return this->m_gpc;} - DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return this->m_gpc;} - - // IntegerGroupParameters - const Integer & GetModulus() const {return this->m_groupPrecomputation.GetModulus();} - const Integer & GetGenerator() const {return this->m_gpc.GetBase(this->GetGroupPrecomputation());} - - void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) // these have to be set together - {this->m_groupPrecomputation.SetModulus(p); this->m_gpc.SetBase(this->GetGroupPrecomputation(), g); this->ParametersChanged();} - - // non-inherited - bool operator==(const DL_GroupParameters_IntegerBasedImpl<GROUP_PRECOMP, BASE_PRECOMP> &rhs) const - {return GetModulus() == rhs.GetModulus() && GetGenerator() == rhs.GetGenerator() && this->GetSubgroupOrder() == rhs.GetSubgroupOrder();} - bool operator!=(const DL_GroupParameters_IntegerBasedImpl<GROUP_PRECOMP, BASE_PRECOMP> &rhs) const - {return !operator==(rhs);} -}; - -CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_IntegerBasedImpl<ModExpPrecomputation>; - -//! GF(p) group parameters -class CRYPTOPP_DLL DL_GroupParameters_GFP : public DL_GroupParameters_IntegerBasedImpl<ModExpPrecomputation> -{ -public: - // DL_GroupParameters - bool IsIdentity(const Integer &element) const {return element == Integer::One();} - void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; - - // NameValuePairs interface - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const - { - return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable(); - } - - // used by MQV - Element MultiplyElements(const Element &a, const Element &b) const; - Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const; - -protected: - int GetFieldType() const {return 1;} -}; - -//! GF(p) group parameters that default to same primes -class CRYPTOPP_DLL DL_GroupParameters_GFP_DefaultSafePrime : public DL_GroupParameters_GFP -{ -public: - typedef NoCofactorMultiplication DefaultCofactorOption; - -protected: - unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;} -}; - -//! GDSA algorithm -template <class T> -class DL_Algorithm_GDSA : public DL_ElgamalLikeSignatureAlgorithm<T> -{ -public: - static const char * CRYPTOPP_API StaticAlgorithmName() {return "DSA-1363";} - - void Sign(const DL_GroupParameters<T> ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const - { - const Integer &q = params.GetSubgroupOrder(); - r %= q; - Integer kInv = k.InverseMod(q); - s = (kInv * (x*r + e)) % q; - assert(!!r && !!s); - } - - bool Verify(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const - { - const Integer &q = params.GetSubgroupOrder(); - if (r>=q || r<1 || s>=q || s<1) - return false; - - Integer w = s.InverseMod(q); - Integer u1 = (e * w) % q; - Integer u2 = (r * w) % q; - // verify r == (g^u1 * y^u2 mod p) mod q - return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q; - } -}; - -CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<Integer>; - -//! NR algorithm -template <class T> -class DL_Algorithm_NR : public DL_ElgamalLikeSignatureAlgorithm<T> -{ -public: - static const char * CRYPTOPP_API StaticAlgorithmName() {return "NR";} - - void Sign(const DL_GroupParameters<T> ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const - { - const Integer &q = params.GetSubgroupOrder(); - r = (r + e) % q; - s = (k - x*r) % q; - assert(!!r); - } - - bool Verify(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const - { - const Integer &q = params.GetSubgroupOrder(); - if (r>=q || r<1 || s>=q) - return false; - - // check r == (m_g^s * m_y^r + m) mod m_q - return r == (params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(s, r)) + e) % q; - } -}; - -/*! DSA public key format is defined in 7.3.3 of RFC 2459. The - private key format is defined in 12.9 of PKCS #11 v2.10. */ -template <class GP> -class DL_PublicKey_GFP : public DL_PublicKeyImpl<GP> -{ -public: - void Initialize(const DL_GroupParameters_IntegerBased ¶ms, const Integer &y) - {this->AccessGroupParameters().Initialize(params); this->SetPublicElement(y);} - void Initialize(const Integer &p, const Integer &g, const Integer &y) - {this->AccessGroupParameters().Initialize(p, g); this->SetPublicElement(y);} - void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &y) - {this->AccessGroupParameters().Initialize(p, q, g); this->SetPublicElement(y);} - - // X509PublicKey - void BERDecodePublicKey(BufferedTransformation &bt, bool, size_t) - {this->SetPublicElement(Integer(bt));} - void DEREncodePublicKey(BufferedTransformation &bt) const - {this->GetPublicElement().DEREncode(bt);} -}; - -//! DL private key (in GF(p) groups) -template <class GP> -class DL_PrivateKey_GFP : public DL_PrivateKeyImpl<GP> -{ -public: - void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits) - {this->GenerateRandomWithKeySize(rng, modulusBits);} - void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g) - {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupGenerator", g));} - void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g) - {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupOrder", q)("SubgroupGenerator", g));} - void Initialize(const DL_GroupParameters_IntegerBased ¶ms, const Integer &x) - {this->AccessGroupParameters().Initialize(params); this->SetPrivateExponent(x);} - void Initialize(const Integer &p, const Integer &g, const Integer &x) - {this->AccessGroupParameters().Initialize(p, g); this->SetPrivateExponent(x);} - void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &x) - {this->AccessGroupParameters().Initialize(p, q, g); this->SetPrivateExponent(x);} -}; - -//! DL signing/verification keys (in GF(p) groups) -struct DL_SignatureKeys_GFP -{ - typedef DL_GroupParameters_GFP GroupParameters; - typedef DL_PublicKey_GFP<GroupParameters> PublicKey; - typedef DL_PrivateKey_GFP<GroupParameters> PrivateKey; -}; - -//! DL encryption/decryption keys (in GF(p) groups) -struct DL_CryptoKeys_GFP -{ - typedef DL_GroupParameters_GFP_DefaultSafePrime GroupParameters; - typedef DL_PublicKey_GFP<GroupParameters> PublicKey; - typedef DL_PrivateKey_GFP<GroupParameters> PrivateKey; -}; - -//! provided for backwards compatibility, this class uses the old non-standard Crypto++ key format -template <class BASE> -class DL_PublicKey_GFP_OldFormat : public BASE -{ -public: - void BERDecode(BufferedTransformation &bt) - { - BERSequenceDecoder seq(bt); - Integer v1(seq); - Integer v2(seq); - Integer v3(seq); - - if (seq.EndReached()) - { - this->AccessGroupParameters().Initialize(v1, v1/2, v2); - this->SetPublicElement(v3); - } - else - { - Integer v4(seq); - this->AccessGroupParameters().Initialize(v1, v2, v3); - this->SetPublicElement(v4); - } - - seq.MessageEnd(); - } - - void DEREncode(BufferedTransformation &bt) const - { - DERSequenceEncoder seq(bt); - this->GetGroupParameters().GetModulus().DEREncode(seq); - if (this->GetGroupParameters().GetCofactor() != 2) - this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq); - this->GetGroupParameters().GetGenerator().DEREncode(seq); - this->GetPublicElement().DEREncode(seq); - seq.MessageEnd(); - } -}; - -//! provided for backwards compatibility, this class uses the old non-standard Crypto++ key format -template <class BASE> -class DL_PrivateKey_GFP_OldFormat : public BASE -{ -public: - void BERDecode(BufferedTransformation &bt) - { - BERSequenceDecoder seq(bt); - Integer v1(seq); - Integer v2(seq); - Integer v3(seq); - Integer v4(seq); - - if (seq.EndReached()) - { - this->AccessGroupParameters().Initialize(v1, v1/2, v2); - this->SetPrivateExponent(v4 % (v1/2)); // some old keys may have x >= q - } - else - { - Integer v5(seq); - this->AccessGroupParameters().Initialize(v1, v2, v3); - this->SetPrivateExponent(v5); - } - - seq.MessageEnd(); - } - - void DEREncode(BufferedTransformation &bt) const - { - DERSequenceEncoder seq(bt); - this->GetGroupParameters().GetModulus().DEREncode(seq); - if (this->GetGroupParameters().GetCofactor() != 2) - this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq); - this->GetGroupParameters().GetGenerator().DEREncode(seq); - this->GetGroupParameters().ExponentiateBase(this->GetPrivateExponent()).DEREncode(seq); - this->GetPrivateExponent().DEREncode(seq); - seq.MessageEnd(); - } -}; - -//! <a href="http://www.weidai.com/scan-mirror/sig.html#DSA-1363">DSA-1363</a> -template <class H> -struct GDSA : public DL_SS< - DL_SignatureKeys_GFP, - DL_Algorithm_GDSA<Integer>, - DL_SignatureMessageEncodingMethod_DSA, - H> -{ -}; - -//! <a href="http://www.weidai.com/scan-mirror/sig.html#NR">NR</a> -template <class H> -struct NR : public DL_SS< - DL_SignatureKeys_GFP, - DL_Algorithm_NR<Integer>, - DL_SignatureMessageEncodingMethod_NR, - H> -{ -}; - -//! DSA group parameters, these are GF(p) group parameters that are allowed by the DSA standard -class CRYPTOPP_DLL DL_GroupParameters_DSA : public DL_GroupParameters_GFP -{ -public: - /*! also checks that the lengths of p and q are allowed by the DSA standard */ - bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; - /*! parameters: (ModulusSize), or (Modulus, SubgroupOrder, SubgroupGenerator) */ - /*! ModulusSize must be between DSA::MIN_PRIME_LENGTH and DSA::MAX_PRIME_LENGTH, and divisible by DSA::PRIME_LENGTH_MULTIPLE */ - void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); - - static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits) - {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;} - - enum {MIN_PRIME_LENGTH = 1024, MAX_PRIME_LENGTH = 3072, PRIME_LENGTH_MULTIPLE = 1024}; -}; - -template <class H> -class DSA2; - -//! DSA keys -struct DL_Keys_DSA -{ - typedef DL_PublicKey_GFP<DL_GroupParameters_DSA> PublicKey; - typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_GFP<DL_GroupParameters_DSA>, DSA2<SHA> > PrivateKey; -}; - -//! <a href="http://en.wikipedia.org/wiki/Digital_Signature_Algorithm">DSA</a>, as specified in FIPS 186-3 -// class named DSA2 instead of DSA for backwards compatibility (DSA was a non-template class) -template <class H> -class DSA2 : public DL_SS< - DL_Keys_DSA, - DL_Algorithm_GDSA<Integer>, - DL_SignatureMessageEncodingMethod_DSA, - H, - DSA2<H> > -{ -public: - static std::string CRYPTOPP_API StaticAlgorithmName() {return "DSA/" + (std::string)H::StaticAlgorithmName();} -}; - -//! DSA with SHA-1, typedef'd for backwards compatibility -typedef DSA2<SHA> DSA; - -CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_GFP<DL_GroupParameters_DSA>; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_GFP<DL_GroupParameters_DSA>; -CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_GFP<DL_GroupParameters_DSA>, DSA2<SHA> >; - -//! the XOR encryption method, for use with DL-based cryptosystems -template <class MAC, bool DHAES_MODE> -class DL_EncryptionAlgorithm_Xor : public DL_SymmetricEncryptionAlgorithm -{ -public: - bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;} - size_t GetSymmetricKeyLength(size_t plaintextLength) const - {return plaintextLength + MAC::DEFAULT_KEYLENGTH;} - size_t GetSymmetricCiphertextLength(size_t plaintextLength) const - {return plaintextLength + MAC::DIGESTSIZE;} - size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const - {return (unsigned int)SaturatingSubtract(ciphertextLength, (unsigned int)MAC::DIGESTSIZE);} - void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const - { - const byte *cipherKey, *macKey; - if (DHAES_MODE) - { - macKey = key; - cipherKey = key + MAC::DEFAULT_KEYLENGTH; - } - else - { - cipherKey = key; - macKey = key + plaintextLength; - } - - ConstByteArrayParameter encodingParameters; - parameters.GetValue(Name::EncodingParameters(), encodingParameters); - - xorbuf(ciphertext, plaintext, cipherKey, plaintextLength); - MAC mac(macKey); - mac.Update(ciphertext, plaintextLength); - mac.Update(encodingParameters.begin(), encodingParameters.size()); - if (DHAES_MODE) - { - byte L[8] = {0,0,0,0}; - PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size())); - mac.Update(L, 8); - } - mac.Final(ciphertext + plaintextLength); - } - DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters) const - { - size_t plaintextLength = GetMaxSymmetricPlaintextLength(ciphertextLength); - const byte *cipherKey, *macKey; - if (DHAES_MODE) - { - macKey = key; - cipherKey = key + MAC::DEFAULT_KEYLENGTH; - } - else - { - cipherKey = key; - macKey = key + plaintextLength; - } - - ConstByteArrayParameter encodingParameters; - parameters.GetValue(Name::EncodingParameters(), encodingParameters); - - MAC mac(macKey); - mac.Update(ciphertext, plaintextLength); - mac.Update(encodingParameters.begin(), encodingParameters.size()); - if (DHAES_MODE) - { - byte L[8] = {0,0,0,0}; - PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size())); - mac.Update(L, 8); - } - if (!mac.Verify(ciphertext + plaintextLength)) - return DecodingResult(); - - xorbuf(plaintext, ciphertext, cipherKey, plaintextLength); - return DecodingResult(plaintextLength); - } -}; - -//! _ -template <class T, bool DHAES_MODE, class KDF> -class DL_KeyDerivationAlgorithm_P1363 : public DL_KeyDerivationAlgorithm<T> -{ -public: - bool ParameterSupported(const char *name) const {return strcmp(name, Name::KeyDerivationParameters()) == 0;} - void Derive(const DL_GroupParameters<T> ¶ms, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs ¶meters) const - { - SecByteBlock agreedSecret; - if (DHAES_MODE) - { - agreedSecret.New(params.GetEncodedElementSize(true) + params.GetEncodedElementSize(false)); - params.EncodeElement(true, ephemeralPublicKey, agreedSecret); - params.EncodeElement(false, agreedElement, agreedSecret + params.GetEncodedElementSize(true)); - } - else - { - agreedSecret.New(params.GetEncodedElementSize(false)); - params.EncodeElement(false, agreedElement, agreedSecret); - } - - ConstByteArrayParameter derivationParameters; - parameters.GetValue(Name::KeyDerivationParameters(), derivationParameters); - KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size(), derivationParameters.begin(), derivationParameters.size()); - } -}; - -//! Discrete Log Integrated Encryption Scheme, AKA <a href="http://www.weidai.com/scan-mirror/ca.html#DLIES">DLIES</a> -template <class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = true> -struct DLIES - : public DL_ES< - DL_CryptoKeys_GFP, - DL_KeyAgreementAlgorithm_DH<Integer, COFACTOR_OPTION>, - DL_KeyDerivationAlgorithm_P1363<Integer, DHAES_MODE, P1363_KDF2<SHA1> >, - DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>, - DLIES<> > -{ - static std::string CRYPTOPP_API StaticAlgorithmName() {return "DLIES";} // TODO: fix this after name is standardized -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/gzip.h b/lib/cryptopp/gzip.h deleted file mode 100644 index f3148ad71..000000000 --- a/lib/cryptopp/gzip.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef CRYPTOPP_GZIP_H -#define CRYPTOPP_GZIP_H - -#include "zdeflate.h" -#include "zinflate.h" -#include "crc.h" - -NAMESPACE_BEGIN(CryptoPP) - -/// GZIP Compression (RFC 1952) -class Gzip : public Deflator -{ -public: - Gzip(BufferedTransformation *attachment=NULL, unsigned int deflateLevel=DEFAULT_DEFLATE_LEVEL, unsigned int log2WindowSize=DEFAULT_LOG2_WINDOW_SIZE, bool detectUncompressible=true) - : Deflator(attachment, deflateLevel, log2WindowSize, detectUncompressible) {} - Gzip(const NameValuePairs ¶meters, BufferedTransformation *attachment=NULL) - : Deflator(parameters, attachment) {} - -protected: - enum {MAGIC1=0x1f, MAGIC2=0x8b, // flags for the header - DEFLATED=8, FAST=4, SLOW=2}; - - void WritePrestreamHeader(); - void ProcessUncompressedData(const byte *string, size_t length); - void WritePoststreamTail(); - - word32 m_totalLen; - CRC32 m_crc; -}; - -/// GZIP Decompression (RFC 1952) -class Gunzip : public Inflator -{ -public: - typedef Inflator::Err Err; - class HeaderErr : public Err {public: HeaderErr() : Err(INVALID_DATA_FORMAT, "Gunzip: header decoding error") {}}; - class TailErr : public Err {public: TailErr() : Err(INVALID_DATA_FORMAT, "Gunzip: tail too short") {}}; - class CrcErr : public Err {public: CrcErr() : Err(DATA_INTEGRITY_CHECK_FAILED, "Gunzip: CRC check error") {}}; - class LengthErr : public Err {public: LengthErr() : Err(DATA_INTEGRITY_CHECK_FAILED, "Gunzip: length check error") {}}; - - /*! \param repeat decompress multiple compressed streams in series - \param autoSignalPropagation 0 to turn off MessageEnd signal - */ - Gunzip(BufferedTransformation *attachment = NULL, bool repeat = false, int autoSignalPropagation = -1); - -protected: - enum {MAGIC1=0x1f, MAGIC2=0x8b, // flags for the header - DEFLATED=8}; - - enum FLAG_MASKS { - CONTINUED=2, EXTRA_FIELDS=4, FILENAME=8, COMMENTS=16, ENCRYPTED=32}; - - unsigned int MaxPrestreamHeaderSize() const {return 1024;} - void ProcessPrestreamHeader(); - void ProcessDecompressedData(const byte *string, size_t length); - unsigned int MaxPoststreamTailSize() const {return 8;} - void ProcessPoststreamTail(); - - word32 m_length; - CRC32 m_crc; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/hex.cpp b/lib/cryptopp/hex.cpp deleted file mode 100644 index 5731df550..000000000 --- a/lib/cryptopp/hex.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// hex.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "hex.h" - -NAMESPACE_BEGIN(CryptoPP) - -static const byte s_vecUpper[] = "0123456789ABCDEF"; -static const byte s_vecLower[] = "0123456789abcdef"; - -void HexEncoder::IsolatedInitialize(const NameValuePairs ¶meters) -{ - bool uppercase = parameters.GetValueWithDefault(Name::Uppercase(), true); - m_filter->Initialize(CombinedNameValuePairs( - parameters, - MakeParameters(Name::EncodingLookupArray(), uppercase ? &s_vecUpper[0] : &s_vecLower[0], false)(Name::Log2Base(), 4, true))); -} - -void HexDecoder::IsolatedInitialize(const NameValuePairs ¶meters) -{ - BaseN_Decoder::IsolatedInitialize(CombinedNameValuePairs( - parameters, - MakeParameters(Name::DecodingLookupArray(), GetDefaultDecodingLookupArray(), false)(Name::Log2Base(), 4, true))); -} - -const int *HexDecoder::GetDefaultDecodingLookupArray() -{ - static volatile bool s_initialized = false; - static int s_array[256]; - - if (!s_initialized) - { - InitializeDecodingLookupArray(s_array, s_vecUpper, 16, true); - s_initialized = true; - } - return s_array; -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/hex.h b/lib/cryptopp/hex.h deleted file mode 100644 index 006914c5a..000000000 --- a/lib/cryptopp/hex.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef CRYPTOPP_HEX_H -#define CRYPTOPP_HEX_H - -#include "basecode.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! Converts given data to base 16 -class CRYPTOPP_DLL HexEncoder : public SimpleProxyFilter -{ -public: - HexEncoder(BufferedTransformation *attachment = NULL, bool uppercase = true, int outputGroupSize = 0, const std::string &separator = ":", const std::string &terminator = "") - : SimpleProxyFilter(new BaseN_Encoder(new Grouper), attachment) - { - IsolatedInitialize(MakeParameters(Name::Uppercase(), uppercase)(Name::GroupSize(), outputGroupSize)(Name::Separator(), ConstByteArrayParameter(separator))(Name::Terminator(), ConstByteArrayParameter(terminator))); - } - - void IsolatedInitialize(const NameValuePairs ¶meters); -}; - -//! Decode base 16 data back to bytes -class CRYPTOPP_DLL HexDecoder : public BaseN_Decoder -{ -public: - HexDecoder(BufferedTransformation *attachment = NULL) - : BaseN_Decoder(GetDefaultDecodingLookupArray(), 4, attachment) {} - - void IsolatedInitialize(const NameValuePairs ¶meters); - -private: - static const int * CRYPTOPP_API GetDefaultDecodingLookupArray(); -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/hmac.cpp b/lib/cryptopp/hmac.cpp deleted file mode 100644 index d4a649c08..000000000 --- a/lib/cryptopp/hmac.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// hmac.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "hmac.h" - -NAMESPACE_BEGIN(CryptoPP) - -void HMAC_Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs &) -{ - AssertValidKeyLength(keylength); - - Restart(); - - HashTransformation &hash = AccessHash(); - unsigned int blockSize = hash.BlockSize(); - - if (!blockSize) - throw InvalidArgument("HMAC: can only be used with a block-based hash function"); - - m_buf.resize(2*AccessHash().BlockSize() + AccessHash().DigestSize()); - - if (keylength <= blockSize) - memcpy(AccessIpad(), userKey, keylength); - else - { - AccessHash().CalculateDigest(AccessIpad(), userKey, keylength); - keylength = hash.DigestSize(); - } - - assert(keylength <= blockSize); - memset(AccessIpad()+keylength, 0, blockSize-keylength); - - for (unsigned int i=0; i<blockSize; i++) - { - AccessOpad()[i] = AccessIpad()[i] ^ 0x5c; - AccessIpad()[i] ^= 0x36; - } -} - -void HMAC_Base::KeyInnerHash() -{ - assert(!m_innerHashKeyed); - HashTransformation &hash = AccessHash(); - hash.Update(AccessIpad(), hash.BlockSize()); - m_innerHashKeyed = true; -} - -void HMAC_Base::Restart() -{ - if (m_innerHashKeyed) - { - AccessHash().Restart(); - m_innerHashKeyed = false; - } -} - -void HMAC_Base::Update(const byte *input, size_t length) -{ - if (!m_innerHashKeyed) - KeyInnerHash(); - AccessHash().Update(input, length); -} - -void HMAC_Base::TruncatedFinal(byte *mac, size_t size) -{ - ThrowIfInvalidTruncatedSize(size); - - HashTransformation &hash = AccessHash(); - - if (!m_innerHashKeyed) - KeyInnerHash(); - hash.Final(AccessInnerHash()); - - hash.Update(AccessOpad(), hash.BlockSize()); - hash.Update(AccessInnerHash(), hash.DigestSize()); - hash.TruncatedFinal(mac, size); - - m_innerHashKeyed = false; -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/hmac.h b/lib/cryptopp/hmac.h deleted file mode 100644 index 62db5ef33..000000000 --- a/lib/cryptopp/hmac.h +++ /dev/null @@ -1,61 +0,0 @@ -// hmac.h - written and placed in the public domain by Wei Dai - -#ifndef CRYPTOPP_HMAC_H -#define CRYPTOPP_HMAC_H - -#include "seckey.h" -#include "secblock.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE HMAC_Base : public VariableKeyLength<16, 0, INT_MAX>, public MessageAuthenticationCode -{ -public: - HMAC_Base() : m_innerHashKeyed(false) {} - void UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs ¶ms); - - void Restart(); - void Update(const byte *input, size_t length); - void TruncatedFinal(byte *mac, size_t size); - unsigned int OptimalBlockSize() const {return const_cast<HMAC_Base*>(this)->AccessHash().OptimalBlockSize();} - unsigned int DigestSize() const {return const_cast<HMAC_Base*>(this)->AccessHash().DigestSize();} - -protected: - virtual HashTransformation & AccessHash() =0; - byte * AccessIpad() {return m_buf;} - byte * AccessOpad() {return m_buf + AccessHash().BlockSize();} - byte * AccessInnerHash() {return m_buf + 2*AccessHash().BlockSize();} - -private: - void KeyInnerHash(); - - SecByteBlock m_buf; - bool m_innerHashKeyed; -}; - -//! <a href="http://www.weidai.com/scan-mirror/mac.html#HMAC">HMAC</a> -/*! HMAC(K, text) = H(K XOR opad, H(K XOR ipad, text)) */ -template <class T> -class HMAC : public MessageAuthenticationCodeImpl<HMAC_Base, HMAC<T> > -{ -public: - CRYPTOPP_CONSTANT(DIGESTSIZE=T::DIGESTSIZE) - CRYPTOPP_CONSTANT(BLOCKSIZE=T::BLOCKSIZE) - - HMAC() {} - HMAC(const byte *key, size_t length=HMAC_Base::DEFAULT_KEYLENGTH) - {this->SetKey(key, length);} - - static std::string StaticAlgorithmName() {return std::string("HMAC(") + T::StaticAlgorithmName() + ")";} - std::string AlgorithmName() const {return std::string("HMAC(") + m_hash.AlgorithmName() + ")";} - -private: - HashTransformation & AccessHash() {return m_hash;} - - T m_hash; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/hrtimer.cpp b/lib/cryptopp/hrtimer.cpp deleted file mode 100644 index 6871a15dc..000000000 --- a/lib/cryptopp/hrtimer.cpp +++ /dev/null @@ -1,138 +0,0 @@ -// hrtimer.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "hrtimer.h" -#include "misc.h" -#include <stddef.h> // for NULL -#include <time.h> - -#if defined(CRYPTOPP_WIN32_AVAILABLE) -#include <windows.h> -#elif defined(CRYPTOPP_UNIX_AVAILABLE) -#include <sys/time.h> -#include <sys/times.h> -#include <unistd.h> -#endif - -#include <assert.h> - -NAMESPACE_BEGIN(CryptoPP) - -#ifndef CRYPTOPP_IMPORTS - -double TimerBase::ConvertTo(TimerWord t, Unit unit) -{ - static unsigned long unitsPerSecondTable[] = {1, 1000, 1000*1000, 1000*1000*1000}; - - assert(unit < sizeof(unitsPerSecondTable) / sizeof(unitsPerSecondTable[0])); - return (double)CRYPTOPP_VC6_INT64 t * unitsPerSecondTable[unit] / CRYPTOPP_VC6_INT64 TicksPerSecond(); -} - -void TimerBase::StartTimer() -{ - m_last = m_start = GetCurrentTimerValue(); - m_started = true; -} - -double TimerBase::ElapsedTimeAsDouble() -{ - if (m_stuckAtZero) - return 0; - - if (m_started) - { - TimerWord now = GetCurrentTimerValue(); - if (m_last < now) // protect against OS bugs where time goes backwards - m_last = now; - return ConvertTo(m_last - m_start, m_timerUnit); - } - - StartTimer(); - return 0; -} - -unsigned long TimerBase::ElapsedTime() -{ - double elapsed = ElapsedTimeAsDouble(); - assert(elapsed <= ULONG_MAX); - return (unsigned long)elapsed; -} - -TimerWord Timer::GetCurrentTimerValue() -{ -#if defined(CRYPTOPP_WIN32_AVAILABLE) - LARGE_INTEGER now; - if (!QueryPerformanceCounter(&now)) - throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceCounter failed with error " + IntToString(GetLastError())); - return now.QuadPart; -#elif defined(CRYPTOPP_UNIX_AVAILABLE) - timeval now; - gettimeofday(&now, NULL); - return (TimerWord)now.tv_sec * 1000000 + now.tv_usec; -#else - return clock(); -#endif -} - -TimerWord Timer::TicksPerSecond() -{ -#if defined(CRYPTOPP_WIN32_AVAILABLE) - static LARGE_INTEGER freq = {0}; - if (freq.QuadPart == 0) - { - if (!QueryPerformanceFrequency(&freq)) - throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceFrequency failed with error " + IntToString(GetLastError())); - } - return freq.QuadPart; -#elif defined(CRYPTOPP_UNIX_AVAILABLE) - return 1000000; -#else - return CLOCKS_PER_SEC; -#endif -} - -#endif // #ifndef CRYPTOPP_IMPORTS - -TimerWord ThreadUserTimer::GetCurrentTimerValue() -{ -#if defined(CRYPTOPP_WIN32_AVAILABLE) - static bool getCurrentThreadImplemented = true; - if (getCurrentThreadImplemented) - { - FILETIME now, ignored; - if (!GetThreadTimes(GetCurrentThread(), &ignored, &ignored, &ignored, &now)) - { - DWORD lastError = GetLastError(); - if (lastError == ERROR_CALL_NOT_IMPLEMENTED) - { - getCurrentThreadImplemented = false; - goto GetCurrentThreadNotImplemented; - } - throw Exception(Exception::OTHER_ERROR, "ThreadUserTimer: GetThreadTimes failed with error " + IntToString(lastError)); - } - return now.dwLowDateTime + ((TimerWord)now.dwHighDateTime << 32); - } -GetCurrentThreadNotImplemented: - return (TimerWord)clock() * (10*1000*1000 / CLOCKS_PER_SEC); -#elif defined(CRYPTOPP_UNIX_AVAILABLE) - tms now; - times(&now); - return now.tms_utime; -#else - return clock(); -#endif -} - -TimerWord ThreadUserTimer::TicksPerSecond() -{ -#if defined(CRYPTOPP_WIN32_AVAILABLE) - return 10*1000*1000; -#elif defined(CRYPTOPP_UNIX_AVAILABLE) - static const long ticksPerSecond = sysconf(_SC_CLK_TCK); - return ticksPerSecond; -#else - return CLOCKS_PER_SEC; -#endif -} - -NAMESPACE_END diff --git a/lib/cryptopp/hrtimer.h b/lib/cryptopp/hrtimer.h deleted file mode 100644 index 858dbd226..000000000 --- a/lib/cryptopp/hrtimer.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef CRYPTOPP_HRTIMER_H -#define CRYPTOPP_HRTIMER_H - -#include "config.h" -#ifndef HIGHRES_TIMER_AVAILABLE -#include <time.h> -#endif - -NAMESPACE_BEGIN(CryptoPP) - -#ifdef HIGHRES_TIMER_AVAILABLE - typedef word64 TimerWord; -#else - typedef clock_t TimerWord; -#endif - -//! _ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TimerBase -{ -public: - enum Unit {SECONDS = 0, MILLISECONDS, MICROSECONDS, NANOSECONDS}; - TimerBase(Unit unit, bool stuckAtZero) : m_timerUnit(unit), m_stuckAtZero(stuckAtZero), m_started(false) {} - - virtual TimerWord GetCurrentTimerValue() =0; // GetCurrentTime is a macro in MSVC 6.0 - virtual TimerWord TicksPerSecond() =0; // this is not the resolution, just a conversion factor into seconds - - void StartTimer(); - double ElapsedTimeAsDouble(); - unsigned long ElapsedTime(); - -private: - double ConvertTo(TimerWord t, Unit unit); - - Unit m_timerUnit; // HPUX workaround: m_unit is a system macro on HPUX - bool m_stuckAtZero, m_started; - TimerWord m_start, m_last; -}; - -//! measure CPU time spent executing instructions of this thread (if supported by OS) -/*! /note This only works correctly on Windows NT or later. On Unix it reports process time, and others wall clock time. -*/ -class ThreadUserTimer : public TimerBase -{ -public: - ThreadUserTimer(Unit unit = TimerBase::SECONDS, bool stuckAtZero = false) : TimerBase(unit, stuckAtZero) {} - TimerWord GetCurrentTimerValue(); - TimerWord TicksPerSecond(); -}; - -//! high resolution timer -class CRYPTOPP_DLL Timer : public TimerBase -{ -public: - Timer(Unit unit = TimerBase::SECONDS, bool stuckAtZero = false) : TimerBase(unit, stuckAtZero) {} - TimerWord GetCurrentTimerValue(); - TimerWord TicksPerSecond(); -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/integer.cpp b/lib/cryptopp/integer.cpp deleted file mode 100644 index f07cce873..000000000 --- a/lib/cryptopp/integer.cpp +++ /dev/null @@ -1,4235 +0,0 @@ -// integer.cpp - written and placed in the public domain by Wei Dai -// contains public domain code contributed by Alister Lee and Leonard Janke - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "integer.h" -#include "modarith.h" -#include "nbtheory.h" -#include "asn.h" -#include "oids.h" -#include "words.h" -#include "algparam.h" -#include "pubkey.h" // for P1363_KDF2 -#include "sha.h" -#include "cpu.h" - -#include <iostream> - -#if _MSC_VER >= 1400 - #include <intrin.h> -#endif - -#ifdef __DECCXX - #include <c_asm.h> -#endif - -#ifdef CRYPTOPP_MSVC6_NO_PP - #pragma message("You do not seem to have the Visual C++ Processor Pack installed, so use of SSE2 instructions will be disabled.") -#endif - -#define CRYPTOPP_INTEGER_SSE2 (CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86) - -NAMESPACE_BEGIN(CryptoPP) - -bool AssignIntToInteger(const std::type_info &valueType, void *pInteger, const void *pInt) -{ - if (valueType != typeid(Integer)) - return false; - *reinterpret_cast<Integer *>(pInteger) = *reinterpret_cast<const int *>(pInt); - return true; -} - -inline static int Compare(const word *A, const word *B, size_t N) -{ - while (N--) - if (A[N] > B[N]) - return 1; - else if (A[N] < B[N]) - return -1; - - return 0; -} - -inline static int Increment(word *A, size_t N, word B=1) -{ - assert(N); - word t = A[0]; - A[0] = t+B; - if (A[0] >= t) - return 0; - for (unsigned i=1; i<N; i++) - if (++A[i]) - return 0; - return 1; -} - -inline static int Decrement(word *A, size_t N, word B=1) -{ - assert(N); - word t = A[0]; - A[0] = t-B; - if (A[0] <= t) - return 0; - for (unsigned i=1; i<N; i++) - if (A[i]--) - return 0; - return 1; -} - -static void TwosComplement(word *A, size_t N) -{ - Decrement(A, N); - for (unsigned i=0; i<N; i++) - A[i] = ~A[i]; -} - -static word AtomicInverseModPower2(word A) -{ - assert(A%2==1); - - word R=A%8; - - for (unsigned i=3; i<WORD_BITS; i*=2) - R = R*(2-R*A); - - assert(R*A==1); - return R; -} - -// ******************************************************** - -#if !defined(CRYPTOPP_NATIVE_DWORD_AVAILABLE) || (defined(__x86_64__) && defined(CRYPTOPP_WORD128_AVAILABLE)) - #define Declare2Words(x) word x##0, x##1; - #define AssignWord(a, b) a##0 = b; a##1 = 0; - #define Add2WordsBy1(a, b, c) a##0 = b##0 + c; a##1 = b##1 + (a##0 < c); - #define LowWord(a) a##0 - #define HighWord(a) a##1 - #ifdef _MSC_VER - #define MultiplyWordsLoHi(p0, p1, a, b) p0 = _umul128(a, b, &p1); - #ifndef __INTEL_COMPILER - #define Double3Words(c, d) d##1 = __shiftleft128(d##0, d##1, 1); d##0 = __shiftleft128(c, d##0, 1); c *= 2; - #endif - #elif defined(__DECCXX) - #define MultiplyWordsLoHi(p0, p1, a, b) p0 = a*b; p1 = asm("umulh %a0, %a1, %v0", a, b); - #elif defined(__x86_64__) - #if defined(__SUNPRO_CC) && __SUNPRO_CC < 0x5100 - // Sun Studio's gcc-style inline assembly is heavily bugged as of version 5.9 Patch 124864-09 2008/12/16, but this one works - #define MultiplyWordsLoHi(p0, p1, a, b) asm ("mulq %3" : "=a"(p0), "=d"(p1) : "a"(a), "r"(b) : "cc"); - #else - #define MultiplyWordsLoHi(p0, p1, a, b) asm ("mulq %3" : "=a"(p0), "=d"(p1) : "a"(a), "g"(b) : "cc"); - #define MulAcc(c, d, a, b) asm ("mulq %6; addq %3, %0; adcq %4, %1; adcq $0, %2;" : "+r"(c), "+r"(d##0), "+r"(d##1), "=a"(p0), "=d"(p1) : "a"(a), "g"(b) : "cc"); - #define Double3Words(c, d) asm ("addq %0, %0; adcq %1, %1; adcq %2, %2;" : "+r"(c), "+r"(d##0), "+r"(d##1) : : "cc"); - #define Acc2WordsBy1(a, b) asm ("addq %2, %0; adcq $0, %1;" : "+r"(a##0), "+r"(a##1) : "r"(b) : "cc"); - #define Acc2WordsBy2(a, b) asm ("addq %2, %0; adcq %3, %1;" : "+r"(a##0), "+r"(a##1) : "r"(b##0), "r"(b##1) : "cc"); - #define Acc3WordsBy2(c, d, e) asm ("addq %5, %0; adcq %6, %1; adcq $0, %2;" : "+r"(c), "=r"(e##0), "=r"(e##1) : "1"(d##0), "2"(d##1), "r"(e##0), "r"(e##1) : "cc"); - #endif - #endif - #define MultiplyWords(p, a, b) MultiplyWordsLoHi(p##0, p##1, a, b) - #ifndef Double3Words - #define Double3Words(c, d) d##1 = 2*d##1 + (d##0>>(WORD_BITS-1)); d##0 = 2*d##0 + (c>>(WORD_BITS-1)); c *= 2; - #endif - #ifndef Acc2WordsBy2 - #define Acc2WordsBy2(a, b) a##0 += b##0; a##1 += a##0 < b##0; a##1 += b##1; - #endif - #define AddWithCarry(u, a, b) {word t = a+b; u##0 = t + u##1; u##1 = (t<a) + (u##0<t);} - #define SubtractWithBorrow(u, a, b) {word t = a-b; u##0 = t - u##1; u##1 = (t>a) + (u##0>t);} - #define GetCarry(u) u##1 - #define GetBorrow(u) u##1 -#else - #define Declare2Words(x) dword x; - #if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER) - #define MultiplyWords(p, a, b) p = __emulu(a, b); - #else - #define MultiplyWords(p, a, b) p = (dword)a*b; - #endif - #define AssignWord(a, b) a = b; - #define Add2WordsBy1(a, b, c) a = b + c; - #define Acc2WordsBy2(a, b) a += b; - #define LowWord(a) word(a) - #define HighWord(a) word(a>>WORD_BITS) - #define Double3Words(c, d) d = 2*d + (c>>(WORD_BITS-1)); c *= 2; - #define AddWithCarry(u, a, b) u = dword(a) + b + GetCarry(u); - #define SubtractWithBorrow(u, a, b) u = dword(a) - b - GetBorrow(u); - #define GetCarry(u) HighWord(u) - #define GetBorrow(u) word(u>>(WORD_BITS*2-1)) -#endif -#ifndef MulAcc - #define MulAcc(c, d, a, b) MultiplyWords(p, a, b); Acc2WordsBy1(p, c); c = LowWord(p); Acc2WordsBy1(d, HighWord(p)); -#endif -#ifndef Acc2WordsBy1 - #define Acc2WordsBy1(a, b) Add2WordsBy1(a, a, b) -#endif -#ifndef Acc3WordsBy2 - #define Acc3WordsBy2(c, d, e) Acc2WordsBy1(e, c); c = LowWord(e); Add2WordsBy1(e, d, HighWord(e)); -#endif - -class DWord -{ -public: - DWord() {} - -#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE - explicit DWord(word low) - { - m_whole = low; - } -#else - explicit DWord(word low) - { - m_halfs.low = low; - m_halfs.high = 0; - } -#endif - - DWord(word low, word high) - { - m_halfs.low = low; - m_halfs.high = high; - } - - static DWord Multiply(word a, word b) - { - DWord r; - #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE - r.m_whole = (dword)a * b; - #elif defined(MultiplyWordsLoHi) - MultiplyWordsLoHi(r.m_halfs.low, r.m_halfs.high, a, b); - #endif - return r; - } - - static DWord MultiplyAndAdd(word a, word b, word c) - { - DWord r = Multiply(a, b); - return r += c; - } - - DWord & operator+=(word a) - { - #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE - m_whole = m_whole + a; - #else - m_halfs.low += a; - m_halfs.high += (m_halfs.low < a); - #endif - return *this; - } - - DWord operator+(word a) - { - DWord r; - #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE - r.m_whole = m_whole + a; - #else - r.m_halfs.low = m_halfs.low + a; - r.m_halfs.high = m_halfs.high + (r.m_halfs.low < a); - #endif - return r; - } - - DWord operator-(DWord a) - { - DWord r; - #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE - r.m_whole = m_whole - a.m_whole; - #else - r.m_halfs.low = m_halfs.low - a.m_halfs.low; - r.m_halfs.high = m_halfs.high - a.m_halfs.high - (r.m_halfs.low > m_halfs.low); - #endif - return r; - } - - DWord operator-(word a) - { - DWord r; - #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE - r.m_whole = m_whole - a; - #else - r.m_halfs.low = m_halfs.low - a; - r.m_halfs.high = m_halfs.high - (r.m_halfs.low > m_halfs.low); - #endif - return r; - } - - // returns quotient, which must fit in a word - word operator/(word divisor); - - word operator%(word a); - - bool operator!() const - { - #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE - return !m_whole; - #else - return !m_halfs.high && !m_halfs.low; - #endif - } - - word GetLowHalf() const {return m_halfs.low;} - word GetHighHalf() const {return m_halfs.high;} - word GetHighHalfAsBorrow() const {return 0-m_halfs.high;} - -private: - union - { - #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE - dword m_whole; - #endif - struct - { - #ifdef IS_LITTLE_ENDIAN - word low; - word high; - #else - word high; - word low; - #endif - } m_halfs; - }; -}; - -class Word -{ -public: - Word() {} - - Word(word value) - { - m_whole = value; - } - - Word(hword low, hword high) - { - m_whole = low | (word(high) << (WORD_BITS/2)); - } - - static Word Multiply(hword a, hword b) - { - Word r; - r.m_whole = (word)a * b; - return r; - } - - Word operator-(Word a) - { - Word r; - r.m_whole = m_whole - a.m_whole; - return r; - } - - Word operator-(hword a) - { - Word r; - r.m_whole = m_whole - a; - return r; - } - - // returns quotient, which must fit in a word - hword operator/(hword divisor) - { - return hword(m_whole / divisor); - } - - bool operator!() const - { - return !m_whole; - } - - word GetWhole() const {return m_whole;} - hword GetLowHalf() const {return hword(m_whole);} - hword GetHighHalf() const {return hword(m_whole>>(WORD_BITS/2));} - hword GetHighHalfAsBorrow() const {return 0-hword(m_whole>>(WORD_BITS/2));} - -private: - word m_whole; -}; - -// do a 3 word by 2 word divide, returns quotient and leaves remainder in A -template <class S, class D> -S DivideThreeWordsByTwo(S *A, S B0, S B1, D *dummy=NULL) -{ - // assert {A[2],A[1]} < {B1,B0}, so quotient can fit in a S - assert(A[2] < B1 || (A[2]==B1 && A[1] < B0)); - - // estimate the quotient: do a 2 S by 1 S divide - S Q; - if (S(B1+1) == 0) - Q = A[2]; - else if (B1 > 0) - Q = D(A[1], A[2]) / S(B1+1); - else - Q = D(A[0], A[1]) / B0; - - // now subtract Q*B from A - D p = D::Multiply(B0, Q); - D u = (D) A[0] - p.GetLowHalf(); - A[0] = u.GetLowHalf(); - u = (D) A[1] - p.GetHighHalf() - u.GetHighHalfAsBorrow() - D::Multiply(B1, Q); - A[1] = u.GetLowHalf(); - A[2] += u.GetHighHalf(); - - // Q <= actual quotient, so fix it - while (A[2] || A[1] > B1 || (A[1]==B1 && A[0]>=B0)) - { - u = (D) A[0] - B0; - A[0] = u.GetLowHalf(); - u = (D) A[1] - B1 - u.GetHighHalfAsBorrow(); - A[1] = u.GetLowHalf(); - A[2] += u.GetHighHalf(); - Q++; - assert(Q); // shouldn't overflow - } - - return Q; -} - -// do a 4 word by 2 word divide, returns 2 word quotient in Q0 and Q1 -template <class S, class D> -inline D DivideFourWordsByTwo(S *T, const D &Al, const D &Ah, const D &B) -{ - if (!B) // if divisor is 0, we assume divisor==2**(2*WORD_BITS) - return D(Ah.GetLowHalf(), Ah.GetHighHalf()); - else - { - S Q[2]; - T[0] = Al.GetLowHalf(); - T[1] = Al.GetHighHalf(); - T[2] = Ah.GetLowHalf(); - T[3] = Ah.GetHighHalf(); - Q[1] = DivideThreeWordsByTwo<S, D>(T+1, B.GetLowHalf(), B.GetHighHalf()); - Q[0] = DivideThreeWordsByTwo<S, D>(T, B.GetLowHalf(), B.GetHighHalf()); - return D(Q[0], Q[1]); - } -} - -// returns quotient, which must fit in a word -inline word DWord::operator/(word a) -{ - #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE - return word(m_whole / a); - #else - hword r[4]; - return DivideFourWordsByTwo<hword, Word>(r, m_halfs.low, m_halfs.high, a).GetWhole(); - #endif -} - -inline word DWord::operator%(word a) -{ - #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE - return word(m_whole % a); - #else - if (a < (word(1) << (WORD_BITS/2))) - { - hword h = hword(a); - word r = m_halfs.high % h; - r = ((m_halfs.low >> (WORD_BITS/2)) + (r << (WORD_BITS/2))) % h; - return hword((hword(m_halfs.low) + (r << (WORD_BITS/2))) % h); - } - else - { - hword r[4]; - DivideFourWordsByTwo<hword, Word>(r, m_halfs.low, m_halfs.high, a); - return Word(r[0], r[1]).GetWhole(); - } - #endif -} - -// ******************************************************** - -// use some tricks to share assembly code between MSVC and GCC -#if defined(__GNUC__) - #define AddPrologue \ - int result; \ - __asm__ __volatile__ \ - ( \ - ".intel_syntax noprefix;" - #define AddEpilogue \ - ".att_syntax prefix;" \ - : "=a" (result)\ - : "d" (C), "a" (A), "D" (B), "c" (N) \ - : "%esi", "memory", "cc" \ - );\ - return result; - #define MulPrologue \ - __asm__ __volatile__ \ - ( \ - ".intel_syntax noprefix;" \ - AS1( push ebx) \ - AS2( mov ebx, edx) - #define MulEpilogue \ - AS1( pop ebx) \ - ".att_syntax prefix;" \ - : \ - : "d" (s_maskLow16), "c" (C), "a" (A), "D" (B) \ - : "%esi", "memory", "cc" \ - ); - #define SquPrologue MulPrologue - #define SquEpilogue \ - AS1( pop ebx) \ - ".att_syntax prefix;" \ - : \ - : "d" (s_maskLow16), "c" (C), "a" (A) \ - : "%esi", "%edi", "memory", "cc" \ - ); - #define TopPrologue MulPrologue - #define TopEpilogue \ - AS1( pop ebx) \ - ".att_syntax prefix;" \ - : \ - : "d" (s_maskLow16), "c" (C), "a" (A), "D" (B), "S" (L) \ - : "memory", "cc" \ - ); -#else - #define AddPrologue \ - __asm push edi \ - __asm push esi \ - __asm mov eax, [esp+12] \ - __asm mov edi, [esp+16] - #define AddEpilogue \ - __asm pop esi \ - __asm pop edi \ - __asm ret 8 -#if _MSC_VER < 1300 - #define SaveEBX __asm push ebx - #define RestoreEBX __asm pop ebx -#else - #define SaveEBX - #define RestoreEBX -#endif - #define SquPrologue \ - AS2( mov eax, A) \ - AS2( mov ecx, C) \ - SaveEBX \ - AS2( lea ebx, s_maskLow16) - #define MulPrologue \ - AS2( mov eax, A) \ - AS2( mov edi, B) \ - AS2( mov ecx, C) \ - SaveEBX \ - AS2( lea ebx, s_maskLow16) - #define TopPrologue \ - AS2( mov eax, A) \ - AS2( mov edi, B) \ - AS2( mov ecx, C) \ - AS2( mov esi, L) \ - SaveEBX \ - AS2( lea ebx, s_maskLow16) - #define SquEpilogue RestoreEBX - #define MulEpilogue RestoreEBX - #define TopEpilogue RestoreEBX -#endif - -#ifdef CRYPTOPP_X64_MASM_AVAILABLE -extern "C" { -int Baseline_Add(size_t N, word *C, const word *A, const word *B); -int Baseline_Sub(size_t N, word *C, const word *A, const word *B); -} -#elif defined(CRYPTOPP_X64_ASM_AVAILABLE) && defined(__GNUC__) && defined(CRYPTOPP_WORD128_AVAILABLE) -int Baseline_Add(size_t N, word *C, const word *A, const word *B) -{ - word result; - __asm__ __volatile__ - ( - ".intel_syntax;" - AS1( neg %1) - ASJ( jz, 1, f) - AS2( mov %0,[%3+8*%1]) - AS2( add %0,[%4+8*%1]) - AS2( mov [%2+8*%1],%0) - ASL(0) - AS2( mov %0,[%3+8*%1+8]) - AS2( adc %0,[%4+8*%1+8]) - AS2( mov [%2+8*%1+8],%0) - AS2( lea %1,[%1+2]) - ASJ( jrcxz, 1, f) - AS2( mov %0,[%3+8*%1]) - AS2( adc %0,[%4+8*%1]) - AS2( mov [%2+8*%1],%0) - ASJ( jmp, 0, b) - ASL(1) - AS2( mov %0, 0) - AS2( adc %0, %0) - ".att_syntax;" - : "=&r" (result), "+c" (N) - : "r" (C+N), "r" (A+N), "r" (B+N) - : "memory", "cc" - ); - return (int)result; -} - -int Baseline_Sub(size_t N, word *C, const word *A, const word *B) -{ - word result; - __asm__ __volatile__ - ( - ".intel_syntax;" - AS1( neg %1) - ASJ( jz, 1, f) - AS2( mov %0,[%3+8*%1]) - AS2( sub %0,[%4+8*%1]) - AS2( mov [%2+8*%1],%0) - ASL(0) - AS2( mov %0,[%3+8*%1+8]) - AS2( sbb %0,[%4+8*%1+8]) - AS2( mov [%2+8*%1+8],%0) - AS2( lea %1,[%1+2]) - ASJ( jrcxz, 1, f) - AS2( mov %0,[%3+8*%1]) - AS2( sbb %0,[%4+8*%1]) - AS2( mov [%2+8*%1],%0) - ASJ( jmp, 0, b) - ASL(1) - AS2( mov %0, 0) - AS2( adc %0, %0) - ".att_syntax;" - : "=&r" (result), "+c" (N) - : "r" (C+N), "r" (A+N), "r" (B+N) - : "memory", "cc" - ); - return (int)result; -} -#elif defined(CRYPTOPP_X86_ASM_AVAILABLE) && CRYPTOPP_BOOL_X86 -CRYPTOPP_NAKED int CRYPTOPP_FASTCALL Baseline_Add(size_t N, word *C, const word *A, const word *B) -{ - AddPrologue - - // now: eax = A, edi = B, edx = C, ecx = N - AS2( lea eax, [eax+4*ecx]) - AS2( lea edi, [edi+4*ecx]) - AS2( lea edx, [edx+4*ecx]) - - AS1( neg ecx) // ecx is negative index - AS2( test ecx, 2) // this clears carry flag - ASJ( jz, 0, f) - AS2( sub ecx, 2) - ASJ( jmp, 1, f) - - ASL(0) - ASJ( jecxz, 2, f) // loop until ecx overflows and becomes zero - AS2( mov esi,[eax+4*ecx]) - AS2( adc esi,[edi+4*ecx]) - AS2( mov [edx+4*ecx],esi) - AS2( mov esi,[eax+4*ecx+4]) - AS2( adc esi,[edi+4*ecx+4]) - AS2( mov [edx+4*ecx+4],esi) - ASL(1) - AS2( mov esi,[eax+4*ecx+8]) - AS2( adc esi,[edi+4*ecx+8]) - AS2( mov [edx+4*ecx+8],esi) - AS2( mov esi,[eax+4*ecx+12]) - AS2( adc esi,[edi+4*ecx+12]) - AS2( mov [edx+4*ecx+12],esi) - - AS2( lea ecx,[ecx+4]) // advance index, avoid inc which causes slowdown on Intel Core 2 - ASJ( jmp, 0, b) - - ASL(2) - AS2( mov eax, 0) - AS1( setc al) // store carry into eax (return result register) - - AddEpilogue -} - -CRYPTOPP_NAKED int CRYPTOPP_FASTCALL Baseline_Sub(size_t N, word *C, const word *A, const word *B) -{ - AddPrologue - - // now: eax = A, edi = B, edx = C, ecx = N - AS2( lea eax, [eax+4*ecx]) - AS2( lea edi, [edi+4*ecx]) - AS2( lea edx, [edx+4*ecx]) - - AS1( neg ecx) // ecx is negative index - AS2( test ecx, 2) // this clears carry flag - ASJ( jz, 0, f) - AS2( sub ecx, 2) - ASJ( jmp, 1, f) - - ASL(0) - ASJ( jecxz, 2, f) // loop until ecx overflows and becomes zero - AS2( mov esi,[eax+4*ecx]) - AS2( sbb esi,[edi+4*ecx]) - AS2( mov [edx+4*ecx],esi) - AS2( mov esi,[eax+4*ecx+4]) - AS2( sbb esi,[edi+4*ecx+4]) - AS2( mov [edx+4*ecx+4],esi) - ASL(1) - AS2( mov esi,[eax+4*ecx+8]) - AS2( sbb esi,[edi+4*ecx+8]) - AS2( mov [edx+4*ecx+8],esi) - AS2( mov esi,[eax+4*ecx+12]) - AS2( sbb esi,[edi+4*ecx+12]) - AS2( mov [edx+4*ecx+12],esi) - - AS2( lea ecx,[ecx+4]) // advance index, avoid inc which causes slowdown on Intel Core 2 - ASJ( jmp, 0, b) - - ASL(2) - AS2( mov eax, 0) - AS1( setc al) // store carry into eax (return result register) - - AddEpilogue -} - -#if CRYPTOPP_INTEGER_SSE2 -CRYPTOPP_NAKED int CRYPTOPP_FASTCALL SSE2_Add(size_t N, word *C, const word *A, const word *B) -{ - AddPrologue - - // now: eax = A, edi = B, edx = C, ecx = N - AS2( lea eax, [eax+4*ecx]) - AS2( lea edi, [edi+4*ecx]) - AS2( lea edx, [edx+4*ecx]) - - AS1( neg ecx) // ecx is negative index - AS2( pxor mm2, mm2) - ASJ( jz, 2, f) - AS2( test ecx, 2) // this clears carry flag - ASJ( jz, 0, f) - AS2( sub ecx, 2) - ASJ( jmp, 1, f) - - ASL(0) - AS2( movd mm0, DWORD PTR [eax+4*ecx]) - AS2( movd mm1, DWORD PTR [edi+4*ecx]) - AS2( paddq mm0, mm1) - AS2( paddq mm2, mm0) - AS2( movd DWORD PTR [edx+4*ecx], mm2) - AS2( psrlq mm2, 32) - - AS2( movd mm0, DWORD PTR [eax+4*ecx+4]) - AS2( movd mm1, DWORD PTR [edi+4*ecx+4]) - AS2( paddq mm0, mm1) - AS2( paddq mm2, mm0) - AS2( movd DWORD PTR [edx+4*ecx+4], mm2) - AS2( psrlq mm2, 32) - - ASL(1) - AS2( movd mm0, DWORD PTR [eax+4*ecx+8]) - AS2( movd mm1, DWORD PTR [edi+4*ecx+8]) - AS2( paddq mm0, mm1) - AS2( paddq mm2, mm0) - AS2( movd DWORD PTR [edx+4*ecx+8], mm2) - AS2( psrlq mm2, 32) - - AS2( movd mm0, DWORD PTR [eax+4*ecx+12]) - AS2( movd mm1, DWORD PTR [edi+4*ecx+12]) - AS2( paddq mm0, mm1) - AS2( paddq mm2, mm0) - AS2( movd DWORD PTR [edx+4*ecx+12], mm2) - AS2( psrlq mm2, 32) - - AS2( add ecx, 4) - ASJ( jnz, 0, b) - - ASL(2) - AS2( movd eax, mm2) - AS1( emms) - - AddEpilogue -} -CRYPTOPP_NAKED int CRYPTOPP_FASTCALL SSE2_Sub(size_t N, word *C, const word *A, const word *B) -{ - AddPrologue - - // now: eax = A, edi = B, edx = C, ecx = N - AS2( lea eax, [eax+4*ecx]) - AS2( lea edi, [edi+4*ecx]) - AS2( lea edx, [edx+4*ecx]) - - AS1( neg ecx) // ecx is negative index - AS2( pxor mm2, mm2) - ASJ( jz, 2, f) - AS2( test ecx, 2) // this clears carry flag - ASJ( jz, 0, f) - AS2( sub ecx, 2) - ASJ( jmp, 1, f) - - ASL(0) - AS2( movd mm0, DWORD PTR [eax+4*ecx]) - AS2( movd mm1, DWORD PTR [edi+4*ecx]) - AS2( psubq mm0, mm1) - AS2( psubq mm0, mm2) - AS2( movd DWORD PTR [edx+4*ecx], mm0) - AS2( psrlq mm0, 63) - - AS2( movd mm2, DWORD PTR [eax+4*ecx+4]) - AS2( movd mm1, DWORD PTR [edi+4*ecx+4]) - AS2( psubq mm2, mm1) - AS2( psubq mm2, mm0) - AS2( movd DWORD PTR [edx+4*ecx+4], mm2) - AS2( psrlq mm2, 63) - - ASL(1) - AS2( movd mm0, DWORD PTR [eax+4*ecx+8]) - AS2( movd mm1, DWORD PTR [edi+4*ecx+8]) - AS2( psubq mm0, mm1) - AS2( psubq mm0, mm2) - AS2( movd DWORD PTR [edx+4*ecx+8], mm0) - AS2( psrlq mm0, 63) - - AS2( movd mm2, DWORD PTR [eax+4*ecx+12]) - AS2( movd mm1, DWORD PTR [edi+4*ecx+12]) - AS2( psubq mm2, mm1) - AS2( psubq mm2, mm0) - AS2( movd DWORD PTR [edx+4*ecx+12], mm2) - AS2( psrlq mm2, 63) - - AS2( add ecx, 4) - ASJ( jnz, 0, b) - - ASL(2) - AS2( movd eax, mm2) - AS1( emms) - - AddEpilogue -} -#endif // #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE -#else -int CRYPTOPP_FASTCALL Baseline_Add(size_t N, word *C, const word *A, const word *B) -{ - assert (N%2 == 0); - - Declare2Words(u); - AssignWord(u, 0); - for (size_t i=0; i<N; i+=2) - { - AddWithCarry(u, A[i], B[i]); - C[i] = LowWord(u); - AddWithCarry(u, A[i+1], B[i+1]); - C[i+1] = LowWord(u); - } - return int(GetCarry(u)); -} - -int CRYPTOPP_FASTCALL Baseline_Sub(size_t N, word *C, const word *A, const word *B) -{ - assert (N%2 == 0); - - Declare2Words(u); - AssignWord(u, 0); - for (size_t i=0; i<N; i+=2) - { - SubtractWithBorrow(u, A[i], B[i]); - C[i] = LowWord(u); - SubtractWithBorrow(u, A[i+1], B[i+1]); - C[i+1] = LowWord(u); - } - return int(GetBorrow(u)); -} -#endif - -static word LinearMultiply(word *C, const word *A, word B, size_t N) -{ - word carry=0; - for(unsigned i=0; i<N; i++) - { - Declare2Words(p); - MultiplyWords(p, A[i], B); - Acc2WordsBy1(p, carry); - C[i] = LowWord(p); - carry = HighWord(p); - } - return carry; -} - -#ifndef CRYPTOPP_DOXYGEN_PROCESSING - -#define Mul_2 \ - Mul_Begin(2) \ - Mul_SaveAcc(0, 0, 1) Mul_Acc(1, 0) \ - Mul_End(1, 1) - -#define Mul_4 \ - Mul_Begin(4) \ - Mul_SaveAcc(0, 0, 1) Mul_Acc(1, 0) \ - Mul_SaveAcc(1, 0, 2) Mul_Acc(1, 1) Mul_Acc(2, 0) \ - Mul_SaveAcc(2, 0, 3) Mul_Acc(1, 2) Mul_Acc(2, 1) Mul_Acc(3, 0) \ - Mul_SaveAcc(3, 1, 3) Mul_Acc(2, 2) Mul_Acc(3, 1) \ - Mul_SaveAcc(4, 2, 3) Mul_Acc(3, 2) \ - Mul_End(5, 3) - -#define Mul_8 \ - Mul_Begin(8) \ - Mul_SaveAcc(0, 0, 1) Mul_Acc(1, 0) \ - Mul_SaveAcc(1, 0, 2) Mul_Acc(1, 1) Mul_Acc(2, 0) \ - Mul_SaveAcc(2, 0, 3) Mul_Acc(1, 2) Mul_Acc(2, 1) Mul_Acc(3, 0) \ - Mul_SaveAcc(3, 0, 4) Mul_Acc(1, 3) Mul_Acc(2, 2) Mul_Acc(3, 1) Mul_Acc(4, 0) \ - Mul_SaveAcc(4, 0, 5) Mul_Acc(1, 4) Mul_Acc(2, 3) Mul_Acc(3, 2) Mul_Acc(4, 1) Mul_Acc(5, 0) \ - Mul_SaveAcc(5, 0, 6) Mul_Acc(1, 5) Mul_Acc(2, 4) Mul_Acc(3, 3) Mul_Acc(4, 2) Mul_Acc(5, 1) Mul_Acc(6, 0) \ - Mul_SaveAcc(6, 0, 7) Mul_Acc(1, 6) Mul_Acc(2, 5) Mul_Acc(3, 4) Mul_Acc(4, 3) Mul_Acc(5, 2) Mul_Acc(6, 1) Mul_Acc(7, 0) \ - Mul_SaveAcc(7, 1, 7) Mul_Acc(2, 6) Mul_Acc(3, 5) Mul_Acc(4, 4) Mul_Acc(5, 3) Mul_Acc(6, 2) Mul_Acc(7, 1) \ - Mul_SaveAcc(8, 2, 7) Mul_Acc(3, 6) Mul_Acc(4, 5) Mul_Acc(5, 4) Mul_Acc(6, 3) Mul_Acc(7, 2) \ - Mul_SaveAcc(9, 3, 7) Mul_Acc(4, 6) Mul_Acc(5, 5) Mul_Acc(6, 4) Mul_Acc(7, 3) \ - Mul_SaveAcc(10, 4, 7) Mul_Acc(5, 6) Mul_Acc(6, 5) Mul_Acc(7, 4) \ - Mul_SaveAcc(11, 5, 7) Mul_Acc(6, 6) Mul_Acc(7, 5) \ - Mul_SaveAcc(12, 6, 7) Mul_Acc(7, 6) \ - Mul_End(13, 7) - -#define Mul_16 \ - Mul_Begin(16) \ - Mul_SaveAcc(0, 0, 1) Mul_Acc(1, 0) \ - Mul_SaveAcc(1, 0, 2) Mul_Acc(1, 1) Mul_Acc(2, 0) \ - Mul_SaveAcc(2, 0, 3) Mul_Acc(1, 2) Mul_Acc(2, 1) Mul_Acc(3, 0) \ - Mul_SaveAcc(3, 0, 4) Mul_Acc(1, 3) Mul_Acc(2, 2) Mul_Acc(3, 1) Mul_Acc(4, 0) \ - Mul_SaveAcc(4, 0, 5) Mul_Acc(1, 4) Mul_Acc(2, 3) Mul_Acc(3, 2) Mul_Acc(4, 1) Mul_Acc(5, 0) \ - Mul_SaveAcc(5, 0, 6) Mul_Acc(1, 5) Mul_Acc(2, 4) Mul_Acc(3, 3) Mul_Acc(4, 2) Mul_Acc(5, 1) Mul_Acc(6, 0) \ - Mul_SaveAcc(6, 0, 7) Mul_Acc(1, 6) Mul_Acc(2, 5) Mul_Acc(3, 4) Mul_Acc(4, 3) Mul_Acc(5, 2) Mul_Acc(6, 1) Mul_Acc(7, 0) \ - Mul_SaveAcc(7, 0, 8) Mul_Acc(1, 7) Mul_Acc(2, 6) Mul_Acc(3, 5) Mul_Acc(4, 4) Mul_Acc(5, 3) Mul_Acc(6, 2) Mul_Acc(7, 1) Mul_Acc(8, 0) \ - Mul_SaveAcc(8, 0, 9) Mul_Acc(1, 8) Mul_Acc(2, 7) Mul_Acc(3, 6) Mul_Acc(4, 5) Mul_Acc(5, 4) Mul_Acc(6, 3) Mul_Acc(7, 2) Mul_Acc(8, 1) Mul_Acc(9, 0) \ - Mul_SaveAcc(9, 0, 10) Mul_Acc(1, 9) Mul_Acc(2, 8) Mul_Acc(3, 7) Mul_Acc(4, 6) Mul_Acc(5, 5) Mul_Acc(6, 4) Mul_Acc(7, 3) Mul_Acc(8, 2) Mul_Acc(9, 1) Mul_Acc(10, 0) \ - Mul_SaveAcc(10, 0, 11) Mul_Acc(1, 10) Mul_Acc(2, 9) Mul_Acc(3, 8) Mul_Acc(4, 7) Mul_Acc(5, 6) Mul_Acc(6, 5) Mul_Acc(7, 4) Mul_Acc(8, 3) Mul_Acc(9, 2) Mul_Acc(10, 1) Mul_Acc(11, 0) \ - Mul_SaveAcc(11, 0, 12) Mul_Acc(1, 11) Mul_Acc(2, 10) Mul_Acc(3, 9) Mul_Acc(4, 8) Mul_Acc(5, 7) Mul_Acc(6, 6) Mul_Acc(7, 5) Mul_Acc(8, 4) Mul_Acc(9, 3) Mul_Acc(10, 2) Mul_Acc(11, 1) Mul_Acc(12, 0) \ - Mul_SaveAcc(12, 0, 13) Mul_Acc(1, 12) Mul_Acc(2, 11) Mul_Acc(3, 10) Mul_Acc(4, 9) Mul_Acc(5, 8) Mul_Acc(6, 7) Mul_Acc(7, 6) Mul_Acc(8, 5) Mul_Acc(9, 4) Mul_Acc(10, 3) Mul_Acc(11, 2) Mul_Acc(12, 1) Mul_Acc(13, 0) \ - Mul_SaveAcc(13, 0, 14) Mul_Acc(1, 13) Mul_Acc(2, 12) Mul_Acc(3, 11) Mul_Acc(4, 10) Mul_Acc(5, 9) Mul_Acc(6, 8) Mul_Acc(7, 7) Mul_Acc(8, 6) Mul_Acc(9, 5) Mul_Acc(10, 4) Mul_Acc(11, 3) Mul_Acc(12, 2) Mul_Acc(13, 1) Mul_Acc(14, 0) \ - Mul_SaveAcc(14, 0, 15) Mul_Acc(1, 14) Mul_Acc(2, 13) Mul_Acc(3, 12) Mul_Acc(4, 11) Mul_Acc(5, 10) Mul_Acc(6, 9) Mul_Acc(7, 8) Mul_Acc(8, 7) Mul_Acc(9, 6) Mul_Acc(10, 5) Mul_Acc(11, 4) Mul_Acc(12, 3) Mul_Acc(13, 2) Mul_Acc(14, 1) Mul_Acc(15, 0) \ - Mul_SaveAcc(15, 1, 15) Mul_Acc(2, 14) Mul_Acc(3, 13) Mul_Acc(4, 12) Mul_Acc(5, 11) Mul_Acc(6, 10) Mul_Acc(7, 9) Mul_Acc(8, 8) Mul_Acc(9, 7) Mul_Acc(10, 6) Mul_Acc(11, 5) Mul_Acc(12, 4) Mul_Acc(13, 3) Mul_Acc(14, 2) Mul_Acc(15, 1) \ - Mul_SaveAcc(16, 2, 15) Mul_Acc(3, 14) Mul_Acc(4, 13) Mul_Acc(5, 12) Mul_Acc(6, 11) Mul_Acc(7, 10) Mul_Acc(8, 9) Mul_Acc(9, 8) Mul_Acc(10, 7) Mul_Acc(11, 6) Mul_Acc(12, 5) Mul_Acc(13, 4) Mul_Acc(14, 3) Mul_Acc(15, 2) \ - Mul_SaveAcc(17, 3, 15) Mul_Acc(4, 14) Mul_Acc(5, 13) Mul_Acc(6, 12) Mul_Acc(7, 11) Mul_Acc(8, 10) Mul_Acc(9, 9) Mul_Acc(10, 8) Mul_Acc(11, 7) Mul_Acc(12, 6) Mul_Acc(13, 5) Mul_Acc(14, 4) Mul_Acc(15, 3) \ - Mul_SaveAcc(18, 4, 15) Mul_Acc(5, 14) Mul_Acc(6, 13) Mul_Acc(7, 12) Mul_Acc(8, 11) Mul_Acc(9, 10) Mul_Acc(10, 9) Mul_Acc(11, 8) Mul_Acc(12, 7) Mul_Acc(13, 6) Mul_Acc(14, 5) Mul_Acc(15, 4) \ - Mul_SaveAcc(19, 5, 15) Mul_Acc(6, 14) Mul_Acc(7, 13) Mul_Acc(8, 12) Mul_Acc(9, 11) Mul_Acc(10, 10) Mul_Acc(11, 9) Mul_Acc(12, 8) Mul_Acc(13, 7) Mul_Acc(14, 6) Mul_Acc(15, 5) \ - Mul_SaveAcc(20, 6, 15) Mul_Acc(7, 14) Mul_Acc(8, 13) Mul_Acc(9, 12) Mul_Acc(10, 11) Mul_Acc(11, 10) Mul_Acc(12, 9) Mul_Acc(13, 8) Mul_Acc(14, 7) Mul_Acc(15, 6) \ - Mul_SaveAcc(21, 7, 15) Mul_Acc(8, 14) Mul_Acc(9, 13) Mul_Acc(10, 12) Mul_Acc(11, 11) Mul_Acc(12, 10) Mul_Acc(13, 9) Mul_Acc(14, 8) Mul_Acc(15, 7) \ - Mul_SaveAcc(22, 8, 15) Mul_Acc(9, 14) Mul_Acc(10, 13) Mul_Acc(11, 12) Mul_Acc(12, 11) Mul_Acc(13, 10) Mul_Acc(14, 9) Mul_Acc(15, 8) \ - Mul_SaveAcc(23, 9, 15) Mul_Acc(10, 14) Mul_Acc(11, 13) Mul_Acc(12, 12) Mul_Acc(13, 11) Mul_Acc(14, 10) Mul_Acc(15, 9) \ - Mul_SaveAcc(24, 10, 15) Mul_Acc(11, 14) Mul_Acc(12, 13) Mul_Acc(13, 12) Mul_Acc(14, 11) Mul_Acc(15, 10) \ - Mul_SaveAcc(25, 11, 15) Mul_Acc(12, 14) Mul_Acc(13, 13) Mul_Acc(14, 12) Mul_Acc(15, 11) \ - Mul_SaveAcc(26, 12, 15) Mul_Acc(13, 14) Mul_Acc(14, 13) Mul_Acc(15, 12) \ - Mul_SaveAcc(27, 13, 15) Mul_Acc(14, 14) Mul_Acc(15, 13) \ - Mul_SaveAcc(28, 14, 15) Mul_Acc(15, 14) \ - Mul_End(29, 15) - -#define Squ_2 \ - Squ_Begin(2) \ - Squ_End(2) - -#define Squ_4 \ - Squ_Begin(4) \ - Squ_SaveAcc(1, 0, 2) Squ_Diag(1) \ - Squ_SaveAcc(2, 0, 3) Squ_Acc(1, 2) Squ_NonDiag \ - Squ_SaveAcc(3, 1, 3) Squ_Diag(2) \ - Squ_SaveAcc(4, 2, 3) Squ_NonDiag \ - Squ_End(4) - -#define Squ_8 \ - Squ_Begin(8) \ - Squ_SaveAcc(1, 0, 2) Squ_Diag(1) \ - Squ_SaveAcc(2, 0, 3) Squ_Acc(1, 2) Squ_NonDiag \ - Squ_SaveAcc(3, 0, 4) Squ_Acc(1, 3) Squ_Diag(2) \ - Squ_SaveAcc(4, 0, 5) Squ_Acc(1, 4) Squ_Acc(2, 3) Squ_NonDiag \ - Squ_SaveAcc(5, 0, 6) Squ_Acc(1, 5) Squ_Acc(2, 4) Squ_Diag(3) \ - Squ_SaveAcc(6, 0, 7) Squ_Acc(1, 6) Squ_Acc(2, 5) Squ_Acc(3, 4) Squ_NonDiag \ - Squ_SaveAcc(7, 1, 7) Squ_Acc(2, 6) Squ_Acc(3, 5) Squ_Diag(4) \ - Squ_SaveAcc(8, 2, 7) Squ_Acc(3, 6) Squ_Acc(4, 5) Squ_NonDiag \ - Squ_SaveAcc(9, 3, 7) Squ_Acc(4, 6) Squ_Diag(5) \ - Squ_SaveAcc(10, 4, 7) Squ_Acc(5, 6) Squ_NonDiag \ - Squ_SaveAcc(11, 5, 7) Squ_Diag(6) \ - Squ_SaveAcc(12, 6, 7) Squ_NonDiag \ - Squ_End(8) - -#define Squ_16 \ - Squ_Begin(16) \ - Squ_SaveAcc(1, 0, 2) Squ_Diag(1) \ - Squ_SaveAcc(2, 0, 3) Squ_Acc(1, 2) Squ_NonDiag \ - Squ_SaveAcc(3, 0, 4) Squ_Acc(1, 3) Squ_Diag(2) \ - Squ_SaveAcc(4, 0, 5) Squ_Acc(1, 4) Squ_Acc(2, 3) Squ_NonDiag \ - Squ_SaveAcc(5, 0, 6) Squ_Acc(1, 5) Squ_Acc(2, 4) Squ_Diag(3) \ - Squ_SaveAcc(6, 0, 7) Squ_Acc(1, 6) Squ_Acc(2, 5) Squ_Acc(3, 4) Squ_NonDiag \ - Squ_SaveAcc(7, 0, 8) Squ_Acc(1, 7) Squ_Acc(2, 6) Squ_Acc(3, 5) Squ_Diag(4) \ - Squ_SaveAcc(8, 0, 9) Squ_Acc(1, 8) Squ_Acc(2, 7) Squ_Acc(3, 6) Squ_Acc(4, 5) Squ_NonDiag \ - Squ_SaveAcc(9, 0, 10) Squ_Acc(1, 9) Squ_Acc(2, 8) Squ_Acc(3, 7) Squ_Acc(4, 6) Squ_Diag(5) \ - Squ_SaveAcc(10, 0, 11) Squ_Acc(1, 10) Squ_Acc(2, 9) Squ_Acc(3, 8) Squ_Acc(4, 7) Squ_Acc(5, 6) Squ_NonDiag \ - Squ_SaveAcc(11, 0, 12) Squ_Acc(1, 11) Squ_Acc(2, 10) Squ_Acc(3, 9) Squ_Acc(4, 8) Squ_Acc(5, 7) Squ_Diag(6) \ - Squ_SaveAcc(12, 0, 13) Squ_Acc(1, 12) Squ_Acc(2, 11) Squ_Acc(3, 10) Squ_Acc(4, 9) Squ_Acc(5, 8) Squ_Acc(6, 7) Squ_NonDiag \ - Squ_SaveAcc(13, 0, 14) Squ_Acc(1, 13) Squ_Acc(2, 12) Squ_Acc(3, 11) Squ_Acc(4, 10) Squ_Acc(5, 9) Squ_Acc(6, 8) Squ_Diag(7) \ - Squ_SaveAcc(14, 0, 15) Squ_Acc(1, 14) Squ_Acc(2, 13) Squ_Acc(3, 12) Squ_Acc(4, 11) Squ_Acc(5, 10) Squ_Acc(6, 9) Squ_Acc(7, 8) Squ_NonDiag \ - Squ_SaveAcc(15, 1, 15) Squ_Acc(2, 14) Squ_Acc(3, 13) Squ_Acc(4, 12) Squ_Acc(5, 11) Squ_Acc(6, 10) Squ_Acc(7, 9) Squ_Diag(8) \ - Squ_SaveAcc(16, 2, 15) Squ_Acc(3, 14) Squ_Acc(4, 13) Squ_Acc(5, 12) Squ_Acc(6, 11) Squ_Acc(7, 10) Squ_Acc(8, 9) Squ_NonDiag \ - Squ_SaveAcc(17, 3, 15) Squ_Acc(4, 14) Squ_Acc(5, 13) Squ_Acc(6, 12) Squ_Acc(7, 11) Squ_Acc(8, 10) Squ_Diag(9) \ - Squ_SaveAcc(18, 4, 15) Squ_Acc(5, 14) Squ_Acc(6, 13) Squ_Acc(7, 12) Squ_Acc(8, 11) Squ_Acc(9, 10) Squ_NonDiag \ - Squ_SaveAcc(19, 5, 15) Squ_Acc(6, 14) Squ_Acc(7, 13) Squ_Acc(8, 12) Squ_Acc(9, 11) Squ_Diag(10) \ - Squ_SaveAcc(20, 6, 15) Squ_Acc(7, 14) Squ_Acc(8, 13) Squ_Acc(9, 12) Squ_Acc(10, 11) Squ_NonDiag \ - Squ_SaveAcc(21, 7, 15) Squ_Acc(8, 14) Squ_Acc(9, 13) Squ_Acc(10, 12) Squ_Diag(11) \ - Squ_SaveAcc(22, 8, 15) Squ_Acc(9, 14) Squ_Acc(10, 13) Squ_Acc(11, 12) Squ_NonDiag \ - Squ_SaveAcc(23, 9, 15) Squ_Acc(10, 14) Squ_Acc(11, 13) Squ_Diag(12) \ - Squ_SaveAcc(24, 10, 15) Squ_Acc(11, 14) Squ_Acc(12, 13) Squ_NonDiag \ - Squ_SaveAcc(25, 11, 15) Squ_Acc(12, 14) Squ_Diag(13) \ - Squ_SaveAcc(26, 12, 15) Squ_Acc(13, 14) Squ_NonDiag \ - Squ_SaveAcc(27, 13, 15) Squ_Diag(14) \ - Squ_SaveAcc(28, 14, 15) Squ_NonDiag \ - Squ_End(16) - -#define Bot_2 \ - Mul_Begin(2) \ - Bot_SaveAcc(0, 0, 1) Bot_Acc(1, 0) \ - Bot_End(2) - -#define Bot_4 \ - Mul_Begin(4) \ - Mul_SaveAcc(0, 0, 1) Mul_Acc(1, 0) \ - Mul_SaveAcc(1, 2, 0) Mul_Acc(1, 1) Mul_Acc(0, 2) \ - Bot_SaveAcc(2, 0, 3) Bot_Acc(1, 2) Bot_Acc(2, 1) Bot_Acc(3, 0) \ - Bot_End(4) - -#define Bot_8 \ - Mul_Begin(8) \ - Mul_SaveAcc(0, 0, 1) Mul_Acc(1, 0) \ - Mul_SaveAcc(1, 0, 2) Mul_Acc(1, 1) Mul_Acc(2, 0) \ - Mul_SaveAcc(2, 0, 3) Mul_Acc(1, 2) Mul_Acc(2, 1) Mul_Acc(3, 0) \ - Mul_SaveAcc(3, 0, 4) Mul_Acc(1, 3) Mul_Acc(2, 2) Mul_Acc(3, 1) Mul_Acc(4, 0) \ - Mul_SaveAcc(4, 0, 5) Mul_Acc(1, 4) Mul_Acc(2, 3) Mul_Acc(3, 2) Mul_Acc(4, 1) Mul_Acc(5, 0) \ - Mul_SaveAcc(5, 0, 6) Mul_Acc(1, 5) Mul_Acc(2, 4) Mul_Acc(3, 3) Mul_Acc(4, 2) Mul_Acc(5, 1) Mul_Acc(6, 0) \ - Bot_SaveAcc(6, 0, 7) Bot_Acc(1, 6) Bot_Acc(2, 5) Bot_Acc(3, 4) Bot_Acc(4, 3) Bot_Acc(5, 2) Bot_Acc(6, 1) Bot_Acc(7, 0) \ - Bot_End(8) - -#define Bot_16 \ - Mul_Begin(16) \ - Mul_SaveAcc(0, 0, 1) Mul_Acc(1, 0) \ - Mul_SaveAcc(1, 0, 2) Mul_Acc(1, 1) Mul_Acc(2, 0) \ - Mul_SaveAcc(2, 0, 3) Mul_Acc(1, 2) Mul_Acc(2, 1) Mul_Acc(3, 0) \ - Mul_SaveAcc(3, 0, 4) Mul_Acc(1, 3) Mul_Acc(2, 2) Mul_Acc(3, 1) Mul_Acc(4, 0) \ - Mul_SaveAcc(4, 0, 5) Mul_Acc(1, 4) Mul_Acc(2, 3) Mul_Acc(3, 2) Mul_Acc(4, 1) Mul_Acc(5, 0) \ - Mul_SaveAcc(5, 0, 6) Mul_Acc(1, 5) Mul_Acc(2, 4) Mul_Acc(3, 3) Mul_Acc(4, 2) Mul_Acc(5, 1) Mul_Acc(6, 0) \ - Mul_SaveAcc(6, 0, 7) Mul_Acc(1, 6) Mul_Acc(2, 5) Mul_Acc(3, 4) Mul_Acc(4, 3) Mul_Acc(5, 2) Mul_Acc(6, 1) Mul_Acc(7, 0) \ - Mul_SaveAcc(7, 0, 8) Mul_Acc(1, 7) Mul_Acc(2, 6) Mul_Acc(3, 5) Mul_Acc(4, 4) Mul_Acc(5, 3) Mul_Acc(6, 2) Mul_Acc(7, 1) Mul_Acc(8, 0) \ - Mul_SaveAcc(8, 0, 9) Mul_Acc(1, 8) Mul_Acc(2, 7) Mul_Acc(3, 6) Mul_Acc(4, 5) Mul_Acc(5, 4) Mul_Acc(6, 3) Mul_Acc(7, 2) Mul_Acc(8, 1) Mul_Acc(9, 0) \ - Mul_SaveAcc(9, 0, 10) Mul_Acc(1, 9) Mul_Acc(2, 8) Mul_Acc(3, 7) Mul_Acc(4, 6) Mul_Acc(5, 5) Mul_Acc(6, 4) Mul_Acc(7, 3) Mul_Acc(8, 2) Mul_Acc(9, 1) Mul_Acc(10, 0) \ - Mul_SaveAcc(10, 0, 11) Mul_Acc(1, 10) Mul_Acc(2, 9) Mul_Acc(3, 8) Mul_Acc(4, 7) Mul_Acc(5, 6) Mul_Acc(6, 5) Mul_Acc(7, 4) Mul_Acc(8, 3) Mul_Acc(9, 2) Mul_Acc(10, 1) Mul_Acc(11, 0) \ - Mul_SaveAcc(11, 0, 12) Mul_Acc(1, 11) Mul_Acc(2, 10) Mul_Acc(3, 9) Mul_Acc(4, 8) Mul_Acc(5, 7) Mul_Acc(6, 6) Mul_Acc(7, 5) Mul_Acc(8, 4) Mul_Acc(9, 3) Mul_Acc(10, 2) Mul_Acc(11, 1) Mul_Acc(12, 0) \ - Mul_SaveAcc(12, 0, 13) Mul_Acc(1, 12) Mul_Acc(2, 11) Mul_Acc(3, 10) Mul_Acc(4, 9) Mul_Acc(5, 8) Mul_Acc(6, 7) Mul_Acc(7, 6) Mul_Acc(8, 5) Mul_Acc(9, 4) Mul_Acc(10, 3) Mul_Acc(11, 2) Mul_Acc(12, 1) Mul_Acc(13, 0) \ - Mul_SaveAcc(13, 0, 14) Mul_Acc(1, 13) Mul_Acc(2, 12) Mul_Acc(3, 11) Mul_Acc(4, 10) Mul_Acc(5, 9) Mul_Acc(6, 8) Mul_Acc(7, 7) Mul_Acc(8, 6) Mul_Acc(9, 5) Mul_Acc(10, 4) Mul_Acc(11, 3) Mul_Acc(12, 2) Mul_Acc(13, 1) Mul_Acc(14, 0) \ - Bot_SaveAcc(14, 0, 15) Bot_Acc(1, 14) Bot_Acc(2, 13) Bot_Acc(3, 12) Bot_Acc(4, 11) Bot_Acc(5, 10) Bot_Acc(6, 9) Bot_Acc(7, 8) Bot_Acc(8, 7) Bot_Acc(9, 6) Bot_Acc(10, 5) Bot_Acc(11, 4) Bot_Acc(12, 3) Bot_Acc(13, 2) Bot_Acc(14, 1) Bot_Acc(15, 0) \ - Bot_End(16) - -#endif - -#if 0 -#define Mul_Begin(n) \ - Declare2Words(p) \ - Declare2Words(c) \ - Declare2Words(d) \ - MultiplyWords(p, A[0], B[0]) \ - AssignWord(c, LowWord(p)) \ - AssignWord(d, HighWord(p)) - -#define Mul_Acc(i, j) \ - MultiplyWords(p, A[i], B[j]) \ - Acc2WordsBy1(c, LowWord(p)) \ - Acc2WordsBy1(d, HighWord(p)) - -#define Mul_SaveAcc(k, i, j) \ - R[k] = LowWord(c); \ - Add2WordsBy1(c, d, HighWord(c)) \ - MultiplyWords(p, A[i], B[j]) \ - AssignWord(d, HighWord(p)) \ - Acc2WordsBy1(c, LowWord(p)) - -#define Mul_End(n) \ - R[2*n-3] = LowWord(c); \ - Acc2WordsBy1(d, HighWord(c)) \ - MultiplyWords(p, A[n-1], B[n-1])\ - Acc2WordsBy2(d, p) \ - R[2*n-2] = LowWord(d); \ - R[2*n-1] = HighWord(d); - -#define Bot_SaveAcc(k, i, j) \ - R[k] = LowWord(c); \ - word e = LowWord(d) + HighWord(c); \ - e += A[i] * B[j]; - -#define Bot_Acc(i, j) \ - e += A[i] * B[j]; - -#define Bot_End(n) \ - R[n-1] = e; -#else -#define Mul_Begin(n) \ - Declare2Words(p) \ - word c; \ - Declare2Words(d) \ - MultiplyWords(p, A[0], B[0]) \ - c = LowWord(p); \ - AssignWord(d, HighWord(p)) - -#define Mul_Acc(i, j) \ - MulAcc(c, d, A[i], B[j]) - -#define Mul_SaveAcc(k, i, j) \ - R[k] = c; \ - c = LowWord(d); \ - AssignWord(d, HighWord(d)) \ - MulAcc(c, d, A[i], B[j]) - -#define Mul_End(k, i) \ - R[k] = c; \ - MultiplyWords(p, A[i], B[i]) \ - Acc2WordsBy2(p, d) \ - R[k+1] = LowWord(p); \ - R[k+2] = HighWord(p); - -#define Bot_SaveAcc(k, i, j) \ - R[k] = c; \ - c = LowWord(d); \ - c += A[i] * B[j]; - -#define Bot_Acc(i, j) \ - c += A[i] * B[j]; - -#define Bot_End(n) \ - R[n-1] = c; -#endif - -#define Squ_Begin(n) \ - Declare2Words(p) \ - word c; \ - Declare2Words(d) \ - Declare2Words(e) \ - MultiplyWords(p, A[0], A[0]) \ - R[0] = LowWord(p); \ - AssignWord(e, HighWord(p)) \ - MultiplyWords(p, A[0], A[1]) \ - c = LowWord(p); \ - AssignWord(d, HighWord(p)) \ - Squ_NonDiag \ - -#define Squ_NonDiag \ - Double3Words(c, d) - -#define Squ_SaveAcc(k, i, j) \ - Acc3WordsBy2(c, d, e) \ - R[k] = c; \ - MultiplyWords(p, A[i], A[j]) \ - c = LowWord(p); \ - AssignWord(d, HighWord(p)) \ - -#define Squ_Acc(i, j) \ - MulAcc(c, d, A[i], A[j]) - -#define Squ_Diag(i) \ - Squ_NonDiag \ - MulAcc(c, d, A[i], A[i]) - -#define Squ_End(n) \ - Acc3WordsBy2(c, d, e) \ - R[2*n-3] = c; \ - MultiplyWords(p, A[n-1], A[n-1])\ - Acc2WordsBy2(p, e) \ - R[2*n-2] = LowWord(p); \ - R[2*n-1] = HighWord(p); - -void Baseline_Multiply2(word *R, const word *A, const word *B) -{ - Mul_2 -} - -void Baseline_Multiply4(word *R, const word *A, const word *B) -{ - Mul_4 -} - -void Baseline_Multiply8(word *R, const word *A, const word *B) -{ - Mul_8 -} - -void Baseline_Square2(word *R, const word *A) -{ - Squ_2 -} - -void Baseline_Square4(word *R, const word *A) -{ - Squ_4 -} - -void Baseline_Square8(word *R, const word *A) -{ - Squ_8 -} - -void Baseline_MultiplyBottom2(word *R, const word *A, const word *B) -{ - Bot_2 -} - -void Baseline_MultiplyBottom4(word *R, const word *A, const word *B) -{ - Bot_4 -} - -void Baseline_MultiplyBottom8(word *R, const word *A, const word *B) -{ - Bot_8 -} - -#define Top_Begin(n) \ - Declare2Words(p) \ - word c; \ - Declare2Words(d) \ - MultiplyWords(p, A[0], B[n-2]);\ - AssignWord(d, HighWord(p)); - -#define Top_Acc(i, j) \ - MultiplyWords(p, A[i], B[j]);\ - Acc2WordsBy1(d, HighWord(p)); - -#define Top_SaveAcc0(i, j) \ - c = LowWord(d); \ - AssignWord(d, HighWord(d)) \ - MulAcc(c, d, A[i], B[j]) - -#define Top_SaveAcc1(i, j) \ - c = L<c; \ - Acc2WordsBy1(d, c); \ - c = LowWord(d); \ - AssignWord(d, HighWord(d)) \ - MulAcc(c, d, A[i], B[j]) - -void Baseline_MultiplyTop2(word *R, const word *A, const word *B, word L) -{ - word T[4]; - Baseline_Multiply2(T, A, B); - R[0] = T[2]; - R[1] = T[3]; -} - -void Baseline_MultiplyTop4(word *R, const word *A, const word *B, word L) -{ - Top_Begin(4) - Top_Acc(1, 1) Top_Acc(2, 0) \ - Top_SaveAcc0(0, 3) Mul_Acc(1, 2) Mul_Acc(2, 1) Mul_Acc(3, 0) \ - Top_SaveAcc1(1, 3) Mul_Acc(2, 2) Mul_Acc(3, 1) \ - Mul_SaveAcc(0, 2, 3) Mul_Acc(3, 2) \ - Mul_End(1, 3) -} - -void Baseline_MultiplyTop8(word *R, const word *A, const word *B, word L) -{ - Top_Begin(8) - Top_Acc(1, 5) Top_Acc(2, 4) Top_Acc(3, 3) Top_Acc(4, 2) Top_Acc(5, 1) Top_Acc(6, 0) \ - Top_SaveAcc0(0, 7) Mul_Acc(1, 6) Mul_Acc(2, 5) Mul_Acc(3, 4) Mul_Acc(4, 3) Mul_Acc(5, 2) Mul_Acc(6, 1) Mul_Acc(7, 0) \ - Top_SaveAcc1(1, 7) Mul_Acc(2, 6) Mul_Acc(3, 5) Mul_Acc(4, 4) Mul_Acc(5, 3) Mul_Acc(6, 2) Mul_Acc(7, 1) \ - Mul_SaveAcc(0, 2, 7) Mul_Acc(3, 6) Mul_Acc(4, 5) Mul_Acc(5, 4) Mul_Acc(6, 3) Mul_Acc(7, 2) \ - Mul_SaveAcc(1, 3, 7) Mul_Acc(4, 6) Mul_Acc(5, 5) Mul_Acc(6, 4) Mul_Acc(7, 3) \ - Mul_SaveAcc(2, 4, 7) Mul_Acc(5, 6) Mul_Acc(6, 5) Mul_Acc(7, 4) \ - Mul_SaveAcc(3, 5, 7) Mul_Acc(6, 6) Mul_Acc(7, 5) \ - Mul_SaveAcc(4, 6, 7) Mul_Acc(7, 6) \ - Mul_End(5, 7) -} - -#if !CRYPTOPP_INTEGER_SSE2 // save memory by not compiling these functions when SSE2 is available -void Baseline_Multiply16(word *R, const word *A, const word *B) -{ - Mul_16 -} - -void Baseline_Square16(word *R, const word *A) -{ - Squ_16 -} - -void Baseline_MultiplyBottom16(word *R, const word *A, const word *B) -{ - Bot_16 -} - -void Baseline_MultiplyTop16(word *R, const word *A, const word *B, word L) -{ - Top_Begin(16) - Top_Acc(1, 13) Top_Acc(2, 12) Top_Acc(3, 11) Top_Acc(4, 10) Top_Acc(5, 9) Top_Acc(6, 8) Top_Acc(7, 7) Top_Acc(8, 6) Top_Acc(9, 5) Top_Acc(10, 4) Top_Acc(11, 3) Top_Acc(12, 2) Top_Acc(13, 1) Top_Acc(14, 0) \ - Top_SaveAcc0(0, 15) Mul_Acc(1, 14) Mul_Acc(2, 13) Mul_Acc(3, 12) Mul_Acc(4, 11) Mul_Acc(5, 10) Mul_Acc(6, 9) Mul_Acc(7, 8) Mul_Acc(8, 7) Mul_Acc(9, 6) Mul_Acc(10, 5) Mul_Acc(11, 4) Mul_Acc(12, 3) Mul_Acc(13, 2) Mul_Acc(14, 1) Mul_Acc(15, 0) \ - Top_SaveAcc1(1, 15) Mul_Acc(2, 14) Mul_Acc(3, 13) Mul_Acc(4, 12) Mul_Acc(5, 11) Mul_Acc(6, 10) Mul_Acc(7, 9) Mul_Acc(8, 8) Mul_Acc(9, 7) Mul_Acc(10, 6) Mul_Acc(11, 5) Mul_Acc(12, 4) Mul_Acc(13, 3) Mul_Acc(14, 2) Mul_Acc(15, 1) \ - Mul_SaveAcc(0, 2, 15) Mul_Acc(3, 14) Mul_Acc(4, 13) Mul_Acc(5, 12) Mul_Acc(6, 11) Mul_Acc(7, 10) Mul_Acc(8, 9) Mul_Acc(9, 8) Mul_Acc(10, 7) Mul_Acc(11, 6) Mul_Acc(12, 5) Mul_Acc(13, 4) Mul_Acc(14, 3) Mul_Acc(15, 2) \ - Mul_SaveAcc(1, 3, 15) Mul_Acc(4, 14) Mul_Acc(5, 13) Mul_Acc(6, 12) Mul_Acc(7, 11) Mul_Acc(8, 10) Mul_Acc(9, 9) Mul_Acc(10, 8) Mul_Acc(11, 7) Mul_Acc(12, 6) Mul_Acc(13, 5) Mul_Acc(14, 4) Mul_Acc(15, 3) \ - Mul_SaveAcc(2, 4, 15) Mul_Acc(5, 14) Mul_Acc(6, 13) Mul_Acc(7, 12) Mul_Acc(8, 11) Mul_Acc(9, 10) Mul_Acc(10, 9) Mul_Acc(11, 8) Mul_Acc(12, 7) Mul_Acc(13, 6) Mul_Acc(14, 5) Mul_Acc(15, 4) \ - Mul_SaveAcc(3, 5, 15) Mul_Acc(6, 14) Mul_Acc(7, 13) Mul_Acc(8, 12) Mul_Acc(9, 11) Mul_Acc(10, 10) Mul_Acc(11, 9) Mul_Acc(12, 8) Mul_Acc(13, 7) Mul_Acc(14, 6) Mul_Acc(15, 5) \ - Mul_SaveAcc(4, 6, 15) Mul_Acc(7, 14) Mul_Acc(8, 13) Mul_Acc(9, 12) Mul_Acc(10, 11) Mul_Acc(11, 10) Mul_Acc(12, 9) Mul_Acc(13, 8) Mul_Acc(14, 7) Mul_Acc(15, 6) \ - Mul_SaveAcc(5, 7, 15) Mul_Acc(8, 14) Mul_Acc(9, 13) Mul_Acc(10, 12) Mul_Acc(11, 11) Mul_Acc(12, 10) Mul_Acc(13, 9) Mul_Acc(14, 8) Mul_Acc(15, 7) \ - Mul_SaveAcc(6, 8, 15) Mul_Acc(9, 14) Mul_Acc(10, 13) Mul_Acc(11, 12) Mul_Acc(12, 11) Mul_Acc(13, 10) Mul_Acc(14, 9) Mul_Acc(15, 8) \ - Mul_SaveAcc(7, 9, 15) Mul_Acc(10, 14) Mul_Acc(11, 13) Mul_Acc(12, 12) Mul_Acc(13, 11) Mul_Acc(14, 10) Mul_Acc(15, 9) \ - Mul_SaveAcc(8, 10, 15) Mul_Acc(11, 14) Mul_Acc(12, 13) Mul_Acc(13, 12) Mul_Acc(14, 11) Mul_Acc(15, 10) \ - Mul_SaveAcc(9, 11, 15) Mul_Acc(12, 14) Mul_Acc(13, 13) Mul_Acc(14, 12) Mul_Acc(15, 11) \ - Mul_SaveAcc(10, 12, 15) Mul_Acc(13, 14) Mul_Acc(14, 13) Mul_Acc(15, 12) \ - Mul_SaveAcc(11, 13, 15) Mul_Acc(14, 14) Mul_Acc(15, 13) \ - Mul_SaveAcc(12, 14, 15) Mul_Acc(15, 14) \ - Mul_End(13, 15) -} -#endif - -// ******************************************************** - -#if CRYPTOPP_INTEGER_SSE2 - -CRYPTOPP_ALIGN_DATA(16) static const word32 s_maskLow16[4] CRYPTOPP_SECTION_ALIGN16 = {0xffff,0xffff,0xffff,0xffff}; - -#undef Mul_Begin -#undef Mul_Acc -#undef Top_Begin -#undef Top_Acc -#undef Squ_Acc -#undef Squ_NonDiag -#undef Squ_Diag -#undef Squ_SaveAcc -#undef Squ_Begin -#undef Mul_SaveAcc -#undef Bot_Acc -#undef Bot_SaveAcc -#undef Bot_End -#undef Squ_End -#undef Mul_End - -#define SSE2_FinalSave(k) \ - AS2( psllq xmm5, 16) \ - AS2( paddq xmm4, xmm5) \ - AS2( movq QWORD PTR [ecx+8*(k)], xmm4) - -#define SSE2_SaveShift(k) \ - AS2( movq xmm0, xmm6) \ - AS2( punpckhqdq xmm6, xmm0) \ - AS2( movq xmm1, xmm7) \ - AS2( punpckhqdq xmm7, xmm1) \ - AS2( paddd xmm6, xmm0) \ - AS2( pslldq xmm6, 4) \ - AS2( paddd xmm7, xmm1) \ - AS2( paddd xmm4, xmm6) \ - AS2( pslldq xmm7, 4) \ - AS2( movq xmm6, xmm4) \ - AS2( paddd xmm5, xmm7) \ - AS2( movq xmm7, xmm5) \ - AS2( movd DWORD PTR [ecx+8*(k)], xmm4) \ - AS2( psrlq xmm6, 16) \ - AS2( paddq xmm6, xmm7) \ - AS2( punpckhqdq xmm4, xmm0) \ - AS2( punpckhqdq xmm5, xmm0) \ - AS2( movq QWORD PTR [ecx+8*(k)+2], xmm6) \ - AS2( psrlq xmm6, 3*16) \ - AS2( paddd xmm4, xmm6) \ - -#define Squ_SSE2_SaveShift(k) \ - AS2( movq xmm0, xmm6) \ - AS2( punpckhqdq xmm6, xmm0) \ - AS2( movq xmm1, xmm7) \ - AS2( punpckhqdq xmm7, xmm1) \ - AS2( paddd xmm6, xmm0) \ - AS2( pslldq xmm6, 4) \ - AS2( paddd xmm7, xmm1) \ - AS2( paddd xmm4, xmm6) \ - AS2( pslldq xmm7, 4) \ - AS2( movhlps xmm6, xmm4) \ - AS2( movd DWORD PTR [ecx+8*(k)], xmm4) \ - AS2( paddd xmm5, xmm7) \ - AS2( movhps QWORD PTR [esp+12], xmm5)\ - AS2( psrlq xmm4, 16) \ - AS2( paddq xmm4, xmm5) \ - AS2( movq QWORD PTR [ecx+8*(k)+2], xmm4) \ - AS2( psrlq xmm4, 3*16) \ - AS2( paddd xmm4, xmm6) \ - AS2( movq QWORD PTR [esp+4], xmm4)\ - -#define SSE2_FirstMultiply(i) \ - AS2( movdqa xmm7, [esi+(i)*16])\ - AS2( movdqa xmm5, [edi-(i)*16])\ - AS2( pmuludq xmm5, xmm7) \ - AS2( movdqa xmm4, [ebx])\ - AS2( movdqa xmm6, xmm4) \ - AS2( pand xmm4, xmm5) \ - AS2( psrld xmm5, 16) \ - AS2( pmuludq xmm7, [edx-(i)*16])\ - AS2( pand xmm6, xmm7) \ - AS2( psrld xmm7, 16) - -#define Squ_Begin(n) \ - SquPrologue \ - AS2( mov esi, esp)\ - AS2( and esp, 0xfffffff0)\ - AS2( lea edi, [esp-32*n])\ - AS2( sub esp, 32*n+16)\ - AS1( push esi)\ - AS2( mov esi, edi) \ - AS2( xor edx, edx) \ - ASL(1) \ - ASS( pshufd xmm0, [eax+edx], 3,1,2,0) \ - ASS( pshufd xmm1, [eax+edx], 2,0,3,1) \ - AS2( movdqa [edi+2*edx], xmm0) \ - AS2( psrlq xmm0, 32) \ - AS2( movdqa [edi+2*edx+16], xmm0) \ - AS2( movdqa [edi+16*n+2*edx], xmm1) \ - AS2( psrlq xmm1, 32) \ - AS2( movdqa [edi+16*n+2*edx+16], xmm1) \ - AS2( add edx, 16) \ - AS2( cmp edx, 8*(n)) \ - ASJ( jne, 1, b) \ - AS2( lea edx, [edi+16*n])\ - SSE2_FirstMultiply(0) \ - -#define Squ_Acc(i) \ - ASL(LSqu##i) \ - AS2( movdqa xmm1, [esi+(i)*16]) \ - AS2( movdqa xmm0, [edi-(i)*16]) \ - AS2( movdqa xmm2, [ebx]) \ - AS2( pmuludq xmm0, xmm1) \ - AS2( pmuludq xmm1, [edx-(i)*16]) \ - AS2( movdqa xmm3, xmm2) \ - AS2( pand xmm2, xmm0) \ - AS2( psrld xmm0, 16) \ - AS2( paddd xmm4, xmm2) \ - AS2( paddd xmm5, xmm0) \ - AS2( pand xmm3, xmm1) \ - AS2( psrld xmm1, 16) \ - AS2( paddd xmm6, xmm3) \ - AS2( paddd xmm7, xmm1) \ - -#define Squ_Acc1(i) -#define Squ_Acc2(i) ASC(call, LSqu##i) -#define Squ_Acc3(i) Squ_Acc2(i) -#define Squ_Acc4(i) Squ_Acc2(i) -#define Squ_Acc5(i) Squ_Acc2(i) -#define Squ_Acc6(i) Squ_Acc2(i) -#define Squ_Acc7(i) Squ_Acc2(i) -#define Squ_Acc8(i) Squ_Acc2(i) - -#define SSE2_End(E, n) \ - SSE2_SaveShift(2*(n)-3) \ - AS2( movdqa xmm7, [esi+16]) \ - AS2( movdqa xmm0, [edi]) \ - AS2( pmuludq xmm0, xmm7) \ - AS2( movdqa xmm2, [ebx]) \ - AS2( pmuludq xmm7, [edx]) \ - AS2( movdqa xmm6, xmm2) \ - AS2( pand xmm2, xmm0) \ - AS2( psrld xmm0, 16) \ - AS2( paddd xmm4, xmm2) \ - AS2( paddd xmm5, xmm0) \ - AS2( pand xmm6, xmm7) \ - AS2( psrld xmm7, 16) \ - SSE2_SaveShift(2*(n)-2) \ - SSE2_FinalSave(2*(n)-1) \ - AS1( pop esp)\ - E - -#define Squ_End(n) SSE2_End(SquEpilogue, n) -#define Mul_End(n) SSE2_End(MulEpilogue, n) -#define Top_End(n) SSE2_End(TopEpilogue, n) - -#define Squ_Column1(k, i) \ - Squ_SSE2_SaveShift(k) \ - AS2( add esi, 16) \ - SSE2_FirstMultiply(1)\ - Squ_Acc##i(i) \ - AS2( paddd xmm4, xmm4) \ - AS2( paddd xmm5, xmm5) \ - AS2( movdqa xmm3, [esi]) \ - AS2( movq xmm1, QWORD PTR [esi+8]) \ - AS2( pmuludq xmm1, xmm3) \ - AS2( pmuludq xmm3, xmm3) \ - AS2( movdqa xmm0, [ebx])\ - AS2( movdqa xmm2, xmm0) \ - AS2( pand xmm0, xmm1) \ - AS2( psrld xmm1, 16) \ - AS2( paddd xmm6, xmm0) \ - AS2( paddd xmm7, xmm1) \ - AS2( pand xmm2, xmm3) \ - AS2( psrld xmm3, 16) \ - AS2( paddd xmm6, xmm6) \ - AS2( paddd xmm7, xmm7) \ - AS2( paddd xmm4, xmm2) \ - AS2( paddd xmm5, xmm3) \ - AS2( movq xmm0, QWORD PTR [esp+4])\ - AS2( movq xmm1, QWORD PTR [esp+12])\ - AS2( paddd xmm4, xmm0)\ - AS2( paddd xmm5, xmm1)\ - -#define Squ_Column0(k, i) \ - Squ_SSE2_SaveShift(k) \ - AS2( add edi, 16) \ - AS2( add edx, 16) \ - SSE2_FirstMultiply(1)\ - Squ_Acc##i(i) \ - AS2( paddd xmm6, xmm6) \ - AS2( paddd xmm7, xmm7) \ - AS2( paddd xmm4, xmm4) \ - AS2( paddd xmm5, xmm5) \ - AS2( movq xmm0, QWORD PTR [esp+4])\ - AS2( movq xmm1, QWORD PTR [esp+12])\ - AS2( paddd xmm4, xmm0)\ - AS2( paddd xmm5, xmm1)\ - -#define SSE2_MulAdd45 \ - AS2( movdqa xmm7, [esi]) \ - AS2( movdqa xmm0, [edi]) \ - AS2( pmuludq xmm0, xmm7) \ - AS2( movdqa xmm2, [ebx]) \ - AS2( pmuludq xmm7, [edx]) \ - AS2( movdqa xmm6, xmm2) \ - AS2( pand xmm2, xmm0) \ - AS2( psrld xmm0, 16) \ - AS2( paddd xmm4, xmm2) \ - AS2( paddd xmm5, xmm0) \ - AS2( pand xmm6, xmm7) \ - AS2( psrld xmm7, 16) - -#define Mul_Begin(n) \ - MulPrologue \ - AS2( mov esi, esp)\ - AS2( and esp, 0xfffffff0)\ - AS2( sub esp, 48*n+16)\ - AS1( push esi)\ - AS2( xor edx, edx) \ - ASL(1) \ - ASS( pshufd xmm0, [eax+edx], 3,1,2,0) \ - ASS( pshufd xmm1, [eax+edx], 2,0,3,1) \ - ASS( pshufd xmm2, [edi+edx], 3,1,2,0) \ - AS2( movdqa [esp+20+2*edx], xmm0) \ - AS2( psrlq xmm0, 32) \ - AS2( movdqa [esp+20+2*edx+16], xmm0) \ - AS2( movdqa [esp+20+16*n+2*edx], xmm1) \ - AS2( psrlq xmm1, 32) \ - AS2( movdqa [esp+20+16*n+2*edx+16], xmm1) \ - AS2( movdqa [esp+20+32*n+2*edx], xmm2) \ - AS2( psrlq xmm2, 32) \ - AS2( movdqa [esp+20+32*n+2*edx+16], xmm2) \ - AS2( add edx, 16) \ - AS2( cmp edx, 8*(n)) \ - ASJ( jne, 1, b) \ - AS2( lea edi, [esp+20])\ - AS2( lea edx, [esp+20+16*n])\ - AS2( lea esi, [esp+20+32*n])\ - SSE2_FirstMultiply(0) \ - -#define Mul_Acc(i) \ - ASL(LMul##i) \ - AS2( movdqa xmm1, [esi+i/2*(1-(i-2*(i/2))*2)*16]) \ - AS2( movdqa xmm0, [edi-i/2*(1-(i-2*(i/2))*2)*16]) \ - AS2( movdqa xmm2, [ebx]) \ - AS2( pmuludq xmm0, xmm1) \ - AS2( pmuludq xmm1, [edx-i/2*(1-(i-2*(i/2))*2)*16]) \ - AS2( movdqa xmm3, xmm2) \ - AS2( pand xmm2, xmm0) \ - AS2( psrld xmm0, 16) \ - AS2( paddd xmm4, xmm2) \ - AS2( paddd xmm5, xmm0) \ - AS2( pand xmm3, xmm1) \ - AS2( psrld xmm1, 16) \ - AS2( paddd xmm6, xmm3) \ - AS2( paddd xmm7, xmm1) \ - -#define Mul_Acc1(i) -#define Mul_Acc2(i) ASC(call, LMul##i) -#define Mul_Acc3(i) Mul_Acc2(i) -#define Mul_Acc4(i) Mul_Acc2(i) -#define Mul_Acc5(i) Mul_Acc2(i) -#define Mul_Acc6(i) Mul_Acc2(i) -#define Mul_Acc7(i) Mul_Acc2(i) -#define Mul_Acc8(i) Mul_Acc2(i) -#define Mul_Acc9(i) Mul_Acc2(i) -#define Mul_Acc10(i) Mul_Acc2(i) -#define Mul_Acc11(i) Mul_Acc2(i) -#define Mul_Acc12(i) Mul_Acc2(i) -#define Mul_Acc13(i) Mul_Acc2(i) -#define Mul_Acc14(i) Mul_Acc2(i) -#define Mul_Acc15(i) Mul_Acc2(i) -#define Mul_Acc16(i) Mul_Acc2(i) - -#define Mul_Column1(k, i) \ - SSE2_SaveShift(k) \ - AS2( add esi, 16) \ - SSE2_MulAdd45\ - Mul_Acc##i(i) \ - -#define Mul_Column0(k, i) \ - SSE2_SaveShift(k) \ - AS2( add edi, 16) \ - AS2( add edx, 16) \ - SSE2_MulAdd45\ - Mul_Acc##i(i) \ - -#define Bot_Acc(i) \ - AS2( movdqa xmm1, [esi+i/2*(1-(i-2*(i/2))*2)*16]) \ - AS2( movdqa xmm0, [edi-i/2*(1-(i-2*(i/2))*2)*16]) \ - AS2( pmuludq xmm0, xmm1) \ - AS2( pmuludq xmm1, [edx-i/2*(1-(i-2*(i/2))*2)*16]) \ - AS2( paddq xmm4, xmm0) \ - AS2( paddd xmm6, xmm1) - -#define Bot_SaveAcc(k) \ - SSE2_SaveShift(k) \ - AS2( add edi, 16) \ - AS2( add edx, 16) \ - AS2( movdqa xmm6, [esi]) \ - AS2( movdqa xmm0, [edi]) \ - AS2( pmuludq xmm0, xmm6) \ - AS2( paddq xmm4, xmm0) \ - AS2( psllq xmm5, 16) \ - AS2( paddq xmm4, xmm5) \ - AS2( pmuludq xmm6, [edx]) - -#define Bot_End(n) \ - AS2( movhlps xmm7, xmm6) \ - AS2( paddd xmm6, xmm7) \ - AS2( psllq xmm6, 32) \ - AS2( paddd xmm4, xmm6) \ - AS2( movq QWORD PTR [ecx+8*((n)-1)], xmm4) \ - AS1( pop esp)\ - MulEpilogue - -#define Top_Begin(n) \ - TopPrologue \ - AS2( mov edx, esp)\ - AS2( and esp, 0xfffffff0)\ - AS2( sub esp, 48*n+16)\ - AS1( push edx)\ - AS2( xor edx, edx) \ - ASL(1) \ - ASS( pshufd xmm0, [eax+edx], 3,1,2,0) \ - ASS( pshufd xmm1, [eax+edx], 2,0,3,1) \ - ASS( pshufd xmm2, [edi+edx], 3,1,2,0) \ - AS2( movdqa [esp+20+2*edx], xmm0) \ - AS2( psrlq xmm0, 32) \ - AS2( movdqa [esp+20+2*edx+16], xmm0) \ - AS2( movdqa [esp+20+16*n+2*edx], xmm1) \ - AS2( psrlq xmm1, 32) \ - AS2( movdqa [esp+20+16*n+2*edx+16], xmm1) \ - AS2( movdqa [esp+20+32*n+2*edx], xmm2) \ - AS2( psrlq xmm2, 32) \ - AS2( movdqa [esp+20+32*n+2*edx+16], xmm2) \ - AS2( add edx, 16) \ - AS2( cmp edx, 8*(n)) \ - ASJ( jne, 1, b) \ - AS2( mov eax, esi) \ - AS2( lea edi, [esp+20+00*n+16*(n/2-1)])\ - AS2( lea edx, [esp+20+16*n+16*(n/2-1)])\ - AS2( lea esi, [esp+20+32*n+16*(n/2-1)])\ - AS2( pxor xmm4, xmm4)\ - AS2( pxor xmm5, xmm5) - -#define Top_Acc(i) \ - AS2( movq xmm0, QWORD PTR [esi+i/2*(1-(i-2*(i/2))*2)*16+8]) \ - AS2( pmuludq xmm0, [edx-i/2*(1-(i-2*(i/2))*2)*16]) \ - AS2( psrlq xmm0, 48) \ - AS2( paddd xmm5, xmm0)\ - -#define Top_Column0(i) \ - AS2( psllq xmm5, 32) \ - AS2( add edi, 16) \ - AS2( add edx, 16) \ - SSE2_MulAdd45\ - Mul_Acc##i(i) \ - -#define Top_Column1(i) \ - SSE2_SaveShift(0) \ - AS2( add esi, 16) \ - SSE2_MulAdd45\ - Mul_Acc##i(i) \ - AS2( shr eax, 16) \ - AS2( movd xmm0, eax)\ - AS2( movd xmm1, [ecx+4])\ - AS2( psrld xmm1, 16)\ - AS2( pcmpgtd xmm1, xmm0)\ - AS2( psrld xmm1, 31)\ - AS2( paddd xmm4, xmm1)\ - -void SSE2_Square4(word *C, const word *A) -{ - Squ_Begin(2) - Squ_Column0(0, 1) - Squ_End(2) -} - -void SSE2_Square8(word *C, const word *A) -{ - Squ_Begin(4) -#ifndef __GNUC__ - ASJ( jmp, 0, f) - Squ_Acc(2) - AS1( ret) ASL(0) -#endif - Squ_Column0(0, 1) - Squ_Column1(1, 1) - Squ_Column0(2, 2) - Squ_Column1(3, 1) - Squ_Column0(4, 1) - Squ_End(4) -} - -void SSE2_Square16(word *C, const word *A) -{ - Squ_Begin(8) -#ifndef __GNUC__ - ASJ( jmp, 0, f) - Squ_Acc(4) Squ_Acc(3) Squ_Acc(2) - AS1( ret) ASL(0) -#endif - Squ_Column0(0, 1) - Squ_Column1(1, 1) - Squ_Column0(2, 2) - Squ_Column1(3, 2) - Squ_Column0(4, 3) - Squ_Column1(5, 3) - Squ_Column0(6, 4) - Squ_Column1(7, 3) - Squ_Column0(8, 3) - Squ_Column1(9, 2) - Squ_Column0(10, 2) - Squ_Column1(11, 1) - Squ_Column0(12, 1) - Squ_End(8) -} - -void SSE2_Square32(word *C, const word *A) -{ - Squ_Begin(16) - ASJ( jmp, 0, f) - Squ_Acc(8) Squ_Acc(7) Squ_Acc(6) Squ_Acc(5) Squ_Acc(4) Squ_Acc(3) Squ_Acc(2) - AS1( ret) ASL(0) - Squ_Column0(0, 1) - Squ_Column1(1, 1) - Squ_Column0(2, 2) - Squ_Column1(3, 2) - Squ_Column0(4, 3) - Squ_Column1(5, 3) - Squ_Column0(6, 4) - Squ_Column1(7, 4) - Squ_Column0(8, 5) - Squ_Column1(9, 5) - Squ_Column0(10, 6) - Squ_Column1(11, 6) - Squ_Column0(12, 7) - Squ_Column1(13, 7) - Squ_Column0(14, 8) - Squ_Column1(15, 7) - Squ_Column0(16, 7) - Squ_Column1(17, 6) - Squ_Column0(18, 6) - Squ_Column1(19, 5) - Squ_Column0(20, 5) - Squ_Column1(21, 4) - Squ_Column0(22, 4) - Squ_Column1(23, 3) - Squ_Column0(24, 3) - Squ_Column1(25, 2) - Squ_Column0(26, 2) - Squ_Column1(27, 1) - Squ_Column0(28, 1) - Squ_End(16) -} - -void SSE2_Multiply4(word *C, const word *A, const word *B) -{ - Mul_Begin(2) -#ifndef __GNUC__ - ASJ( jmp, 0, f) - Mul_Acc(2) - AS1( ret) ASL(0) -#endif - Mul_Column0(0, 2) - Mul_End(2) -} - -void SSE2_Multiply8(word *C, const word *A, const word *B) -{ - Mul_Begin(4) -#ifndef __GNUC__ - ASJ( jmp, 0, f) - Mul_Acc(4) Mul_Acc(3) Mul_Acc(2) - AS1( ret) ASL(0) -#endif - Mul_Column0(0, 2) - Mul_Column1(1, 3) - Mul_Column0(2, 4) - Mul_Column1(3, 3) - Mul_Column0(4, 2) - Mul_End(4) -} - -void SSE2_Multiply16(word *C, const word *A, const word *B) -{ - Mul_Begin(8) -#ifndef __GNUC__ - ASJ( jmp, 0, f) - Mul_Acc(8) Mul_Acc(7) Mul_Acc(6) Mul_Acc(5) Mul_Acc(4) Mul_Acc(3) Mul_Acc(2) - AS1( ret) ASL(0) -#endif - Mul_Column0(0, 2) - Mul_Column1(1, 3) - Mul_Column0(2, 4) - Mul_Column1(3, 5) - Mul_Column0(4, 6) - Mul_Column1(5, 7) - Mul_Column0(6, 8) - Mul_Column1(7, 7) - Mul_Column0(8, 6) - Mul_Column1(9, 5) - Mul_Column0(10, 4) - Mul_Column1(11, 3) - Mul_Column0(12, 2) - Mul_End(8) -} - -void SSE2_Multiply32(word *C, const word *A, const word *B) -{ - Mul_Begin(16) - ASJ( jmp, 0, f) - Mul_Acc(16) Mul_Acc(15) Mul_Acc(14) Mul_Acc(13) Mul_Acc(12) Mul_Acc(11) Mul_Acc(10) Mul_Acc(9) Mul_Acc(8) Mul_Acc(7) Mul_Acc(6) Mul_Acc(5) Mul_Acc(4) Mul_Acc(3) Mul_Acc(2) - AS1( ret) ASL(0) - Mul_Column0(0, 2) - Mul_Column1(1, 3) - Mul_Column0(2, 4) - Mul_Column1(3, 5) - Mul_Column0(4, 6) - Mul_Column1(5, 7) - Mul_Column0(6, 8) - Mul_Column1(7, 9) - Mul_Column0(8, 10) - Mul_Column1(9, 11) - Mul_Column0(10, 12) - Mul_Column1(11, 13) - Mul_Column0(12, 14) - Mul_Column1(13, 15) - Mul_Column0(14, 16) - Mul_Column1(15, 15) - Mul_Column0(16, 14) - Mul_Column1(17, 13) - Mul_Column0(18, 12) - Mul_Column1(19, 11) - Mul_Column0(20, 10) - Mul_Column1(21, 9) - Mul_Column0(22, 8) - Mul_Column1(23, 7) - Mul_Column0(24, 6) - Mul_Column1(25, 5) - Mul_Column0(26, 4) - Mul_Column1(27, 3) - Mul_Column0(28, 2) - Mul_End(16) -} - -void SSE2_MultiplyBottom4(word *C, const word *A, const word *B) -{ - Mul_Begin(2) - Bot_SaveAcc(0) Bot_Acc(2) - Bot_End(2) -} - -void SSE2_MultiplyBottom8(word *C, const word *A, const word *B) -{ - Mul_Begin(4) -#ifndef __GNUC__ - ASJ( jmp, 0, f) - Mul_Acc(3) Mul_Acc(2) - AS1( ret) ASL(0) -#endif - Mul_Column0(0, 2) - Mul_Column1(1, 3) - Bot_SaveAcc(2) Bot_Acc(4) Bot_Acc(3) Bot_Acc(2) - Bot_End(4) -} - -void SSE2_MultiplyBottom16(word *C, const word *A, const word *B) -{ - Mul_Begin(8) -#ifndef __GNUC__ - ASJ( jmp, 0, f) - Mul_Acc(7) Mul_Acc(6) Mul_Acc(5) Mul_Acc(4) Mul_Acc(3) Mul_Acc(2) - AS1( ret) ASL(0) -#endif - Mul_Column0(0, 2) - Mul_Column1(1, 3) - Mul_Column0(2, 4) - Mul_Column1(3, 5) - Mul_Column0(4, 6) - Mul_Column1(5, 7) - Bot_SaveAcc(6) Bot_Acc(8) Bot_Acc(7) Bot_Acc(6) Bot_Acc(5) Bot_Acc(4) Bot_Acc(3) Bot_Acc(2) - Bot_End(8) -} - -void SSE2_MultiplyBottom32(word *C, const word *A, const word *B) -{ - Mul_Begin(16) -#ifndef __GNUC__ - ASJ( jmp, 0, f) - Mul_Acc(15) Mul_Acc(14) Mul_Acc(13) Mul_Acc(12) Mul_Acc(11) Mul_Acc(10) Mul_Acc(9) Mul_Acc(8) Mul_Acc(7) Mul_Acc(6) Mul_Acc(5) Mul_Acc(4) Mul_Acc(3) Mul_Acc(2) - AS1( ret) ASL(0) -#endif - Mul_Column0(0, 2) - Mul_Column1(1, 3) - Mul_Column0(2, 4) - Mul_Column1(3, 5) - Mul_Column0(4, 6) - Mul_Column1(5, 7) - Mul_Column0(6, 8) - Mul_Column1(7, 9) - Mul_Column0(8, 10) - Mul_Column1(9, 11) - Mul_Column0(10, 12) - Mul_Column1(11, 13) - Mul_Column0(12, 14) - Mul_Column1(13, 15) - Bot_SaveAcc(14) Bot_Acc(16) Bot_Acc(15) Bot_Acc(14) Bot_Acc(13) Bot_Acc(12) Bot_Acc(11) Bot_Acc(10) Bot_Acc(9) Bot_Acc(8) Bot_Acc(7) Bot_Acc(6) Bot_Acc(5) Bot_Acc(4) Bot_Acc(3) Bot_Acc(2) - Bot_End(16) -} - -void SSE2_MultiplyTop8(word *C, const word *A, const word *B, word L) -{ - Top_Begin(4) - Top_Acc(3) Top_Acc(2) Top_Acc(1) -#ifndef __GNUC__ - ASJ( jmp, 0, f) - Mul_Acc(4) Mul_Acc(3) Mul_Acc(2) - AS1( ret) ASL(0) -#endif - Top_Column0(4) - Top_Column1(3) - Mul_Column0(0, 2) - Top_End(2) -} - -void SSE2_MultiplyTop16(word *C, const word *A, const word *B, word L) -{ - Top_Begin(8) - Top_Acc(7) Top_Acc(6) Top_Acc(5) Top_Acc(4) Top_Acc(3) Top_Acc(2) Top_Acc(1) -#ifndef __GNUC__ - ASJ( jmp, 0, f) - Mul_Acc(8) Mul_Acc(7) Mul_Acc(6) Mul_Acc(5) Mul_Acc(4) Mul_Acc(3) Mul_Acc(2) - AS1( ret) ASL(0) -#endif - Top_Column0(8) - Top_Column1(7) - Mul_Column0(0, 6) - Mul_Column1(1, 5) - Mul_Column0(2, 4) - Mul_Column1(3, 3) - Mul_Column0(4, 2) - Top_End(4) -} - -void SSE2_MultiplyTop32(word *C, const word *A, const word *B, word L) -{ - Top_Begin(16) - Top_Acc(15) Top_Acc(14) Top_Acc(13) Top_Acc(12) Top_Acc(11) Top_Acc(10) Top_Acc(9) Top_Acc(8) Top_Acc(7) Top_Acc(6) Top_Acc(5) Top_Acc(4) Top_Acc(3) Top_Acc(2) Top_Acc(1) -#ifndef __GNUC__ - ASJ( jmp, 0, f) - Mul_Acc(16) Mul_Acc(15) Mul_Acc(14) Mul_Acc(13) Mul_Acc(12) Mul_Acc(11) Mul_Acc(10) Mul_Acc(9) Mul_Acc(8) Mul_Acc(7) Mul_Acc(6) Mul_Acc(5) Mul_Acc(4) Mul_Acc(3) Mul_Acc(2) - AS1( ret) ASL(0) -#endif - Top_Column0(16) - Top_Column1(15) - Mul_Column0(0, 14) - Mul_Column1(1, 13) - Mul_Column0(2, 12) - Mul_Column1(3, 11) - Mul_Column0(4, 10) - Mul_Column1(5, 9) - Mul_Column0(6, 8) - Mul_Column1(7, 7) - Mul_Column0(8, 6) - Mul_Column1(9, 5) - Mul_Column0(10, 4) - Mul_Column1(11, 3) - Mul_Column0(12, 2) - Top_End(8) -} - -#endif // #if CRYPTOPP_INTEGER_SSE2 - -// ******************************************************** - -typedef int (CRYPTOPP_FASTCALL * PAdd)(size_t N, word *C, const word *A, const word *B); -typedef void (* PMul)(word *C, const word *A, const word *B); -typedef void (* PSqu)(word *C, const word *A); -typedef void (* PMulTop)(word *C, const word *A, const word *B, word L); - -#if CRYPTOPP_INTEGER_SSE2 -static PAdd s_pAdd = &Baseline_Add, s_pSub = &Baseline_Sub; -static size_t s_recursionLimit = 8; -#else -static const size_t s_recursionLimit = 16; -#endif - -static PMul s_pMul[9], s_pBot[9]; -static PSqu s_pSqu[9]; -static PMulTop s_pTop[9]; - -static void SetFunctionPointers() -{ - s_pMul[0] = &Baseline_Multiply2; - s_pBot[0] = &Baseline_MultiplyBottom2; - s_pSqu[0] = &Baseline_Square2; - s_pTop[0] = &Baseline_MultiplyTop2; - s_pTop[1] = &Baseline_MultiplyTop4; - -#if CRYPTOPP_INTEGER_SSE2 - if (HasSSE2()) - { -#if _MSC_VER != 1200 || defined(NDEBUG) - if (IsP4()) - { - s_pAdd = &SSE2_Add; - s_pSub = &SSE2_Sub; - } -#endif - - s_recursionLimit = 32; - - s_pMul[1] = &SSE2_Multiply4; - s_pMul[2] = &SSE2_Multiply8; - s_pMul[4] = &SSE2_Multiply16; - s_pMul[8] = &SSE2_Multiply32; - - s_pBot[1] = &SSE2_MultiplyBottom4; - s_pBot[2] = &SSE2_MultiplyBottom8; - s_pBot[4] = &SSE2_MultiplyBottom16; - s_pBot[8] = &SSE2_MultiplyBottom32; - - s_pSqu[1] = &SSE2_Square4; - s_pSqu[2] = &SSE2_Square8; - s_pSqu[4] = &SSE2_Square16; - s_pSqu[8] = &SSE2_Square32; - - s_pTop[2] = &SSE2_MultiplyTop8; - s_pTop[4] = &SSE2_MultiplyTop16; - s_pTop[8] = &SSE2_MultiplyTop32; - } - else -#endif - { - s_pMul[1] = &Baseline_Multiply4; - s_pMul[2] = &Baseline_Multiply8; - - s_pBot[1] = &Baseline_MultiplyBottom4; - s_pBot[2] = &Baseline_MultiplyBottom8; - - s_pSqu[1] = &Baseline_Square4; - s_pSqu[2] = &Baseline_Square8; - - s_pTop[2] = &Baseline_MultiplyTop8; - -#if !CRYPTOPP_INTEGER_SSE2 - s_pMul[4] = &Baseline_Multiply16; - s_pBot[4] = &Baseline_MultiplyBottom16; - s_pSqu[4] = &Baseline_Square16; - s_pTop[4] = &Baseline_MultiplyTop16; -#endif - } -} - -inline int Add(word *C, const word *A, const word *B, size_t N) -{ -#if CRYPTOPP_INTEGER_SSE2 - return s_pAdd(N, C, A, B); -#else - return Baseline_Add(N, C, A, B); -#endif -} - -inline int Subtract(word *C, const word *A, const word *B, size_t N) -{ -#if CRYPTOPP_INTEGER_SSE2 - return s_pSub(N, C, A, B); -#else - return Baseline_Sub(N, C, A, B); -#endif -} - -// ******************************************************** - - -#define A0 A -#define A1 (A+N2) -#define B0 B -#define B1 (B+N2) - -#define T0 T -#define T1 (T+N2) -#define T2 (T+N) -#define T3 (T+N+N2) - -#define R0 R -#define R1 (R+N2) -#define R2 (R+N) -#define R3 (R+N+N2) - -// R[2*N] - result = A*B -// T[2*N] - temporary work space -// A[N] --- multiplier -// B[N] --- multiplicant - -void RecursiveMultiply(word *R, word *T, const word *A, const word *B, size_t N) -{ - assert(N>=2 && N%2==0); - - if (N <= s_recursionLimit) - s_pMul[N/4](R, A, B); - else - { - const size_t N2 = N/2; - - size_t AN2 = Compare(A0, A1, N2) > 0 ? 0 : N2; - Subtract(R0, A + AN2, A + (N2 ^ AN2), N2); - - size_t BN2 = Compare(B0, B1, N2) > 0 ? 0 : N2; - Subtract(R1, B + BN2, B + (N2 ^ BN2), N2); - - RecursiveMultiply(R2, T2, A1, B1, N2); - RecursiveMultiply(T0, T2, R0, R1, N2); - RecursiveMultiply(R0, T2, A0, B0, N2); - - // now T[01] holds (A1-A0)*(B0-B1), R[01] holds A0*B0, R[23] holds A1*B1 - - int c2 = Add(R2, R2, R1, N2); - int c3 = c2; - c2 += Add(R1, R2, R0, N2); - c3 += Add(R2, R2, R3, N2); - - if (AN2 == BN2) - c3 -= Subtract(R1, R1, T0, N); - else - c3 += Add(R1, R1, T0, N); - - c3 += Increment(R2, N2, c2); - assert (c3 >= 0 && c3 <= 2); - Increment(R3, N2, c3); - } -} - -// R[2*N] - result = A*A -// T[2*N] - temporary work space -// A[N] --- number to be squared - -void RecursiveSquare(word *R, word *T, const word *A, size_t N) -{ - assert(N && N%2==0); - - if (N <= s_recursionLimit) - s_pSqu[N/4](R, A); - else - { - const size_t N2 = N/2; - - RecursiveSquare(R0, T2, A0, N2); - RecursiveSquare(R2, T2, A1, N2); - RecursiveMultiply(T0, T2, A0, A1, N2); - - int carry = Add(R1, R1, T0, N); - carry += Add(R1, R1, T0, N); - Increment(R3, N2, carry); - } -} - -// R[N] - bottom half of A*B -// T[3*N/2] - temporary work space -// A[N] - multiplier -// B[N] - multiplicant - -void RecursiveMultiplyBottom(word *R, word *T, const word *A, const word *B, size_t N) -{ - assert(N>=2 && N%2==0); - - if (N <= s_recursionLimit) - s_pBot[N/4](R, A, B); - else - { - const size_t N2 = N/2; - - RecursiveMultiply(R, T, A0, B0, N2); - RecursiveMultiplyBottom(T0, T1, A1, B0, N2); - Add(R1, R1, T0, N2); - RecursiveMultiplyBottom(T0, T1, A0, B1, N2); - Add(R1, R1, T0, N2); - } -} - -// R[N] --- upper half of A*B -// T[2*N] - temporary work space -// L[N] --- lower half of A*B -// A[N] --- multiplier -// B[N] --- multiplicant - -void MultiplyTop(word *R, word *T, const word *L, const word *A, const word *B, size_t N) -{ - assert(N>=2 && N%2==0); - - if (N <= s_recursionLimit) - s_pTop[N/4](R, A, B, L[N-1]); - else - { - const size_t N2 = N/2; - - size_t AN2 = Compare(A0, A1, N2) > 0 ? 0 : N2; - Subtract(R0, A + AN2, A + (N2 ^ AN2), N2); - - size_t BN2 = Compare(B0, B1, N2) > 0 ? 0 : N2; - Subtract(R1, B + BN2, B + (N2 ^ BN2), N2); - - RecursiveMultiply(T0, T2, R0, R1, N2); - RecursiveMultiply(R0, T2, A1, B1, N2); - - // now T[01] holds (A1-A0)*(B0-B1) = A1*B0+A0*B1-A1*B1-A0*B0, R[01] holds A1*B1 - - int t, c3; - int c2 = Subtract(T2, L+N2, L, N2); - - if (AN2 == BN2) - { - c2 -= Add(T2, T2, T0, N2); - t = (Compare(T2, R0, N2) == -1); - c3 = t - Subtract(T2, T2, T1, N2); - } - else - { - c2 += Subtract(T2, T2, T0, N2); - t = (Compare(T2, R0, N2) == -1); - c3 = t + Add(T2, T2, T1, N2); - } - - c2 += t; - if (c2 >= 0) - c3 += Increment(T2, N2, c2); - else - c3 -= Decrement(T2, N2, -c2); - c3 += Add(R0, T2, R1, N2); - - assert (c3 >= 0 && c3 <= 2); - Increment(R1, N2, c3); - } -} - -inline void Multiply(word *R, word *T, const word *A, const word *B, size_t N) -{ - RecursiveMultiply(R, T, A, B, N); -} - -inline void Square(word *R, word *T, const word *A, size_t N) -{ - RecursiveSquare(R, T, A, N); -} - -inline void MultiplyBottom(word *R, word *T, const word *A, const word *B, size_t N) -{ - RecursiveMultiplyBottom(R, T, A, B, N); -} - -// R[NA+NB] - result = A*B -// T[NA+NB] - temporary work space -// A[NA] ---- multiplier -// B[NB] ---- multiplicant - -void AsymmetricMultiply(word *R, word *T, const word *A, size_t NA, const word *B, size_t NB) -{ - if (NA == NB) - { - if (A == B) - Square(R, T, A, NA); - else - Multiply(R, T, A, B, NA); - - return; - } - - if (NA > NB) - { - std::swap(A, B); - std::swap(NA, NB); - } - - assert(NB % NA == 0); - - if (NA==2 && !A[1]) - { - switch (A[0]) - { - case 0: - SetWords(R, 0, NB+2); - return; - case 1: - CopyWords(R, B, NB); - R[NB] = R[NB+1] = 0; - return; - default: - R[NB] = LinearMultiply(R, B, A[0], NB); - R[NB+1] = 0; - return; - } - } - - size_t i; - if ((NB/NA)%2 == 0) - { - Multiply(R, T, A, B, NA); - CopyWords(T+2*NA, R+NA, NA); - - for (i=2*NA; i<NB; i+=2*NA) - Multiply(T+NA+i, T, A, B+i, NA); - for (i=NA; i<NB; i+=2*NA) - Multiply(R+i, T, A, B+i, NA); - } - else - { - for (i=0; i<NB; i+=2*NA) - Multiply(R+i, T, A, B+i, NA); - for (i=NA; i<NB; i+=2*NA) - Multiply(T+NA+i, T, A, B+i, NA); - } - - if (Add(R+NA, R+NA, T+2*NA, NB-NA)) - Increment(R+NB, NA); -} - -// R[N] ----- result = A inverse mod 2**(WORD_BITS*N) -// T[3*N/2] - temporary work space -// A[N] ----- an odd number as input - -void RecursiveInverseModPower2(word *R, word *T, const word *A, size_t N) -{ - if (N==2) - { - T[0] = AtomicInverseModPower2(A[0]); - T[1] = 0; - s_pBot[0](T+2, T, A); - TwosComplement(T+2, 2); - Increment(T+2, 2, 2); - s_pBot[0](R, T, T+2); - } - else - { - const size_t N2 = N/2; - RecursiveInverseModPower2(R0, T0, A0, N2); - T0[0] = 1; - SetWords(T0+1, 0, N2-1); - MultiplyTop(R1, T1, T0, R0, A0, N2); - MultiplyBottom(T0, T1, R0, A1, N2); - Add(T0, R1, T0, N2); - TwosComplement(T0, N2); - MultiplyBottom(R1, T1, R0, T0, N2); - } -} - -// R[N] --- result = X/(2**(WORD_BITS*N)) mod M -// T[3*N] - temporary work space -// X[2*N] - number to be reduced -// M[N] --- modulus -// U[N] --- multiplicative inverse of M mod 2**(WORD_BITS*N) - -void MontgomeryReduce(word *R, word *T, word *X, const word *M, const word *U, size_t N) -{ -#if 1 - MultiplyBottom(R, T, X, U, N); - MultiplyTop(T, T+N, X, R, M, N); - word borrow = Subtract(T, X+N, T, N); - // defend against timing attack by doing this Add even when not needed - word carry = Add(T+N, T, M, N); - assert(carry | !borrow); - CopyWords(R, T + ((0-borrow) & N), N); -#elif 0 - const word u = 0-U[0]; - Declare2Words(p) - for (size_t i=0; i<N; i++) - { - const word t = u * X[i]; - word c = 0; - for (size_t j=0; j<N; j+=2) - { - MultiplyWords(p, t, M[j]); - Acc2WordsBy1(p, X[i+j]); - Acc2WordsBy1(p, c); - X[i+j] = LowWord(p); - c = HighWord(p); - MultiplyWords(p, t, M[j+1]); - Acc2WordsBy1(p, X[i+j+1]); - Acc2WordsBy1(p, c); - X[i+j+1] = LowWord(p); - c = HighWord(p); - } - - if (Increment(X+N+i, N-i, c)) - while (!Subtract(X+N, X+N, M, N)) {} - } - - memcpy(R, X+N, N*WORD_SIZE); -#else - __m64 u = _mm_cvtsi32_si64(0-U[0]), p; - for (size_t i=0; i<N; i++) - { - __m64 t = _mm_cvtsi32_si64(X[i]); - t = _mm_mul_su32(t, u); - __m64 c = _mm_setzero_si64(); - for (size_t j=0; j<N; j+=2) - { - p = _mm_mul_su32(t, _mm_cvtsi32_si64(M[j])); - p = _mm_add_si64(p, _mm_cvtsi32_si64(X[i+j])); - c = _mm_add_si64(c, p); - X[i+j] = _mm_cvtsi64_si32(c); - c = _mm_srli_si64(c, 32); - p = _mm_mul_su32(t, _mm_cvtsi32_si64(M[j+1])); - p = _mm_add_si64(p, _mm_cvtsi32_si64(X[i+j+1])); - c = _mm_add_si64(c, p); - X[i+j+1] = _mm_cvtsi64_si32(c); - c = _mm_srli_si64(c, 32); - } - - if (Increment(X+N+i, N-i, _mm_cvtsi64_si32(c))) - while (!Subtract(X+N, X+N, M, N)) {} - } - - memcpy(R, X+N, N*WORD_SIZE); - _mm_empty(); -#endif -} - -// R[N] --- result = X/(2**(WORD_BITS*N/2)) mod M -// T[2*N] - temporary work space -// X[2*N] - number to be reduced -// M[N] --- modulus -// U[N/2] - multiplicative inverse of M mod 2**(WORD_BITS*N/2) -// V[N] --- 2**(WORD_BITS*3*N/2) mod M - -void HalfMontgomeryReduce(word *R, word *T, const word *X, const word *M, const word *U, const word *V, size_t N) -{ - assert(N%2==0 && N>=4); - -#define M0 M -#define M1 (M+N2) -#define V0 V -#define V1 (V+N2) - -#define X0 X -#define X1 (X+N2) -#define X2 (X+N) -#define X3 (X+N+N2) - - const size_t N2 = N/2; - Multiply(T0, T2, V0, X3, N2); - int c2 = Add(T0, T0, X0, N); - MultiplyBottom(T3, T2, T0, U, N2); - MultiplyTop(T2, R, T0, T3, M0, N2); - c2 -= Subtract(T2, T1, T2, N2); - Multiply(T0, R, T3, M1, N2); - c2 -= Subtract(T0, T2, T0, N2); - int c3 = -(int)Subtract(T1, X2, T1, N2); - Multiply(R0, T2, V1, X3, N2); - c3 += Add(R, R, T, N); - - if (c2>0) - c3 += Increment(R1, N2); - else if (c2<0) - c3 -= Decrement(R1, N2, -c2); - - assert(c3>=-1 && c3<=1); - if (c3>0) - Subtract(R, R, M, N); - else if (c3<0) - Add(R, R, M, N); - -#undef M0 -#undef M1 -#undef V0 -#undef V1 - -#undef X0 -#undef X1 -#undef X2 -#undef X3 -} - -#undef A0 -#undef A1 -#undef B0 -#undef B1 - -#undef T0 -#undef T1 -#undef T2 -#undef T3 - -#undef R0 -#undef R1 -#undef R2 -#undef R3 - -/* -// do a 3 word by 2 word divide, returns quotient and leaves remainder in A -static word SubatomicDivide(word *A, word B0, word B1) -{ - // assert {A[2],A[1]} < {B1,B0}, so quotient can fit in a word - assert(A[2] < B1 || (A[2]==B1 && A[1] < B0)); - - // estimate the quotient: do a 2 word by 1 word divide - word Q; - if (B1+1 == 0) - Q = A[2]; - else - Q = DWord(A[1], A[2]).DividedBy(B1+1); - - // now subtract Q*B from A - DWord p = DWord::Multiply(B0, Q); - DWord u = (DWord) A[0] - p.GetLowHalf(); - A[0] = u.GetLowHalf(); - u = (DWord) A[1] - p.GetHighHalf() - u.GetHighHalfAsBorrow() - DWord::Multiply(B1, Q); - A[1] = u.GetLowHalf(); - A[2] += u.GetHighHalf(); - - // Q <= actual quotient, so fix it - while (A[2] || A[1] > B1 || (A[1]==B1 && A[0]>=B0)) - { - u = (DWord) A[0] - B0; - A[0] = u.GetLowHalf(); - u = (DWord) A[1] - B1 - u.GetHighHalfAsBorrow(); - A[1] = u.GetLowHalf(); - A[2] += u.GetHighHalf(); - Q++; - assert(Q); // shouldn't overflow - } - - return Q; -} - -// do a 4 word by 2 word divide, returns 2 word quotient in Q0 and Q1 -static inline void AtomicDivide(word *Q, const word *A, const word *B) -{ - if (!B[0] && !B[1]) // if divisor is 0, we assume divisor==2**(2*WORD_BITS) - { - Q[0] = A[2]; - Q[1] = A[3]; - } - else - { - word T[4]; - T[0] = A[0]; T[1] = A[1]; T[2] = A[2]; T[3] = A[3]; - Q[1] = SubatomicDivide(T+1, B[0], B[1]); - Q[0] = SubatomicDivide(T, B[0], B[1]); - -#ifndef NDEBUG - // multiply quotient and divisor and add remainder, make sure it equals dividend - assert(!T[2] && !T[3] && (T[1] < B[1] || (T[1]==B[1] && T[0]<B[0]))); - word P[4]; - LowLevel::Multiply2(P, Q, B); - Add(P, P, T, 4); - assert(memcmp(P, A, 4*WORD_SIZE)==0); -#endif - } -} -*/ - -static inline void AtomicDivide(word *Q, const word *A, const word *B) -{ - word T[4]; - DWord q = DivideFourWordsByTwo<word, DWord>(T, DWord(A[0], A[1]), DWord(A[2], A[3]), DWord(B[0], B[1])); - Q[0] = q.GetLowHalf(); - Q[1] = q.GetHighHalf(); - -#ifndef NDEBUG - if (B[0] || B[1]) - { - // multiply quotient and divisor and add remainder, make sure it equals dividend - assert(!T[2] && !T[3] && (T[1] < B[1] || (T[1]==B[1] && T[0]<B[0]))); - word P[4]; - s_pMul[0](P, Q, B); - Add(P, P, T, 4); - assert(memcmp(P, A, 4*WORD_SIZE)==0); - } -#endif -} - -// for use by Divide(), corrects the underestimated quotient {Q1,Q0} -static void CorrectQuotientEstimate(word *R, word *T, word *Q, const word *B, size_t N) -{ - assert(N && N%2==0); - - AsymmetricMultiply(T, T+N+2, Q, 2, B, N); - - word borrow = Subtract(R, R, T, N+2); - assert(!borrow && !R[N+1]); - - while (R[N] || Compare(R, B, N) >= 0) - { - R[N] -= Subtract(R, R, B, N); - Q[1] += (++Q[0]==0); - assert(Q[0] || Q[1]); // no overflow - } -} - -// R[NB] -------- remainder = A%B -// Q[NA-NB+2] --- quotient = A/B -// T[NA+3*(NB+2)] - temp work space -// A[NA] -------- dividend -// B[NB] -------- divisor - -void Divide(word *R, word *Q, word *T, const word *A, size_t NA, const word *B, size_t NB) -{ - assert(NA && NB && NA%2==0 && NB%2==0); - assert(B[NB-1] || B[NB-2]); - assert(NB <= NA); - - // set up temporary work space - word *const TA=T; - word *const TB=T+NA+2; - word *const TP=T+NA+2+NB; - - // copy B into TB and normalize it so that TB has highest bit set to 1 - unsigned shiftWords = (B[NB-1]==0); - TB[0] = TB[NB-1] = 0; - CopyWords(TB+shiftWords, B, NB-shiftWords); - unsigned shiftBits = WORD_BITS - BitPrecision(TB[NB-1]); - assert(shiftBits < WORD_BITS); - ShiftWordsLeftByBits(TB, NB, shiftBits); - - // copy A into TA and normalize it - TA[0] = TA[NA] = TA[NA+1] = 0; - CopyWords(TA+shiftWords, A, NA); - ShiftWordsLeftByBits(TA, NA+2, shiftBits); - - if (TA[NA+1]==0 && TA[NA] <= 1) - { - Q[NA-NB+1] = Q[NA-NB] = 0; - while (TA[NA] || Compare(TA+NA-NB, TB, NB) >= 0) - { - TA[NA] -= Subtract(TA+NA-NB, TA+NA-NB, TB, NB); - ++Q[NA-NB]; - } - } - else - { - NA+=2; - assert(Compare(TA+NA-NB, TB, NB) < 0); - } - - word BT[2]; - BT[0] = TB[NB-2] + 1; - BT[1] = TB[NB-1] + (BT[0]==0); - - // start reducing TA mod TB, 2 words at a time - for (size_t i=NA-2; i>=NB; i-=2) - { - AtomicDivide(Q+i-NB, TA+i-2, BT); - CorrectQuotientEstimate(TA+i-NB, TP, Q+i-NB, TB, NB); - } - - // copy TA into R, and denormalize it - CopyWords(R, TA+shiftWords, NB); - ShiftWordsRightByBits(R, NB, shiftBits); -} - -static inline size_t EvenWordCount(const word *X, size_t N) -{ - while (N && X[N-2]==0 && X[N-1]==0) - N-=2; - return N; -} - -// return k -// R[N] --- result = A^(-1) * 2^k mod M -// T[4*N] - temporary work space -// A[NA] -- number to take inverse of -// M[N] --- modulus - -unsigned int AlmostInverse(word *R, word *T, const word *A, size_t NA, const word *M, size_t N) -{ - assert(NA<=N && N && N%2==0); - - word *b = T; - word *c = T+N; - word *f = T+2*N; - word *g = T+3*N; - size_t bcLen=2, fgLen=EvenWordCount(M, N); - unsigned int k=0; - bool s=false; - - SetWords(T, 0, 3*N); - b[0]=1; - CopyWords(f, A, NA); - CopyWords(g, M, N); - - while (1) - { - word t=f[0]; - while (!t) - { - if (EvenWordCount(f, fgLen)==0) - { - SetWords(R, 0, N); - return 0; - } - - ShiftWordsRightByWords(f, fgLen, 1); - bcLen += 2 * (c[bcLen-1] != 0); - assert(bcLen <= N); - ShiftWordsLeftByWords(c, bcLen, 1); - k+=WORD_BITS; - t=f[0]; - } - - unsigned int i = TrailingZeros(t); - t >>= i; - k += i; - - if (t==1 && f[1]==0 && EvenWordCount(f+2, fgLen-2)==0) - { - if (s) - Subtract(R, M, b, N); - else - CopyWords(R, b, N); - return k; - } - - ShiftWordsRightByBits(f, fgLen, i); - t = ShiftWordsLeftByBits(c, bcLen, i); - c[bcLen] += t; - bcLen += 2 * (t!=0); - assert(bcLen <= N); - - bool swap = Compare(f, g, fgLen)==-1; - ConditionalSwapPointers(swap, f, g); - ConditionalSwapPointers(swap, b, c); - s ^= swap; - - fgLen -= 2 * !(f[fgLen-2] | f[fgLen-1]); - - Subtract(f, f, g, fgLen); - t = Add(b, b, c, bcLen); - b[bcLen] += t; - bcLen += 2*t; - assert(bcLen <= N); - } -} - -// R[N] - result = A/(2^k) mod M -// A[N] - input -// M[N] - modulus - -void DivideByPower2Mod(word *R, const word *A, size_t k, const word *M, size_t N) -{ - CopyWords(R, A, N); - - while (k--) - { - if (R[0]%2==0) - ShiftWordsRightByBits(R, N, 1); - else - { - word carry = Add(R, R, M, N); - ShiftWordsRightByBits(R, N, 1); - R[N-1] += carry<<(WORD_BITS-1); - } - } -} - -// R[N] - result = A*(2^k) mod M -// A[N] - input -// M[N] - modulus - -void MultiplyByPower2Mod(word *R, const word *A, size_t k, const word *M, size_t N) -{ - CopyWords(R, A, N); - - while (k--) - if (ShiftWordsLeftByBits(R, N, 1) || Compare(R, M, N)>=0) - Subtract(R, R, M, N); -} - -// ****************************************************************** - -InitializeInteger::InitializeInteger() -{ - if (!g_pAssignIntToInteger) - { - SetFunctionPointers(); - g_pAssignIntToInteger = AssignIntToInteger; - } -} - -static const unsigned int RoundupSizeTable[] = {2, 2, 2, 4, 4, 8, 8, 8, 8}; - -static inline size_t RoundupSize(size_t n) -{ - if (n<=8) - return RoundupSizeTable[n]; - else if (n<=16) - return 16; - else if (n<=32) - return 32; - else if (n<=64) - return 64; - else return size_t(1) << BitPrecision(n-1); -} - -Integer::Integer() - : reg(2), sign(POSITIVE) -{ - reg[0] = reg[1] = 0; -} - -Integer::Integer(const Integer& t) - : reg(RoundupSize(t.WordCount())), sign(t.sign) -{ - CopyWords(reg, t.reg, reg.size()); -} - -Integer::Integer(Sign s, lword value) - : reg(2), sign(s) -{ - reg[0] = word(value); - reg[1] = word(SafeRightShift<WORD_BITS>(value)); -} - -Integer::Integer(signed long value) - : reg(2) -{ - if (value >= 0) - sign = POSITIVE; - else - { - sign = NEGATIVE; - value = -value; - } - reg[0] = word(value); - reg[1] = word(SafeRightShift<WORD_BITS>((unsigned long)value)); -} - -Integer::Integer(Sign s, word high, word low) - : reg(2), sign(s) -{ - reg[0] = low; - reg[1] = high; -} - -bool Integer::IsConvertableToLong() const -{ - if (ByteCount() > sizeof(long)) - return false; - - unsigned long value = (unsigned long)reg[0]; - value += SafeLeftShift<WORD_BITS, unsigned long>((unsigned long)reg[1]); - - if (sign==POSITIVE) - return (signed long)value >= 0; - else - return -(signed long)value < 0; -} - -signed long Integer::ConvertToLong() const -{ - assert(IsConvertableToLong()); - - unsigned long value = (unsigned long)reg[0]; - value += SafeLeftShift<WORD_BITS, unsigned long>((unsigned long)reg[1]); - return sign==POSITIVE ? value : -(signed long)value; -} - -Integer::Integer(BufferedTransformation &encodedInteger, size_t byteCount, Signedness s) -{ - Decode(encodedInteger, byteCount, s); -} - -Integer::Integer(const byte *encodedInteger, size_t byteCount, Signedness s) -{ - Decode(encodedInteger, byteCount, s); -} - -Integer::Integer(BufferedTransformation &bt) -{ - BERDecode(bt); -} - -Integer::Integer(RandomNumberGenerator &rng, size_t bitcount) -{ - Randomize(rng, bitcount); -} - -Integer::Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType, const Integer &equiv, const Integer &mod) -{ - if (!Randomize(rng, min, max, rnType, equiv, mod)) - throw Integer::RandomNumberNotFound(); -} - -Integer Integer::Power2(size_t e) -{ - Integer r((word)0, BitsToWords(e+1)); - r.SetBit(e); - return r; -} - -template <long i> -struct NewInteger -{ - Integer * operator()() const - { - return new Integer(i); - } -}; - -const Integer &Integer::Zero() -{ - return Singleton<Integer>().Ref(); -} - -const Integer &Integer::One() -{ - return Singleton<Integer, NewInteger<1> >().Ref(); -} - -const Integer &Integer::Two() -{ - return Singleton<Integer, NewInteger<2> >().Ref(); -} - -bool Integer::operator!() const -{ - return IsNegative() ? false : (reg[0]==0 && WordCount()==0); -} - -Integer& Integer::operator=(const Integer& t) -{ - if (this != &t) - { - if (reg.size() != t.reg.size() || t.reg[t.reg.size()/2] == 0) - reg.New(RoundupSize(t.WordCount())); - CopyWords(reg, t.reg, reg.size()); - sign = t.sign; - } - return *this; -} - -bool Integer::GetBit(size_t n) const -{ - if (n/WORD_BITS >= reg.size()) - return 0; - else - return bool((reg[n/WORD_BITS] >> (n % WORD_BITS)) & 1); -} - -void Integer::SetBit(size_t n, bool value) -{ - if (value) - { - reg.CleanGrow(RoundupSize(BitsToWords(n+1))); - reg[n/WORD_BITS] |= (word(1) << (n%WORD_BITS)); - } - else - { - if (n/WORD_BITS < reg.size()) - reg[n/WORD_BITS] &= ~(word(1) << (n%WORD_BITS)); - } -} - -byte Integer::GetByte(size_t n) const -{ - if (n/WORD_SIZE >= reg.size()) - return 0; - else - return byte(reg[n/WORD_SIZE] >> ((n%WORD_SIZE)*8)); -} - -void Integer::SetByte(size_t n, byte value) -{ - reg.CleanGrow(RoundupSize(BytesToWords(n+1))); - reg[n/WORD_SIZE] &= ~(word(0xff) << 8*(n%WORD_SIZE)); - reg[n/WORD_SIZE] |= (word(value) << 8*(n%WORD_SIZE)); -} - -lword Integer::GetBits(size_t i, size_t n) const -{ - lword v = 0; - assert(n <= sizeof(v)*8); - for (unsigned int j=0; j<n; j++) - v |= lword(GetBit(i+j)) << j; - return v; -} - -Integer Integer::operator-() const -{ - Integer result(*this); - result.Negate(); - return result; -} - -Integer Integer::AbsoluteValue() const -{ - Integer result(*this); - result.sign = POSITIVE; - return result; -} - -void Integer::swap(Integer &a) -{ - reg.swap(a.reg); - std::swap(sign, a.sign); -} - -Integer::Integer(word value, size_t length) - : reg(RoundupSize(length)), sign(POSITIVE) -{ - reg[0] = value; - SetWords(reg+1, 0, reg.size()-1); -} - -template <class T> -static Integer StringToInteger(const T *str) -{ - int radix; - // GCC workaround - // std::char_traits<wchar_t>::length() not defined in GCC 3.2 and STLport 4.5.3 - unsigned int length; - for (length = 0; str[length] != 0; length++) {} - - Integer v; - - if (length == 0) - return v; - - switch (str[length-1]) - { - case 'h': - case 'H': - radix=16; - break; - case 'o': - case 'O': - radix=8; - break; - case 'b': - case 'B': - radix=2; - break; - default: - radix=10; - } - - if (length > 2 && str[0] == '0' && str[1] == 'x') - radix = 16; - - for (unsigned i=0; i<length; i++) - { - int digit; - - if (str[i] >= '0' && str[i] <= '9') - digit = str[i] - '0'; - else if (str[i] >= 'A' && str[i] <= 'F') - digit = str[i] - 'A' + 10; - else if (str[i] >= 'a' && str[i] <= 'f') - digit = str[i] - 'a' + 10; - else - digit = radix; - - if (digit < radix) - { - v *= radix; - v += digit; - } - } - - if (str[0] == '-') - v.Negate(); - - return v; -} - -Integer::Integer(const char *str) - : reg(2), sign(POSITIVE) -{ - *this = StringToInteger(str); -} - -Integer::Integer(const wchar_t *str) - : reg(2), sign(POSITIVE) -{ - *this = StringToInteger(str); -} - -unsigned int Integer::WordCount() const -{ - return (unsigned int)CountWords(reg, reg.size()); -} - -unsigned int Integer::ByteCount() const -{ - unsigned wordCount = WordCount(); - if (wordCount) - return (wordCount-1)*WORD_SIZE + BytePrecision(reg[wordCount-1]); - else - return 0; -} - -unsigned int Integer::BitCount() const -{ - unsigned wordCount = WordCount(); - if (wordCount) - return (wordCount-1)*WORD_BITS + BitPrecision(reg[wordCount-1]); - else - return 0; -} - -void Integer::Decode(const byte *input, size_t inputLen, Signedness s) -{ - StringStore store(input, inputLen); - Decode(store, inputLen, s); -} - -void Integer::Decode(BufferedTransformation &bt, size_t inputLen, Signedness s) -{ - assert(bt.MaxRetrievable() >= inputLen); - - byte b; - bt.Peek(b); - sign = ((s==SIGNED) && (b & 0x80)) ? NEGATIVE : POSITIVE; - - while (inputLen>0 && (sign==POSITIVE ? b==0 : b==0xff)) - { - bt.Skip(1); - inputLen--; - bt.Peek(b); - } - - reg.CleanNew(RoundupSize(BytesToWords(inputLen))); - - for (size_t i=inputLen; i > 0; i--) - { - bt.Get(b); - reg[(i-1)/WORD_SIZE] |= word(b) << ((i-1)%WORD_SIZE)*8; - } - - if (sign == NEGATIVE) - { - for (size_t i=inputLen; i<reg.size()*WORD_SIZE; i++) - reg[i/WORD_SIZE] |= word(0xff) << (i%WORD_SIZE)*8; - TwosComplement(reg, reg.size()); - } -} - -size_t Integer::MinEncodedSize(Signedness signedness) const -{ - unsigned int outputLen = STDMAX(1U, ByteCount()); - if (signedness == UNSIGNED) - return outputLen; - if (NotNegative() && (GetByte(outputLen-1) & 0x80)) - outputLen++; - if (IsNegative() && *this < -Power2(outputLen*8-1)) - outputLen++; - return outputLen; -} - -void Integer::Encode(byte *output, size_t outputLen, Signedness signedness) const -{ - ArraySink sink(output, outputLen); - Encode(sink, outputLen, signedness); -} - -void Integer::Encode(BufferedTransformation &bt, size_t outputLen, Signedness signedness) const -{ - if (signedness == UNSIGNED || NotNegative()) - { - for (size_t i=outputLen; i > 0; i--) - bt.Put(GetByte(i-1)); - } - else - { - // take two's complement of *this - Integer temp = Integer::Power2(8*STDMAX((size_t)ByteCount(), outputLen)) + *this; - temp.Encode(bt, outputLen, UNSIGNED); - } -} - -void Integer::DEREncode(BufferedTransformation &bt) const -{ - DERGeneralEncoder enc(bt, INTEGER); - Encode(enc, MinEncodedSize(SIGNED), SIGNED); - enc.MessageEnd(); -} - -void Integer::BERDecode(const byte *input, size_t len) -{ - StringStore store(input, len); - BERDecode(store); -} - -void Integer::BERDecode(BufferedTransformation &bt) -{ - BERGeneralDecoder dec(bt, INTEGER); - if (!dec.IsDefiniteLength() || dec.MaxRetrievable() < dec.RemainingLength()) - BERDecodeError(); - Decode(dec, (size_t)dec.RemainingLength(), SIGNED); - dec.MessageEnd(); -} - -void Integer::DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const -{ - DERGeneralEncoder enc(bt, OCTET_STRING); - Encode(enc, length); - enc.MessageEnd(); -} - -void Integer::BERDecodeAsOctetString(BufferedTransformation &bt, size_t length) -{ - BERGeneralDecoder dec(bt, OCTET_STRING); - if (!dec.IsDefiniteLength() || dec.RemainingLength() != length) - BERDecodeError(); - Decode(dec, length); - dec.MessageEnd(); -} - -size_t Integer::OpenPGPEncode(byte *output, size_t len) const -{ - ArraySink sink(output, len); - return OpenPGPEncode(sink); -} - -size_t Integer::OpenPGPEncode(BufferedTransformation &bt) const -{ - word16 bitCount = BitCount(); - bt.PutWord16(bitCount); - size_t byteCount = BitsToBytes(bitCount); - Encode(bt, byteCount); - return 2 + byteCount; -} - -void Integer::OpenPGPDecode(const byte *input, size_t len) -{ - StringStore store(input, len); - OpenPGPDecode(store); -} - -void Integer::OpenPGPDecode(BufferedTransformation &bt) -{ - word16 bitCount; - if (bt.GetWord16(bitCount) != 2 || bt.MaxRetrievable() < BitsToBytes(bitCount)) - throw OpenPGPDecodeErr(); - Decode(bt, BitsToBytes(bitCount)); -} - -void Integer::Randomize(RandomNumberGenerator &rng, size_t nbits) -{ - const size_t nbytes = nbits/8 + 1; - SecByteBlock buf(nbytes); - rng.GenerateBlock(buf, nbytes); - if (nbytes) - buf[0] = (byte)Crop(buf[0], nbits % 8); - Decode(buf, nbytes, UNSIGNED); -} - -void Integer::Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max) -{ - if (min > max) - throw InvalidArgument("Integer: Min must be no greater than Max"); - - Integer range = max - min; - const unsigned int nbits = range.BitCount(); - - do - { - Randomize(rng, nbits); - } - while (*this > range); - - *this += min; -} - -bool Integer::Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType, const Integer &equiv, const Integer &mod) -{ - return GenerateRandomNoThrow(rng, MakeParameters("Min", min)("Max", max)("RandomNumberType", rnType)("EquivalentTo", equiv)("Mod", mod)); -} - -class KDF2_RNG : public RandomNumberGenerator -{ -public: - KDF2_RNG(const byte *seed, size_t seedSize) - : m_counter(0), m_counterAndSeed(seedSize + 4) - { - memcpy(m_counterAndSeed + 4, seed, seedSize); - } - - void GenerateBlock(byte *output, size_t size) - { - PutWord(false, BIG_ENDIAN_ORDER, m_counterAndSeed, m_counter); - ++m_counter; - P1363_KDF2<SHA1>::DeriveKey(output, size, m_counterAndSeed, m_counterAndSeed.size(), NULL, 0); - } - -private: - word32 m_counter; - SecByteBlock m_counterAndSeed; -}; - -bool Integer::GenerateRandomNoThrow(RandomNumberGenerator &i_rng, const NameValuePairs ¶ms) -{ - Integer min = params.GetValueWithDefault("Min", Integer::Zero()); - Integer max; - if (!params.GetValue("Max", max)) - { - int bitLength; - if (params.GetIntValue("BitLength", bitLength)) - max = Integer::Power2(bitLength); - else - throw InvalidArgument("Integer: missing Max argument"); - } - if (min > max) - throw InvalidArgument("Integer: Min must be no greater than Max"); - - Integer equiv = params.GetValueWithDefault("EquivalentTo", Integer::Zero()); - Integer mod = params.GetValueWithDefault("Mod", Integer::One()); - - if (equiv.IsNegative() || equiv >= mod) - throw InvalidArgument("Integer: invalid EquivalentTo and/or Mod argument"); - - Integer::RandomNumberType rnType = params.GetValueWithDefault("RandomNumberType", Integer::ANY); - - member_ptr<KDF2_RNG> kdf2Rng; - ConstByteArrayParameter seed; - if (params.GetValue(Name::Seed(), seed)) - { - ByteQueue bq; - DERSequenceEncoder seq(bq); - min.DEREncode(seq); - max.DEREncode(seq); - equiv.DEREncode(seq); - mod.DEREncode(seq); - DEREncodeUnsigned(seq, rnType); - DEREncodeOctetString(seq, seed.begin(), seed.size()); - seq.MessageEnd(); - - SecByteBlock finalSeed((size_t)bq.MaxRetrievable()); - bq.Get(finalSeed, finalSeed.size()); - kdf2Rng.reset(new KDF2_RNG(finalSeed.begin(), finalSeed.size())); - } - RandomNumberGenerator &rng = kdf2Rng.get() ? (RandomNumberGenerator &)*kdf2Rng : i_rng; - - switch (rnType) - { - case ANY: - if (mod == One()) - Randomize(rng, min, max); - else - { - Integer min1 = min + (equiv-min)%mod; - if (max < min1) - return false; - Randomize(rng, Zero(), (max - min1) / mod); - *this *= mod; - *this += min1; - } - return true; - - case PRIME: - { - const PrimeSelector *pSelector = params.GetValueWithDefault(Name::PointerToPrimeSelector(), (const PrimeSelector *)NULL); - - int i; - i = 0; - while (1) - { - if (++i==16) - { - // check if there are any suitable primes in [min, max] - Integer first = min; - if (FirstPrime(first, max, equiv, mod, pSelector)) - { - // if there is only one suitable prime, we're done - *this = first; - if (!FirstPrime(first, max, equiv, mod, pSelector)) - return true; - } - else - return false; - } - - Randomize(rng, min, max); - if (FirstPrime(*this, STDMIN(*this+mod*PrimeSearchInterval(max), max), equiv, mod, pSelector)) - return true; - } - } - - default: - throw InvalidArgument("Integer: invalid RandomNumberType argument"); - } -} - -std::istream& operator>>(std::istream& in, Integer &a) -{ - char c; - unsigned int length = 0; - SecBlock<char> str(length + 16); - - std::ws(in); - - do - { - in.read(&c, 1); - str[length++] = c; - if (length >= str.size()) - str.Grow(length + 16); - } - while (in && (c=='-' || c=='x' || (c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F') || c=='h' || c=='H' || c=='o' || c=='O' || c==',' || c=='.')); - - if (in.gcount()) - in.putback(c); - str[length-1] = '\0'; - a = Integer(str); - - return in; -} - -std::ostream& operator<<(std::ostream& out, const Integer &a) -{ - // Get relevant conversion specifications from ostream. - long f = out.flags() & std::ios::basefield; // Get base digits. - int base, block; - char suffix; - switch(f) - { - case std::ios::oct : - base = 8; - block = 8; - suffix = 'o'; - break; - case std::ios::hex : - base = 16; - block = 4; - suffix = 'h'; - break; - default : - base = 10; - block = 3; - suffix = '.'; - } - - Integer temp1=a, temp2; - - if (a.IsNegative()) - { - out << '-'; - temp1.Negate(); - } - - if (!a) - out << '0'; - - static const char upper[]="0123456789ABCDEF"; - static const char lower[]="0123456789abcdef"; - - const char* vec = (out.flags() & std::ios::uppercase) ? upper : lower; - unsigned i=0; - SecBlock<char> s(a.BitCount() / (BitPrecision(base)-1) + 1); - - while (!!temp1) - { - word digit; - Integer::Divide(digit, temp2, temp1, base); - s[i++]=vec[digit]; - temp1.swap(temp2); - } - - while (i--) - { - out << s[i]; -// if (i && !(i%block)) -// out << ","; - } - return out << suffix; -} - -Integer& Integer::operator++() -{ - if (NotNegative()) - { - if (Increment(reg, reg.size())) - { - reg.CleanGrow(2*reg.size()); - reg[reg.size()/2]=1; - } - } - else - { - word borrow = Decrement(reg, reg.size()); - assert(!borrow); - if (WordCount()==0) - *this = Zero(); - } - return *this; -} - -Integer& Integer::operator--() -{ - if (IsNegative()) - { - if (Increment(reg, reg.size())) - { - reg.CleanGrow(2*reg.size()); - reg[reg.size()/2]=1; - } - } - else - { - if (Decrement(reg, reg.size())) - *this = -One(); - } - return *this; -} - -void PositiveAdd(Integer &sum, const Integer &a, const Integer& b) -{ - int carry; - if (a.reg.size() == b.reg.size()) - carry = Add(sum.reg, a.reg, b.reg, a.reg.size()); - else if (a.reg.size() > b.reg.size()) - { - carry = Add(sum.reg, a.reg, b.reg, b.reg.size()); - CopyWords(sum.reg+b.reg.size(), a.reg+b.reg.size(), a.reg.size()-b.reg.size()); - carry = Increment(sum.reg+b.reg.size(), a.reg.size()-b.reg.size(), carry); - } - else - { - carry = Add(sum.reg, a.reg, b.reg, a.reg.size()); - CopyWords(sum.reg+a.reg.size(), b.reg+a.reg.size(), b.reg.size()-a.reg.size()); - carry = Increment(sum.reg+a.reg.size(), b.reg.size()-a.reg.size(), carry); - } - - if (carry) - { - sum.reg.CleanGrow(2*sum.reg.size()); - sum.reg[sum.reg.size()/2] = 1; - } - sum.sign = Integer::POSITIVE; -} - -void PositiveSubtract(Integer &diff, const Integer &a, const Integer& b) -{ - unsigned aSize = a.WordCount(); - aSize += aSize%2; - unsigned bSize = b.WordCount(); - bSize += bSize%2; - - if (aSize == bSize) - { - if (Compare(a.reg, b.reg, aSize) >= 0) - { - Subtract(diff.reg, a.reg, b.reg, aSize); - diff.sign = Integer::POSITIVE; - } - else - { - Subtract(diff.reg, b.reg, a.reg, aSize); - diff.sign = Integer::NEGATIVE; - } - } - else if (aSize > bSize) - { - word borrow = Subtract(diff.reg, a.reg, b.reg, bSize); - CopyWords(diff.reg+bSize, a.reg+bSize, aSize-bSize); - borrow = Decrement(diff.reg+bSize, aSize-bSize, borrow); - assert(!borrow); - diff.sign = Integer::POSITIVE; - } - else - { - word borrow = Subtract(diff.reg, b.reg, a.reg, aSize); - CopyWords(diff.reg+aSize, b.reg+aSize, bSize-aSize); - borrow = Decrement(diff.reg+aSize, bSize-aSize, borrow); - assert(!borrow); - diff.sign = Integer::NEGATIVE; - } -} - -// MSVC .NET 2003 workaround -template <class T> inline const T& STDMAX2(const T& a, const T& b) -{ - return a < b ? b : a; -} - -Integer Integer::Plus(const Integer& b) const -{ - Integer sum((word)0, STDMAX2(reg.size(), b.reg.size())); - if (NotNegative()) - { - if (b.NotNegative()) - PositiveAdd(sum, *this, b); - else - PositiveSubtract(sum, *this, b); - } - else - { - if (b.NotNegative()) - PositiveSubtract(sum, b, *this); - else - { - PositiveAdd(sum, *this, b); - sum.sign = Integer::NEGATIVE; - } - } - return sum; -} - -Integer& Integer::operator+=(const Integer& t) -{ - reg.CleanGrow(t.reg.size()); - if (NotNegative()) - { - if (t.NotNegative()) - PositiveAdd(*this, *this, t); - else - PositiveSubtract(*this, *this, t); - } - else - { - if (t.NotNegative()) - PositiveSubtract(*this, t, *this); - else - { - PositiveAdd(*this, *this, t); - sign = Integer::NEGATIVE; - } - } - return *this; -} - -Integer Integer::Minus(const Integer& b) const -{ - Integer diff((word)0, STDMAX2(reg.size(), b.reg.size())); - if (NotNegative()) - { - if (b.NotNegative()) - PositiveSubtract(diff, *this, b); - else - PositiveAdd(diff, *this, b); - } - else - { - if (b.NotNegative()) - { - PositiveAdd(diff, *this, b); - diff.sign = Integer::NEGATIVE; - } - else - PositiveSubtract(diff, b, *this); - } - return diff; -} - -Integer& Integer::operator-=(const Integer& t) -{ - reg.CleanGrow(t.reg.size()); - if (NotNegative()) - { - if (t.NotNegative()) - PositiveSubtract(*this, *this, t); - else - PositiveAdd(*this, *this, t); - } - else - { - if (t.NotNegative()) - { - PositiveAdd(*this, *this, t); - sign = Integer::NEGATIVE; - } - else - PositiveSubtract(*this, t, *this); - } - return *this; -} - -Integer& Integer::operator<<=(size_t n) -{ - const size_t wordCount = WordCount(); - const size_t shiftWords = n / WORD_BITS; - const unsigned int shiftBits = (unsigned int)(n % WORD_BITS); - - reg.CleanGrow(RoundupSize(wordCount+BitsToWords(n))); - ShiftWordsLeftByWords(reg, wordCount + shiftWords, shiftWords); - ShiftWordsLeftByBits(reg+shiftWords, wordCount+BitsToWords(shiftBits), shiftBits); - return *this; -} - -Integer& Integer::operator>>=(size_t n) -{ - const size_t wordCount = WordCount(); - const size_t shiftWords = n / WORD_BITS; - const unsigned int shiftBits = (unsigned int)(n % WORD_BITS); - - ShiftWordsRightByWords(reg, wordCount, shiftWords); - if (wordCount > shiftWords) - ShiftWordsRightByBits(reg, wordCount-shiftWords, shiftBits); - if (IsNegative() && WordCount()==0) // avoid -0 - *this = Zero(); - return *this; -} - -void PositiveMultiply(Integer &product, const Integer &a, const Integer &b) -{ - size_t aSize = RoundupSize(a.WordCount()); - size_t bSize = RoundupSize(b.WordCount()); - - product.reg.CleanNew(RoundupSize(aSize+bSize)); - product.sign = Integer::POSITIVE; - - IntegerSecBlock workspace(aSize + bSize); - AsymmetricMultiply(product.reg, workspace, a.reg, aSize, b.reg, bSize); -} - -void Multiply(Integer &product, const Integer &a, const Integer &b) -{ - PositiveMultiply(product, a, b); - - if (a.NotNegative() != b.NotNegative()) - product.Negate(); -} - -Integer Integer::Times(const Integer &b) const -{ - Integer product; - Multiply(product, *this, b); - return product; -} - -/* -void PositiveDivide(Integer &remainder, Integer "ient, - const Integer ÷nd, const Integer &divisor) -{ - remainder.reg.CleanNew(divisor.reg.size()); - remainder.sign = Integer::POSITIVE; - quotient.reg.New(0); - quotient.sign = Integer::POSITIVE; - unsigned i=dividend.BitCount(); - while (i--) - { - word overflow = ShiftWordsLeftByBits(remainder.reg, remainder.reg.size(), 1); - remainder.reg[0] |= dividend[i]; - if (overflow || remainder >= divisor) - { - Subtract(remainder.reg, remainder.reg, divisor.reg, remainder.reg.size()); - quotient.SetBit(i); - } - } -} -*/ - -void PositiveDivide(Integer &remainder, Integer "ient, - const Integer &a, const Integer &b) -{ - unsigned aSize = a.WordCount(); - unsigned bSize = b.WordCount(); - - if (!bSize) - throw Integer::DivideByZero(); - - if (aSize < bSize) - { - remainder = a; - remainder.sign = Integer::POSITIVE; - quotient = Integer::Zero(); - return; - } - - aSize += aSize%2; // round up to next even number - bSize += bSize%2; - - remainder.reg.CleanNew(RoundupSize(bSize)); - remainder.sign = Integer::POSITIVE; - quotient.reg.CleanNew(RoundupSize(aSize-bSize+2)); - quotient.sign = Integer::POSITIVE; - - IntegerSecBlock T(aSize+3*(bSize+2)); - Divide(remainder.reg, quotient.reg, T, a.reg, aSize, b.reg, bSize); -} - -void Integer::Divide(Integer &remainder, Integer "ient, const Integer ÷nd, const Integer &divisor) -{ - PositiveDivide(remainder, quotient, dividend, divisor); - - if (dividend.IsNegative()) - { - quotient.Negate(); - if (remainder.NotZero()) - { - --quotient; - remainder = divisor.AbsoluteValue() - remainder; - } - } - - if (divisor.IsNegative()) - quotient.Negate(); -} - -void Integer::DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, unsigned int n) -{ - q = a; - q >>= n; - - const size_t wordCount = BitsToWords(n); - if (wordCount <= a.WordCount()) - { - r.reg.resize(RoundupSize(wordCount)); - CopyWords(r.reg, a.reg, wordCount); - SetWords(r.reg+wordCount, 0, r.reg.size()-wordCount); - if (n % WORD_BITS != 0) - r.reg[wordCount-1] %= (word(1) << (n % WORD_BITS)); - } - else - { - r.reg.resize(RoundupSize(a.WordCount())); - CopyWords(r.reg, a.reg, r.reg.size()); - } - r.sign = POSITIVE; - - if (a.IsNegative() && r.NotZero()) - { - --q; - r = Power2(n) - r; - } -} - -Integer Integer::DividedBy(const Integer &b) const -{ - Integer remainder, quotient; - Integer::Divide(remainder, quotient, *this, b); - return quotient; -} - -Integer Integer::Modulo(const Integer &b) const -{ - Integer remainder, quotient; - Integer::Divide(remainder, quotient, *this, b); - return remainder; -} - -void Integer::Divide(word &remainder, Integer "ient, const Integer ÷nd, word divisor) -{ - if (!divisor) - throw Integer::DivideByZero(); - - assert(divisor); - - if ((divisor & (divisor-1)) == 0) // divisor is a power of 2 - { - quotient = dividend >> (BitPrecision(divisor)-1); - remainder = dividend.reg[0] & (divisor-1); - return; - } - - unsigned int i = dividend.WordCount(); - quotient.reg.CleanNew(RoundupSize(i)); - remainder = 0; - while (i--) - { - quotient.reg[i] = DWord(dividend.reg[i], remainder) / divisor; - remainder = DWord(dividend.reg[i], remainder) % divisor; - } - - if (dividend.NotNegative()) - quotient.sign = POSITIVE; - else - { - quotient.sign = NEGATIVE; - if (remainder) - { - --quotient; - remainder = divisor - remainder; - } - } -} - -Integer Integer::DividedBy(word b) const -{ - word remainder; - Integer quotient; - Integer::Divide(remainder, quotient, *this, b); - return quotient; -} - -word Integer::Modulo(word divisor) const -{ - if (!divisor) - throw Integer::DivideByZero(); - - assert(divisor); - - word remainder; - - if ((divisor & (divisor-1)) == 0) // divisor is a power of 2 - remainder = reg[0] & (divisor-1); - else - { - unsigned int i = WordCount(); - - if (divisor <= 5) - { - DWord sum(0, 0); - while (i--) - sum += reg[i]; - remainder = sum % divisor; - } - else - { - remainder = 0; - while (i--) - remainder = DWord(reg[i], remainder) % divisor; - } - } - - if (IsNegative() && remainder) - remainder = divisor - remainder; - - return remainder; -} - -void Integer::Negate() -{ - if (!!(*this)) // don't flip sign if *this==0 - sign = Sign(1-sign); -} - -int Integer::PositiveCompare(const Integer& t) const -{ - unsigned size = WordCount(), tSize = t.WordCount(); - - if (size == tSize) - return CryptoPP::Compare(reg, t.reg, size); - else - return size > tSize ? 1 : -1; -} - -int Integer::Compare(const Integer& t) const -{ - if (NotNegative()) - { - if (t.NotNegative()) - return PositiveCompare(t); - else - return 1; - } - else - { - if (t.NotNegative()) - return -1; - else - return -PositiveCompare(t); - } -} - -Integer Integer::SquareRoot() const -{ - if (!IsPositive()) - return Zero(); - - // overestimate square root - Integer x, y = Power2((BitCount()+1)/2); - assert(y*y >= *this); - - do - { - x = y; - y = (x + *this/x) >> 1; - } while (y<x); - - return x; -} - -bool Integer::IsSquare() const -{ - Integer r = SquareRoot(); - return *this == r.Squared(); -} - -bool Integer::IsUnit() const -{ - return (WordCount() == 1) && (reg[0] == 1); -} - -Integer Integer::MultiplicativeInverse() const -{ - return IsUnit() ? *this : Zero(); -} - -Integer a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m) -{ - return x*y%m; -} - -Integer a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m) -{ - ModularArithmetic mr(m); - return mr.Exponentiate(x, e); -} - -Integer Integer::Gcd(const Integer &a, const Integer &b) -{ - return EuclideanDomainOf<Integer>().Gcd(a, b); -} - -Integer Integer::InverseMod(const Integer &m) const -{ - assert(m.NotNegative()); - - if (IsNegative()) - return Modulo(m).InverseMod(m); - - if (m.IsEven()) - { - if (!m || IsEven()) - return Zero(); // no inverse - if (*this == One()) - return One(); - - Integer u = m.Modulo(*this).InverseMod(*this); - return !u ? Zero() : (m*(*this-u)+1)/(*this); - } - - SecBlock<word> T(m.reg.size() * 4); - Integer r((word)0, m.reg.size()); - unsigned k = AlmostInverse(r.reg, T, reg, reg.size(), m.reg, m.reg.size()); - DivideByPower2Mod(r.reg, r.reg, k, m.reg, m.reg.size()); - return r; -} - -word Integer::InverseMod(word mod) const -{ - word g0 = mod, g1 = *this % mod; - word v0 = 0, v1 = 1; - word y; - - while (g1) - { - if (g1 == 1) - return v1; - y = g0 / g1; - g0 = g0 % g1; - v0 += y * v1; - - if (!g0) - break; - if (g0 == 1) - return mod-v0; - y = g1 / g0; - g1 = g1 % g0; - v1 += y * v0; - } - return 0; -} - -// ******************************************************** - -ModularArithmetic::ModularArithmetic(BufferedTransformation &bt) -{ - BERSequenceDecoder seq(bt); - OID oid(seq); - if (oid != ASN1::prime_field()) - BERDecodeError(); - m_modulus.BERDecode(seq); - seq.MessageEnd(); - m_result.reg.resize(m_modulus.reg.size()); -} - -void ModularArithmetic::DEREncode(BufferedTransformation &bt) const -{ - DERSequenceEncoder seq(bt); - ASN1::prime_field().DEREncode(seq); - m_modulus.DEREncode(seq); - seq.MessageEnd(); -} - -void ModularArithmetic::DEREncodeElement(BufferedTransformation &out, const Element &a) const -{ - a.DEREncodeAsOctetString(out, MaxElementByteLength()); -} - -void ModularArithmetic::BERDecodeElement(BufferedTransformation &in, Element &a) const -{ - a.BERDecodeAsOctetString(in, MaxElementByteLength()); -} - -const Integer& ModularArithmetic::Half(const Integer &a) const -{ - if (a.reg.size()==m_modulus.reg.size()) - { - CryptoPP::DivideByPower2Mod(m_result.reg.begin(), a.reg, 1, m_modulus.reg, a.reg.size()); - return m_result; - } - else - return m_result1 = (a.IsEven() ? (a >> 1) : ((a+m_modulus) >> 1)); -} - -const Integer& ModularArithmetic::Add(const Integer &a, const Integer &b) const -{ - if (a.reg.size()==m_modulus.reg.size() && b.reg.size()==m_modulus.reg.size()) - { - if (CryptoPP::Add(m_result.reg.begin(), a.reg, b.reg, a.reg.size()) - || Compare(m_result.reg, m_modulus.reg, a.reg.size()) >= 0) - { - CryptoPP::Subtract(m_result.reg.begin(), m_result.reg, m_modulus.reg, a.reg.size()); - } - return m_result; - } - else - { - m_result1 = a+b; - if (m_result1 >= m_modulus) - m_result1 -= m_modulus; - return m_result1; - } -} - -Integer& ModularArithmetic::Accumulate(Integer &a, const Integer &b) const -{ - if (a.reg.size()==m_modulus.reg.size() && b.reg.size()==m_modulus.reg.size()) - { - if (CryptoPP::Add(a.reg, a.reg, b.reg, a.reg.size()) - || Compare(a.reg, m_modulus.reg, a.reg.size()) >= 0) - { - CryptoPP::Subtract(a.reg, a.reg, m_modulus.reg, a.reg.size()); - } - } - else - { - a+=b; - if (a>=m_modulus) - a-=m_modulus; - } - - return a; -} - -const Integer& ModularArithmetic::Subtract(const Integer &a, const Integer &b) const -{ - if (a.reg.size()==m_modulus.reg.size() && b.reg.size()==m_modulus.reg.size()) - { - if (CryptoPP::Subtract(m_result.reg.begin(), a.reg, b.reg, a.reg.size())) - CryptoPP::Add(m_result.reg.begin(), m_result.reg, m_modulus.reg, a.reg.size()); - return m_result; - } - else - { - m_result1 = a-b; - if (m_result1.IsNegative()) - m_result1 += m_modulus; - return m_result1; - } -} - -Integer& ModularArithmetic::Reduce(Integer &a, const Integer &b) const -{ - if (a.reg.size()==m_modulus.reg.size() && b.reg.size()==m_modulus.reg.size()) - { - if (CryptoPP::Subtract(a.reg, a.reg, b.reg, a.reg.size())) - CryptoPP::Add(a.reg, a.reg, m_modulus.reg, a.reg.size()); - } - else - { - a-=b; - if (a.IsNegative()) - a+=m_modulus; - } - - return a; -} - -const Integer& ModularArithmetic::Inverse(const Integer &a) const -{ - if (!a) - return a; - - CopyWords(m_result.reg.begin(), m_modulus.reg, m_modulus.reg.size()); - if (CryptoPP::Subtract(m_result.reg.begin(), m_result.reg, a.reg, a.reg.size())) - Decrement(m_result.reg.begin()+a.reg.size(), m_modulus.reg.size()-a.reg.size()); - - return m_result; -} - -Integer ModularArithmetic::CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const -{ - if (m_modulus.IsOdd()) - { - MontgomeryRepresentation dr(m_modulus); - return dr.ConvertOut(dr.CascadeExponentiate(dr.ConvertIn(x), e1, dr.ConvertIn(y), e2)); - } - else - return AbstractRing<Integer>::CascadeExponentiate(x, e1, y, e2); -} - -void ModularArithmetic::SimultaneousExponentiate(Integer *results, const Integer &base, const Integer *exponents, unsigned int exponentsCount) const -{ - if (m_modulus.IsOdd()) - { - MontgomeryRepresentation dr(m_modulus); - dr.SimultaneousExponentiate(results, dr.ConvertIn(base), exponents, exponentsCount); - for (unsigned int i=0; i<exponentsCount; i++) - results[i] = dr.ConvertOut(results[i]); - } - else - AbstractRing<Integer>::SimultaneousExponentiate(results, base, exponents, exponentsCount); -} - -MontgomeryRepresentation::MontgomeryRepresentation(const Integer &m) // modulus must be odd - : ModularArithmetic(m), - m_u((word)0, m_modulus.reg.size()), - m_workspace(5*m_modulus.reg.size()) -{ - if (!m_modulus.IsOdd()) - throw InvalidArgument("MontgomeryRepresentation: Montgomery representation requires an odd modulus"); - - RecursiveInverseModPower2(m_u.reg, m_workspace, m_modulus.reg, m_modulus.reg.size()); -} - -const Integer& MontgomeryRepresentation::Multiply(const Integer &a, const Integer &b) const -{ - word *const T = m_workspace.begin(); - word *const R = m_result.reg.begin(); - const size_t N = m_modulus.reg.size(); - assert(a.reg.size()<=N && b.reg.size()<=N); - - AsymmetricMultiply(T, T+2*N, a.reg, a.reg.size(), b.reg, b.reg.size()); - SetWords(T+a.reg.size()+b.reg.size(), 0, 2*N-a.reg.size()-b.reg.size()); - MontgomeryReduce(R, T+2*N, T, m_modulus.reg, m_u.reg, N); - return m_result; -} - -const Integer& MontgomeryRepresentation::Square(const Integer &a) const -{ - word *const T = m_workspace.begin(); - word *const R = m_result.reg.begin(); - const size_t N = m_modulus.reg.size(); - assert(a.reg.size()<=N); - - CryptoPP::Square(T, T+2*N, a.reg, a.reg.size()); - SetWords(T+2*a.reg.size(), 0, 2*N-2*a.reg.size()); - MontgomeryReduce(R, T+2*N, T, m_modulus.reg, m_u.reg, N); - return m_result; -} - -Integer MontgomeryRepresentation::ConvertOut(const Integer &a) const -{ - word *const T = m_workspace.begin(); - word *const R = m_result.reg.begin(); - const size_t N = m_modulus.reg.size(); - assert(a.reg.size()<=N); - - CopyWords(T, a.reg, a.reg.size()); - SetWords(T+a.reg.size(), 0, 2*N-a.reg.size()); - MontgomeryReduce(R, T+2*N, T, m_modulus.reg, m_u.reg, N); - return m_result; -} - -const Integer& MontgomeryRepresentation::MultiplicativeInverse(const Integer &a) const -{ -// return (EuclideanMultiplicativeInverse(a, modulus)<<(2*WORD_BITS*modulus.reg.size()))%modulus; - word *const T = m_workspace.begin(); - word *const R = m_result.reg.begin(); - const size_t N = m_modulus.reg.size(); - assert(a.reg.size()<=N); - - CopyWords(T, a.reg, a.reg.size()); - SetWords(T+a.reg.size(), 0, 2*N-a.reg.size()); - MontgomeryReduce(R, T+2*N, T, m_modulus.reg, m_u.reg, N); - unsigned k = AlmostInverse(R, T, R, N, m_modulus.reg, N); - -// cout << "k=" << k << " N*32=" << 32*N << endl; - - if (k>N*WORD_BITS) - DivideByPower2Mod(R, R, k-N*WORD_BITS, m_modulus.reg, N); - else - MultiplyByPower2Mod(R, R, N*WORD_BITS-k, m_modulus.reg, N); - - return m_result; -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/integer.h b/lib/cryptopp/integer.h deleted file mode 100644 index 6d844fa57..000000000 --- a/lib/cryptopp/integer.h +++ /dev/null @@ -1,420 +0,0 @@ -#ifndef CRYPTOPP_INTEGER_H -#define CRYPTOPP_INTEGER_H - -/** \file */ - -#include "cryptlib.h" -#include "secblock.h" - -#include <iosfwd> -#include <algorithm> - -NAMESPACE_BEGIN(CryptoPP) - -struct InitializeInteger // used to initialize static variables -{ - InitializeInteger(); -}; - -typedef SecBlock<word, AllocatorWithCleanup<word, CRYPTOPP_BOOL_X86> > IntegerSecBlock; - -//! multiple precision integer and basic arithmetics -/*! This class can represent positive and negative integers - with absolute value less than (256**sizeof(word)) ** (256**sizeof(int)). - \nosubgrouping -*/ -class CRYPTOPP_DLL Integer : private InitializeInteger, public ASN1Object -{ -public: - //! \name ENUMS, EXCEPTIONS, and TYPEDEFS - //@{ - //! division by zero exception - class DivideByZero : public Exception - { - public: - DivideByZero() : Exception(OTHER_ERROR, "Integer: division by zero") {} - }; - - //! - class RandomNumberNotFound : public Exception - { - public: - RandomNumberNotFound() : Exception(OTHER_ERROR, "Integer: no integer satisfies the given parameters") {} - }; - - //! - enum Sign {POSITIVE=0, NEGATIVE=1}; - - //! - enum Signedness { - //! - UNSIGNED, - //! - SIGNED}; - - //! - enum RandomNumberType { - //! - ANY, - //! - PRIME}; - //@} - - //! \name CREATORS - //@{ - //! creates the zero integer - Integer(); - - //! copy constructor - Integer(const Integer& t); - - //! convert from signed long - Integer(signed long value); - - //! convert from lword - Integer(Sign s, lword value); - - //! convert from two words - Integer(Sign s, word highWord, word lowWord); - - //! convert from string - /*! str can be in base 2, 8, 10, or 16. Base is determined by a - case insensitive suffix of 'h', 'o', or 'b'. No suffix means base 10. - */ - explicit Integer(const char *str); - explicit Integer(const wchar_t *str); - - //! convert from big-endian byte array - Integer(const byte *encodedInteger, size_t byteCount, Signedness s=UNSIGNED); - - //! convert from big-endian form stored in a BufferedTransformation - Integer(BufferedTransformation &bt, size_t byteCount, Signedness s=UNSIGNED); - - //! convert from BER encoded byte array stored in a BufferedTransformation object - explicit Integer(BufferedTransformation &bt); - - //! create a random integer - /*! The random integer created is uniformly distributed over [0, 2**bitcount). */ - Integer(RandomNumberGenerator &rng, size_t bitcount); - - //! avoid calling constructors for these frequently used integers - static const Integer & CRYPTOPP_API Zero(); - //! avoid calling constructors for these frequently used integers - static const Integer & CRYPTOPP_API One(); - //! avoid calling constructors for these frequently used integers - static const Integer & CRYPTOPP_API Two(); - - //! create a random integer of special type - /*! Ideally, the random integer created should be uniformly distributed - over {x | min <= x <= max and x is of rnType and x % mod == equiv}. - However the actual distribution may not be uniform because sequential - search is used to find an appropriate number from a random starting - point. - May return (with very small probability) a pseudoprime when a prime - is requested and max > lastSmallPrime*lastSmallPrime (lastSmallPrime - is declared in nbtheory.h). - \throw RandomNumberNotFound if the set is empty. - */ - Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType=ANY, const Integer &equiv=Zero(), const Integer &mod=One()); - - //! return the integer 2**e - static Integer CRYPTOPP_API Power2(size_t e); - //@} - - //! \name ENCODE/DECODE - //@{ - //! minimum number of bytes to encode this integer - /*! MinEncodedSize of 0 is 1 */ - size_t MinEncodedSize(Signedness=UNSIGNED) const; - //! encode in big-endian format - /*! unsigned means encode absolute value, signed means encode two's complement if negative. - if outputLen < MinEncodedSize, the most significant bytes will be dropped - if outputLen > MinEncodedSize, the most significant bytes will be padded - */ - void Encode(byte *output, size_t outputLen, Signedness=UNSIGNED) const; - //! - void Encode(BufferedTransformation &bt, size_t outputLen, Signedness=UNSIGNED) const; - - //! encode using Distinguished Encoding Rules, put result into a BufferedTransformation object - void DEREncode(BufferedTransformation &bt) const; - - //! encode absolute value as big-endian octet string - void DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const; - - //! encode absolute value in OpenPGP format, return length of output - size_t OpenPGPEncode(byte *output, size_t bufferSize) const; - //! encode absolute value in OpenPGP format, put result into a BufferedTransformation object - size_t OpenPGPEncode(BufferedTransformation &bt) const; - - //! - void Decode(const byte *input, size_t inputLen, Signedness=UNSIGNED); - //! - //* Precondition: bt.MaxRetrievable() >= inputLen - void Decode(BufferedTransformation &bt, size_t inputLen, Signedness=UNSIGNED); - - //! - void BERDecode(const byte *input, size_t inputLen); - //! - void BERDecode(BufferedTransformation &bt); - - //! decode nonnegative value as big-endian octet string - void BERDecodeAsOctetString(BufferedTransformation &bt, size_t length); - - class OpenPGPDecodeErr : public Exception - { - public: - OpenPGPDecodeErr() : Exception(INVALID_DATA_FORMAT, "OpenPGP decode error") {} - }; - - //! - void OpenPGPDecode(const byte *input, size_t inputLen); - //! - void OpenPGPDecode(BufferedTransformation &bt); - //@} - - //! \name ACCESSORS - //@{ - //! return true if *this can be represented as a signed long - bool IsConvertableToLong() const; - //! return equivalent signed long if possible, otherwise undefined - signed long ConvertToLong() const; - - //! number of significant bits = floor(log2(abs(*this))) + 1 - unsigned int BitCount() const; - //! number of significant bytes = ceiling(BitCount()/8) - unsigned int ByteCount() const; - //! number of significant words = ceiling(ByteCount()/sizeof(word)) - unsigned int WordCount() const; - - //! return the i-th bit, i=0 being the least significant bit - bool GetBit(size_t i) const; - //! return the i-th byte - byte GetByte(size_t i) const; - //! return n lowest bits of *this >> i - lword GetBits(size_t i, size_t n) const; - - //! - bool IsZero() const {return !*this;} - //! - bool NotZero() const {return !IsZero();} - //! - bool IsNegative() const {return sign == NEGATIVE;} - //! - bool NotNegative() const {return !IsNegative();} - //! - bool IsPositive() const {return NotNegative() && NotZero();} - //! - bool NotPositive() const {return !IsPositive();} - //! - bool IsEven() const {return GetBit(0) == 0;} - //! - bool IsOdd() const {return GetBit(0) == 1;} - //@} - - //! \name MANIPULATORS - //@{ - //! - Integer& operator=(const Integer& t); - - //! - Integer& operator+=(const Integer& t); - //! - Integer& operator-=(const Integer& t); - //! - Integer& operator*=(const Integer& t) {return *this = Times(t);} - //! - Integer& operator/=(const Integer& t) {return *this = DividedBy(t);} - //! - Integer& operator%=(const Integer& t) {return *this = Modulo(t);} - //! - Integer& operator/=(word t) {return *this = DividedBy(t);} - //! - Integer& operator%=(word t) {return *this = Integer(POSITIVE, 0, Modulo(t));} - - //! - Integer& operator<<=(size_t); - //! - Integer& operator>>=(size_t); - - //! - void Randomize(RandomNumberGenerator &rng, size_t bitcount); - //! - void Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max); - //! set this Integer to a random element of {x | min <= x <= max and x is of rnType and x % mod == equiv} - /*! returns false if the set is empty */ - bool Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType, const Integer &equiv=Zero(), const Integer &mod=One()); - - bool GenerateRandomNoThrow(RandomNumberGenerator &rng, const NameValuePairs ¶ms = g_nullNameValuePairs); - void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms = g_nullNameValuePairs) - { - if (!GenerateRandomNoThrow(rng, params)) - throw RandomNumberNotFound(); - } - - //! set the n-th bit to value - void SetBit(size_t n, bool value=1); - //! set the n-th byte to value - void SetByte(size_t n, byte value); - - //! - void Negate(); - //! - void SetPositive() {sign = POSITIVE;} - //! - void SetNegative() {if (!!(*this)) sign = NEGATIVE;} - - //! - void swap(Integer &a); - //@} - - //! \name UNARY OPERATORS - //@{ - //! - bool operator!() const; - //! - Integer operator+() const {return *this;} - //! - Integer operator-() const; - //! - Integer& operator++(); - //! - Integer& operator--(); - //! - Integer operator++(int) {Integer temp = *this; ++*this; return temp;} - //! - Integer operator--(int) {Integer temp = *this; --*this; return temp;} - //@} - - //! \name BINARY OPERATORS - //@{ - //! signed comparison - /*! \retval -1 if *this < a - \retval 0 if *this = a - \retval 1 if *this > a - */ - int Compare(const Integer& a) const; - - //! - Integer Plus(const Integer &b) const; - //! - Integer Minus(const Integer &b) const; - //! - Integer Times(const Integer &b) const; - //! - Integer DividedBy(const Integer &b) const; - //! - Integer Modulo(const Integer &b) const; - //! - Integer DividedBy(word b) const; - //! - word Modulo(word b) const; - - //! - Integer operator>>(size_t n) const {return Integer(*this)>>=n;} - //! - Integer operator<<(size_t n) const {return Integer(*this)<<=n;} - //@} - - //! \name OTHER ARITHMETIC FUNCTIONS - //@{ - //! - Integer AbsoluteValue() const; - //! - Integer Doubled() const {return Plus(*this);} - //! - Integer Squared() const {return Times(*this);} - //! extract square root, if negative return 0, else return floor of square root - Integer SquareRoot() const; - //! return whether this integer is a perfect square - bool IsSquare() const; - - //! is 1 or -1 - bool IsUnit() const; - //! return inverse if 1 or -1, otherwise return 0 - Integer MultiplicativeInverse() const; - - //! modular multiplication - CRYPTOPP_DLL friend Integer CRYPTOPP_API a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m); - //! modular exponentiation - CRYPTOPP_DLL friend Integer CRYPTOPP_API a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m); - - //! calculate r and q such that (a == d*q + r) && (0 <= r < abs(d)) - static void CRYPTOPP_API Divide(Integer &r, Integer &q, const Integer &a, const Integer &d); - //! use a faster division algorithm when divisor is short - static void CRYPTOPP_API Divide(word &r, Integer &q, const Integer &a, word d); - - //! returns same result as Divide(r, q, a, Power2(n)), but faster - static void CRYPTOPP_API DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, unsigned int n); - - //! greatest common divisor - static Integer CRYPTOPP_API Gcd(const Integer &a, const Integer &n); - //! calculate multiplicative inverse of *this mod n - Integer InverseMod(const Integer &n) const; - //! - word InverseMod(word n) const; - //@} - - //! \name INPUT/OUTPUT - //@{ - //! - friend CRYPTOPP_DLL std::istream& CRYPTOPP_API operator>>(std::istream& in, Integer &a); - //! - friend CRYPTOPP_DLL std::ostream& CRYPTOPP_API operator<<(std::ostream& out, const Integer &a); - //@} - -private: - friend class ModularArithmetic; - friend class MontgomeryRepresentation; - friend class HalfMontgomeryRepresentation; - - Integer(word value, size_t length); - - int PositiveCompare(const Integer &t) const; - friend void PositiveAdd(Integer &sum, const Integer &a, const Integer &b); - friend void PositiveSubtract(Integer &diff, const Integer &a, const Integer &b); - friend void PositiveMultiply(Integer &product, const Integer &a, const Integer &b); - friend void PositiveDivide(Integer &remainder, Integer "ient, const Integer ÷nd, const Integer &divisor); - - IntegerSecBlock reg; - Sign sign; -}; - -//! -inline bool operator==(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)==0;} -//! -inline bool operator!=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)!=0;} -//! -inline bool operator> (const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)> 0;} -//! -inline bool operator>=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)>=0;} -//! -inline bool operator< (const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)< 0;} -//! -inline bool operator<=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)<=0;} -//! -inline CryptoPP::Integer operator+(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Plus(b);} -//! -inline CryptoPP::Integer operator-(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Minus(b);} -//! -inline CryptoPP::Integer operator*(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Times(b);} -//! -inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.DividedBy(b);} -//! -inline CryptoPP::Integer operator%(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Modulo(b);} -//! -inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, CryptoPP::word b) {return a.DividedBy(b);} -//! -inline CryptoPP::word operator%(const CryptoPP::Integer &a, CryptoPP::word b) {return a.Modulo(b);} - -NAMESPACE_END - -#ifndef __BORLANDC__ -NAMESPACE_BEGIN(std) -inline void swap(CryptoPP::Integer &a, CryptoPP::Integer &b) -{ - a.swap(b); -} -NAMESPACE_END -#endif - -#endif diff --git a/lib/cryptopp/iterhash.cpp b/lib/cryptopp/iterhash.cpp deleted file mode 100644 index 1e31e9fb3..000000000 --- a/lib/cryptopp/iterhash.cpp +++ /dev/null @@ -1,160 +0,0 @@ -// iterhash.cpp - written and placed in the public domain by Wei Dai - -#ifndef __GNUC__ -#define CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES -#endif - -#include "iterhash.h" -#include "misc.h" - -NAMESPACE_BEGIN(CryptoPP) - -template <class T, class BASE> void IteratedHashBase<T, BASE>::Update(const byte *input, size_t len) -{ - HashWordType oldCountLo = m_countLo, oldCountHi = m_countHi; - if ((m_countLo = oldCountLo + HashWordType(len)) < oldCountLo) - m_countHi++; // carry from low to high - m_countHi += (HashWordType)SafeRightShift<8*sizeof(HashWordType)>(len); - if (m_countHi < oldCountHi || SafeRightShift<2*8*sizeof(HashWordType)>(len) != 0) - throw HashInputTooLong(this->AlgorithmName()); - - unsigned int blockSize = this->BlockSize(); - unsigned int num = ModPowerOf2(oldCountLo, blockSize); - T* dataBuf = this->DataBuf(); - byte* data = (byte *)dataBuf; - - if (num != 0) // process left over data - { - if (num+len >= blockSize) - { - memcpy(data+num, input, blockSize-num); - HashBlock(dataBuf); - input += (blockSize-num); - len -= (blockSize-num); - num = 0; - // drop through and do the rest - } - else - { - memcpy(data+num, input, len); - return; - } - } - - // now process the input data in blocks of blockSize bytes and save the leftovers to m_data - if (len >= blockSize) - { - if (input == data) - { - assert(len == blockSize); - HashBlock(dataBuf); - return; - } - else if (IsAligned<T>(input)) - { - size_t leftOver = HashMultipleBlocks((T *)input, len); - input += (len - leftOver); - len = leftOver; - } - else - do - { // copy input first if it's not aligned correctly - memcpy(data, input, blockSize); - HashBlock(dataBuf); - input+=blockSize; - len-=blockSize; - } while (len >= blockSize); - } - - if (len && data != input) - memcpy(data, input, len); -} - -template <class T, class BASE> byte * IteratedHashBase<T, BASE>::CreateUpdateSpace(size_t &size) -{ - unsigned int blockSize = this->BlockSize(); - unsigned int num = ModPowerOf2(m_countLo, blockSize); - size = blockSize - num; - return (byte *)DataBuf() + num; -} - -template <class T, class BASE> size_t IteratedHashBase<T, BASE>::HashMultipleBlocks(const T *input, size_t length) -{ - unsigned int blockSize = this->BlockSize(); - bool noReverse = NativeByteOrderIs(this->GetByteOrder()); - T* dataBuf = this->DataBuf(); - do - { - if (noReverse) - this->HashEndianCorrectedBlock(input); - else - { - ByteReverse(dataBuf, input, this->BlockSize()); - this->HashEndianCorrectedBlock(dataBuf); - } - - input += blockSize/sizeof(T); - length -= blockSize; - } - while (length >= blockSize); - return length; -} - -template <class T, class BASE> void IteratedHashBase<T, BASE>::PadLastBlock(unsigned int lastBlockSize, byte padFirst) -{ - unsigned int blockSize = this->BlockSize(); - unsigned int num = ModPowerOf2(m_countLo, blockSize); - T* dataBuf = this->DataBuf(); - byte* data = (byte *)dataBuf; - data[num++] = padFirst; - if (num <= lastBlockSize) - memset(data+num, 0, lastBlockSize-num); - else - { - memset(data+num, 0, blockSize-num); - HashBlock(dataBuf); - memset(data, 0, lastBlockSize); - } -} - -template <class T, class BASE> void IteratedHashBase<T, BASE>::Restart() -{ - m_countLo = m_countHi = 0; - Init(); -} - -template <class T, class BASE> void IteratedHashBase<T, BASE>::TruncatedFinal(byte *digest, size_t size) -{ - this->ThrowIfInvalidTruncatedSize(size); - - T* dataBuf = this->DataBuf(); - T* stateBuf = this->StateBuf(); - unsigned int blockSize = this->BlockSize(); - ByteOrder order = this->GetByteOrder(); - - PadLastBlock(blockSize - 2*sizeof(HashWordType)); - dataBuf[blockSize/sizeof(T)-2+order] = ConditionalByteReverse(order, this->GetBitCountLo()); - dataBuf[blockSize/sizeof(T)-1-order] = ConditionalByteReverse(order, this->GetBitCountHi()); - - HashBlock(dataBuf); - - if (IsAligned<HashWordType>(digest) && size%sizeof(HashWordType)==0) - ConditionalByteReverse<HashWordType>(order, (HashWordType *)digest, stateBuf, size); - else - { - ConditionalByteReverse<HashWordType>(order, stateBuf, stateBuf, this->DigestSize()); - memcpy(digest, stateBuf, size); - } - - this->Restart(); // reinit for next use -} - -#ifdef __GNUC__ - template class IteratedHashBase<word64, HashTransformation>; - template class IteratedHashBase<word64, MessageAuthenticationCode>; - - template class IteratedHashBase<word32, HashTransformation>; - template class IteratedHashBase<word32, MessageAuthenticationCode>; -#endif - -NAMESPACE_END diff --git a/lib/cryptopp/iterhash.h b/lib/cryptopp/iterhash.h deleted file mode 100644 index cce9e8211..000000000 --- a/lib/cryptopp/iterhash.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef CRYPTOPP_ITERHASH_H -#define CRYPTOPP_ITERHASH_H - -#include "cryptlib.h" -#include "secblock.h" -#include "misc.h" -#include "simple.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! exception thrown when trying to hash more data than is allowed by a hash function -class CRYPTOPP_DLL HashInputTooLong : public InvalidDataFormat -{ -public: - explicit HashInputTooLong(const std::string &alg) - : InvalidDataFormat("IteratedHashBase: input data exceeds maximum allowed by hash function " + alg) {} -}; - -//! _ -template <class T, class BASE> -class CRYPTOPP_NO_VTABLE IteratedHashBase : public BASE -{ -public: - typedef T HashWordType; - - IteratedHashBase() : m_countLo(0), m_countHi(0) {} - unsigned int OptimalBlockSize() const {return this->BlockSize();} - unsigned int OptimalDataAlignment() const {return GetAlignmentOf<T>();} - void Update(const byte *input, size_t length); - byte * CreateUpdateSpace(size_t &size); - void Restart(); - void TruncatedFinal(byte *digest, size_t size); - -protected: - inline T GetBitCountHi() const {return (m_countLo >> (8*sizeof(T)-3)) + (m_countHi << 3);} - inline T GetBitCountLo() const {return m_countLo << 3;} - - void PadLastBlock(unsigned int lastBlockSize, byte padFirst=0x80); - virtual void Init() =0; - - virtual ByteOrder GetByteOrder() const =0; - virtual void HashEndianCorrectedBlock(const HashWordType *data) =0; - virtual size_t HashMultipleBlocks(const T *input, size_t length); - void HashBlock(const HashWordType *input) {HashMultipleBlocks(input, this->BlockSize());} - - virtual T* DataBuf() =0; - virtual T* StateBuf() =0; - -private: - T m_countLo, m_countHi; -}; - -//! _ -template <class T_HashWordType, class T_Endianness, unsigned int T_BlockSize, class T_Base = HashTransformation> -class CRYPTOPP_NO_VTABLE IteratedHash : public IteratedHashBase<T_HashWordType, T_Base> -{ -public: - typedef T_Endianness ByteOrderClass; - typedef T_HashWordType HashWordType; - - CRYPTOPP_CONSTANT(BLOCKSIZE = T_BlockSize) - // BCB2006 workaround: can't use BLOCKSIZE here - CRYPTOPP_COMPILE_ASSERT((T_BlockSize & (T_BlockSize - 1)) == 0); // blockSize is a power of 2 - unsigned int BlockSize() const {return T_BlockSize;} - - ByteOrder GetByteOrder() const {return T_Endianness::ToEnum();} - - inline static void CorrectEndianess(HashWordType *out, const HashWordType *in, size_t byteCount) - { - ConditionalByteReverse(T_Endianness::ToEnum(), out, in, byteCount); - } - -protected: - T_HashWordType* DataBuf() {return this->m_data;} - FixedSizeSecBlock<T_HashWordType, T_BlockSize/sizeof(T_HashWordType)> m_data; -}; - -//! _ -template <class T_HashWordType, class T_Endianness, unsigned int T_BlockSize, unsigned int T_StateSize, class T_Transform, unsigned int T_DigestSize = 0, bool T_StateAligned = false> -class CRYPTOPP_NO_VTABLE IteratedHashWithStaticTransform - : public ClonableImpl<T_Transform, AlgorithmImpl<IteratedHash<T_HashWordType, T_Endianness, T_BlockSize>, T_Transform> > -{ -public: - CRYPTOPP_CONSTANT(DIGESTSIZE = T_DigestSize ? T_DigestSize : T_StateSize) - unsigned int DigestSize() const {return DIGESTSIZE;}; - -protected: - IteratedHashWithStaticTransform() {this->Init();} - void HashEndianCorrectedBlock(const T_HashWordType *data) {T_Transform::Transform(this->m_state, data);} - void Init() {T_Transform::InitState(this->m_state);} - - T_HashWordType* StateBuf() {return this->m_state;} - FixedSizeAlignedSecBlock<T_HashWordType, T_BlockSize/sizeof(T_HashWordType), T_StateAligned> m_state; -}; - -#ifndef __GNUC__ - CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase<word64, HashTransformation>; - CRYPTOPP_STATIC_TEMPLATE_CLASS IteratedHashBase<word64, MessageAuthenticationCode>; - - CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase<word32, HashTransformation>; - CRYPTOPP_STATIC_TEMPLATE_CLASS IteratedHashBase<word32, MessageAuthenticationCode>; -#endif - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/lubyrack.h b/lib/cryptopp/lubyrack.h deleted file mode 100644 index e8fd2f748..000000000 --- a/lib/cryptopp/lubyrack.h +++ /dev/null @@ -1,141 +0,0 @@ -// lubyrack.h - written and placed in the public domain by Wei Dai - -#ifndef CRYPTOPP_LUBYRACK_H -#define CRYPTOPP_LUBYRACK_H - -/** \file */ - -#include "simple.h" -#include "secblock.h" - -NAMESPACE_BEGIN(CryptoPP) - -template <class T> struct DigestSizeDoubleWorkaround // VC60 workaround -{ - CRYPTOPP_CONSTANT(RESULT = 2*T::DIGESTSIZE) -}; - -//! algorithm info -template <class T> -struct LR_Info : public VariableKeyLength<16, 0, 2*(INT_MAX/2), 2>, public FixedBlockSize<DigestSizeDoubleWorkaround<T>::RESULT> -{ - static std::string StaticAlgorithmName() {return std::string("LR/")+T::StaticAlgorithmName();} -}; - -//! Luby-Rackoff -template <class T> -class LR : public LR_Info<T>, public BlockCipherDocumentation -{ - class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<LR_Info<T> > - { - public: - // VC60 workaround: have to define these functions within class definition - void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) - { - this->AssertValidKeyLength(length); - - L = length/2; - buffer.New(2*S); - digest.New(S); - key.Assign(userKey, 2*L); - } - - protected: - CRYPTOPP_CONSTANT(S=T::DIGESTSIZE) - unsigned int L; // key length / 2 - SecByteBlock key; - - mutable T hm; - mutable SecByteBlock buffer, digest; - }; - - class CRYPTOPP_NO_VTABLE Enc : public Base - { - public: - -#define KL this->key -#define KR this->key+this->L -#define BL this->buffer -#define BR this->buffer+this->S -#define IL inBlock -#define IR inBlock+this->S -#define OL outBlock -#define OR outBlock+this->S - - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const - { - this->hm.Update(KL, this->L); - this->hm.Update(IL, this->S); - this->hm.Final(BR); - xorbuf(BR, IR, this->S); - - this->hm.Update(KR, this->L); - this->hm.Update(BR, this->S); - this->hm.Final(BL); - xorbuf(BL, IL, this->S); - - this->hm.Update(KL, this->L); - this->hm.Update(BL, this->S); - this->hm.Final(this->digest); - xorbuf(BR, this->digest, this->S); - - this->hm.Update(KR, this->L); - this->hm.Update(OR, this->S); - this->hm.Final(this->digest); - xorbuf(BL, this->digest, this->S); - - if (xorBlock) - xorbuf(outBlock, xorBlock, this->buffer, 2*this->S); - else - memcpy_s(outBlock, 2*this->S, this->buffer, 2*this->S); - } - }; - - class CRYPTOPP_NO_VTABLE Dec : public Base - { - public: - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const - { - this->hm.Update(KR, this->L); - this->hm.Update(IR, this->S); - this->hm.Final(BL); - xorbuf(BL, IL, this->S); - - this->hm.Update(KL, this->L); - this->hm.Update(BL, this->S); - this->hm.Final(BR); - xorbuf(BR, IR, this->S); - - this->hm.Update(KR, this->L); - this->hm.Update(BR, this->S); - this->hm.Final(this->digest); - xorbuf(BL, this->digest, this->S); - - this->hm.Update(KL, this->L); - this->hm.Update(OL, this->S); - this->hm.Final(this->digest); - xorbuf(BR, this->digest, this->S); - - if (xorBlock) - xorbuf(outBlock, xorBlock, this->buffer, 2*this->S); - else - memcpy(outBlock, this->buffer, 2*this->S); - } -#undef KL -#undef KR -#undef BL -#undef BR -#undef IL -#undef IR -#undef OL -#undef OR - }; - -public: - typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption; - typedef BlockCipherFinal<DECRYPTION, Dec> Decryption; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/luc.cpp b/lib/cryptopp/luc.cpp deleted file mode 100644 index 43cd2ed21..000000000 --- a/lib/cryptopp/luc.cpp +++ /dev/null @@ -1,210 +0,0 @@ -// luc.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "luc.h" -#include "asn.h" -#include "nbtheory.h" -#include "sha.h" -#include "algparam.h" - -NAMESPACE_BEGIN(CryptoPP) - -void LUC_TestInstantiations() -{ - LUC_HMP<SHA>::Signer t1; - LUCFunction t2; - InvertibleLUCFunction t3; -} - -void DL_Algorithm_LUC_HMP::Sign(const DL_GroupParameters<Integer> ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const -{ - const Integer &q = params.GetSubgroupOrder(); - r = params.ExponentiateBase(k); - s = (k + x*(r+e)) % q; -} - -bool DL_Algorithm_LUC_HMP::Verify(const DL_GroupParameters<Integer> ¶ms, const DL_PublicKey<Integer> &publicKey, const Integer &e, const Integer &r, const Integer &s) const -{ - Integer p = params.GetGroupOrder()-1; - const Integer &q = params.GetSubgroupOrder(); - - Integer Vsg = params.ExponentiateBase(s); - Integer Vry = publicKey.ExponentiatePublicElement((r+e)%q); - return (Vsg*Vsg + Vry*Vry + r*r) % p == (Vsg * Vry * r + 4) % p; -} - -Integer DL_BasePrecomputation_LUC::Exponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent) const -{ - return Lucas(exponent, m_g, static_cast<const DL_GroupPrecomputation_LUC &>(group).GetModulus()); -} - -void DL_GroupParameters_LUC::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const -{ - for (unsigned int i=0; i<exponentsCount; i++) - results[i] = Lucas(exponents[i], base, GetModulus()); -} - -void LUCFunction::BERDecode(BufferedTransformation &bt) -{ - BERSequenceDecoder seq(bt); - m_n.BERDecode(seq); - m_e.BERDecode(seq); - seq.MessageEnd(); -} - -void LUCFunction::DEREncode(BufferedTransformation &bt) const -{ - DERSequenceEncoder seq(bt); - m_n.DEREncode(seq); - m_e.DEREncode(seq); - seq.MessageEnd(); -} - -Integer LUCFunction::ApplyFunction(const Integer &x) const -{ - DoQuickSanityCheck(); - return Lucas(m_e, x, m_n); -} - -bool LUCFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const -{ - bool pass = true; - pass = pass && m_n > Integer::One() && m_n.IsOdd(); - pass = pass && m_e > Integer::One() && m_e.IsOdd() && m_e < m_n; - return pass; -} - -bool LUCFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const -{ - return GetValueHelper(this, name, valueType, pValue).Assignable() - CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) - CRYPTOPP_GET_FUNCTION_ENTRY(PublicExponent) - ; -} - -void LUCFunction::AssignFrom(const NameValuePairs &source) -{ - AssignFromHelper(this, source) - CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) - CRYPTOPP_SET_FUNCTION_ENTRY(PublicExponent) - ; -} - -// ***************************************************************************** -// private key operations: - -class LUCPrimeSelector : public PrimeSelector -{ -public: - LUCPrimeSelector(const Integer &e) : m_e(e) {} - bool IsAcceptable(const Integer &candidate) const - { - return RelativelyPrime(m_e, candidate+1) && RelativelyPrime(m_e, candidate-1); - } - Integer m_e; -}; - -void InvertibleLUCFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) -{ - int modulusSize = 2048; - alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize); - - if (modulusSize < 16) - throw InvalidArgument("InvertibleLUCFunction: specified modulus size is too small"); - - m_e = alg.GetValueWithDefault("PublicExponent", Integer(17)); - - if (m_e < 5 || m_e.IsEven()) - throw InvalidArgument("InvertibleLUCFunction: invalid public exponent"); - - LUCPrimeSelector selector(m_e); - AlgorithmParameters primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize) - ("PointerToPrimeSelector", selector.GetSelectorPointer()); - m_p.GenerateRandom(rng, primeParam); - m_q.GenerateRandom(rng, primeParam); - - m_n = m_p * m_q; - m_u = m_q.InverseMod(m_p); -} - -void InvertibleLUCFunction::Initialize(RandomNumberGenerator &rng, unsigned int keybits, const Integer &e) -{ - GenerateRandom(rng, MakeParameters("ModulusSize", (int)keybits)("PublicExponent", e)); -} - -void InvertibleLUCFunction::BERDecode(BufferedTransformation &bt) -{ - BERSequenceDecoder seq(bt); - - Integer version(seq); - if (!!version) // make sure version is 0 - BERDecodeError(); - - m_n.BERDecode(seq); - m_e.BERDecode(seq); - m_p.BERDecode(seq); - m_q.BERDecode(seq); - m_u.BERDecode(seq); - seq.MessageEnd(); -} - -void InvertibleLUCFunction::DEREncode(BufferedTransformation &bt) const -{ - DERSequenceEncoder seq(bt); - - const byte version[] = {INTEGER, 1, 0}; - seq.Put(version, sizeof(version)); - m_n.DEREncode(seq); - m_e.DEREncode(seq); - m_p.DEREncode(seq); - m_q.DEREncode(seq); - m_u.DEREncode(seq); - seq.MessageEnd(); -} - -Integer InvertibleLUCFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const -{ - // not clear how to do blinding with LUC - DoQuickSanityCheck(); - return InverseLucas(m_e, x, m_q, m_p, m_u); -} - -bool InvertibleLUCFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const -{ - bool pass = LUCFunction::Validate(rng, level); - pass = pass && m_p > Integer::One() && m_p.IsOdd() && m_p < m_n; - pass = pass && m_q > Integer::One() && m_q.IsOdd() && m_q < m_n; - pass = pass && m_u.IsPositive() && m_u < m_p; - if (level >= 1) - { - pass = pass && m_p * m_q == m_n; - pass = pass && RelativelyPrime(m_e, m_p+1); - pass = pass && RelativelyPrime(m_e, m_p-1); - pass = pass && RelativelyPrime(m_e, m_q+1); - pass = pass && RelativelyPrime(m_e, m_q-1); - pass = pass && m_u * m_q % m_p == 1; - } - if (level >= 2) - pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); - return pass; -} - -bool InvertibleLUCFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const -{ - return GetValueHelper<LUCFunction>(this, name, valueType, pValue).Assignable() - CRYPTOPP_GET_FUNCTION_ENTRY(Prime1) - CRYPTOPP_GET_FUNCTION_ENTRY(Prime2) - CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) - ; -} - -void InvertibleLUCFunction::AssignFrom(const NameValuePairs &source) -{ - AssignFromHelper<LUCFunction>(this, source) - CRYPTOPP_SET_FUNCTION_ENTRY(Prime1) - CRYPTOPP_SET_FUNCTION_ENTRY(Prime2) - CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) - ; -} - -NAMESPACE_END diff --git a/lib/cryptopp/luc.h b/lib/cryptopp/luc.h deleted file mode 100644 index 730776d57..000000000 --- a/lib/cryptopp/luc.h +++ /dev/null @@ -1,236 +0,0 @@ -#ifndef CRYPTOPP_LUC_H -#define CRYPTOPP_LUC_H - -/** \file -*/ - -#include "pkcspad.h" -#include "oaep.h" -#include "integer.h" -#include "dh.h" - -#include <limits.h> - -NAMESPACE_BEGIN(CryptoPP) - -//! The LUC function. -/*! This class is here for historical and pedagogical interest. It has no - practical advantages over other trapdoor functions and probably shouldn't - be used in production software. The discrete log based LUC schemes - defined later in this .h file may be of more practical interest. -*/ -class LUCFunction : public TrapdoorFunction, public PublicKey -{ - typedef LUCFunction ThisClass; - -public: - void Initialize(const Integer &n, const Integer &e) - {m_n = n; m_e = e;} - - void BERDecode(BufferedTransformation &bt); - void DEREncode(BufferedTransformation &bt) const; - - Integer ApplyFunction(const Integer &x) const; - Integer PreimageBound() const {return m_n;} - Integer ImageBound() const {return m_n;} - - bool Validate(RandomNumberGenerator &rng, unsigned int level) const; - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; - void AssignFrom(const NameValuePairs &source); - - // non-derived interface - const Integer & GetModulus() const {return m_n;} - const Integer & GetPublicExponent() const {return m_e;} - - void SetModulus(const Integer &n) {m_n = n;} - void SetPublicExponent(const Integer &e) {m_e = e;} - -protected: - Integer m_n, m_e; -}; - -//! _ -class InvertibleLUCFunction : public LUCFunction, public TrapdoorFunctionInverse, public PrivateKey -{ - typedef InvertibleLUCFunction ThisClass; - -public: - void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits, const Integer &eStart=17); - void Initialize(const Integer &n, const Integer &e, const Integer &p, const Integer &q, const Integer &u) - {m_n = n; m_e = e; m_p = p; m_q = q; m_u = u;} - - void BERDecode(BufferedTransformation &bt); - void DEREncode(BufferedTransformation &bt) const; - - Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; - - bool Validate(RandomNumberGenerator &rng, unsigned int level) const; - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; - void AssignFrom(const NameValuePairs &source); - /*! parameters: (ModulusSize, PublicExponent (default 17)) */ - void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); - - // non-derived interface - const Integer& GetPrime1() const {return m_p;} - const Integer& GetPrime2() const {return m_q;} - const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const {return m_u;} - - void SetPrime1(const Integer &p) {m_p = p;} - void SetPrime2(const Integer &q) {m_q = q;} - void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer &u) {m_u = u;} - -protected: - Integer m_p, m_q, m_u; -}; - -struct LUC -{ - static std::string StaticAlgorithmName() {return "LUC";} - typedef LUCFunction PublicKey; - typedef InvertibleLUCFunction PrivateKey; -}; - -//! LUC cryptosystem -template <class STANDARD> -struct LUCES : public TF_ES<STANDARD, LUC> -{ -}; - -//! LUC signature scheme with appendix -template <class STANDARD, class H> -struct LUCSS : public TF_SS<STANDARD, H, LUC> -{ -}; - -// analagous to the RSA schemes defined in PKCS #1 v2.0 -typedef LUCES<OAEP<SHA> >::Decryptor LUCES_OAEP_SHA_Decryptor; -typedef LUCES<OAEP<SHA> >::Encryptor LUCES_OAEP_SHA_Encryptor; - -typedef LUCSS<PKCS1v15, SHA>::Signer LUCSSA_PKCS1v15_SHA_Signer; -typedef LUCSS<PKCS1v15, SHA>::Verifier LUCSSA_PKCS1v15_SHA_Verifier; - -// ******************************************************** - -// no actual precomputation -class DL_GroupPrecomputation_LUC : public DL_GroupPrecomputation<Integer> -{ -public: - const AbstractGroup<Element> & GetGroup() const {assert(false); throw 0;} - Element BERDecodeElement(BufferedTransformation &bt) const {return Integer(bt);} - void DEREncodeElement(BufferedTransformation &bt, const Element &v) const {v.DEREncode(bt);} - - // non-inherited - void SetModulus(const Integer &v) {m_p = v;} - const Integer & GetModulus() const {return m_p;} - -private: - Integer m_p; -}; - -//! _ -class DL_BasePrecomputation_LUC : public DL_FixedBasePrecomputation<Integer> -{ -public: - // DL_FixedBasePrecomputation - bool IsInitialized() const {return m_g.NotZero();} - void SetBase(const DL_GroupPrecomputation<Element> &group, const Integer &base) {m_g = base;} - const Integer & GetBase(const DL_GroupPrecomputation<Element> &group) const {return m_g;} - void Precompute(const DL_GroupPrecomputation<Element> &group, unsigned int maxExpBits, unsigned int storage) {} - void Load(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &storedPrecomputation) {} - void Save(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &storedPrecomputation) const {} - Integer Exponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent) const; - Integer CascadeExponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent, const DL_FixedBasePrecomputation<Integer> &pc2, const Integer &exponent2) const - {throw NotImplemented("DL_BasePrecomputation_LUC: CascadeExponentiate not implemented");} // shouldn't be called - -private: - Integer m_g; -}; - -//! _ -class DL_GroupParameters_LUC : public DL_GroupParameters_IntegerBasedImpl<DL_GroupPrecomputation_LUC, DL_BasePrecomputation_LUC> -{ -public: - // DL_GroupParameters - bool IsIdentity(const Integer &element) const {return element == Integer::Two();} - void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; - Element MultiplyElements(const Element &a, const Element &b) const - {throw NotImplemented("LUC_GroupParameters: MultiplyElements can not be implemented");} - Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const - {throw NotImplemented("LUC_GroupParameters: MultiplyElements can not be implemented");} - - // NameValuePairs interface - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const - { - return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable(); - } - -private: - int GetFieldType() const {return 2;} -}; - -//! _ -class DL_GroupParameters_LUC_DefaultSafePrime : public DL_GroupParameters_LUC -{ -public: - typedef NoCofactorMultiplication DefaultCofactorOption; - -protected: - unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;} -}; - -//! _ -class DL_Algorithm_LUC_HMP : public DL_ElgamalLikeSignatureAlgorithm<Integer> -{ -public: - static const char * StaticAlgorithmName() {return "LUC-HMP";} - - void Sign(const DL_GroupParameters<Integer> ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const; - bool Verify(const DL_GroupParameters<Integer> ¶ms, const DL_PublicKey<Integer> &publicKey, const Integer &e, const Integer &r, const Integer &s) const; - - size_t RLen(const DL_GroupParameters<Integer> ¶ms) const - {return params.GetGroupOrder().ByteCount();} -}; - -//! _ -struct DL_SignatureKeys_LUC -{ - typedef DL_GroupParameters_LUC GroupParameters; - typedef DL_PublicKey_GFP<GroupParameters> PublicKey; - typedef DL_PrivateKey_GFP<GroupParameters> PrivateKey; -}; - -//! LUC-HMP, based on "Digital signature schemes based on Lucas functions" by Patrick Horster, Markus Michels, Holger Petersen -template <class H> -struct LUC_HMP : public DL_SS<DL_SignatureKeys_LUC, DL_Algorithm_LUC_HMP, DL_SignatureMessageEncodingMethod_DSA, H> -{ -}; - -//! _ -struct DL_CryptoKeys_LUC -{ - typedef DL_GroupParameters_LUC_DefaultSafePrime GroupParameters; - typedef DL_PublicKey_GFP<GroupParameters> PublicKey; - typedef DL_PrivateKey_GFP<GroupParameters> PrivateKey; -}; - -//! LUC-IES -template <class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = true> -struct LUC_IES - : public DL_ES< - DL_CryptoKeys_LUC, - DL_KeyAgreementAlgorithm_DH<Integer, COFACTOR_OPTION>, - DL_KeyDerivationAlgorithm_P1363<Integer, DHAES_MODE, P1363_KDF2<SHA1> >, - DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>, - LUC_IES<> > -{ - static std::string StaticAlgorithmName() {return "LUC-IES";} // non-standard name -}; - -// ******************************************************** - -//! LUC-DH -typedef DH_Domain<DL_GroupParameters_LUC_DefaultSafePrime> LUC_DH; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/md2.cpp b/lib/cryptopp/md2.cpp deleted file mode 100644 index 41f714b59..000000000 --- a/lib/cryptopp/md2.cpp +++ /dev/null @@ -1,120 +0,0 @@ -// md2.cpp - modified by Wei Dai from Andrew M. Kuchling's md2.c -// The original code and all modifications are in the public domain. - -// This is the original introductory comment: - -/* - * md2.c : MD2 hash algorithm. - * - * Part of the Python Cryptography Toolkit, version 1.1 - * - * Distribute and use freely; there are no restrictions on further - * dissemination and usage except those imposed by the laws of your - * country of residence. - * - */ - -#include "pch.h" -#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 -#include "md2.h" - -NAMESPACE_BEGIN(CryptoPP) -namespace Weak1 { - -MD2::MD2() - : m_X(48), m_C(16), m_buf(16) -{ - Init(); -} - -void MD2::Init() -{ - memset(m_X, 0, 48); - memset(m_C, 0, 16); - memset(m_buf, 0, 16); - m_count = 0; -} - -void MD2::Update(const byte *buf, size_t len) -{ - static const byte S[256] = { - 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, - 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, - 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, - 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, - 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, - 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, - 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, - 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, - 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, - 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, - 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, - 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, - 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, - 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, - 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, - 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, - 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, - 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 - }; - - while (len) - { - unsigned int L = UnsignedMin(16U-m_count, len); - memcpy(m_buf+m_count, buf, L); - m_count+=L; - buf+=L; - len-=L; - if (m_count==16) - { - byte t; - int i,j; - - m_count=0; - memcpy(m_X+16, m_buf, 16); - t=m_C[15]; - for(i=0; i<16; i++) - { - m_X[32+i]=m_X[16+i]^m_X[i]; - t=m_C[i]^=S[m_buf[i]^t]; - } - - t=0; - for(i=0; i<18; i++) - { - for(j=0; j<48; j+=8) - { - t=m_X[j+0]^=S[t]; - t=m_X[j+1]^=S[t]; - t=m_X[j+2]^=S[t]; - t=m_X[j+3]^=S[t]; - t=m_X[j+4]^=S[t]; - t=m_X[j+5]^=S[t]; - t=m_X[j+6]^=S[t]; - t=m_X[j+7]^=S[t]; - } - t=(t+i) & 0xFF; - } - } - } -} - -void MD2::TruncatedFinal(byte *hash, size_t size) -{ - ThrowIfInvalidTruncatedSize(size); - - byte padding[16]; - word32 padlen; - unsigned int i; - - padlen= 16-m_count; - for(i=0; i<padlen; i++) padding[i]=(byte)padlen; - Update(padding, padlen); - Update(m_C, 16); - memcpy(hash, m_X, size); - - Init(); -} - -} -NAMESPACE_END diff --git a/lib/cryptopp/md2.h b/lib/cryptopp/md2.h deleted file mode 100644 index b0837c882..000000000 --- a/lib/cryptopp/md2.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef CRYPTOPP_MD2_H -#define CRYPTOPP_MD2_H - -#include "cryptlib.h" -#include "secblock.h" - -NAMESPACE_BEGIN(CryptoPP) - -namespace Weak1 { - -/// <a href="http://www.cryptolounge.org/wiki/MD2">MD2</a> -class MD2 : public HashTransformation -{ -public: - MD2(); - void Update(const byte *input, size_t length); - void TruncatedFinal(byte *hash, size_t size); - unsigned int DigestSize() const {return DIGESTSIZE;} - unsigned int BlockSize() const {return BLOCKSIZE;} - static const char * StaticAlgorithmName() {return "MD2";} - - CRYPTOPP_CONSTANT(DIGESTSIZE = 16) - CRYPTOPP_CONSTANT(BLOCKSIZE = 16) - -private: - void Transform(); - void Init(); - SecByteBlock m_X, m_C, m_buf; - unsigned int m_count; -}; - -} -#if CRYPTOPP_ENABLE_NAMESPACE_WEAK >= 1 -namespace Weak {using namespace Weak1;} // import Weak1 into CryptoPP::Weak -#else -using namespace Weak1; // import Weak1 into CryptoPP with warning -#ifdef __GNUC__ -#warning "You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning." -#else -#pragma message("You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning.") -#endif -#endif - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/md4.cpp b/lib/cryptopp/md4.cpp deleted file mode 100644 index 9ed639cb9..000000000 --- a/lib/cryptopp/md4.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// md4.cpp - modified by Wei Dai from Andrew M. Kuchling's md4.c -// The original code and all modifications are in the public domain. - -// This is the original introductory comment: - -/* - * md4.c : MD4 hash algorithm. - * - * Part of the Python Cryptography Toolkit, version 1.1 - * - * Distribute and use freely; there are no restrictions on further - * dissemination and usage except those imposed by the laws of your - * country of residence. - * - */ - -#include "pch.h" -#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 -#include "md4.h" -#include "misc.h" - -NAMESPACE_BEGIN(CryptoPP) -namespace Weak1 { - -void MD4::InitState(HashWordType *state) -{ - state[0] = 0x67452301L; - state[1] = 0xefcdab89L; - state[2] = 0x98badcfeL; - state[3] = 0x10325476L; -} - -void MD4::Transform (word32 *digest, const word32 *in) -{ -// #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#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)) - - word32 A, B, C, D; - - A=digest[0]; - B=digest[1]; - C=digest[2]; - D=digest[3]; - -#define function(a,b,c,d,k,s) a=rotlFixed(a+F(b,c,d)+in[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)+in[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)+in[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); - - digest[0]+=A; - digest[1]+=B; - digest[2]+=C; - digest[3]+=D; -} - -} -NAMESPACE_END diff --git a/lib/cryptopp/md4.h b/lib/cryptopp/md4.h deleted file mode 100644 index 53387003c..000000000 --- a/lib/cryptopp/md4.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef CRYPTOPP_MD4_H -#define CRYPTOPP_MD4_H - -#include "iterhash.h" - -NAMESPACE_BEGIN(CryptoPP) - -namespace Weak1 { - -//! <a href="http://www.weidai.com/scan-mirror/md.html#MD4">MD4</a> -/*! \warning MD4 is considered insecure, and should not be used - unless you absolutely need it for compatibility. */ -class MD4 : public IteratedHashWithStaticTransform<word32, LittleEndian, 64, 16, MD4> -{ -public: - static void InitState(HashWordType *state); - static void Transform(word32 *digest, const word32 *data); - static const char *StaticAlgorithmName() {return "MD4";} -}; - -} -#if CRYPTOPP_ENABLE_NAMESPACE_WEAK >= 1 -namespace Weak {using namespace Weak1;} // import Weak1 into CryptoPP::Weak -#else -using namespace Weak1; // import Weak1 into CryptoPP with warning -#ifdef __GNUC__ -#warning "You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning." -#else -#pragma message("You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning.") -#endif -#endif - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/md5.cpp b/lib/cryptopp/md5.cpp deleted file mode 100644 index a52297816..000000000 --- a/lib/cryptopp/md5.cpp +++ /dev/null @@ -1,118 +0,0 @@ -// md5.cpp - modified by Wei Dai from Colin Plumb's public domain md5.c -// any modifications are placed in the public domain - -#include "pch.h" -#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 -#include "md5.h" -#include "misc.h" - -NAMESPACE_BEGIN(CryptoPP) -namespace Weak1 { - -void MD5_TestInstantiations() -{ - MD5 x; -} - -void MD5::InitState(HashWordType *state) -{ - state[0] = 0x67452301L; - state[1] = 0xefcdab89L; - state[2] = 0x98badcfeL; - state[3] = 0x10325476L; -} - -void MD5::Transform (word32 *digest, const word32 *in) -{ -// #define F1(x, y, z) (x & y | ~x & z) -#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 - - word32 a, b, c, d; - - a=digest[0]; - b=digest[1]; - c=digest[2]; - d=digest[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); - - digest[0]+=a; - digest[1]+=b; - digest[2]+=c; - digest[3]+=d; -} - -} -NAMESPACE_END diff --git a/lib/cryptopp/md5.h b/lib/cryptopp/md5.h deleted file mode 100644 index 73ec5326c..000000000 --- a/lib/cryptopp/md5.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef CRYPTOPP_MD5_H -#define CRYPTOPP_MD5_H - -#include "iterhash.h" - -NAMESPACE_BEGIN(CryptoPP) - -namespace Weak1 { - -//! <a href="http://www.cryptolounge.org/wiki/MD5">MD5</a> -class MD5 : public IteratedHashWithStaticTransform<word32, LittleEndian, 64, 16, MD5> -{ -public: - static void InitState(HashWordType *state); - static void Transform(word32 *digest, const word32 *data); - static const char * StaticAlgorithmName() {return "MD5";} -}; - -} -#if CRYPTOPP_ENABLE_NAMESPACE_WEAK >= 1 -namespace Weak {using namespace Weak1;} // import Weak1 into CryptoPP::Weak -#else -using namespace Weak1; // import Weak1 into CryptoPP with warning -#ifdef __GNUC__ -#warning "You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning." -#else -#pragma message("You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning.") -#endif -#endif - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/mdc.h b/lib/cryptopp/mdc.h deleted file mode 100644 index cc90cdc45..000000000 --- a/lib/cryptopp/mdc.h +++ /dev/null @@ -1,72 +0,0 @@ - // mdc.h - written and placed in the public domain by Wei Dai - -#ifndef CRYPTOPP_MDC_H -#define CRYPTOPP_MDC_H - -/** \file -*/ - -#include "seckey.h" -#include "misc.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -template <class T> -struct MDC_Info : public FixedBlockSize<T::DIGESTSIZE>, public FixedKeyLength<T::BLOCKSIZE> -{ - static std::string StaticAlgorithmName() {return std::string("MDC/")+T::StaticAlgorithmName();} -}; - -//! <a href="http://www.weidai.com/scan-mirror/cs.html#MDC">MDC</a> -/*! a construction by Peter Gutmann to turn an iterated hash function into a PRF */ -template <class T> -class MDC : public MDC_Info<T> -{ - class CRYPTOPP_NO_VTABLE Enc : public BlockCipherImpl<MDC_Info<T> > - { - typedef typename T::HashWordType HashWordType; - - public: - void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) - { - this->AssertValidKeyLength(length); - memcpy_s(m_key, m_key.size(), userKey, this->KEYLENGTH); - T::CorrectEndianess(Key(), Key(), this->KEYLENGTH); - } - - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const - { - T::CorrectEndianess(Buffer(), (HashWordType *)inBlock, this->BLOCKSIZE); - T::Transform(Buffer(), Key()); - if (xorBlock) - { - T::CorrectEndianess(Buffer(), Buffer(), this->BLOCKSIZE); - xorbuf(outBlock, xorBlock, m_buffer, this->BLOCKSIZE); - } - else - T::CorrectEndianess((HashWordType *)outBlock, Buffer(), this->BLOCKSIZE); - } - - bool IsPermutation() const {return false;} - - unsigned int OptimalDataAlignment() const {return sizeof(HashWordType);} - - private: - HashWordType *Key() {return (HashWordType *)m_key.data();} - const HashWordType *Key() const {return (const HashWordType *)m_key.data();} - HashWordType *Buffer() const {return (HashWordType *)m_buffer.data();} - - // VC60 workaround: bug triggered if using FixedSizeAllocatorWithCleanup - FixedSizeSecBlock<byte, MDC_Info<T>::KEYLENGTH, AllocatorWithCleanup<byte> > m_key; - mutable FixedSizeSecBlock<byte, MDC_Info<T>::BLOCKSIZE, AllocatorWithCleanup<byte> > m_buffer; - }; - -public: - //! use BlockCipher interface - typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/misc.cpp b/lib/cryptopp/misc.cpp deleted file mode 100644 index 93760e3a3..000000000 --- a/lib/cryptopp/misc.cpp +++ /dev/null @@ -1,189 +0,0 @@ -// misc.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "misc.h" -#include "words.h" -#include <new> - -#if defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE) || defined(QNX) -#include <malloc.h> -#endif - -NAMESPACE_BEGIN(CryptoPP) - -void xorbuf(byte *buf, const byte *mask, size_t count) -{ - size_t i; - - if (IsAligned<word32>(buf) && IsAligned<word32>(mask)) - { - if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(mask)) - { - for (i=0; i<count/8; i++) - ((word64*)buf)[i] ^= ((word64*)mask)[i]; - count -= 8*i; - if (!count) - return; - buf += 8*i; - mask += 8*i; - } - - for (i=0; i<count/4; i++) - ((word32*)buf)[i] ^= ((word32*)mask)[i]; - count -= 4*i; - if (!count) - return; - buf += 4*i; - mask += 4*i; - } - - for (i=0; i<count; i++) - buf[i] ^= mask[i]; -} - -void xorbuf(byte *output, const byte *input, const byte *mask, size_t count) -{ - size_t i; - - if (IsAligned<word32>(output) && IsAligned<word32>(input) && IsAligned<word32>(mask)) - { - if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(output) && IsAligned<word64>(input) && IsAligned<word64>(mask)) - { - for (i=0; i<count/8; i++) - ((word64*)output)[i] = ((word64*)input)[i] ^ ((word64*)mask)[i]; - count -= 8*i; - if (!count) - return; - output += 8*i; - input += 8*i; - mask += 8*i; - } - - for (i=0; i<count/4; i++) - ((word32*)output)[i] = ((word32*)input)[i] ^ ((word32*)mask)[i]; - count -= 4*i; - if (!count) - return; - output += 4*i; - input += 4*i; - mask += 4*i; - } - - for (i=0; i<count; i++) - output[i] = input[i] ^ mask[i]; -} - -bool VerifyBufsEqual(const byte *buf, const byte *mask, size_t count) -{ - size_t i; - byte acc8 = 0; - - if (IsAligned<word32>(buf) && IsAligned<word32>(mask)) - { - word32 acc32 = 0; - if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(mask)) - { - word64 acc64 = 0; - for (i=0; i<count/8; i++) - acc64 |= ((word64*)buf)[i] ^ ((word64*)mask)[i]; - count -= 8*i; - if (!count) - return acc64 == 0; - buf += 8*i; - mask += 8*i; - acc32 = word32(acc64) | word32(acc64>>32); - } - - for (i=0; i<count/4; i++) - acc32 |= ((word32*)buf)[i] ^ ((word32*)mask)[i]; - count -= 4*i; - if (!count) - return acc32 == 0; - buf += 4*i; - mask += 4*i; - acc8 = byte(acc32) | byte(acc32>>8) | byte(acc32>>16) | byte(acc32>>24); - } - - for (i=0; i<count; i++) - acc8 |= buf[i] ^ mask[i]; - return acc8 == 0; -} - -#if !(defined(_MSC_VER) && (_MSC_VER < 1300)) && !defined(ANDROID_NDK) -using std::new_handler; -using std::set_new_handler; -#endif - -void CallNewHandler() -{ -#if !defined(ANDROID_NDK) - new_handler newHandler = set_new_handler(NULL); - if (newHandler) - set_new_handler(newHandler); - - if (newHandler) - newHandler(); - else - throw std::bad_alloc(); -#endif -} - -#if CRYPTOPP_BOOL_ALIGN16_ENABLED - -void * AlignedAllocate(size_t size) -{ - byte *p; -#ifdef CRYPTOPP_MM_MALLOC_AVAILABLE - while (!(p = (byte *)_mm_malloc(size, 16))) -#elif defined(CRYPTOPP_MEMALIGN_AVAILABLE) - while (!(p = (byte *)memalign(16, size))) -#elif defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16) - while (!(p = (byte *)malloc(size))) -#else - while (!(p = (byte *)malloc(size + 16))) -#endif - CallNewHandler(); - -#ifdef CRYPTOPP_NO_ALIGNED_ALLOC - size_t adjustment = 16-((size_t)p%16); - p += adjustment; - p[-1] = (byte)adjustment; -#endif - - assert(IsAlignedOn(p, 16)); - return p; -} - -void AlignedDeallocate(void *p) -{ -#ifdef CRYPTOPP_MM_MALLOC_AVAILABLE - _mm_free(p); -#elif defined(CRYPTOPP_NO_ALIGNED_ALLOC) - p = (byte *)p - ((byte *)p)[-1]; - free(p); -#else - free(p); -#endif -} - -#endif - -void * UnalignedAllocate(size_t size) -{ - void *p; - while (!(p = malloc(size))) - CallNewHandler(); - return p; -} - -void UnalignedDeallocate(void *p) -{ - free(p); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/misc.h b/lib/cryptopp/misc.h deleted file mode 100644 index 9149b9ac0..000000000 --- a/lib/cryptopp/misc.h +++ /dev/null @@ -1,1282 +0,0 @@ -#ifndef CRYPTOPP_MISC_H -#define CRYPTOPP_MISC_H - -#include "cryptlib.h" -#include "smartptr.h" -#include <string.h> // for memcpy and memmove - -#ifdef _MSC_VER - #if _MSC_VER >= 1400 - // VC2005 workaround: disable declarations that conflict with winnt.h - #define _interlockedbittestandset CRYPTOPP_DISABLED_INTRINSIC_1 - #define _interlockedbittestandreset CRYPTOPP_DISABLED_INTRINSIC_2 - #define _interlockedbittestandset64 CRYPTOPP_DISABLED_INTRINSIC_3 - #define _interlockedbittestandreset64 CRYPTOPP_DISABLED_INTRINSIC_4 - #include <intrin.h> - #undef _interlockedbittestandset - #undef _interlockedbittestandreset - #undef _interlockedbittestandset64 - #undef _interlockedbittestandreset64 - #define CRYPTOPP_FAST_ROTATE(x) 1 - #elif _MSC_VER >= 1300 - #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64) - #else - #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32) - #endif -#elif (defined(__MWERKS__) && TARGET_CPU_PPC) || \ - (defined(__GNUC__) && (defined(_ARCH_PWR2) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_COM))) - #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32) -#elif defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86) // depend on GCC's peephole optimization to generate rotate instructions - #define CRYPTOPP_FAST_ROTATE(x) 1 -#else - #define CRYPTOPP_FAST_ROTATE(x) 0 -#endif - -#ifdef __BORLANDC__ -#include <mem.h> -#endif - -#if defined(__GNUC__) && defined(__linux__) -#define CRYPTOPP_BYTESWAP_AVAILABLE -#include <byteswap.h> -#endif - -NAMESPACE_BEGIN(CryptoPP) - -// ************** compile-time assertion *************** - -template <bool b> -struct CompileAssert -{ - static char dummy[2*b-1]; -}; - -#define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__) -#if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS) -#define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) -#else -#define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) static CompileAssert<(assertion)> CRYPTOPP_ASSERT_JOIN(cryptopp_assert_, instance) -#endif -#define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y) -#define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y - -// ************** misc classes *************** - -class CRYPTOPP_DLL Empty -{ -}; - -//! _ -template <class BASE1, class BASE2> -class CRYPTOPP_NO_VTABLE TwoBases : public BASE1, public BASE2 -{ -}; - -//! _ -template <class BASE1, class BASE2, class BASE3> -class CRYPTOPP_NO_VTABLE ThreeBases : public BASE1, public BASE2, public BASE3 -{ -}; - -template <class T> -class ObjectHolder -{ -protected: - T m_object; -}; - -class NotCopyable -{ -public: - NotCopyable() {} -private: - NotCopyable(const NotCopyable &); - void operator=(const NotCopyable &); -}; - -template <class T> -struct NewObject -{ - T* operator()() const {return new T;} -}; - -/*! This function safely initializes a static object in a multithreaded environment without using locks (for portability). - Note that if two threads call Ref() at the same time, they may get back different references, and one object - may end up being memory leaked. This is by design. -*/ -template <class T, class F = NewObject<T>, int instance=0> -class Singleton -{ -public: - Singleton(F objectFactory = F()) : m_objectFactory(objectFactory) {} - - // prevent this function from being inlined - CRYPTOPP_NOINLINE const T & Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const; - -private: - F m_objectFactory; -}; - -template <class T, class F, int instance> -const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const -{ - static volatile simple_ptr<T> s_pObject; - T *p = s_pObject.m_p; - - if (p) - return *p; - - T *newObject = m_objectFactory(); - p = s_pObject.m_p; - - if (p) - { - delete newObject; - return *p; - } - - s_pObject.m_p = newObject; - return *newObject; -} - -// ************** misc functions *************** - -#if (!__STDC_WANT_SECURE_LIB__ && !defined(_MEMORY_S_DEFINED)) -inline void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count) -{ - if (count > sizeInBytes) - throw InvalidArgument("memcpy_s: buffer overflow"); - memcpy(dest, src, count); -} - -inline void memmove_s(void *dest, size_t sizeInBytes, const void *src, size_t count) -{ - if (count > sizeInBytes) - throw InvalidArgument("memmove_s: buffer overflow"); - memmove(dest, src, count); -} - -#if __BORLANDC__ >= 0x620 -// C++Builder 2010 workaround: can't use std::memcpy_s because it doesn't allow 0 lengths -#define memcpy_s CryptoPP::memcpy_s -#define memmove_s CryptoPP::memmove_s -#endif -#endif - -inline void * memset_z(void *ptr, int value, size_t num) -{ -// avoid extranous warning on GCC 4.3.2 Ubuntu 8.10 -#if CRYPTOPP_GCC_VERSION >= 30001 - if (__builtin_constant_p(num) && num==0) - return ptr; -#endif - return memset(ptr, value, num); -} - -// can't use std::min or std::max in MSVC60 or Cygwin 1.1.0 -template <class T> inline const T& STDMIN(const T& a, const T& b) -{ - return b < a ? b : a; -} - -template <class T1, class T2> inline const T1 UnsignedMin(const T1& a, const T2& b) -{ - CRYPTOPP_COMPILE_ASSERT((sizeof(T1)<=sizeof(T2) && T2(-1)>0) || (sizeof(T1)>sizeof(T2) && T1(-1)>0)); - assert(a==0 || a>0); // GCC workaround: get rid of the warning "comparison is always true due to limited range of data type" - assert(b>=0); - - if (sizeof(T1)<=sizeof(T2)) - return b < (T2)a ? (T1)b : a; - else - return (T1)b < a ? (T1)b : a; -} - -template <class T> inline const T& STDMAX(const T& a, const T& b) -{ - return a < b ? b : a; -} - -#define RETURN_IF_NONZERO(x) size_t returnedValue = x; if (returnedValue) return returnedValue - -// this version of the macro is fastest on Pentium 3 and Pentium 4 with MSVC 6 SP5 w/ Processor Pack -#define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y))) -// these may be faster on other CPUs/compilers -// #define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255) -// #define GETBYTE(x, y) (((byte *)&(x))[y]) - -#define CRYPTOPP_GET_BYTE_AS_BYTE(x, y) byte((x)>>(8*(y))) - -template <class T> -unsigned int Parity(T value) -{ - for (unsigned int i=8*sizeof(value)/2; i>0; i/=2) - value ^= value >> i; - return (unsigned int)value&1; -} - -template <class T> -unsigned int BytePrecision(const T &value) -{ - if (!value) - return 0; - - unsigned int l=0, h=8*sizeof(value); - - while (h-l > 8) - { - unsigned int t = (l+h)/2; - if (value >> t) - l = t; - else - h = t; - } - - return h/8; -} - -template <class T> -unsigned int BitPrecision(const T &value) -{ - if (!value) - return 0; - - unsigned int l=0, h=8*sizeof(value); - - while (h-l > 1) - { - unsigned int t = (l+h)/2; - if (value >> t) - l = t; - else - h = t; - } - - return h; -} - -inline unsigned int TrailingZeros(word32 v) -{ -#if defined(__GNUC__) && CRYPTOPP_GCC_VERSION >= 30400 - return __builtin_ctz(v); -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - unsigned long result; - _BitScanForward(&result, v); - return result; -#else - // from http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup - static const int MultiplyDeBruijnBitPosition[32] = - { - 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, - 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 - }; - return MultiplyDeBruijnBitPosition[((word32)((v & -v) * 0x077CB531U)) >> 27]; -#endif -} - -inline unsigned int TrailingZeros(word64 v) -{ -#if defined(__GNUC__) && CRYPTOPP_GCC_VERSION >= 30400 - return __builtin_ctzll(v); -#elif defined(_MSC_VER) && _MSC_VER >= 1400 && (defined(_M_X64) || defined(_M_IA64)) - unsigned long result; - _BitScanForward64(&result, v); - return result; -#else - return word32(v) ? TrailingZeros(word32(v)) : 32 + TrailingZeros(word32(v>>32)); -#endif -} - -template <class T> -inline T Crop(T value, size_t size) -{ - if (size < 8*sizeof(value)) - return T(value & ((T(1) << size) - 1)); - else - return value; -} - -template <class T1, class T2> -inline bool SafeConvert(T1 from, T2 &to) -{ - to = (T2)from; - if (from != to || (from > 0) != (to > 0)) - return false; - return true; -} - -inline size_t BitsToBytes(size_t bitCount) -{ - return ((bitCount+7)/(8)); -} - -inline size_t BytesToWords(size_t byteCount) -{ - return ((byteCount+WORD_SIZE-1)/WORD_SIZE); -} - -inline size_t BitsToWords(size_t bitCount) -{ - return ((bitCount+WORD_BITS-1)/(WORD_BITS)); -} - -inline size_t BitsToDwords(size_t bitCount) -{ - return ((bitCount+2*WORD_BITS-1)/(2*WORD_BITS)); -} - -CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *buf, const byte *mask, size_t count); -CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *output, const byte *input, const byte *mask, size_t count); - -CRYPTOPP_DLL bool CRYPTOPP_API VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count); - -template <class T> -inline bool IsPowerOf2(const T &n) -{ - return n > 0 && (n & (n-1)) == 0; -} - -template <class T1, class T2> -inline T2 ModPowerOf2(const T1 &a, const T2 &b) -{ - assert(IsPowerOf2(b)); - return T2(a) & (b-1); -} - -template <class T1, class T2> -inline T1 RoundDownToMultipleOf(const T1 &n, const T2 &m) -{ - if (IsPowerOf2(m)) - return n - ModPowerOf2(n, m); - else - return n - n%m; -} - -template <class T1, class T2> -inline T1 RoundUpToMultipleOf(const T1 &n, const T2 &m) -{ - if (n+m-1 < n) - throw InvalidArgument("RoundUpToMultipleOf: integer overflow"); - return RoundDownToMultipleOf(n+m-1, m); -} - -template <class T> -inline unsigned int GetAlignmentOf(T *dummy=NULL) // VC60 workaround -{ -#ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS - if (sizeof(T) < 16) - return 1; -#endif - -#if (_MSC_VER >= 1300) - return __alignof(T); -#elif defined(__GNUC__) - return __alignof__(T); -#elif CRYPTOPP_BOOL_SLOW_WORD64 - return UnsignedMin(4U, sizeof(T)); -#else - return sizeof(T); -#endif -} - -inline bool IsAlignedOn(const void *p, unsigned int alignment) -{ - return alignment==1 || (IsPowerOf2(alignment) ? ModPowerOf2((size_t)p, alignment) == 0 : (size_t)p % alignment == 0); -} - -template <class T> -inline bool IsAligned(const void *p, T *dummy=NULL) // VC60 workaround -{ - return IsAlignedOn(p, GetAlignmentOf<T>()); -} - -#ifdef IS_LITTLE_ENDIAN - typedef LittleEndian NativeByteOrder; -#else - typedef BigEndian NativeByteOrder; -#endif - -inline ByteOrder GetNativeByteOrder() -{ - return NativeByteOrder::ToEnum(); -} - -inline bool NativeByteOrderIs(ByteOrder order) -{ - return order == GetNativeByteOrder(); -} - -template <class T> -std::string IntToString(T a, unsigned int base = 10) -{ - if (a == 0) - return "0"; - bool negate = false; - if (a < 0) - { - negate = true; - a = 0-a; // VC .NET does not like -a - } - std::string result; - while (a > 0) - { - T digit = a % base; - result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result; - a /= base; - } - if (negate) - result = "-" + result; - return result; -} - -template <class T1, class T2> -inline T1 SaturatingSubtract(const T1 &a, const T2 &b) -{ - return T1((a > b) ? (a - b) : 0); -} - -template <class T> -inline CipherDir GetCipherDir(const T &obj) -{ - return obj.IsForwardTransformation() ? ENCRYPTION : DECRYPTION; -} - -CRYPTOPP_DLL void CRYPTOPP_API CallNewHandler(); - -inline void IncrementCounterByOne(byte *inout, unsigned int s) -{ - for (int i=s-1, carry=1; i>=0 && carry; i--) - carry = !++inout[i]; -} - -inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int s) -{ - int i, carry; - for (i=s-1, carry=1; i>=0 && carry; i--) - carry = ((output[i] = input[i]+1) == 0); - memcpy_s(output, s, input, i+1); -} - -template <class T> -inline void ConditionalSwap(bool c, T &a, T &b) -{ - T t = c * (a ^ b); - a ^= t; - b ^= t; -} - -template <class T> -inline void ConditionalSwapPointers(bool c, T &a, T &b) -{ - ptrdiff_t t = c * (a - b); - a -= t; - b += t; -} - -// see http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/protect-secrets.html -// and https://www.securecoding.cert.org/confluence/display/cplusplus/MSC06-CPP.+Be+aware+of+compiler+optimization+when+dealing+with+sensitive+data -template <class T> -void SecureWipeBuffer(T *buf, size_t n) -{ - // GCC 4.3.2 on Cygwin optimizes away the first store if this loop is done in the forward direction - volatile T *p = buf+n; - while (n--) - *(--p) = 0; -} - -#if (_MSC_VER >= 1400 || defined(__GNUC__)) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86) - -template<> inline void SecureWipeBuffer(byte *buf, size_t n) -{ - volatile byte *p = buf; -#ifdef __GNUC__ - asm volatile("rep stosb" : "+c"(n), "+D"(p) : "a"(0) : "memory"); -#else - __stosb((byte *)(size_t)p, 0, n); -#endif -} - -template<> inline void SecureWipeBuffer(word16 *buf, size_t n) -{ - volatile word16 *p = buf; -#ifdef __GNUC__ - asm volatile("rep stosw" : "+c"(n), "+D"(p) : "a"(0) : "memory"); -#else - __stosw((word16 *)(size_t)p, 0, n); -#endif -} - -template<> inline void SecureWipeBuffer(word32 *buf, size_t n) -{ - volatile word32 *p = buf; -#ifdef __GNUC__ - asm volatile("rep stosl" : "+c"(n), "+D"(p) : "a"(0) : "memory"); -#else - __stosd((unsigned long *)(size_t)p, 0, n); -#endif -} - -template<> inline void SecureWipeBuffer(word64 *buf, size_t n) -{ -#if CRYPTOPP_BOOL_X64 - volatile word64 *p = buf; -#ifdef __GNUC__ - asm volatile("rep stosq" : "+c"(n), "+D"(p) : "a"(0) : "memory"); -#else - __stosq((word64 *)(size_t)p, 0, n); -#endif -#else - SecureWipeBuffer((word32 *)buf, 2*n); -#endif -} - -#endif // #if (_MSC_VER >= 1400 || defined(__GNUC__)) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86) - -template <class T> -inline void SecureWipeArray(T *buf, size_t n) -{ - if (sizeof(T) % 8 == 0 && GetAlignmentOf<T>() % GetAlignmentOf<word64>() == 0) - SecureWipeBuffer((word64 *)buf, n * (sizeof(T)/8)); - else if (sizeof(T) % 4 == 0 && GetAlignmentOf<T>() % GetAlignmentOf<word32>() == 0) - SecureWipeBuffer((word32 *)buf, n * (sizeof(T)/4)); - else if (sizeof(T) % 2 == 0 && GetAlignmentOf<T>() % GetAlignmentOf<word16>() == 0) - SecureWipeBuffer((word16 *)buf, n * (sizeof(T)/2)); - else - SecureWipeBuffer((byte *)buf, n * sizeof(T)); -} - -// this function uses wcstombs(), which assumes that setlocale() has been called -inline std::string StringNarrow(const wchar_t *str, bool throwOnError = true) -{ -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4996) // 'wcstombs': This function or variable may be unsafe. -#endif - size_t size = wcstombs(NULL, str, 0); - if (size == size_t(0)-1) - { - if (throwOnError) - throw InvalidArgument("StringNarrow: wcstombs() call failed"); - else - return std::string(); - } - std::string result(size, 0); - wcstombs(&result[0], str, size); - return result; -#ifdef _MSC_VER -#pragma warning(pop) -#endif -} - -#if CRYPTOPP_BOOL_ALIGN16_ENABLED -CRYPTOPP_DLL void * CRYPTOPP_API AlignedAllocate(size_t size); -CRYPTOPP_DLL void CRYPTOPP_API AlignedDeallocate(void *p); -#endif - -CRYPTOPP_DLL void * CRYPTOPP_API UnalignedAllocate(size_t size); -CRYPTOPP_DLL void CRYPTOPP_API UnalignedDeallocate(void *p); - -// ************** rotate functions *************** - -template <class T> inline T rotlFixed(T x, unsigned int y) -{ - assert(y < sizeof(T)*8); - return y ? T((x<<y) | (x>>(sizeof(T)*8-y))) : x; -} - -template <class T> inline T rotrFixed(T x, unsigned int y) -{ - assert(y < sizeof(T)*8); - return y ? T((x>>y) | (x<<(sizeof(T)*8-y))) : x; -} - -template <class T> inline T rotlVariable(T x, unsigned int y) -{ - assert(y < sizeof(T)*8); - return T((x<<y) | (x>>(sizeof(T)*8-y))); -} - -template <class T> inline T rotrVariable(T x, unsigned int y) -{ - assert(y < sizeof(T)*8); - return T((x>>y) | (x<<(sizeof(T)*8-y))); -} - -template <class T> inline T rotlMod(T x, unsigned int y) -{ - y %= sizeof(T)*8; - return T((x<<y) | (x>>(sizeof(T)*8-y))); -} - -template <class T> inline T rotrMod(T x, unsigned int y) -{ - y %= sizeof(T)*8; - return T((x>>y) | (x<<(sizeof(T)*8-y))); -} - -#ifdef _MSC_VER - -template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return y ? _lrotl(x, y) : x; -} - -template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return y ? _lrotr(x, y) : x; -} - -template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return _lrotl(x, y); -} - -template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return _lrotr(x, y); -} - -template<> inline word32 rotlMod<word32>(word32 x, unsigned int y) -{ - return _lrotl(x, y); -} - -template<> inline word32 rotrMod<word32>(word32 x, unsigned int y) -{ - return _lrotr(x, y); -} - -#endif // #ifdef _MSC_VER - -#if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) -// Intel C++ Compiler 10.0 calls a function instead of using the rotate instruction when using these instructions - -template<> inline word64 rotlFixed<word64>(word64 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return y ? _rotl64(x, y) : x; -} - -template<> inline word64 rotrFixed<word64>(word64 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return y ? _rotr64(x, y) : x; -} - -template<> inline word64 rotlVariable<word64>(word64 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return _rotl64(x, y); -} - -template<> inline word64 rotrVariable<word64>(word64 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return _rotr64(x, y); -} - -template<> inline word64 rotlMod<word64>(word64 x, unsigned int y) -{ - return _rotl64(x, y); -} - -template<> inline word64 rotrMod<word64>(word64 x, unsigned int y) -{ - return _rotr64(x, y); -} - -#endif // #if _MSC_VER >= 1310 - -#if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER) -// Intel C++ Compiler 10.0 gives undefined externals with these - -template<> inline word16 rotlFixed<word16>(word16 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return y ? _rotl16(x, y) : x; -} - -template<> inline word16 rotrFixed<word16>(word16 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return y ? _rotr16(x, y) : x; -} - -template<> inline word16 rotlVariable<word16>(word16 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return _rotl16(x, y); -} - -template<> inline word16 rotrVariable<word16>(word16 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return _rotr16(x, y); -} - -template<> inline word16 rotlMod<word16>(word16 x, unsigned int y) -{ - return _rotl16(x, y); -} - -template<> inline word16 rotrMod<word16>(word16 x, unsigned int y) -{ - return _rotr16(x, y); -} - -template<> inline byte rotlFixed<byte>(byte x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return y ? _rotl8(x, y) : x; -} - -template<> inline byte rotrFixed<byte>(byte x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return y ? _rotr8(x, y) : x; -} - -template<> inline byte rotlVariable<byte>(byte x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return _rotl8(x, y); -} - -template<> inline byte rotrVariable<byte>(byte x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return _rotr8(x, y); -} - -template<> inline byte rotlMod<byte>(byte x, unsigned int y) -{ - return _rotl8(x, y); -} - -template<> inline byte rotrMod<byte>(byte x, unsigned int y) -{ - return _rotr8(x, y); -} - -#endif // #if _MSC_VER >= 1400 - -#if (defined(__MWERKS__) && TARGET_CPU_PPC) - -template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y) -{ - assert(y < 32); - return y ? __rlwinm(x,y,0,31) : x; -} - -template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y) -{ - assert(y < 32); - return y ? __rlwinm(x,32-y,0,31) : x; -} - -template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y) -{ - assert(y < 32); - return (__rlwnm(x,y,0,31)); -} - -template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y) -{ - assert(y < 32); - return (__rlwnm(x,32-y,0,31)); -} - -template<> inline word32 rotlMod<word32>(word32 x, unsigned int y) -{ - return (__rlwnm(x,y,0,31)); -} - -template<> inline word32 rotrMod<word32>(word32 x, unsigned int y) -{ - return (__rlwnm(x,32-y,0,31)); -} - -#endif // #if (defined(__MWERKS__) && TARGET_CPU_PPC) - -// ************** endian reversal *************** - -template <class T> -inline unsigned int GetByte(ByteOrder order, T value, unsigned int index) -{ - if (order == LITTLE_ENDIAN_ORDER) - return GETBYTE(value, index); - else - return GETBYTE(value, sizeof(T)-index-1); -} - -inline byte ByteReverse(byte value) -{ - return value; -} - -inline word16 ByteReverse(word16 value) -{ -#ifdef CRYPTOPP_BYTESWAP_AVAILABLE - return bswap_16(value); -#elif defined(_MSC_VER) && _MSC_VER >= 1300 - return _byteswap_ushort(value); -#else - return rotlFixed(value, 8U); -#endif -} - -inline word32 ByteReverse(word32 value) -{ -#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) - __asm__ ("bswap %0" : "=r" (value) : "0" (value)); - return value; -#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE) - return bswap_32(value); -#elif defined(__MWERKS__) && TARGET_CPU_PPC - return (word32)__lwbrx(&value,0); -#elif _MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL)) - return _byteswap_ulong(value); -#elif CRYPTOPP_FAST_ROTATE(32) - // 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 -} - -inline word64 ByteReverse(word64 value) -{ -#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__x86_64__) - __asm__ ("bswap %0" : "=r" (value) : "0" (value)); - return value; -#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE) - return bswap_64(value); -#elif defined(_MSC_VER) && _MSC_VER >= 1300 - return _byteswap_uint64(value); -#elif CRYPTOPP_BOOL_SLOW_WORD64 - return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32)); -#else - value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8); - value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16); - return rotlFixed(value, 32U); -#endif -} - -inline byte BitReverse(byte value) -{ - value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1); - value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2); - return rotlFixed(value, 4U); -} - -inline word16 BitReverse(word16 value) -{ - value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1); - value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2); - value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4); - return ByteReverse(value); -} - -inline word32 BitReverse(word32 value) -{ - value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1); - value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2); - value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4); - return ByteReverse(value); -} - -inline word64 BitReverse(word64 value) -{ -#if CRYPTOPP_BOOL_SLOW_WORD64 - return (word64(BitReverse(word32(value))) << 32) | BitReverse(word32(value>>32)); -#else - value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1); - value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2); - value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4); - return ByteReverse(value); -#endif -} - -template <class T> -inline T BitReverse(T value) -{ - if (sizeof(T) == 1) - return (T)BitReverse((byte)value); - else if (sizeof(T) == 2) - return (T)BitReverse((word16)value); - else if (sizeof(T) == 4) - return (T)BitReverse((word32)value); - else - { - assert(sizeof(T) == 8); - return (T)BitReverse((word64)value); - } -} - -template <class T> -inline T ConditionalByteReverse(ByteOrder order, T value) -{ - return NativeByteOrderIs(order) ? value : ByteReverse(value); -} - -template <class T> -void ByteReverse(T *out, const T *in, size_t byteCount) -{ - assert(byteCount % sizeof(T) == 0); - size_t count = byteCount/sizeof(T); - for (size_t i=0; i<count; i++) - out[i] = ByteReverse(in[i]); -} - -template <class T> -inline void ConditionalByteReverse(ByteOrder order, T *out, const T *in, size_t byteCount) -{ - if (!NativeByteOrderIs(order)) - ByteReverse(out, in, byteCount); - else if (in != out) - memcpy_s(out, byteCount, in, byteCount); -} - -template <class T> -inline void GetUserKey(ByteOrder order, T *out, size_t outlen, const byte *in, size_t inlen) -{ - const size_t U = sizeof(T); - assert(inlen <= outlen*U); - memcpy_s(out, outlen*U, in, inlen); - memset_z((byte *)out+inlen, 0, outlen*U-inlen); - ConditionalByteReverse(order, out, out, RoundUpToMultipleOf(inlen, U)); -} - -#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS -inline byte UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const byte *) -{ - return block[0]; -} - -inline word16 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word16 *) -{ - return (order == BIG_ENDIAN_ORDER) - ? block[1] | (block[0] << 8) - : block[0] | (block[1] << 8); -} - -inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word32 *) -{ - return (order == BIG_ENDIAN_ORDER) - ? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16) | (word32(block[0]) << 24) - : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24); -} - -inline word64 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word64 *) -{ - return (order == BIG_ENDIAN_ORDER) - ? - (word64(block[7]) | - (word64(block[6]) << 8) | - (word64(block[5]) << 16) | - (word64(block[4]) << 24) | - (word64(block[3]) << 32) | - (word64(block[2]) << 40) | - (word64(block[1]) << 48) | - (word64(block[0]) << 56)) - : - (word64(block[0]) | - (word64(block[1]) << 8) | - (word64(block[2]) << 16) | - (word64(block[3]) << 24) | - (word64(block[4]) << 32) | - (word64(block[5]) << 40) | - (word64(block[6]) << 48) | - (word64(block[7]) << 56)); -} - -inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, byte value, const byte *xorBlock) -{ - block[0] = xorBlock ? (value ^ xorBlock[0]) : value; -} - -inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word16 value, const byte *xorBlock) -{ - if (order == BIG_ENDIAN_ORDER) - { - if (xorBlock) - { - block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - } - else - { - block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - } - } - else - { - if (xorBlock) - { - block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - } - else - { - block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - } - } -} - -inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word32 value, const byte *xorBlock) -{ - if (order == BIG_ENDIAN_ORDER) - { - if (xorBlock) - { - block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); - block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); - block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - } - else - { - block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); - block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); - block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - } - } - else - { - if (xorBlock) - { - block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); - block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); - } - else - { - block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); - block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); - } - } -} - -inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word64 value, const byte *xorBlock) -{ - if (order == BIG_ENDIAN_ORDER) - { - if (xorBlock) - { - block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7); - block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6); - block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5); - block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4); - block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); - block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); - block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - } - else - { - block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7); - block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6); - block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5); - block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4); - block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); - block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); - block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - } - } - else - { - if (xorBlock) - { - block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); - block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); - block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4); - block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5); - block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6); - block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7); - } - else - { - block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); - block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); - block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4); - block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5); - block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6); - block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7); - } - } -} -#endif // #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS - -template <class T> -inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block) -{ -#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS - if (!assumeAligned) - return UnalignedGetWordNonTemplate(order, block, (T*)NULL); - assert(IsAligned<T>(block)); -#endif - return ConditionalByteReverse(order, *reinterpret_cast<const T *>(block)); -} - -template <class T> -inline void GetWord(bool assumeAligned, ByteOrder order, T &result, const byte *block) -{ - result = GetWord<T>(assumeAligned, order, block); -} - -template <class T> -inline void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock = NULL) -{ -#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS - if (!assumeAligned) - return UnalignedPutWordNonTemplate(order, block, value, xorBlock); - assert(IsAligned<T>(block)); - assert(IsAligned<T>(xorBlock)); -#endif - *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value) ^ (xorBlock ? *reinterpret_cast<const T *>(xorBlock) : 0); -} - -template <class T, class B, bool A=false> -class GetBlock -{ -public: - GetBlock(const void *block) - : m_block((const byte *)block) {} - - template <class U> - inline GetBlock<T, B, A> & operator()(U &x) - { - CRYPTOPP_COMPILE_ASSERT(sizeof(U) >= sizeof(T)); - x = GetWord<T>(A, B::ToEnum(), m_block); - m_block += sizeof(T); - return *this; - } - -private: - const byte *m_block; -}; - -template <class T, class B, bool A=false> -class PutBlock -{ -public: - PutBlock(const void *xorBlock, void *block) - : m_xorBlock((const byte *)xorBlock), m_block((byte *)block) {} - - template <class U> - inline PutBlock<T, B, A> & operator()(U x) - { - PutWord(A, B::ToEnum(), m_block, (T)x, m_xorBlock); - m_block += sizeof(T); - if (m_xorBlock) - m_xorBlock += sizeof(T); - return *this; - } - -private: - const byte *m_xorBlock; - byte *m_block; -}; - -template <class T, class B, bool GA=false, bool PA=false> -struct BlockGetAndPut -{ - // function needed because of C++ grammatical ambiguity between expression-statements and declarations - static inline GetBlock<T, B, GA> Get(const void *block) {return GetBlock<T, B, GA>(block);} - typedef PutBlock<T, B, PA> Put; -}; - -template <class T> -std::string WordToString(T value, ByteOrder order = BIG_ENDIAN_ORDER) -{ - if (!NativeByteOrderIs(order)) - value = ByteReverse(value); - - return std::string((char *)&value, sizeof(value)); -} - -template <class T> -T StringToWord(const std::string &str, ByteOrder order = BIG_ENDIAN_ORDER) -{ - T value = 0; - memcpy_s(&value, sizeof(value), str.data(), UnsignedMin(str.size(), sizeof(value))); - return NativeByteOrderIs(order) ? value : ByteReverse(value); -} - -// ************** help remove warning on g++ *************** - -template <bool overflow> struct SafeShifter; - -template<> struct SafeShifter<true> -{ - template <class T> - static inline T RightShift(T value, unsigned int bits) - { - return 0; - } - - template <class T> - static inline T LeftShift(T value, unsigned int bits) - { - return 0; - } -}; - -template<> struct SafeShifter<false> -{ - template <class T> - static inline T RightShift(T value, unsigned int bits) - { - return value >> bits; - } - - template <class T> - static inline T LeftShift(T value, unsigned int bits) - { - return value << bits; - } -}; - -template <unsigned int bits, class T> -inline T SafeRightShift(T value) -{ - return SafeShifter<(bits>=(8*sizeof(T)))>::RightShift(value, bits); -} - -template <unsigned int bits, class T> -inline T SafeLeftShift(T value) -{ - return SafeShifter<(bits>=(8*sizeof(T)))>::LeftShift(value, bits); -} - -// ************** use one buffer for multiple data members *************** - -#define CRYPTOPP_BLOCK_1(n, t, s) t* m_##n() {return (t *)(m_aggregate+0);} size_t SS1() {return sizeof(t)*(s);} size_t m_##n##Size() {return (s);} -#define CRYPTOPP_BLOCK_2(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS1());} size_t SS2() {return SS1()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} -#define CRYPTOPP_BLOCK_3(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS2());} size_t SS3() {return SS2()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} -#define CRYPTOPP_BLOCK_4(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS3());} size_t SS4() {return SS3()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} -#define CRYPTOPP_BLOCK_5(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS4());} size_t SS5() {return SS4()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} -#define CRYPTOPP_BLOCK_6(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS5());} size_t SS6() {return SS5()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} -#define CRYPTOPP_BLOCK_7(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS6());} size_t SS7() {return SS6()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} -#define CRYPTOPP_BLOCK_8(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS7());} size_t SS8() {return SS7()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} -#define CRYPTOPP_BLOCKS_END(i) size_t SST() {return SS##i();} void AllocateBlocks() {m_aggregate.New(SST());} AlignedSecByteBlock m_aggregate; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/modarith.h b/lib/cryptopp/modarith.h deleted file mode 100644 index c0368e3fb..000000000 --- a/lib/cryptopp/modarith.h +++ /dev/null @@ -1,158 +0,0 @@ -#ifndef CRYPTOPP_MODARITH_H -#define CRYPTOPP_MODARITH_H - -// implementations are in integer.cpp - -#include "cryptlib.h" -#include "misc.h" -#include "integer.h" -#include "algebra.h" - -NAMESPACE_BEGIN(CryptoPP) - -CRYPTOPP_DLL_TEMPLATE_CLASS AbstractGroup<Integer>; -CRYPTOPP_DLL_TEMPLATE_CLASS AbstractRing<Integer>; -CRYPTOPP_DLL_TEMPLATE_CLASS AbstractEuclideanDomain<Integer>; - -//! ring of congruence classes modulo n -/*! \note this implementation represents each congruence class as the smallest non-negative integer in that class */ -class CRYPTOPP_DLL ModularArithmetic : public AbstractRing<Integer> -{ -public: - - typedef int RandomizationParameter; - typedef Integer Element; - - ModularArithmetic(const Integer &modulus = Integer::One()) - : m_modulus(modulus), m_result((word)0, modulus.reg.size()) {} - - ModularArithmetic(const ModularArithmetic &ma) - : m_modulus(ma.m_modulus), m_result((word)0, m_modulus.reg.size()) {} - - ModularArithmetic(BufferedTransformation &bt); // construct from BER encoded parameters - - virtual ModularArithmetic * Clone() const {return new ModularArithmetic(*this);} - - void DEREncode(BufferedTransformation &bt) const; - - void DEREncodeElement(BufferedTransformation &out, const Element &a) const; - void BERDecodeElement(BufferedTransformation &in, Element &a) const; - - const Integer& GetModulus() const {return m_modulus;} - void SetModulus(const Integer &newModulus) {m_modulus = newModulus; m_result.reg.resize(m_modulus.reg.size());} - - virtual bool IsMontgomeryRepresentation() const {return false;} - - virtual Integer ConvertIn(const Integer &a) const - {return a%m_modulus;} - - virtual Integer ConvertOut(const Integer &a) const - {return a;} - - const Integer& Half(const Integer &a) const; - - bool Equal(const Integer &a, const Integer &b) const - {return a==b;} - - const Integer& Identity() const - {return Integer::Zero();} - - const Integer& Add(const Integer &a, const Integer &b) const; - - Integer& Accumulate(Integer &a, const Integer &b) const; - - const Integer& Inverse(const Integer &a) const; - - const Integer& Subtract(const Integer &a, const Integer &b) const; - - Integer& Reduce(Integer &a, const Integer &b) const; - - const Integer& Double(const Integer &a) const - {return Add(a, a);} - - const Integer& MultiplicativeIdentity() const - {return Integer::One();} - - const Integer& Multiply(const Integer &a, const Integer &b) const - {return m_result1 = a*b%m_modulus;} - - const Integer& Square(const Integer &a) const - {return m_result1 = a.Squared()%m_modulus;} - - bool IsUnit(const Integer &a) const - {return Integer::Gcd(a, m_modulus).IsUnit();} - - const Integer& MultiplicativeInverse(const Integer &a) const - {return m_result1 = a.InverseMod(m_modulus);} - - const Integer& Divide(const Integer &a, const Integer &b) const - {return Multiply(a, MultiplicativeInverse(b));} - - Integer CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const; - - void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; - - unsigned int MaxElementBitLength() const - {return (m_modulus-1).BitCount();} - - unsigned int MaxElementByteLength() const - {return (m_modulus-1).ByteCount();} - - Element RandomElement( RandomNumberGenerator &rng , const RandomizationParameter &ignore_for_now = 0 ) const - // left RandomizationParameter arg as ref in case RandomizationParameter becomes a more complicated struct - { - return Element( rng , Integer( (long) 0) , m_modulus - Integer( (long) 1 ) ) ; - } - - bool operator==(const ModularArithmetic &rhs) const - {return m_modulus == rhs.m_modulus;} - - static const RandomizationParameter DefaultRandomizationParameter ; - -protected: - Integer m_modulus; - mutable Integer m_result, m_result1; - -}; - -// const ModularArithmetic::RandomizationParameter ModularArithmetic::DefaultRandomizationParameter = 0 ; - -//! do modular arithmetics in Montgomery representation for increased speed -/*! \note the Montgomery representation represents each congruence class [a] as a*r%n, where r is a convenient power of 2 */ -class CRYPTOPP_DLL MontgomeryRepresentation : public ModularArithmetic -{ -public: - MontgomeryRepresentation(const Integer &modulus); // modulus must be odd - - virtual ModularArithmetic * Clone() const {return new MontgomeryRepresentation(*this);} - - bool IsMontgomeryRepresentation() const {return true;} - - Integer ConvertIn(const Integer &a) const - {return (a<<(WORD_BITS*m_modulus.reg.size()))%m_modulus;} - - Integer ConvertOut(const Integer &a) const; - - const Integer& MultiplicativeIdentity() const - {return m_result1 = Integer::Power2(WORD_BITS*m_modulus.reg.size())%m_modulus;} - - const Integer& Multiply(const Integer &a, const Integer &b) const; - - const Integer& Square(const Integer &a) const; - - const Integer& MultiplicativeInverse(const Integer &a) const; - - Integer CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const - {return AbstractRing<Integer>::CascadeExponentiate(x, e1, y, e2);} - - void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const - {AbstractRing<Integer>::SimultaneousExponentiate(results, base, exponents, exponentsCount);} - -private: - Integer m_u; - mutable IntegerSecBlock m_workspace; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/modes.cpp b/lib/cryptopp/modes.cpp deleted file mode 100644 index 46332284b..000000000 --- a/lib/cryptopp/modes.cpp +++ /dev/null @@ -1,245 +0,0 @@ -// modes.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "modes.h" - -#ifndef NDEBUG -#include "des.h" -#endif - -NAMESPACE_BEGIN(CryptoPP) - -#ifndef NDEBUG -void Modes_TestInstantiations() -{ - CFB_Mode<DES>::Encryption m0; - CFB_Mode<DES>::Decryption m1; - OFB_Mode<DES>::Encryption m2; - CTR_Mode<DES>::Encryption m3; - ECB_Mode<DES>::Encryption m4; - CBC_Mode<DES>::Encryption m5; -} -#endif - -void CFB_ModePolicy::Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount) -{ - assert(m_cipher->IsForwardTransformation()); // CFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt - assert(m_feedbackSize == BlockSize()); - - unsigned int s = BlockSize(); - if (dir == ENCRYPTION) - { - m_cipher->ProcessAndXorBlock(m_register, input, output); - m_cipher->AdvancedProcessBlocks(output, input+s, output+s, (iterationCount-1)*s, 0); - memcpy(m_register, output+(iterationCount-1)*s, s); - } - else - { - memcpy(m_temp, input+(iterationCount-1)*s, s); // make copy first in case of in-place decryption - m_cipher->AdvancedProcessBlocks(input, input+s, output+s, (iterationCount-1)*s, BlockTransformation::BT_ReverseDirection); - m_cipher->ProcessAndXorBlock(m_register, input, output); - memcpy(m_register, m_temp, s); - } -} - -void CFB_ModePolicy::TransformRegister() -{ - assert(m_cipher->IsForwardTransformation()); // CFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt - m_cipher->ProcessBlock(m_register, m_temp); - unsigned int updateSize = BlockSize()-m_feedbackSize; - memmove_s(m_register, m_register.size(), m_register+m_feedbackSize, updateSize); - memcpy_s(m_register+updateSize, m_register.size()-updateSize, m_temp, m_feedbackSize); -} - -void CFB_ModePolicy::CipherResynchronize(const byte *iv, size_t length) -{ - assert(length == BlockSize()); - CopyOrZero(m_register, iv, length); - TransformRegister(); -} - -void CFB_ModePolicy::SetFeedbackSize(unsigned int feedbackSize) -{ - if (feedbackSize > BlockSize()) - throw InvalidArgument("CFB_Mode: invalid feedback size"); - m_feedbackSize = feedbackSize ? feedbackSize : BlockSize(); -} - -void CFB_ModePolicy::ResizeBuffers() -{ - CipherModeBase::ResizeBuffers(); - m_temp.New(BlockSize()); -} - -void OFB_ModePolicy::WriteKeystream(byte *keystreamBuffer, size_t iterationCount) -{ - assert(m_cipher->IsForwardTransformation()); // OFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt - unsigned int s = BlockSize(); - m_cipher->ProcessBlock(m_register, keystreamBuffer); - if (iterationCount > 1) - m_cipher->AdvancedProcessBlocks(keystreamBuffer, NULL, keystreamBuffer+s, s*(iterationCount-1), 0); - memcpy(m_register, keystreamBuffer+s*(iterationCount-1), s); -} - -void OFB_ModePolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length) -{ - assert(length == BlockSize()); - CopyOrZero(m_register, iv, length); -} - -void CTR_ModePolicy::SeekToIteration(lword iterationCount) -{ - int carry=0; - for (int i=BlockSize()-1; i>=0; i--) - { - unsigned int sum = m_register[i] + byte(iterationCount) + carry; - m_counterArray[i] = (byte) sum; - carry = sum >> 8; - iterationCount >>= 8; - } -} - -void CTR_ModePolicy::IncrementCounterBy256() -{ - IncrementCounterByOne(m_counterArray, BlockSize()-1); -} - -void CTR_ModePolicy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) -{ - assert(m_cipher->IsForwardTransformation()); // CTR mode needs the "encrypt" direction of the underlying block cipher, even to decrypt - unsigned int s = BlockSize(); - unsigned int inputIncrement = input ? s : 0; - - while (iterationCount) - { - byte lsb = m_counterArray[s-1]; - size_t blocks = UnsignedMin(iterationCount, 256U-lsb); - m_cipher->AdvancedProcessBlocks(m_counterArray, input, output, blocks*s, BlockTransformation::BT_InBlockIsCounter|BlockTransformation::BT_AllowParallel); - if ((m_counterArray[s-1] = lsb + (byte)blocks) == 0) - IncrementCounterBy256(); - - output += blocks*s; - input += blocks*inputIncrement; - iterationCount -= blocks; - } -} - -void CTR_ModePolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length) -{ - assert(length == BlockSize()); - CopyOrZero(m_register, iv, length); - m_counterArray = m_register; -} - -void BlockOrientedCipherModeBase::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) -{ - m_cipher->SetKey(key, length, params); - ResizeBuffers(); - if (IsResynchronizable()) - { - size_t ivLength; - const byte *iv = GetIVAndThrowIfInvalid(params, ivLength); - Resynchronize(iv, (int)ivLength); - } -} - -void ECB_OneWay::ProcessData(byte *outString, const byte *inString, size_t length) -{ - assert(length%BlockSize()==0); - m_cipher->AdvancedProcessBlocks(inString, NULL, outString, length, BlockTransformation::BT_AllowParallel); -} - -void CBC_Encryption::ProcessData(byte *outString, const byte *inString, size_t length) -{ - if (!length) - return; - assert(length%BlockSize()==0); - - unsigned int blockSize = BlockSize(); - m_cipher->AdvancedProcessBlocks(inString, m_register, outString, blockSize, BlockTransformation::BT_XorInput); - if (length > blockSize) - m_cipher->AdvancedProcessBlocks(inString+blockSize, outString, outString+blockSize, length-blockSize, BlockTransformation::BT_XorInput); - memcpy(m_register, outString + length - blockSize, blockSize); -} - -void CBC_CTS_Encryption::ProcessLastBlock(byte *outString, const byte *inString, size_t length) -{ - if (length <= BlockSize()) - { - if (!m_stolenIV) - throw InvalidArgument("CBC_Encryption: message is too short for ciphertext stealing"); - - // steal from IV - memcpy(outString, m_register, length); - outString = m_stolenIV; - } - else - { - // steal from next to last block - xorbuf(m_register, inString, BlockSize()); - m_cipher->ProcessBlock(m_register); - inString += BlockSize(); - length -= BlockSize(); - memcpy(outString+BlockSize(), m_register, length); - } - - // output last full ciphertext block - xorbuf(m_register, inString, length); - m_cipher->ProcessBlock(m_register); - memcpy(outString, m_register, BlockSize()); -} - -void CBC_Decryption::ProcessData(byte *outString, const byte *inString, size_t length) -{ - if (!length) - return; - assert(length%BlockSize()==0); - - unsigned int blockSize = BlockSize(); - memcpy(m_temp, inString+length-blockSize, blockSize); // save copy now in case of in-place decryption - if (length > blockSize) - m_cipher->AdvancedProcessBlocks(inString+blockSize, inString, outString+blockSize, length-blockSize, BlockTransformation::BT_ReverseDirection|BlockTransformation::BT_AllowParallel); - m_cipher->ProcessAndXorBlock(inString, m_register, outString); - m_register.swap(m_temp); -} - -void CBC_CTS_Decryption::ProcessLastBlock(byte *outString, const byte *inString, size_t length) -{ - const byte *pn, *pn1; - bool stealIV = length <= BlockSize(); - - if (stealIV) - { - pn = inString; - pn1 = m_register; - } - else - { - pn = inString + BlockSize(); - pn1 = inString; - length -= BlockSize(); - } - - // decrypt last partial plaintext block - memcpy(m_temp, pn1, BlockSize()); - m_cipher->ProcessBlock(m_temp); - xorbuf(m_temp, pn, length); - - if (stealIV) - memcpy(outString, m_temp, length); - else - { - memcpy(outString+BlockSize(), m_temp, length); - // decrypt next to last plaintext block - memcpy(m_temp, pn, length); - m_cipher->ProcessBlock(m_temp); - xorbuf(outString, m_temp, m_register, BlockSize()); - } -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/modes.h b/lib/cryptopp/modes.h deleted file mode 100644 index c0c30c476..000000000 --- a/lib/cryptopp/modes.h +++ /dev/null @@ -1,422 +0,0 @@ -#ifndef CRYPTOPP_MODES_H -#define CRYPTOPP_MODES_H - -/*! \file -*/ - -#include "cryptlib.h" -#include "secblock.h" -#include "misc.h" -#include "strciphr.h" -#include "argnames.h" -#include "algparam.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! Cipher modes documentation. See NIST SP 800-38A for definitions of these modes. See AuthenticatedSymmetricCipherDocumentation for authenticated encryption modes. - -/*! Each class derived from this one defines two types, Encryption and Decryption, - both of which implement the SymmetricCipher interface. - For each mode there are two classes, one of which is a template class, - and the other one has a name that ends in "_ExternalCipher". - The "external cipher" mode objects hold a reference to the underlying block cipher, - instead of holding an instance of it. The reference must be passed in to the constructor. - For the "cipher holder" classes, the CIPHER template parameter should be a class - derived from BlockCipherDocumentation, for example DES or AES. -*/ -struct CipherModeDocumentation : public SymmetricCipherDocumentation -{ -}; - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CipherModeBase : public SymmetricCipher -{ -public: - size_t MinKeyLength() const {return m_cipher->MinKeyLength();} - size_t MaxKeyLength() const {return m_cipher->MaxKeyLength();} - size_t DefaultKeyLength() const {return m_cipher->DefaultKeyLength();} - size_t GetValidKeyLength(size_t n) const {return m_cipher->GetValidKeyLength(n);} - bool IsValidKeyLength(size_t n) const {return m_cipher->IsValidKeyLength(n);} - - unsigned int OptimalDataAlignment() const {return m_cipher->OptimalDataAlignment();} - - unsigned int IVSize() const {return BlockSize();} - virtual IV_Requirement IVRequirement() const =0; - - void SetCipher(BlockCipher &cipher) - { - this->ThrowIfResynchronizable(); - this->m_cipher = &cipher; - this->ResizeBuffers(); - } - - void SetCipherWithIV(BlockCipher &cipher, const byte *iv, int feedbackSize = 0) - { - this->ThrowIfInvalidIV(iv); - this->m_cipher = &cipher; - this->ResizeBuffers(); - this->SetFeedbackSize(feedbackSize); - if (this->IsResynchronizable()) - this->Resynchronize(iv); - } - -protected: - CipherModeBase() : m_cipher(NULL) {} - inline unsigned int BlockSize() const {assert(m_register.size() > 0); return (unsigned int)m_register.size();} - virtual void SetFeedbackSize(unsigned int feedbackSize) - { - if (!(feedbackSize == 0 || feedbackSize == BlockSize())) - throw InvalidArgument("CipherModeBase: feedback size cannot be specified for this cipher mode"); - } - virtual void ResizeBuffers() - { - m_register.New(m_cipher->BlockSize()); - } - - BlockCipher *m_cipher; - AlignedSecByteBlock m_register; -}; - -template <class POLICY_INTERFACE> -class CRYPTOPP_NO_VTABLE ModePolicyCommonTemplate : public CipherModeBase, public POLICY_INTERFACE -{ - unsigned int GetAlignment() const {return m_cipher->OptimalDataAlignment();} - void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); -}; - -template <class POLICY_INTERFACE> -void ModePolicyCommonTemplate<POLICY_INTERFACE>::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) -{ - m_cipher->SetKey(key, length, params); - ResizeBuffers(); - int feedbackSize = params.GetIntValueWithDefault(Name::FeedbackSize(), 0); - SetFeedbackSize(feedbackSize); -} - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_ModePolicy : public ModePolicyCommonTemplate<CFB_CipherAbstractPolicy> -{ -public: - IV_Requirement IVRequirement() const {return RANDOM_IV;} - static const char * CRYPTOPP_API StaticAlgorithmName() {return "CFB";} - -protected: - unsigned int GetBytesPerIteration() const {return m_feedbackSize;} - byte * GetRegisterBegin() {return m_register + BlockSize() - m_feedbackSize;} - bool CanIterate() const {return m_feedbackSize == BlockSize();} - void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount); - void TransformRegister(); - void CipherResynchronize(const byte *iv, size_t length); - void SetFeedbackSize(unsigned int feedbackSize); - void ResizeBuffers(); - - SecByteBlock m_temp; - unsigned int m_feedbackSize; -}; - -inline void CopyOrZero(void *dest, const void *src, size_t s) -{ - if (src) - memcpy_s(dest, s, src, s); - else - memset(dest, 0, s); -} - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE OFB_ModePolicy : public ModePolicyCommonTemplate<AdditiveCipherAbstractPolicy> -{ -public: - bool CipherIsRandomAccess() const {return false;} - IV_Requirement IVRequirement() const {return UNIQUE_IV;} - static const char * CRYPTOPP_API StaticAlgorithmName() {return "OFB";} - -private: - unsigned int GetBytesPerIteration() const {return BlockSize();} - unsigned int GetIterationsToBuffer() const {return m_cipher->OptimalNumberOfParallelBlocks();} - void WriteKeystream(byte *keystreamBuffer, size_t iterationCount); - void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length); -}; - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CTR_ModePolicy : public ModePolicyCommonTemplate<AdditiveCipherAbstractPolicy> -{ -public: - bool CipherIsRandomAccess() const {return true;} - IV_Requirement IVRequirement() const {return RANDOM_IV;} - static const char * CRYPTOPP_API StaticAlgorithmName() {return "CTR";} - -protected: - virtual void IncrementCounterBy256(); - - unsigned int GetAlignment() const {return m_cipher->OptimalDataAlignment();} - unsigned int GetBytesPerIteration() const {return BlockSize();} - unsigned int GetIterationsToBuffer() const {return m_cipher->OptimalNumberOfParallelBlocks();} - void WriteKeystream(byte *buffer, size_t iterationCount) - {OperateKeystream(WRITE_KEYSTREAM, buffer, NULL, iterationCount);} - bool CanOperateKeystream() const {return true;} - void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); - void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length); - void SeekToIteration(lword iterationCount); - - AlignedSecByteBlock m_counterArray; -}; - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockOrientedCipherModeBase : public CipherModeBase -{ -public: - void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); - unsigned int MandatoryBlockSize() const {return BlockSize();} - bool IsRandomAccess() const {return false;} - bool IsSelfInverting() const {return false;} - bool IsForwardTransformation() const {return m_cipher->IsForwardTransformation();} - void Resynchronize(const byte *iv, int length=-1) {memcpy_s(m_register, m_register.size(), iv, ThrowIfInvalidIVLength(length));} - -protected: - bool RequireAlignedInput() const {return true;} - void ResizeBuffers() - { - CipherModeBase::ResizeBuffers(); - m_buffer.New(BlockSize()); - } - - SecByteBlock m_buffer; -}; - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ECB_OneWay : public BlockOrientedCipherModeBase -{ -public: - void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms = g_nullNameValuePairs) - {m_cipher->SetKey(key, length, params); BlockOrientedCipherModeBase::ResizeBuffers();} - IV_Requirement IVRequirement() const {return NOT_RESYNCHRONIZABLE;} - unsigned int OptimalBlockSize() const {return BlockSize() * m_cipher->OptimalNumberOfParallelBlocks();} - void ProcessData(byte *outString, const byte *inString, size_t length); - static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECB";} -}; - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_ModeBase : public BlockOrientedCipherModeBase -{ -public: - IV_Requirement IVRequirement() const {return UNPREDICTABLE_RANDOM_IV;} - bool RequireAlignedInput() const {return false;} - unsigned int MinLastBlockSize() const {return 0;} - static const char * CRYPTOPP_API StaticAlgorithmName() {return "CBC";} -}; - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_Encryption : public CBC_ModeBase -{ -public: - void ProcessData(byte *outString, const byte *inString, size_t length); -}; - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_CTS_Encryption : public CBC_Encryption -{ -public: - void SetStolenIV(byte *iv) {m_stolenIV = iv;} - unsigned int MinLastBlockSize() const {return BlockSize()+1;} - void ProcessLastBlock(byte *outString, const byte *inString, size_t length); - static const char * CRYPTOPP_API StaticAlgorithmName() {return "CBC/CTS";} - -protected: - void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) - { - CBC_Encryption::UncheckedSetKey(key, length, params); - m_stolenIV = params.GetValueWithDefault(Name::StolenIV(), (byte *)NULL); - } - - byte *m_stolenIV; -}; - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_Decryption : public CBC_ModeBase -{ -public: - void ProcessData(byte *outString, const byte *inString, size_t length); - -protected: - void ResizeBuffers() - { - BlockOrientedCipherModeBase::ResizeBuffers(); - m_temp.New(BlockSize()); - } - AlignedSecByteBlock m_temp; -}; - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_CTS_Decryption : public CBC_Decryption -{ -public: - unsigned int MinLastBlockSize() const {return BlockSize()+1;} - void ProcessLastBlock(byte *outString, const byte *inString, size_t length); -}; - -//! _ -template <class CIPHER, class BASE> -class CipherModeFinalTemplate_CipherHolder : protected ObjectHolder<CIPHER>, public AlgorithmImpl<BASE, CipherModeFinalTemplate_CipherHolder<CIPHER, BASE> > -{ -public: - CipherModeFinalTemplate_CipherHolder() - { - this->m_cipher = &this->m_object; - this->ResizeBuffers(); - } - CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length) - { - this->m_cipher = &this->m_object; - this->SetKey(key, length); - } - CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length, const byte *iv) - { - this->m_cipher = &this->m_object; - this->SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, this->m_cipher->BlockSize()))); - } - CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length, const byte *iv, int feedbackSize) - { - this->m_cipher = &this->m_object; - this->SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, this->m_cipher->BlockSize()))(Name::FeedbackSize(), feedbackSize)); - } - - static std::string CRYPTOPP_API StaticAlgorithmName() - {return CIPHER::StaticAlgorithmName() + "/" + BASE::StaticAlgorithmName();} -}; - -//! _ -template <class BASE> -class CipherModeFinalTemplate_ExternalCipher : public BASE -{ -public: - CipherModeFinalTemplate_ExternalCipher() {} - CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher) - {this->SetCipher(cipher);} - CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher, const byte *iv, int feedbackSize = 0) - {this->SetCipherWithIV(cipher, iv, feedbackSize);} - - std::string AlgorithmName() const - {return (this->m_cipher ? this->m_cipher->AlgorithmName() + "/" : std::string("")) + BASE::StaticAlgorithmName();} -}; - -CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >; -CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >; -CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >; - -//! CFB mode -template <class CIPHER> -struct CFB_Mode : public CipherModeDocumentation -{ - typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption; - typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption; -}; - -//! CFB mode, external cipher -struct CFB_Mode_ExternalCipher : public CipherModeDocumentation -{ - typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption; - typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption; -}; - -//! CFB mode FIPS variant, requiring full block plaintext according to FIPS 800-38A -template <class CIPHER> -struct CFB_FIPS_Mode : public CipherModeDocumentation -{ - typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Encryption; - typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Decryption; -}; - -//! CFB mode FIPS variant, requiring full block plaintext according to FIPS 800-38A, external cipher -struct CFB_FIPS_Mode_ExternalCipher : public CipherModeDocumentation -{ - typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Encryption; - typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_RequireFullDataBlocks<CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > > Decryption; -}; - -CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> >; - -//! OFB mode -template <class CIPHER> -struct OFB_Mode : public CipherModeDocumentation -{ - typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption; - typedef Encryption Decryption; -}; - -//! OFB mode, external cipher -struct OFB_Mode_ExternalCipher : public CipherModeDocumentation -{ - typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption; - typedef Encryption Decryption; -}; - -CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> >; -CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > >; - -//! CTR mode -template <class CIPHER> -struct CTR_Mode : public CipherModeDocumentation -{ - typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption; - typedef Encryption Decryption; -}; - -//! CTR mode, external cipher -struct CTR_Mode_ExternalCipher : public CipherModeDocumentation -{ - typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption; - typedef Encryption Decryption; -}; - -//! ECB mode -template <class CIPHER> -struct ECB_Mode : public CipherModeDocumentation -{ - typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ECB_OneWay> Encryption; - typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, ECB_OneWay> Decryption; -}; - -CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<ECB_OneWay>; - -//! ECB mode, external cipher -struct ECB_Mode_ExternalCipher : public CipherModeDocumentation -{ - typedef CipherModeFinalTemplate_ExternalCipher<ECB_OneWay> Encryption; - typedef Encryption Decryption; -}; - -//! CBC mode -template <class CIPHER> -struct CBC_Mode : public CipherModeDocumentation -{ - typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, CBC_Encryption> Encryption; - typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, CBC_Decryption> Decryption; -}; - -CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_Encryption>; -CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_Decryption>; - -//! CBC mode, external cipher -struct CBC_Mode_ExternalCipher : public CipherModeDocumentation -{ - typedef CipherModeFinalTemplate_ExternalCipher<CBC_Encryption> Encryption; - typedef CipherModeFinalTemplate_ExternalCipher<CBC_Decryption> Decryption; -}; - -//! CBC mode with ciphertext stealing -template <class CIPHER> -struct CBC_CTS_Mode : public CipherModeDocumentation -{ - typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, CBC_CTS_Encryption> Encryption; - typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, CBC_CTS_Decryption> Decryption; -}; - -CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption>; -CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption>; - -//! CBC mode with ciphertext stealing, external cipher -struct CBC_CTS_Mode_ExternalCipher : public CipherModeDocumentation -{ - typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption> Encryption; - typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption> Decryption; -}; - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY -typedef CFB_Mode_ExternalCipher::Encryption CFBEncryption; -typedef CFB_Mode_ExternalCipher::Decryption CFBDecryption; -typedef OFB_Mode_ExternalCipher::Encryption OFB; -typedef CTR_Mode_ExternalCipher::Encryption CounterMode; -#endif - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/modexppc.h b/lib/cryptopp/modexppc.h deleted file mode 100644 index fbe701279..000000000 --- a/lib/cryptopp/modexppc.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef CRYPTOPP_MODEXPPC_H -#define CRYPTOPP_MODEXPPC_H - -#include "modarith.h" -#include "eprecomp.h" -#include "smartptr.h" -#include "pubkey.h" - -NAMESPACE_BEGIN(CryptoPP) - -CRYPTOPP_DLL_TEMPLATE_CLASS DL_FixedBasePrecomputationImpl<Integer>; - -class ModExpPrecomputation : public DL_GroupPrecomputation<Integer> -{ -public: - // DL_GroupPrecomputation - bool NeedConversions() const {return true;} - Element ConvertIn(const Element &v) const {return m_mr->ConvertIn(v);} - virtual Element ConvertOut(const Element &v) const {return m_mr->ConvertOut(v);} - const AbstractGroup<Element> & GetGroup() const {return m_mr->MultiplicativeGroup();} - Element BERDecodeElement(BufferedTransformation &bt) const {return Integer(bt);} - void DEREncodeElement(BufferedTransformation &bt, const Element &v) const {v.DEREncode(bt);} - - // non-inherited - void SetModulus(const Integer &v) {m_mr.reset(new MontgomeryRepresentation(v));} - const Integer & GetModulus() const {return m_mr->GetModulus();} - -private: - value_ptr<MontgomeryRepresentation> m_mr; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/mqueue.cpp b/lib/cryptopp/mqueue.cpp deleted file mode 100644 index 1d645d83d..000000000 --- a/lib/cryptopp/mqueue.cpp +++ /dev/null @@ -1,174 +0,0 @@ -// mqueue.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "mqueue.h" - -NAMESPACE_BEGIN(CryptoPP) - -MessageQueue::MessageQueue(unsigned int nodeSize) - : m_queue(nodeSize), m_lengths(1, 0U), m_messageCounts(1, 0U) -{ -} - -size_t MessageQueue::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const -{ - if (begin >= MaxRetrievable()) - return 0; - - return m_queue.CopyRangeTo2(target, begin, STDMIN(MaxRetrievable(), end), channel, blocking); -} - -size_t MessageQueue::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) -{ - transferBytes = STDMIN(MaxRetrievable(), transferBytes); - size_t blockedBytes = m_queue.TransferTo2(target, transferBytes, channel, blocking); - m_lengths.front() -= transferBytes; - return blockedBytes; -} - -bool MessageQueue::GetNextMessage() -{ - if (NumberOfMessages() > 0 && !AnyRetrievable()) - { - m_lengths.pop_front(); - if (m_messageCounts[0] == 0 && m_messageCounts.size() > 1) - m_messageCounts.pop_front(); - return true; - } - else - return false; -} - -unsigned int MessageQueue::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const -{ - ByteQueue::Walker walker(m_queue); - std::deque<lword>::const_iterator it = m_lengths.begin(); - unsigned int i; - for (i=0; i<count && it != --m_lengths.end(); ++i, ++it) - { - walker.TransferTo(target, *it, channel); - if (GetAutoSignalPropagation()) - target.ChannelMessageEnd(channel, GetAutoSignalPropagation()-1); - } - return i; -} - -void MessageQueue::swap(MessageQueue &rhs) -{ - m_queue.swap(rhs.m_queue); - m_lengths.swap(rhs.m_lengths); -} - -const byte * MessageQueue::Spy(size_t &contiguousSize) const -{ - const byte *result = m_queue.Spy(contiguousSize); - contiguousSize = UnsignedMin(contiguousSize, MaxRetrievable()); - return result; -} - -// ************************************************************* - -unsigned int EqualityComparisonFilter::MapChannel(const std::string &channel) const -{ - if (channel == m_firstChannel) - return 0; - else if (channel == m_secondChannel) - return 1; - else - return 2; -} - -size_t EqualityComparisonFilter::ChannelPut2(const std::string &channel, const byte *inString, size_t length, int messageEnd, bool blocking) -{ - if (!blocking) - throw BlockingInputOnly("EqualityComparisonFilter"); - - unsigned int i = MapChannel(channel); - - if (i == 2) - return Output(3, inString, length, messageEnd, blocking, channel); - else if (m_mismatchDetected) - return 0; - else - { - MessageQueue &q1 = m_q[i], &q2 = m_q[1-i]; - - if (q2.AnyMessages() && q2.MaxRetrievable() < length) - goto mismatch; - - while (length > 0 && q2.AnyRetrievable()) - { - size_t len = length; - const byte *data = q2.Spy(len); - len = STDMIN(len, length); - if (memcmp(inString, data, len) != 0) - goto mismatch; - inString += len; - length -= len; - q2.Skip(len); - } - - q1.Put(inString, length); - - if (messageEnd) - { - if (q2.AnyRetrievable()) - goto mismatch; - else if (q2.AnyMessages()) - q2.GetNextMessage(); - else if (q2.NumberOfMessageSeries() > 0) - goto mismatch; - else - q1.MessageEnd(); - } - - return 0; - -mismatch: - return HandleMismatchDetected(blocking); - } -} - -bool EqualityComparisonFilter::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking) -{ - unsigned int i = MapChannel(channel); - - if (i == 2) - { - OutputMessageSeriesEnd(4, propagation, blocking, channel); - return false; - } - else if (m_mismatchDetected) - return false; - else - { - MessageQueue &q1 = m_q[i], &q2 = m_q[1-i]; - - if (q2.AnyRetrievable() || q2.AnyMessages()) - goto mismatch; - else if (q2.NumberOfMessageSeries() > 0) - return Output(2, (const byte *)"\1", 1, 0, blocking) != 0; - else - q1.MessageSeriesEnd(); - - return false; - -mismatch: - return HandleMismatchDetected(blocking); - } -} - -bool EqualityComparisonFilter::HandleMismatchDetected(bool blocking) -{ - m_mismatchDetected = true; - if (m_throwIfNotEqual) - throw MismatchDetected(); - return Output(1, (const byte *)"\0", 1, 0, blocking) != 0; -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/mqueue.h b/lib/cryptopp/mqueue.h deleted file mode 100644 index efa57a7cf..000000000 --- a/lib/cryptopp/mqueue.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef CRYPTOPP_MQUEUE_H -#define CRYPTOPP_MQUEUE_H - -#include "queue.h" -#include "filters.h" -#include <deque> - -NAMESPACE_BEGIN(CryptoPP) - -//! Message Queue -class CRYPTOPP_DLL MessageQueue : public AutoSignaling<BufferedTransformation> -{ -public: - MessageQueue(unsigned int nodeSize=256); - - void IsolatedInitialize(const NameValuePairs ¶meters) - {m_queue.IsolatedInitialize(parameters); m_lengths.assign(1, 0U); m_messageCounts.assign(1, 0U);} - size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) - { - m_queue.Put(begin, length); - m_lengths.back() += length; - if (messageEnd) - { - m_lengths.push_back(0); - m_messageCounts.back()++; - } - return 0; - } - bool IsolatedFlush(bool hardFlush, bool blocking) {return false;} - bool IsolatedMessageSeriesEnd(bool blocking) - {m_messageCounts.push_back(0); return false;} - - lword MaxRetrievable() const - {return m_lengths.front();} - bool AnyRetrievable() const - {return m_lengths.front() > 0;} - - size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); - size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; - - lword TotalBytesRetrievable() const - {return m_queue.MaxRetrievable();} - unsigned int NumberOfMessages() const - {return (unsigned int)m_lengths.size()-1;} - bool GetNextMessage(); - - unsigned int NumberOfMessagesInThisSeries() const - {return m_messageCounts[0];} - unsigned int NumberOfMessageSeries() const - {return (unsigned int)m_messageCounts.size()-1;} - - unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) const; - - const byte * Spy(size_t &contiguousSize) const; - - void swap(MessageQueue &rhs); - -private: - ByteQueue m_queue; - std::deque<lword> m_lengths; - std::deque<unsigned int> m_messageCounts; -}; - - -//! A filter that checks messages on two channels for equality -class CRYPTOPP_DLL EqualityComparisonFilter : public Unflushable<Multichannel<Filter> > -{ -public: - struct MismatchDetected : public Exception {MismatchDetected() : Exception(DATA_INTEGRITY_CHECK_FAILED, "EqualityComparisonFilter: did not receive the same data on two channels") {}}; - - /*! if throwIfNotEqual is false, this filter will output a '\\0' byte when it detects a mismatch, '\\1' otherwise */ - EqualityComparisonFilter(BufferedTransformation *attachment=NULL, bool throwIfNotEqual=true, const std::string &firstChannel="0", const std::string &secondChannel="1") - : m_throwIfNotEqual(throwIfNotEqual), m_mismatchDetected(false) - , m_firstChannel(firstChannel), m_secondChannel(secondChannel) - {Detach(attachment);} - - size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking); - bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true); - -private: - unsigned int MapChannel(const std::string &channel) const; - bool HandleMismatchDetected(bool blocking); - - bool m_throwIfNotEqual, m_mismatchDetected; - std::string m_firstChannel, m_secondChannel; - MessageQueue m_q[2]; -}; - -NAMESPACE_END - -#ifndef __BORLANDC__ -NAMESPACE_BEGIN(std) -template<> inline void swap(CryptoPP::MessageQueue &a, CryptoPP::MessageQueue &b) -{ - a.swap(b); -} -NAMESPACE_END -#endif - -#endif diff --git a/lib/cryptopp/mqv.cpp b/lib/cryptopp/mqv.cpp deleted file mode 100644 index c427561b2..000000000 --- a/lib/cryptopp/mqv.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// mqv.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "mqv.h" - -NAMESPACE_BEGIN(CryptoPP) - -void TestInstantiations_MQV() -{ - MQV mqv; -} - -NAMESPACE_END diff --git a/lib/cryptopp/mqv.h b/lib/cryptopp/mqv.h deleted file mode 100644 index 2683817b0..000000000 --- a/lib/cryptopp/mqv.h +++ /dev/null @@ -1,141 +0,0 @@ -#ifndef CRYPTOPP_MQV_H -#define CRYPTOPP_MQV_H - -/** \file -*/ - -#include "gfpcrypt.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -template <class GROUP_PARAMETERS, class COFACTOR_OPTION = CPP_TYPENAME GROUP_PARAMETERS::DefaultCofactorOption> -class MQV_Domain : public AuthenticatedKeyAgreementDomain -{ -public: - typedef GROUP_PARAMETERS GroupParameters; - typedef typename GroupParameters::Element Element; - typedef MQV_Domain<GROUP_PARAMETERS, COFACTOR_OPTION> Domain; - - MQV_Domain() {} - - MQV_Domain(const GroupParameters ¶ms) - : m_groupParameters(params) {} - - MQV_Domain(BufferedTransformation &bt) - {m_groupParameters.BERDecode(bt);} - - template <class T1, class T2> - MQV_Domain(T1 v1, T2 v2) - {m_groupParameters.Initialize(v1, v2);} - - template <class T1, class T2, class T3> - MQV_Domain(T1 v1, T2 v2, T3 v3) - {m_groupParameters.Initialize(v1, v2, v3);} - - template <class T1, class T2, class T3, class T4> - MQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4) - {m_groupParameters.Initialize(v1, v2, v3, v4);} - - const GroupParameters & GetGroupParameters() const {return m_groupParameters;} - GroupParameters & AccessGroupParameters() {return m_groupParameters;} - - CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();} - - unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} - unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} - unsigned int StaticPublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);} - - void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const - { - Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); - x.Encode(privateKey, StaticPrivateKeyLength()); - } - - void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const - { - const DL_GroupParameters<Element> ¶ms = GetAbstractGroupParameters(); - Integer x(privateKey, StaticPrivateKeyLength()); - Element y = params.ExponentiateBase(x); - params.EncodeElement(true, y, publicKey); - } - - unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();} - unsigned int EphemeralPublicKeyLength() const {return StaticPublicKeyLength();} - - void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const - { - const DL_GroupParameters<Element> ¶ms = GetAbstractGroupParameters(); - Integer x(rng, Integer::One(), params.GetMaxExponent()); - x.Encode(privateKey, StaticPrivateKeyLength()); - Element y = params.ExponentiateBase(x); - params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength()); - } - - void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const - { - memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength()); - } - - bool Agree(byte *agreedValue, - const byte *staticPrivateKey, const byte *ephemeralPrivateKey, - const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, - bool validateStaticOtherPublicKey=true) const - { - try - { - const DL_GroupParameters<Element> ¶ms = GetAbstractGroupParameters(); - Element WW = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey); - Element VV = params.DecodeElement(ephemeralOtherPublicKey, true); - - Integer s(staticPrivateKey, StaticPrivateKeyLength()); - Integer u(ephemeralPrivateKey, StaticPrivateKeyLength()); - Element V = params.DecodeElement(ephemeralPrivateKey+StaticPrivateKeyLength(), false); - - const Integer &r = params.GetSubgroupOrder(); - Integer h2 = Integer::Power2((r.BitCount()+1)/2); - Integer e = ((h2+params.ConvertElementToInteger(V)%h2)*s+u) % r; - Integer tt = h2 + params.ConvertElementToInteger(VV) % h2; - - if (COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION) - { - Element P = params.ExponentiateElement(WW, tt); - P = m_groupParameters.MultiplyElements(P, VV); - Element R[2]; - const Integer e2[2] = {r, e}; - params.SimultaneousExponentiate(R, P, e2, 2); - if (!params.IsIdentity(R[0]) || params.IsIdentity(R[1])) - return false; - params.EncodeElement(false, R[1], agreedValue); - } - else - { - const Integer &k = params.GetCofactor(); - if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION) - e = ModularArithmetic(r).Divide(e, k); - Element P = m_groupParameters.CascadeExponentiate(VV, k*e, WW, k*(e*tt%r)); - if (params.IsIdentity(P)) - return false; - params.EncodeElement(false, P, agreedValue); - } - } - catch (DL_BadElement &) - { - return false; - } - return true; - } - -private: - DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return m_groupParameters;} - const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return m_groupParameters;} - - GroupParameters m_groupParameters; -}; - -//! Menezes-Qu-Vanstone in GF(p) with key validation, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#MQV">MQV</a> -typedef MQV_Domain<DL_GroupParameters_GFP_DefaultSafePrime> MQV; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/nbtheory.cpp b/lib/cryptopp/nbtheory.cpp deleted file mode 100644 index 3fdea4e69..000000000 --- a/lib/cryptopp/nbtheory.cpp +++ /dev/null @@ -1,1123 +0,0 @@ -// nbtheory.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "nbtheory.h" -#include "modarith.h" -#include "algparam.h" - -#include <math.h> -#include <vector> - -#ifdef _OPENMP -// needed in MSVC 2005 to generate correct manifest -#include <omp.h> -#endif - -NAMESPACE_BEGIN(CryptoPP) - -const word s_lastSmallPrime = 32719; - -struct NewPrimeTable -{ - std::vector<word16> * operator()() const - { - const unsigned int maxPrimeTableSize = 3511; - - std::auto_ptr<std::vector<word16> > pPrimeTable(new std::vector<word16>); - std::vector<word16> &primeTable = *pPrimeTable; - primeTable.reserve(maxPrimeTableSize); - - primeTable.push_back(2); - unsigned int testEntriesEnd = 1; - - for (unsigned int p=3; p<=s_lastSmallPrime; p+=2) - { - unsigned int j; - for (j=1; j<testEntriesEnd; j++) - if (p%primeTable[j] == 0) - break; - if (j == testEntriesEnd) - { - primeTable.push_back(p); - testEntriesEnd = UnsignedMin(54U, primeTable.size()); - } - } - - return pPrimeTable.release(); - } -}; - -const word16 * GetPrimeTable(unsigned int &size) -{ - const std::vector<word16> &primeTable = Singleton<std::vector<word16>, NewPrimeTable>().Ref(); - size = (unsigned int)primeTable.size(); - return &primeTable[0]; -} - -bool IsSmallPrime(const Integer &p) -{ - unsigned int primeTableSize; - const word16 * primeTable = GetPrimeTable(primeTableSize); - - if (p.IsPositive() && p <= primeTable[primeTableSize-1]) - return std::binary_search(primeTable, primeTable+primeTableSize, (word16)p.ConvertToLong()); - else - return false; -} - -bool TrialDivision(const Integer &p, unsigned bound) -{ - unsigned int primeTableSize; - const word16 * primeTable = GetPrimeTable(primeTableSize); - - assert(primeTable[primeTableSize-1] >= bound); - - unsigned int i; - for (i = 0; primeTable[i]<bound; i++) - if ((p % primeTable[i]) == 0) - return true; - - if (bound == primeTable[i]) - return (p % bound == 0); - else - return false; -} - -bool SmallDivisorsTest(const Integer &p) -{ - unsigned int primeTableSize; - const word16 * primeTable = GetPrimeTable(primeTableSize); - return !TrialDivision(p, primeTable[primeTableSize-1]); -} - -bool IsFermatProbablePrime(const Integer &n, const Integer &b) -{ - if (n <= 3) - return n==2 || n==3; - - assert(n>3 && b>1 && b<n-1); - return a_exp_b_mod_c(b, n-1, n)==1; -} - -bool IsStrongProbablePrime(const Integer &n, const Integer &b) -{ - if (n <= 3) - return n==2 || n==3; - - assert(n>3 && b>1 && b<n-1); - - if ((n.IsEven() && n!=2) || GCD(b, n) != 1) - return false; - - Integer nminus1 = (n-1); - unsigned int a; - - // calculate a = largest power of 2 that divides (n-1) - for (a=0; ; a++) - if (nminus1.GetBit(a)) - break; - Integer m = nminus1>>a; - - Integer z = a_exp_b_mod_c(b, m, n); - if (z==1 || z==nminus1) - return true; - for (unsigned j=1; j<a; j++) - { - z = z.Squared()%n; - if (z==nminus1) - return true; - if (z==1) - return false; - } - return false; -} - -bool RabinMillerTest(RandomNumberGenerator &rng, const Integer &n, unsigned int rounds) -{ - if (n <= 3) - return n==2 || n==3; - - assert(n>3); - - Integer b; - for (unsigned int i=0; i<rounds; i++) - { - b.Randomize(rng, 2, n-2); - if (!IsStrongProbablePrime(n, b)) - return false; - } - return true; -} - -bool IsLucasProbablePrime(const Integer &n) -{ - if (n <= 1) - return false; - - if (n.IsEven()) - return n==2; - - assert(n>2); - - Integer b=3; - unsigned int i=0; - int j; - - while ((j=Jacobi(b.Squared()-4, n)) == 1) - { - if (++i==64 && n.IsSquare()) // avoid infinite loop if n is a square - return false; - ++b; ++b; - } - - if (j==0) - return false; - else - return Lucas(n+1, b, n)==2; -} - -bool IsStrongLucasProbablePrime(const Integer &n) -{ - if (n <= 1) - return false; - - if (n.IsEven()) - return n==2; - - assert(n>2); - - Integer b=3; - unsigned int i=0; - int j; - - while ((j=Jacobi(b.Squared()-4, n)) == 1) - { - if (++i==64 && n.IsSquare()) // avoid infinite loop if n is a square - return false; - ++b; ++b; - } - - if (j==0) - return false; - - Integer n1 = n+1; - unsigned int a; - - // calculate a = largest power of 2 that divides n1 - for (a=0; ; a++) - if (n1.GetBit(a)) - break; - Integer m = n1>>a; - - Integer z = Lucas(m, b, n); - if (z==2 || z==n-2) - return true; - for (i=1; i<a; i++) - { - z = (z.Squared()-2)%n; - if (z==n-2) - return true; - if (z==2) - return false; - } - return false; -} - -struct NewLastSmallPrimeSquared -{ - Integer * operator()() const - { - return new Integer(Integer(s_lastSmallPrime).Squared()); - } -}; - -bool IsPrime(const Integer &p) -{ - if (p <= s_lastSmallPrime) - return IsSmallPrime(p); - else if (p <= Singleton<Integer, NewLastSmallPrimeSquared>().Ref()) - return SmallDivisorsTest(p); - else - return SmallDivisorsTest(p) && IsStrongProbablePrime(p, 3) && IsStrongLucasProbablePrime(p); -} - -bool VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level) -{ - bool pass = IsPrime(p) && RabinMillerTest(rng, p, 1); - if (level >= 1) - pass = pass && RabinMillerTest(rng, p, 10); - return pass; -} - -unsigned int PrimeSearchInterval(const Integer &max) -{ - return max.BitCount(); -} - -static inline bool FastProbablePrimeTest(const Integer &n) -{ - return IsStrongProbablePrime(n,2); -} - -AlgorithmParameters MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength) -{ - if (productBitLength < 16) - throw InvalidArgument("invalid bit length"); - - Integer minP, maxP; - - if (productBitLength%2==0) - { - minP = Integer(182) << (productBitLength/2-8); - maxP = Integer::Power2(productBitLength/2)-1; - } - else - { - minP = Integer::Power2((productBitLength-1)/2); - maxP = Integer(181) << ((productBitLength+1)/2-8); - } - - return MakeParameters("RandomNumberType", Integer::PRIME)("Min", minP)("Max", maxP); -} - -class PrimeSieve -{ -public: - // delta == 1 or -1 means double sieve with p = 2*q + delta - PrimeSieve(const Integer &first, const Integer &last, const Integer &step, signed int delta=0); - bool NextCandidate(Integer &c); - - void DoSieve(); - static void SieveSingle(std::vector<bool> &sieve, word16 p, const Integer &first, const Integer &step, word16 stepInv); - - Integer m_first, m_last, m_step; - signed int m_delta; - word m_next; - std::vector<bool> m_sieve; -}; - -PrimeSieve::PrimeSieve(const Integer &first, const Integer &last, const Integer &step, signed int delta) - : m_first(first), m_last(last), m_step(step), m_delta(delta), m_next(0) -{ - DoSieve(); -} - -bool PrimeSieve::NextCandidate(Integer &c) -{ - bool safe = SafeConvert(std::find(m_sieve.begin()+m_next, m_sieve.end(), false) - m_sieve.begin(), m_next); - assert(safe); - if (m_next == m_sieve.size()) - { - m_first += long(m_sieve.size())*m_step; - if (m_first > m_last) - return false; - else - { - m_next = 0; - DoSieve(); - return NextCandidate(c); - } - } - else - { - c = m_first + long(m_next)*m_step; - ++m_next; - return true; - } -} - -void PrimeSieve::SieveSingle(std::vector<bool> &sieve, word16 p, const Integer &first, const Integer &step, word16 stepInv) -{ - if (stepInv) - { - size_t sieveSize = sieve.size(); - size_t j = (word32(p-(first%p))*stepInv) % p; - // if the first multiple of p is p, skip it - if (first.WordCount() <= 1 && first + step*long(j) == p) - j += p; - for (; j < sieveSize; j += p) - sieve[j] = true; - } -} - -void PrimeSieve::DoSieve() -{ - unsigned int primeTableSize; - const word16 * primeTable = GetPrimeTable(primeTableSize); - - const unsigned int maxSieveSize = 32768; - unsigned int sieveSize = STDMIN(Integer(maxSieveSize), (m_last-m_first)/m_step+1).ConvertToLong(); - - m_sieve.clear(); - m_sieve.resize(sieveSize, false); - - if (m_delta == 0) - { - for (unsigned int i = 0; i < primeTableSize; ++i) - SieveSingle(m_sieve, primeTable[i], m_first, m_step, (word16)m_step.InverseMod(primeTable[i])); - } - else - { - assert(m_step%2==0); - Integer qFirst = (m_first-m_delta) >> 1; - Integer halfStep = m_step >> 1; - for (unsigned int i = 0; i < primeTableSize; ++i) - { - word16 p = primeTable[i]; - word16 stepInv = (word16)m_step.InverseMod(p); - SieveSingle(m_sieve, p, m_first, m_step, stepInv); - - word16 halfStepInv = 2*stepInv < p ? 2*stepInv : 2*stepInv-p; - SieveSingle(m_sieve, p, qFirst, halfStep, halfStepInv); - } - } -} - -bool FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector) -{ - assert(!equiv.IsNegative() && equiv < mod); - - Integer gcd = GCD(equiv, mod); - if (gcd != Integer::One()) - { - // the only possible prime p such that p%mod==equiv where GCD(mod,equiv)!=1 is GCD(mod,equiv) - if (p <= gcd && gcd <= max && IsPrime(gcd) && (!pSelector || pSelector->IsAcceptable(gcd))) - { - p = gcd; - return true; - } - else - return false; - } - - unsigned int primeTableSize; - const word16 * primeTable = GetPrimeTable(primeTableSize); - - if (p <= primeTable[primeTableSize-1]) - { - const word16 *pItr; - - --p; - if (p.IsPositive()) - pItr = std::upper_bound(primeTable, primeTable+primeTableSize, (word)p.ConvertToLong()); - else - pItr = primeTable; - - while (pItr < primeTable+primeTableSize && !(*pItr%mod == equiv && (!pSelector || pSelector->IsAcceptable(*pItr)))) - ++pItr; - - if (pItr < primeTable+primeTableSize) - { - p = *pItr; - return p <= max; - } - - p = primeTable[primeTableSize-1]+1; - } - - assert(p > primeTable[primeTableSize-1]); - - if (mod.IsOdd()) - return FirstPrime(p, max, CRT(equiv, mod, 1, 2, 1), mod<<1, pSelector); - - p += (equiv-p)%mod; - - if (p>max) - return false; - - PrimeSieve sieve(p, max, mod); - - while (sieve.NextCandidate(p)) - { - if ((!pSelector || pSelector->IsAcceptable(p)) && FastProbablePrimeTest(p) && IsPrime(p)) - return true; - } - - return false; -} - -// the following two functions are based on code and comments provided by Preda Mihailescu -static bool ProvePrime(const Integer &p, const Integer &q) -{ - assert(p < q*q*q); - assert(p % q == 1); - -// this is the Quisquater test. Numbers p having passed the Lucas - Lehmer test -// for q and verifying p < q^3 can only be built up of two factors, both = 1 mod q, -// or be prime. The next two lines build the discriminant of a quadratic equation -// which holds iff p is built up of two factors (excercise ... ) - - Integer r = (p-1)/q; - if (((r%q).Squared()-4*(r/q)).IsSquare()) - return false; - - unsigned int primeTableSize; - const word16 * primeTable = GetPrimeTable(primeTableSize); - - assert(primeTableSize >= 50); - for (int i=0; i<50; i++) - { - Integer b = a_exp_b_mod_c(primeTable[i], r, p); - if (b != 1) - return a_exp_b_mod_c(b, q, p) == 1; - } - return false; -} - -Integer MihailescuProvablePrime(RandomNumberGenerator &rng, unsigned int pbits) -{ - Integer p; - Integer minP = Integer::Power2(pbits-1); - Integer maxP = Integer::Power2(pbits) - 1; - - if (maxP <= Integer(s_lastSmallPrime).Squared()) - { - // Randomize() will generate a prime provable by trial division - p.Randomize(rng, minP, maxP, Integer::PRIME); - return p; - } - - unsigned int qbits = (pbits+2)/3 + 1 + rng.GenerateWord32(0, pbits/36); - Integer q = MihailescuProvablePrime(rng, qbits); - Integer q2 = q<<1; - - while (true) - { - // this initializes the sieve to search in the arithmetic - // progression p = p_0 + \lambda * q2 = p_0 + 2 * \lambda * q, - // with q the recursively generated prime above. We will be able - // to use Lucas tets for proving primality. A trick of Quisquater - // allows taking q > cubic_root(p) rather then square_root: this - // decreases the recursion. - - p.Randomize(rng, minP, maxP, Integer::ANY, 1, q2); - PrimeSieve sieve(p, STDMIN(p+PrimeSearchInterval(maxP)*q2, maxP), q2); - - while (sieve.NextCandidate(p)) - { - if (FastProbablePrimeTest(p) && ProvePrime(p, q)) - return p; - } - } - - // not reached - return p; -} - -Integer MaurerProvablePrime(RandomNumberGenerator &rng, unsigned int bits) -{ - const unsigned smallPrimeBound = 29, c_opt=10; - Integer p; - - unsigned int primeTableSize; - const word16 * primeTable = GetPrimeTable(primeTableSize); - - if (bits < smallPrimeBound) - { - do - p.Randomize(rng, Integer::Power2(bits-1), Integer::Power2(bits)-1, Integer::ANY, 1, 2); - while (TrialDivision(p, 1 << ((bits+1)/2))); - } - else - { - const unsigned margin = bits > 50 ? 20 : (bits-10)/2; - double relativeSize; - do - relativeSize = pow(2.0, double(rng.GenerateWord32())/0xffffffff - 1); - while (bits * relativeSize >= bits - margin); - - Integer a,b; - Integer q = MaurerProvablePrime(rng, unsigned(bits*relativeSize)); - Integer I = Integer::Power2(bits-2)/q; - Integer I2 = I << 1; - unsigned int trialDivisorBound = (unsigned int)STDMIN((unsigned long)primeTable[primeTableSize-1], (unsigned long)bits*bits/c_opt); - bool success = false; - while (!success) - { - p.Randomize(rng, I, I2, Integer::ANY); - p *= q; p <<= 1; ++p; - if (!TrialDivision(p, trialDivisorBound)) - { - a.Randomize(rng, 2, p-1, Integer::ANY); - b = a_exp_b_mod_c(a, (p-1)/q, p); - success = (GCD(b-1, p) == 1) && (a_exp_b_mod_c(b, q, p) == 1); - } - } - } - return p; -} - -Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q, const Integer &u) -{ - // isn't operator overloading great? - return p * (u * (xq-xp) % q) + xp; -/* - Integer t1 = xq-xp; - cout << hex << t1 << endl; - Integer t2 = u * t1; - cout << hex << t2 << endl; - Integer t3 = t2 % q; - cout << hex << t3 << endl; - Integer t4 = p * t3; - cout << hex << t4 << endl; - Integer t5 = t4 + xp; - cout << hex << t5 << endl; - return t5; -*/ -} - -Integer ModularSquareRoot(const Integer &a, const Integer &p) -{ - if (p%4 == 3) - return a_exp_b_mod_c(a, (p+1)/4, p); - - Integer q=p-1; - unsigned int r=0; - while (q.IsEven()) - { - r++; - q >>= 1; - } - - Integer n=2; - while (Jacobi(n, p) != -1) - ++n; - - Integer y = a_exp_b_mod_c(n, q, p); - Integer x = a_exp_b_mod_c(a, (q-1)/2, p); - Integer b = (x.Squared()%p)*a%p; - x = a*x%p; - Integer tempb, t; - - while (b != 1) - { - unsigned m=0; - tempb = b; - do - { - m++; - b = b.Squared()%p; - if (m==r) - return Integer::Zero(); - } - while (b != 1); - - t = y; - for (unsigned i=0; i<r-m-1; i++) - t = t.Squared()%p; - y = t.Squared()%p; - r = m; - x = x*t%p; - b = tempb*y%p; - } - - assert(x.Squared()%p == a); - return x; -} - -bool SolveModularQuadraticEquation(Integer &r1, Integer &r2, const Integer &a, const Integer &b, const Integer &c, const Integer &p) -{ - Integer D = (b.Squared() - 4*a*c) % p; - switch (Jacobi(D, p)) - { - default: - assert(false); // not reached - return false; - case -1: - return false; - case 0: - r1 = r2 = (-b*(a+a).InverseMod(p)) % p; - assert(((r1.Squared()*a + r1*b + c) % p).IsZero()); - return true; - case 1: - Integer s = ModularSquareRoot(D, p); - Integer t = (a+a).InverseMod(p); - r1 = (s-b)*t % p; - r2 = (-s-b)*t % p; - assert(((r1.Squared()*a + r1*b + c) % p).IsZero()); - assert(((r2.Squared()*a + r2*b + c) % p).IsZero()); - return true; - } -} - -Integer ModularRoot(const Integer &a, const Integer &dp, const Integer &dq, - const Integer &p, const Integer &q, const Integer &u) -{ - Integer p2, q2; - #pragma omp parallel - #pragma omp sections - { - #pragma omp section - p2 = ModularExponentiation((a % p), dp, p); - #pragma omp section - q2 = ModularExponentiation((a % q), dq, q); - } - return CRT(p2, p, q2, q, u); -} - -Integer ModularRoot(const Integer &a, const Integer &e, - const Integer &p, const Integer &q) -{ - Integer dp = EuclideanMultiplicativeInverse(e, p-1); - Integer dq = EuclideanMultiplicativeInverse(e, q-1); - Integer u = EuclideanMultiplicativeInverse(p, q); - assert(!!dp && !!dq && !!u); - return ModularRoot(a, dp, dq, p, q, u); -} - -/* -Integer GCDI(const Integer &x, const Integer &y) -{ - Integer a=x, b=y; - unsigned k=0; - - assert(!!a && !!b); - - while (a[0]==0 && b[0]==0) - { - a >>= 1; - b >>= 1; - k++; - } - - while (a[0]==0) - a >>= 1; - - while (b[0]==0) - b >>= 1; - - while (1) - { - switch (a.Compare(b)) - { - case -1: - b -= a; - while (b[0]==0) - b >>= 1; - break; - - case 0: - return (a <<= k); - - case 1: - a -= b; - while (a[0]==0) - a >>= 1; - break; - - default: - assert(false); - } - } -} - -Integer EuclideanMultiplicativeInverse(const Integer &a, const Integer &b) -{ - assert(b.Positive()); - - if (a.Negative()) - return EuclideanMultiplicativeInverse(a%b, b); - - if (b[0]==0) - { - if (!b || a[0]==0) - return Integer::Zero(); // no inverse - if (a==1) - return 1; - Integer u = EuclideanMultiplicativeInverse(b, a); - if (!u) - return Integer::Zero(); // no inverse - else - return (b*(a-u)+1)/a; - } - - Integer u=1, d=a, v1=b, v3=b, t1, t3, b2=(b+1)>>1; - - if (a[0]) - { - t1 = Integer::Zero(); - t3 = -b; - } - else - { - t1 = b2; - t3 = a>>1; - } - - while (!!t3) - { - while (t3[0]==0) - { - t3 >>= 1; - if (t1[0]==0) - t1 >>= 1; - else - { - t1 >>= 1; - t1 += b2; - } - } - if (t3.Positive()) - { - u = t1; - d = t3; - } - else - { - v1 = b-t1; - v3 = -t3; - } - t1 = u-v1; - t3 = d-v3; - if (t1.Negative()) - t1 += b; - } - if (d==1) - return u; - else - return Integer::Zero(); // no inverse -} -*/ - -int Jacobi(const Integer &aIn, const Integer &bIn) -{ - assert(bIn.IsOdd()); - - Integer b = bIn, a = aIn%bIn; - int result = 1; - - while (!!a) - { - unsigned i=0; - while (a.GetBit(i)==0) - i++; - a>>=i; - - if (i%2==1 && (b%8==3 || b%8==5)) - result = -result; - - if (a%4==3 && b%4==3) - result = -result; - - std::swap(a, b); - a %= b; - } - - return (b==1) ? result : 0; -} - -Integer Lucas(const Integer &e, const Integer &pIn, const Integer &n) -{ - unsigned i = e.BitCount(); - if (i==0) - return Integer::Two(); - - MontgomeryRepresentation m(n); - Integer p=m.ConvertIn(pIn%n), two=m.ConvertIn(Integer::Two()); - Integer v=p, v1=m.Subtract(m.Square(p), two); - - i--; - while (i--) - { - if (e.GetBit(i)) - { - // v = (v*v1 - p) % m; - v = m.Subtract(m.Multiply(v,v1), p); - // v1 = (v1*v1 - 2) % m; - v1 = m.Subtract(m.Square(v1), two); - } - else - { - // v1 = (v*v1 - p) % m; - v1 = m.Subtract(m.Multiply(v,v1), p); - // v = (v*v - 2) % m; - v = m.Subtract(m.Square(v), two); - } - } - return m.ConvertOut(v); -} - -// This is Peter Montgomery's unpublished Lucas sequence evalutation algorithm. -// The total number of multiplies and squares used is less than the binary -// algorithm (see above). Unfortunately I can't get it to run as fast as -// the binary algorithm because of the extra overhead. -/* -Integer Lucas(const Integer &n, const Integer &P, const Integer &modulus) -{ - if (!n) - return 2; - -#define f(A, B, C) m.Subtract(m.Multiply(A, B), C) -#define X2(A) m.Subtract(m.Square(A), two) -#define X3(A) m.Multiply(A, m.Subtract(m.Square(A), three)) - - MontgomeryRepresentation m(modulus); - Integer two=m.ConvertIn(2), three=m.ConvertIn(3); - Integer A=m.ConvertIn(P), B, C, p, d=n, e, r, t, T, U; - - while (d!=1) - { - p = d; - unsigned int b = WORD_BITS * p.WordCount(); - Integer alpha = (Integer(5)<<(2*b-2)).SquareRoot() - Integer::Power2(b-1); - r = (p*alpha)>>b; - e = d-r; - B = A; - C = two; - d = r; - - while (d!=e) - { - if (d<e) - { - swap(d, e); - swap(A, B); - } - - unsigned int dm2 = d[0], em2 = e[0]; - unsigned int dm3 = d%3, em3 = e%3; - -// if ((dm6+em6)%3 == 0 && d <= e + (e>>2)) - if ((dm3+em3==0 || dm3+em3==3) && (t = e, t >>= 2, t += e, d <= t)) - { - // #1 -// t = (d+d-e)/3; -// t = d; t += d; t -= e; t /= 3; -// e = (e+e-d)/3; -// e += e; e -= d; e /= 3; -// d = t; - -// t = (d+e)/3 - t = d; t += e; t /= 3; - e -= t; - d -= t; - - T = f(A, B, C); - U = f(T, A, B); - B = f(T, B, A); - A = U; - continue; - } - -// if (dm6 == em6 && d <= e + (e>>2)) - if (dm3 == em3 && dm2 == em2 && (t = e, t >>= 2, t += e, d <= t)) - { - // #2 -// d = (d-e)>>1; - d -= e; d >>= 1; - B = f(A, B, C); - A = X2(A); - continue; - } - -// if (d <= (e<<2)) - if (d <= (t = e, t <<= 2)) - { - // #3 - d -= e; - C = f(A, B, C); - swap(B, C); - continue; - } - - if (dm2 == em2) - { - // #4 -// d = (d-e)>>1; - d -= e; d >>= 1; - B = f(A, B, C); - A = X2(A); - continue; - } - - if (dm2 == 0) - { - // #5 - d >>= 1; - C = f(A, C, B); - A = X2(A); - continue; - } - - if (dm3 == 0) - { - // #6 -// d = d/3 - e; - d /= 3; d -= e; - T = X2(A); - C = f(T, f(A, B, C), C); - swap(B, C); - A = f(T, A, A); - continue; - } - - if (dm3+em3==0 || dm3+em3==3) - { - // #7 -// d = (d-e-e)/3; - d -= e; d -= e; d /= 3; - T = f(A, B, C); - B = f(T, A, B); - A = X3(A); - continue; - } - - if (dm3 == em3) - { - // #8 -// d = (d-e)/3; - d -= e; d /= 3; - T = f(A, B, C); - C = f(A, C, B); - B = T; - A = X3(A); - continue; - } - - assert(em2 == 0); - // #9 - e >>= 1; - C = f(C, B, A); - B = X2(B); - } - - A = f(A, B, C); - } - -#undef f -#undef X2 -#undef X3 - - return m.ConvertOut(A); -} -*/ - -Integer InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q, const Integer &u) -{ - Integer d = (m*m-4); - Integer p2, q2; - #pragma omp parallel - #pragma omp sections - { - #pragma omp section - { - p2 = p-Jacobi(d,p); - p2 = Lucas(EuclideanMultiplicativeInverse(e,p2), m, p); - } - #pragma omp section - { - q2 = q-Jacobi(d,q); - q2 = Lucas(EuclideanMultiplicativeInverse(e,q2), m, q); - } - } - return CRT(p2, p, q2, q, u); -} - -unsigned int FactoringWorkFactor(unsigned int n) -{ - // extrapolated from the table in Odlyzko's "The Future of Integer Factorization" - // updated to reflect the factoring of RSA-130 - if (n<5) return 0; - else return (unsigned int)(2.4 * pow((double)n, 1.0/3.0) * pow(log(double(n)), 2.0/3.0) - 5); -} - -unsigned int DiscreteLogWorkFactor(unsigned int n) -{ - // assuming discrete log takes about the same time as factoring - if (n<5) return 0; - else return (unsigned int)(2.4 * pow((double)n, 1.0/3.0) * pow(log(double(n)), 2.0/3.0) - 5); -} - -// ******************************************************** - -void PrimeAndGenerator::Generate(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned int qbits) -{ - // no prime exists for delta = -1, qbits = 4, and pbits = 5 - assert(qbits > 4); - assert(pbits > qbits); - - if (qbits+1 == pbits) - { - Integer minP = Integer::Power2(pbits-1); - Integer maxP = Integer::Power2(pbits) - 1; - bool success = false; - - while (!success) - { - p.Randomize(rng, minP, maxP, Integer::ANY, 6+5*delta, 12); - PrimeSieve sieve(p, STDMIN(p+PrimeSearchInterval(maxP)*12, maxP), 12, delta); - - while (sieve.NextCandidate(p)) - { - assert(IsSmallPrime(p) || SmallDivisorsTest(p)); - q = (p-delta) >> 1; - assert(IsSmallPrime(q) || SmallDivisorsTest(q)); - if (FastProbablePrimeTest(q) && FastProbablePrimeTest(p) && IsPrime(q) && IsPrime(p)) - { - success = true; - break; - } - } - } - - if (delta == 1) - { - // find g such that g is a quadratic residue mod p, then g has order q - // g=4 always works, but this way we get the smallest quadratic residue (other than 1) - for (g=2; Jacobi(g, p) != 1; ++g) {} - // contributed by Walt Tuvell: g should be the following according to the Law of Quadratic Reciprocity - assert((p%8==1 || p%8==7) ? g==2 : (p%12==1 || p%12==11) ? g==3 : g==4); - } - else - { - assert(delta == -1); - // find g such that g*g-4 is a quadratic non-residue, - // and such that g has order q - for (g=3; ; ++g) - if (Jacobi(g*g-4, p)==-1 && Lucas(q, g, p)==2) - break; - } - } - else - { - Integer minQ = Integer::Power2(qbits-1); - Integer maxQ = Integer::Power2(qbits) - 1; - Integer minP = Integer::Power2(pbits-1); - Integer maxP = Integer::Power2(pbits) - 1; - - do - { - q.Randomize(rng, minQ, maxQ, Integer::PRIME); - } while (!p.Randomize(rng, minP, maxP, Integer::PRIME, delta%q, q)); - - // find a random g of order q - if (delta==1) - { - do - { - Integer h(rng, 2, p-2, Integer::ANY); - g = a_exp_b_mod_c(h, (p-1)/q, p); - } while (g <= 1); - assert(a_exp_b_mod_c(g, q, p)==1); - } - else - { - assert(delta==-1); - do - { - Integer h(rng, 3, p-1, Integer::ANY); - if (Jacobi(h*h-4, p)==1) - continue; - g = Lucas((p+1)/q, h, p); - } while (g <= 2); - assert(Lucas(q, g, p) == 2); - } - } -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/nbtheory.h b/lib/cryptopp/nbtheory.h deleted file mode 100644 index 636479269..000000000 --- a/lib/cryptopp/nbtheory.h +++ /dev/null @@ -1,131 +0,0 @@ -// nbtheory.h - written and placed in the public domain by Wei Dai - -#ifndef CRYPTOPP_NBTHEORY_H -#define CRYPTOPP_NBTHEORY_H - -#include "integer.h" -#include "algparam.h" - -NAMESPACE_BEGIN(CryptoPP) - -// obtain pointer to small prime table and get its size -CRYPTOPP_DLL const word16 * CRYPTOPP_API GetPrimeTable(unsigned int &size); - -// ************ primality testing **************** - -// generate a provable prime -CRYPTOPP_DLL Integer CRYPTOPP_API MaurerProvablePrime(RandomNumberGenerator &rng, unsigned int bits); -CRYPTOPP_DLL Integer CRYPTOPP_API MihailescuProvablePrime(RandomNumberGenerator &rng, unsigned int bits); - -CRYPTOPP_DLL bool CRYPTOPP_API IsSmallPrime(const Integer &p); - -// returns true if p is divisible by some prime less than bound -// bound not be greater than the largest entry in the prime table -CRYPTOPP_DLL bool CRYPTOPP_API TrialDivision(const Integer &p, unsigned bound); - -// returns true if p is NOT divisible by small primes -CRYPTOPP_DLL bool CRYPTOPP_API SmallDivisorsTest(const Integer &p); - -// These is no reason to use these two, use the ones below instead -CRYPTOPP_DLL bool CRYPTOPP_API IsFermatProbablePrime(const Integer &n, const Integer &b); -CRYPTOPP_DLL bool CRYPTOPP_API IsLucasProbablePrime(const Integer &n); - -CRYPTOPP_DLL bool CRYPTOPP_API IsStrongProbablePrime(const Integer &n, const Integer &b); -CRYPTOPP_DLL bool CRYPTOPP_API IsStrongLucasProbablePrime(const Integer &n); - -// Rabin-Miller primality test, i.e. repeating the strong probable prime test -// for several rounds with random bases -CRYPTOPP_DLL bool CRYPTOPP_API RabinMillerTest(RandomNumberGenerator &rng, const Integer &w, unsigned int rounds); - -// primality test, used to generate primes -CRYPTOPP_DLL bool CRYPTOPP_API IsPrime(const Integer &p); - -// more reliable than IsPrime(), used to verify primes generated by others -CRYPTOPP_DLL bool CRYPTOPP_API VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level = 1); - -class CRYPTOPP_DLL PrimeSelector -{ -public: - const PrimeSelector *GetSelectorPointer() const {return this;} - virtual bool IsAcceptable(const Integer &candidate) const =0; -}; - -// use a fast sieve to find the first probable prime in {x | p<=x<=max and x%mod==equiv} -// returns true iff successful, value of p is undefined if no such prime exists -CRYPTOPP_DLL bool CRYPTOPP_API FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector); - -CRYPTOPP_DLL unsigned int CRYPTOPP_API PrimeSearchInterval(const Integer &max); - -CRYPTOPP_DLL AlgorithmParameters CRYPTOPP_API MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength); - -// ********** other number theoretic functions ************ - -inline Integer GCD(const Integer &a, const Integer &b) - {return Integer::Gcd(a,b);} -inline bool RelativelyPrime(const Integer &a, const Integer &b) - {return Integer::Gcd(a,b) == Integer::One();} -inline Integer LCM(const Integer &a, const Integer &b) - {return a/Integer::Gcd(a,b)*b;} -inline Integer EuclideanMultiplicativeInverse(const Integer &a, const Integer &b) - {return a.InverseMod(b);} - -// use Chinese Remainder Theorem to calculate x given x mod p and x mod q, and u = inverse of p mod q -CRYPTOPP_DLL Integer CRYPTOPP_API CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q, const Integer &u); - -// if b is prime, then Jacobi(a, b) returns 0 if a%b==0, 1 if a is quadratic residue mod b, -1 otherwise -// check a number theory book for what Jacobi symbol means when b is not prime -CRYPTOPP_DLL int CRYPTOPP_API Jacobi(const Integer &a, const Integer &b); - -// calculates the Lucas function V_e(p, 1) mod n -CRYPTOPP_DLL Integer CRYPTOPP_API Lucas(const Integer &e, const Integer &p, const Integer &n); -// calculates x such that m==Lucas(e, x, p*q), p q primes, u=inverse of p mod q -CRYPTOPP_DLL Integer CRYPTOPP_API InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q, const Integer &u); - -inline Integer ModularExponentiation(const Integer &a, const Integer &e, const Integer &m) - {return a_exp_b_mod_c(a, e, m);} -// returns x such that x*x%p == a, p prime -CRYPTOPP_DLL Integer CRYPTOPP_API ModularSquareRoot(const Integer &a, const Integer &p); -// returns x such that a==ModularExponentiation(x, e, p*q), p q primes, -// and e relatively prime to (p-1)*(q-1) -// dp=d%(p-1), dq=d%(q-1), (d is inverse of e mod (p-1)*(q-1)) -// and u=inverse of p mod q -CRYPTOPP_DLL Integer CRYPTOPP_API ModularRoot(const Integer &a, const Integer &dp, const Integer &dq, const Integer &p, const Integer &q, const Integer &u); - -// find r1 and r2 such that ax^2 + bx + c == 0 (mod p) for x in {r1, r2}, p prime -// returns true if solutions exist -CRYPTOPP_DLL bool CRYPTOPP_API SolveModularQuadraticEquation(Integer &r1, Integer &r2, const Integer &a, const Integer &b, const Integer &c, const Integer &p); - -// returns log base 2 of estimated number of operations to calculate discrete log or factor a number -CRYPTOPP_DLL unsigned int CRYPTOPP_API DiscreteLogWorkFactor(unsigned int bitlength); -CRYPTOPP_DLL unsigned int CRYPTOPP_API FactoringWorkFactor(unsigned int bitlength); - -// ******************************************************** - -//! generator of prime numbers of special forms -class CRYPTOPP_DLL PrimeAndGenerator -{ -public: - PrimeAndGenerator() {} - // generate a random prime p of the form 2*q+delta, where delta is 1 or -1 and q is also prime - // Precondition: pbits > 5 - // warning: this is slow, because primes of this form are harder to find - PrimeAndGenerator(signed int delta, RandomNumberGenerator &rng, unsigned int pbits) - {Generate(delta, rng, pbits, pbits-1);} - // generate a random prime p of the form 2*r*q+delta, where q is also prime - // Precondition: qbits > 4 && pbits > qbits - PrimeAndGenerator(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned qbits) - {Generate(delta, rng, pbits, qbits);} - - void Generate(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned qbits); - - const Integer& Prime() const {return p;} - const Integer& SubPrime() const {return q;} - const Integer& Generator() const {return g;} - -private: - Integer p, q, g; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/network.cpp b/lib/cryptopp/network.cpp deleted file mode 100644 index 9b7198d16..000000000 --- a/lib/cryptopp/network.cpp +++ /dev/null @@ -1,550 +0,0 @@ -// network.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "network.h" -#include "wait.h" - -#define CRYPTOPP_TRACE_NETWORK 0 - -NAMESPACE_BEGIN(CryptoPP) - -#ifdef HIGHRES_TIMER_AVAILABLE - -lword LimitedBandwidth::ComputeCurrentTransceiveLimit() -{ - if (!m_maxBytesPerSecond) - return ULONG_MAX; - - double curTime = GetCurTimeAndCleanUp(); - lword total = 0; - for (OpQueue::size_type i=0; i!=m_ops.size(); ++i) - total += m_ops[i].second; - return SaturatingSubtract(m_maxBytesPerSecond, total); -} - -double LimitedBandwidth::TimeToNextTransceive() -{ - if (!m_maxBytesPerSecond) - return 0; - - if (!m_nextTransceiveTime) - ComputeNextTransceiveTime(); - - return SaturatingSubtract(m_nextTransceiveTime, m_timer.ElapsedTimeAsDouble()); -} - -void LimitedBandwidth::NoteTransceive(lword size) -{ - if (m_maxBytesPerSecond) - { - double curTime = GetCurTimeAndCleanUp(); - m_ops.push_back(std::make_pair(curTime, size)); - m_nextTransceiveTime = 0; - } -} - -void LimitedBandwidth::ComputeNextTransceiveTime() -{ - double curTime = GetCurTimeAndCleanUp(); - lword total = 0; - for (unsigned int i=0; i!=m_ops.size(); ++i) - total += m_ops[i].second; - m_nextTransceiveTime = - (total < m_maxBytesPerSecond) ? curTime : m_ops.front().first + 1000; -} - -double LimitedBandwidth::GetCurTimeAndCleanUp() -{ - if (!m_maxBytesPerSecond) - return 0; - - double curTime = m_timer.ElapsedTimeAsDouble(); - while (m_ops.size() && (m_ops.front().first + 1000 < curTime)) - m_ops.pop_front(); - return curTime; -} - -void LimitedBandwidth::GetWaitObjects(WaitObjectContainer &container, const CallStack &callStack) -{ - double nextTransceiveTime = TimeToNextTransceive(); - if (nextTransceiveTime) - container.ScheduleEvent(nextTransceiveTime, CallStack("LimitedBandwidth::GetWaitObjects()", &callStack)); -} - -// ************************************************************* - -size_t NonblockingSource::GeneralPump2( - lword& byteCount, bool blockingOutput, - unsigned long maxTime, bool checkDelimiter, byte delimiter) -{ - m_blockedBySpeedLimit = false; - - if (!GetMaxBytesPerSecond()) - { - size_t ret = DoPump(byteCount, blockingOutput, maxTime, checkDelimiter, delimiter); - m_doPumpBlocked = (ret != 0); - return ret; - } - - bool forever = (maxTime == INFINITE_TIME); - unsigned long timeToGo = maxTime; - Timer timer(Timer::MILLISECONDS, forever); - lword maxSize = byteCount; - byteCount = 0; - - timer.StartTimer(); - - while (true) - { - lword curMaxSize = UnsignedMin(ComputeCurrentTransceiveLimit(), maxSize - byteCount); - - if (curMaxSize || m_doPumpBlocked) - { - if (!forever) timeToGo = SaturatingSubtract(maxTime, timer.ElapsedTime()); - size_t ret = DoPump(curMaxSize, blockingOutput, timeToGo, checkDelimiter, delimiter); - m_doPumpBlocked = (ret != 0); - if (curMaxSize) - { - NoteTransceive(curMaxSize); - byteCount += curMaxSize; - } - if (ret) - return ret; - } - - if (maxSize != ULONG_MAX && byteCount >= maxSize) - break; - - if (!forever) - { - timeToGo = SaturatingSubtract(maxTime, timer.ElapsedTime()); - if (!timeToGo) - break; - } - - double waitTime = TimeToNextTransceive(); - if (!forever && waitTime > timeToGo) - { - m_blockedBySpeedLimit = true; - break; - } - - WaitObjectContainer container; - LimitedBandwidth::GetWaitObjects(container, CallStack("NonblockingSource::GeneralPump2() - speed limit", 0)); - container.Wait((unsigned long)waitTime); - } - - return 0; -} - -size_t NonblockingSource::PumpMessages2(unsigned int &messageCount, bool blocking) -{ - if (messageCount == 0) - return 0; - - messageCount = 0; - - lword byteCount; - do { - byteCount = LWORD_MAX; - RETURN_IF_NONZERO(Pump2(byteCount, blocking)); - } while(byteCount == LWORD_MAX); - - if (!m_messageEndSent && SourceExhausted()) - { - RETURN_IF_NONZERO(AttachedTransformation()->Put2(NULL, 0, GetAutoSignalPropagation(), true)); - m_messageEndSent = true; - messageCount = 1; - } - return 0; -} - -lword NonblockingSink::TimedFlush(unsigned long maxTime, size_t targetSize) -{ - m_blockedBySpeedLimit = false; - - size_t curBufSize = GetCurrentBufferSize(); - if (curBufSize <= targetSize && (targetSize || !EofPending())) - return 0; - - if (!GetMaxBytesPerSecond()) - return DoFlush(maxTime, targetSize); - - bool forever = (maxTime == INFINITE_TIME); - unsigned long timeToGo = maxTime; - Timer timer(Timer::MILLISECONDS, forever); - lword totalFlushed = 0; - - timer.StartTimer(); - - while (true) - { - size_t flushSize = UnsignedMin(curBufSize - targetSize, ComputeCurrentTransceiveLimit()); - if (flushSize || EofPending()) - { - if (!forever) timeToGo = SaturatingSubtract(maxTime, timer.ElapsedTime()); - size_t ret = (size_t)DoFlush(timeToGo, curBufSize - flushSize); - if (ret) - { - NoteTransceive(ret); - curBufSize -= ret; - totalFlushed += ret; - } - } - - if (curBufSize <= targetSize && (targetSize || !EofPending())) - break; - - if (!forever) - { - timeToGo = SaturatingSubtract(maxTime, timer.ElapsedTime()); - if (!timeToGo) - break; - } - - double waitTime = TimeToNextTransceive(); - if (!forever && waitTime > timeToGo) - { - m_blockedBySpeedLimit = true; - break; - } - - WaitObjectContainer container; - LimitedBandwidth::GetWaitObjects(container, CallStack("NonblockingSink::TimedFlush() - speed limit", 0)); - container.Wait((unsigned long)waitTime); - } - - return totalFlushed; -} - -bool NonblockingSink::IsolatedFlush(bool hardFlush, bool blocking) -{ - TimedFlush(blocking ? INFINITE_TIME : 0); - return hardFlush && (!!GetCurrentBufferSize() || EofPending()); -} - -// ************************************************************* - -NetworkSource::NetworkSource(BufferedTransformation *attachment) - : NonblockingSource(attachment), m_buf(1024*16) - , m_waitingForResult(false), m_outputBlocked(false) - , m_dataBegin(0), m_dataEnd(0) -{ -} - -unsigned int NetworkSource::GetMaxWaitObjectCount() const -{ - return LimitedBandwidth::GetMaxWaitObjectCount() - + GetReceiver().GetMaxWaitObjectCount() - + AttachedTransformation()->GetMaxWaitObjectCount(); -} - -void NetworkSource::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) -{ - if (BlockedBySpeedLimit()) - LimitedBandwidth::GetWaitObjects(container, CallStack("NetworkSource::GetWaitObjects() - speed limit", &callStack)); - else if (!m_outputBlocked) - { - if (m_dataBegin == m_dataEnd) - AccessReceiver().GetWaitObjects(container, CallStack("NetworkSource::GetWaitObjects() - no data", &callStack)); - else - container.SetNoWait(CallStack("NetworkSource::GetWaitObjects() - have data", &callStack)); - } - - AttachedTransformation()->GetWaitObjects(container, CallStack("NetworkSource::GetWaitObjects() - attachment", &callStack)); -} - -size_t NetworkSource::DoPump(lword &byteCount, bool blockingOutput, unsigned long maxTime, bool checkDelimiter, byte delimiter) -{ - NetworkReceiver &receiver = AccessReceiver(); - - lword maxSize = byteCount; - byteCount = 0; - bool forever = maxTime == INFINITE_TIME; - Timer timer(Timer::MILLISECONDS, forever); - BufferedTransformation *t = AttachedTransformation(); - - if (m_outputBlocked) - goto DoOutput; - - while (true) - { - if (m_dataBegin == m_dataEnd) - { - if (receiver.EofReceived()) - break; - - if (m_waitingForResult) - { - if (receiver.MustWaitForResult() && - !receiver.Wait(SaturatingSubtract(maxTime, timer.ElapsedTime()), - CallStack("NetworkSource::DoPump() - wait receive result", 0))) - break; - - unsigned int recvResult = receiver.GetReceiveResult(); -#if CRYPTOPP_TRACE_NETWORK - OutputDebugString((IntToString((unsigned int)this) + ": Received " + IntToString(recvResult) + " bytes\n").c_str()); -#endif - m_dataEnd += recvResult; - m_waitingForResult = false; - - if (!receiver.MustWaitToReceive() && !receiver.EofReceived() && m_dataEnd != m_buf.size()) - goto ReceiveNoWait; - } - else - { - m_dataEnd = m_dataBegin = 0; - - if (receiver.MustWaitToReceive()) - { - if (!receiver.Wait(SaturatingSubtract(maxTime, timer.ElapsedTime()), - CallStack("NetworkSource::DoPump() - wait receive", 0))) - break; - - receiver.Receive(m_buf+m_dataEnd, m_buf.size()-m_dataEnd); - m_waitingForResult = true; - } - else - { -ReceiveNoWait: - m_waitingForResult = true; - // call Receive repeatedly as long as data is immediately available, - // because some receivers tend to return data in small pieces -#if CRYPTOPP_TRACE_NETWORK - OutputDebugString((IntToString((unsigned int)this) + ": Receiving " + IntToString(m_buf.size()-m_dataEnd) + " bytes\n").c_str()); -#endif - while (receiver.Receive(m_buf+m_dataEnd, m_buf.size()-m_dataEnd)) - { - unsigned int recvResult = receiver.GetReceiveResult(); -#if CRYPTOPP_TRACE_NETWORK - OutputDebugString((IntToString((unsigned int)this) + ": Received " + IntToString(recvResult) + " bytes\n").c_str()); -#endif - m_dataEnd += recvResult; - if (receiver.EofReceived() || m_dataEnd > m_buf.size() /2) - { - m_waitingForResult = false; - break; - } - } - } - } - } - else - { - m_putSize = UnsignedMin(m_dataEnd - m_dataBegin, maxSize - byteCount); - - if (checkDelimiter) - m_putSize = std::find(m_buf+m_dataBegin, m_buf+m_dataBegin+m_putSize, delimiter) - (m_buf+m_dataBegin); - -DoOutput: - size_t result = t->PutModifiable2(m_buf+m_dataBegin, m_putSize, 0, forever || blockingOutput); - if (result) - { - if (t->Wait(SaturatingSubtract(maxTime, timer.ElapsedTime()), - CallStack("NetworkSource::DoPump() - wait attachment", 0))) - goto DoOutput; - else - { - m_outputBlocked = true; - return result; - } - } - m_outputBlocked = false; - - byteCount += m_putSize; - m_dataBegin += m_putSize; - if (checkDelimiter && m_dataBegin < m_dataEnd && m_buf[m_dataBegin] == delimiter) - break; - if (maxSize != ULONG_MAX && byteCount == maxSize) - break; - // once time limit is reached, return even if there is more data waiting - // but make 0 a special case so caller can request a large amount of data to be - // pumped as long as it is immediately available - if (maxTime > 0 && timer.ElapsedTime() > maxTime) - break; - } - } - - return 0; -} - -// ************************************************************* - -NetworkSink::NetworkSink(unsigned int maxBufferSize, unsigned int autoFlushBound) - : m_maxBufferSize(maxBufferSize), m_autoFlushBound(autoFlushBound) - , m_needSendResult(false), m_wasBlocked(false), m_eofState(EOF_NONE) - , m_buffer(STDMIN(16U*1024U+256, maxBufferSize)), m_skipBytes(0) - , m_speedTimer(Timer::MILLISECONDS), m_byteCountSinceLastTimerReset(0) - , m_currentSpeed(0), m_maxObservedSpeed(0) -{ -} - -float NetworkSink::ComputeCurrentSpeed() -{ - if (m_speedTimer.ElapsedTime() > 1000) - { - m_currentSpeed = m_byteCountSinceLastTimerReset * 1000 / m_speedTimer.ElapsedTime(); - m_maxObservedSpeed = STDMAX(m_currentSpeed, m_maxObservedSpeed * 0.98f); - m_byteCountSinceLastTimerReset = 0; - m_speedTimer.StartTimer(); -// OutputDebugString(("max speed: " + IntToString((int)m_maxObservedSpeed) + " current speed: " + IntToString((int)m_currentSpeed) + "\n").c_str()); - } - return m_currentSpeed; -} - -float NetworkSink::GetMaxObservedSpeed() const -{ - lword m = GetMaxBytesPerSecond(); - return m ? STDMIN(m_maxObservedSpeed, float(CRYPTOPP_VC6_INT64 m)) : m_maxObservedSpeed; -} - -unsigned int NetworkSink::GetMaxWaitObjectCount() const -{ - return LimitedBandwidth::GetMaxWaitObjectCount() + GetSender().GetMaxWaitObjectCount(); -} - -void NetworkSink::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) -{ - if (BlockedBySpeedLimit()) - LimitedBandwidth::GetWaitObjects(container, CallStack("NetworkSink::GetWaitObjects() - speed limit", &callStack)); - else if (m_wasBlocked) - AccessSender().GetWaitObjects(container, CallStack("NetworkSink::GetWaitObjects() - was blocked", &callStack)); - else if (!m_buffer.IsEmpty()) - AccessSender().GetWaitObjects(container, CallStack("NetworkSink::GetWaitObjects() - buffer not empty", &callStack)); - else if (EofPending()) - AccessSender().GetWaitObjects(container, CallStack("NetworkSink::GetWaitObjects() - EOF pending", &callStack)); -} - -size_t NetworkSink::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) -{ - if (m_eofState == EOF_DONE) - { - if (length || messageEnd) - throw Exception(Exception::OTHER_ERROR, "NetworkSink::Put2() being called after EOF had been sent"); - - return 0; - } - - if (m_eofState > EOF_NONE) - goto EofSite; - - { - if (m_skipBytes) - { - assert(length >= m_skipBytes); - inString += m_skipBytes; - length -= m_skipBytes; - } - - m_buffer.Put(inString, length); - - if (!blocking || m_buffer.CurrentSize() > m_autoFlushBound) - TimedFlush(0, 0); - - size_t targetSize = messageEnd ? 0 : m_maxBufferSize; - if (blocking) - TimedFlush(INFINITE_TIME, targetSize); - - if (m_buffer.CurrentSize() > targetSize) - { - assert(!blocking); - m_wasBlocked = true; - m_skipBytes += length; - size_t blockedBytes = UnsignedMin(length, m_buffer.CurrentSize() - targetSize); - return STDMAX<size_t>(blockedBytes, 1); - } - - m_wasBlocked = false; - m_skipBytes = 0; - } - - if (messageEnd) - { - m_eofState = EOF_PENDING_SEND; - - EofSite: - TimedFlush(blocking ? INFINITE_TIME : 0, 0); - if (m_eofState != EOF_DONE) - return 1; - } - - return 0; -} - -lword NetworkSink::DoFlush(unsigned long maxTime, size_t targetSize) -{ - NetworkSender &sender = AccessSender(); - - bool forever = maxTime == INFINITE_TIME; - Timer timer(Timer::MILLISECONDS, forever); - unsigned int totalFlushSize = 0; - - while (true) - { - if (m_buffer.CurrentSize() <= targetSize) - break; - - if (m_needSendResult) - { - if (sender.MustWaitForResult() && - !sender.Wait(SaturatingSubtract(maxTime, timer.ElapsedTime()), - CallStack("NetworkSink::DoFlush() - wait send result", 0))) - break; - - unsigned int sendResult = sender.GetSendResult(); -#if CRYPTOPP_TRACE_NETWORK - OutputDebugString((IntToString((unsigned int)this) + ": Sent " + IntToString(sendResult) + " bytes\n").c_str()); -#endif - m_buffer.Skip(sendResult); - totalFlushSize += sendResult; - m_needSendResult = false; - - if (!m_buffer.AnyRetrievable()) - break; - } - - unsigned long timeOut = maxTime ? SaturatingSubtract(maxTime, timer.ElapsedTime()) : 0; - if (sender.MustWaitToSend() && !sender.Wait(timeOut, CallStack("NetworkSink::DoFlush() - wait send", 0))) - break; - - size_t contiguousSize = 0; - const byte *block = m_buffer.Spy(contiguousSize); - -#if CRYPTOPP_TRACE_NETWORK - OutputDebugString((IntToString((unsigned int)this) + ": Sending " + IntToString(contiguousSize) + " bytes\n").c_str()); -#endif - sender.Send(block, contiguousSize); - m_needSendResult = true; - - if (maxTime > 0 && timeOut == 0) - break; // once time limit is reached, return even if there is more data waiting - } - - m_byteCountSinceLastTimerReset += totalFlushSize; - ComputeCurrentSpeed(); - - if (m_buffer.IsEmpty() && !m_needSendResult) - { - if (m_eofState == EOF_PENDING_SEND) - { - sender.SendEof(); - m_eofState = sender.MustWaitForEof() ? EOF_PENDING_DELIVERY : EOF_DONE; - } - - while (m_eofState == EOF_PENDING_DELIVERY) - { - unsigned long timeOut = maxTime ? SaturatingSubtract(maxTime, timer.ElapsedTime()) : 0; - if (!sender.Wait(timeOut, CallStack("NetworkSink::DoFlush() - wait EOF", 0))) - break; - - if (sender.EofSent()) - m_eofState = EOF_DONE; - } - } - - return totalFlushSize; -} - -#endif // #ifdef HIGHRES_TIMER_AVAILABLE - -NAMESPACE_END diff --git a/lib/cryptopp/network.h b/lib/cryptopp/network.h deleted file mode 100644 index 96cd4567e..000000000 --- a/lib/cryptopp/network.h +++ /dev/null @@ -1,235 +0,0 @@ -#ifndef CRYPTOPP_NETWORK_H -#define CRYPTOPP_NETWORK_H - -#include "config.h" - -#ifdef HIGHRES_TIMER_AVAILABLE - -#include "filters.h" -#include "hrtimer.h" - -#include <deque> - -NAMESPACE_BEGIN(CryptoPP) - -class LimitedBandwidth -{ -public: - LimitedBandwidth(lword maxBytesPerSecond = 0) - : m_maxBytesPerSecond(maxBytesPerSecond), m_timer(Timer::MILLISECONDS) - , m_nextTransceiveTime(0) - { m_timer.StartTimer(); } - - lword GetMaxBytesPerSecond() const - { return m_maxBytesPerSecond; } - - void SetMaxBytesPerSecond(lword v) - { m_maxBytesPerSecond = v; } - - lword ComputeCurrentTransceiveLimit(); - - double TimeToNextTransceive(); - - void NoteTransceive(lword size); - -public: - /*! GetWaitObjects() must be called despite the 0 return from GetMaxWaitObjectCount(); - the 0 is because the ScheduleEvent() method is used instead of adding a wait object */ - unsigned int GetMaxWaitObjectCount() const { return 0; } - void GetWaitObjects(WaitObjectContainer &container, const CallStack &callStack); - -private: - lword m_maxBytesPerSecond; - - typedef std::deque<std::pair<double, lword> > OpQueue; - OpQueue m_ops; - - Timer m_timer; - double m_nextTransceiveTime; - - void ComputeNextTransceiveTime(); - double GetCurTimeAndCleanUp(); -}; - -//! a Source class that can pump from a device for a specified amount of time. -class CRYPTOPP_NO_VTABLE NonblockingSource : public AutoSignaling<Source>, public LimitedBandwidth -{ -public: - NonblockingSource(BufferedTransformation *attachment) - : m_messageEndSent(false) , m_doPumpBlocked(false), m_blockedBySpeedLimit(false) {Detach(attachment);} - - //! \name NONBLOCKING SOURCE - //@{ - - //! pump up to maxSize bytes using at most maxTime milliseconds - /*! If checkDelimiter is true, pump up to delimiter, which itself is not extracted or pumped. */ - size_t GeneralPump2(lword &byteCount, bool blockingOutput=true, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n'); - - lword GeneralPump(lword maxSize=LWORD_MAX, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n') - { - GeneralPump2(maxSize, true, maxTime, checkDelimiter, delimiter); - return maxSize; - } - lword TimedPump(unsigned long maxTime) - {return GeneralPump(LWORD_MAX, maxTime);} - lword PumpLine(byte delimiter='\n', lword maxSize=1024) - {return GeneralPump(maxSize, INFINITE_TIME, true, delimiter);} - - size_t Pump2(lword &byteCount, bool blocking=true) - {return GeneralPump2(byteCount, blocking, blocking ? INFINITE_TIME : 0);} - size_t PumpMessages2(unsigned int &messageCount, bool blocking=true); - //@} - -protected: - virtual size_t DoPump(lword &byteCount, bool blockingOutput, - unsigned long maxTime, bool checkDelimiter, byte delimiter) =0; - - bool BlockedBySpeedLimit() const { return m_blockedBySpeedLimit; } - -private: - bool m_messageEndSent, m_doPumpBlocked, m_blockedBySpeedLimit; -}; - -//! Network Receiver -class CRYPTOPP_NO_VTABLE NetworkReceiver : public Waitable -{ -public: - virtual bool MustWaitToReceive() {return false;} - virtual bool MustWaitForResult() {return false;} - //! receive data from network source, returns whether result is immediately available - virtual bool Receive(byte* buf, size_t bufLen) =0; - virtual unsigned int GetReceiveResult() =0; - virtual bool EofReceived() const =0; -}; - -class CRYPTOPP_NO_VTABLE NonblockingSinkInfo -{ -public: - virtual ~NonblockingSinkInfo() {} - virtual size_t GetMaxBufferSize() const =0; - virtual size_t GetCurrentBufferSize() const =0; - virtual bool EofPending() const =0; - //! compute the current speed of this sink in bytes per second - virtual float ComputeCurrentSpeed() =0; - //! get the maximum observed speed of this sink in bytes per second - virtual float GetMaxObservedSpeed() const =0; -}; - -//! a Sink class that queues input and can flush to a device for a specified amount of time. -class CRYPTOPP_NO_VTABLE NonblockingSink : public Sink, public NonblockingSinkInfo, public LimitedBandwidth -{ -public: - NonblockingSink() : m_blockedBySpeedLimit(false) {} - - bool IsolatedFlush(bool hardFlush, bool blocking); - - //! flush to device for no more than maxTime milliseconds - /*! This function will repeatedly attempt to flush data to some device, until - the queue is empty, or a total of maxTime milliseconds have elapsed. - If maxTime == 0, at least one attempt will be made to flush some data, but - it is likely that not all queued data will be flushed, even if the device - is ready to receive more data without waiting. If you want to flush as much data - as possible without waiting for the device, call this function in a loop. - For example: while (sink.TimedFlush(0) > 0) {} - \return number of bytes flushed - */ - lword TimedFlush(unsigned long maxTime, size_t targetSize = 0); - - virtual void SetMaxBufferSize(size_t maxBufferSize) =0; - //! set a bound which will cause sink to flush if exceeded by GetCurrentBufferSize() - virtual void SetAutoFlushBound(size_t bound) =0; - -protected: - virtual lword DoFlush(unsigned long maxTime, size_t targetSize) = 0; - - bool BlockedBySpeedLimit() const { return m_blockedBySpeedLimit; } - -private: - bool m_blockedBySpeedLimit; -}; - -//! Network Sender -class CRYPTOPP_NO_VTABLE NetworkSender : public Waitable -{ -public: - virtual bool MustWaitToSend() {return false;} - virtual bool MustWaitForResult() {return false;} - virtual void Send(const byte* buf, size_t bufLen) =0; - virtual unsigned int GetSendResult() =0; - virtual bool MustWaitForEof() {return false;} - virtual void SendEof() =0; - virtual bool EofSent() {return false;} // implement if MustWaitForEof() == true -}; - -//! Network Source -class CRYPTOPP_NO_VTABLE NetworkSource : public NonblockingSource -{ -public: - NetworkSource(BufferedTransformation *attachment); - - unsigned int GetMaxWaitObjectCount() const; - void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); - - bool SourceExhausted() const {return m_dataBegin == m_dataEnd && GetReceiver().EofReceived();} - -protected: - size_t DoPump(lword &byteCount, bool blockingOutput, unsigned long maxTime, bool checkDelimiter, byte delimiter); - - virtual NetworkReceiver & AccessReceiver() =0; - const NetworkReceiver & GetReceiver() const {return const_cast<NetworkSource *>(this)->AccessReceiver();} - -private: - SecByteBlock m_buf; - size_t m_putSize, m_dataBegin, m_dataEnd; - bool m_waitingForResult, m_outputBlocked; -}; - -//! Network Sink -class CRYPTOPP_NO_VTABLE NetworkSink : public NonblockingSink -{ -public: - NetworkSink(unsigned int maxBufferSize, unsigned int autoFlushBound); - - unsigned int GetMaxWaitObjectCount() const; - void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); - - size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); - - void SetMaxBufferSize(size_t maxBufferSize) {m_maxBufferSize = maxBufferSize; m_buffer.SetNodeSize(UnsignedMin(maxBufferSize, 16U*1024U+256U));} - void SetAutoFlushBound(size_t bound) {m_autoFlushBound = bound;} - - size_t GetMaxBufferSize() const {return m_maxBufferSize;} - size_t GetCurrentBufferSize() const {return (size_t)m_buffer.CurrentSize();} - - void ClearBuffer() { m_buffer.Clear(); } - - bool EofPending() const { return m_eofState > EOF_NONE && m_eofState < EOF_DONE; } - - //! compute the current speed of this sink in bytes per second - float ComputeCurrentSpeed(); - //! get the maximum observed speed of this sink in bytes per second - float GetMaxObservedSpeed() const; - -protected: - lword DoFlush(unsigned long maxTime, size_t targetSize); - - virtual NetworkSender & AccessSender() =0; - const NetworkSender & GetSender() const {return const_cast<NetworkSink *>(this)->AccessSender();} - -private: - enum EofState { EOF_NONE, EOF_PENDING_SEND, EOF_PENDING_DELIVERY, EOF_DONE }; - - size_t m_maxBufferSize, m_autoFlushBound; - bool m_needSendResult, m_wasBlocked; - EofState m_eofState; - ByteQueue m_buffer; - size_t m_skipBytes; - Timer m_speedTimer; - float m_byteCountSinceLastTimerReset, m_currentSpeed, m_maxObservedSpeed; -}; - -NAMESPACE_END - -#endif // #ifdef HIGHRES_TIMER_AVAILABLE - -#endif diff --git a/lib/cryptopp/nr.h b/lib/cryptopp/nr.h deleted file mode 100644 index c398e3550..000000000 --- a/lib/cryptopp/nr.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef CRYPTOPP_NR_H -#define CRYPTOPP_NR_H - -#include "gfpcrypt.h" - -#endif diff --git a/lib/cryptopp/oaep.cpp b/lib/cryptopp/oaep.cpp deleted file mode 100644 index 1d474be52..000000000 --- a/lib/cryptopp/oaep.cpp +++ /dev/null @@ -1,97 +0,0 @@ -// oaep.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "oaep.h" -#include <functional> - -NAMESPACE_BEGIN(CryptoPP) - -// ******************************************************** - -size_t OAEP_Base::MaxUnpaddedLength(size_t paddedLength) const -{ - return SaturatingSubtract(paddedLength/8, 1+2*DigestSize()); -} - -void OAEP_Base::Pad(RandomNumberGenerator &rng, const byte *input, size_t inputLength, byte *oaepBlock, size_t oaepBlockLen, const NameValuePairs ¶meters) const -{ - assert (inputLength <= MaxUnpaddedLength(oaepBlockLen)); - - // convert from bit length to byte length - if (oaepBlockLen % 8 != 0) - { - oaepBlock[0] = 0; - oaepBlock++; - } - oaepBlockLen /= 8; - - std::auto_ptr<HashTransformation> pHash(NewHash()); - const size_t hLen = pHash->DigestSize(); - const size_t seedLen = hLen, dbLen = oaepBlockLen-seedLen; - byte *const maskedSeed = oaepBlock; - byte *const maskedDB = oaepBlock+seedLen; - - ConstByteArrayParameter encodingParameters; - parameters.GetValue(Name::EncodingParameters(), encodingParameters); - - // DB = pHash || 00 ... || 01 || M - pHash->CalculateDigest(maskedDB, encodingParameters.begin(), encodingParameters.size()); - memset(maskedDB+hLen, 0, dbLen-hLen-inputLength-1); - maskedDB[dbLen-inputLength-1] = 0x01; - memcpy(maskedDB+dbLen-inputLength, input, inputLength); - - rng.GenerateBlock(maskedSeed, seedLen); - std::auto_ptr<MaskGeneratingFunction> pMGF(NewMGF()); - pMGF->GenerateAndMask(*pHash, maskedDB, dbLen, maskedSeed, seedLen); - pMGF->GenerateAndMask(*pHash, maskedSeed, seedLen, maskedDB, dbLen); -} - -DecodingResult OAEP_Base::Unpad(const byte *oaepBlock, size_t oaepBlockLen, byte *output, const NameValuePairs ¶meters) const -{ - bool invalid = false; - - // convert from bit length to byte length - if (oaepBlockLen % 8 != 0) - { - invalid = (oaepBlock[0] != 0) || invalid; - oaepBlock++; - } - oaepBlockLen /= 8; - - std::auto_ptr<HashTransformation> pHash(NewHash()); - const size_t hLen = pHash->DigestSize(); - const size_t seedLen = hLen, dbLen = oaepBlockLen-seedLen; - - invalid = (oaepBlockLen < 2*hLen+1) || invalid; - - SecByteBlock t(oaepBlock, oaepBlockLen); - byte *const maskedSeed = t; - byte *const maskedDB = t+seedLen; - - std::auto_ptr<MaskGeneratingFunction> pMGF(NewMGF()); - pMGF->GenerateAndMask(*pHash, maskedSeed, seedLen, maskedDB, dbLen); - pMGF->GenerateAndMask(*pHash, maskedDB, dbLen, maskedSeed, seedLen); - - ConstByteArrayParameter encodingParameters; - parameters.GetValue(Name::EncodingParameters(), encodingParameters); - - // DB = pHash' || 00 ... || 01 || M - byte *M = std::find(maskedDB+hLen, maskedDB+dbLen, 0x01); - invalid = (M == maskedDB+dbLen) || invalid; - invalid = (std::find_if(maskedDB+hLen, M, std::bind2nd(std::not_equal_to<byte>(), 0)) != M) || invalid; - invalid = !pHash->VerifyDigest(maskedDB, encodingParameters.begin(), encodingParameters.size()) || invalid; - - if (invalid) - return DecodingResult(); - - M++; - memcpy(output, M, maskedDB+dbLen-M); - return DecodingResult(maskedDB+dbLen-M); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/oaep.h b/lib/cryptopp/oaep.h deleted file mode 100644 index 4bf6b0d83..000000000 --- a/lib/cryptopp/oaep.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef CRYPTOPP_OAEP_H -#define CRYPTOPP_OAEP_H - -#include "pubkey.h" -#include "sha.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -class CRYPTOPP_DLL OAEP_Base : public PK_EncryptionMessageEncodingMethod -{ -public: - bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;} - size_t MaxUnpaddedLength(size_t paddedLength) const; - void Pad(RandomNumberGenerator &rng, const byte *raw, size_t inputLength, byte *padded, size_t paddedLength, const NameValuePairs ¶meters) const; - DecodingResult Unpad(const byte *padded, size_t paddedLength, byte *raw, const NameValuePairs ¶meters) const; - -protected: - virtual unsigned int DigestSize() const =0; - virtual HashTransformation * NewHash() const =0; - virtual MaskGeneratingFunction * NewMGF() const =0; -}; - -//! <a href="http://www.weidai.com/scan-mirror/ca.html#cem_OAEP-MGF1">EME-OAEP</a>, for use with classes derived from TF_ES -template <class H, class MGF=P1363_MGF1> -class OAEP : public OAEP_Base, public EncryptionStandard -{ -public: - static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string("OAEP-") + MGF::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";} - typedef OAEP<H, MGF> EncryptionMessageEncodingMethod; - -protected: - unsigned int DigestSize() const {return H::DIGESTSIZE;} - HashTransformation * NewHash() const {return new H;} - MaskGeneratingFunction * NewMGF() const {return new MGF;} -}; - -CRYPTOPP_DLL_TEMPLATE_CLASS OAEP<SHA>; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/oids.h b/lib/cryptopp/oids.h deleted file mode 100644 index 8b1030150..000000000 --- a/lib/cryptopp/oids.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef CRYPTOPP_OIDS_H -#define CRYPTOPP_OIDS_H - -// crypto-related ASN.1 object identifiers - -#include "asn.h" - -NAMESPACE_BEGIN(CryptoPP) - -NAMESPACE_BEGIN(ASN1) - -#define DEFINE_OID(value, name) inline OID name() {return value;} - -DEFINE_OID(1, iso) - DEFINE_OID(iso()+2, member_body) - DEFINE_OID(member_body()+840, iso_us) - DEFINE_OID(iso_us()+10040, ansi_x9_57) - DEFINE_OID(ansi_x9_57()+4+1, id_dsa) - DEFINE_OID(iso_us()+10045, ansi_x9_62) - DEFINE_OID(ansi_x9_62()+1, id_fieldType) - DEFINE_OID(id_fieldType()+1, prime_field) - DEFINE_OID(id_fieldType()+2, characteristic_two_field) - DEFINE_OID(characteristic_two_field()+3, id_characteristic_two_basis) - DEFINE_OID(id_characteristic_two_basis()+1, gnBasis) - DEFINE_OID(id_characteristic_two_basis()+2, tpBasis) - DEFINE_OID(id_characteristic_two_basis()+3, ppBasis) - DEFINE_OID(ansi_x9_62()+2, id_publicKeyType) - DEFINE_OID(id_publicKeyType()+1, id_ecPublicKey) - DEFINE_OID(ansi_x9_62()+3, ansi_x9_62_curves) - DEFINE_OID(ansi_x9_62_curves()+1, ansi_x9_62_curves_prime) - DEFINE_OID(ansi_x9_62_curves_prime()+1, secp192r1) - DEFINE_OID(ansi_x9_62_curves_prime()+7, secp256r1) - DEFINE_OID(iso_us()+113549, rsadsi) - DEFINE_OID(rsadsi()+1, pkcs) - DEFINE_OID(pkcs()+1, pkcs_1) - DEFINE_OID(pkcs_1()+1, rsaEncryption); - DEFINE_OID(rsadsi()+2, rsadsi_digestAlgorithm) - DEFINE_OID(rsadsi_digestAlgorithm()+2, id_md2) - DEFINE_OID(rsadsi_digestAlgorithm()+5, id_md5) - DEFINE_OID(iso()+3, identified_organization); - DEFINE_OID(identified_organization()+14, oiw); - DEFINE_OID(oiw()+3, oiw_secsig); - DEFINE_OID(oiw_secsig()+2, oiw_secsig_algorithms); - DEFINE_OID(oiw_secsig_algorithms()+26, id_sha1); - - DEFINE_OID(identified_organization()+36, teletrust); - DEFINE_OID(teletrust()+3, teletrust_algorithm) - DEFINE_OID(teletrust_algorithm()+2+1, id_ripemd160) - DEFINE_OID(teletrust_algorithm()+3+2+8+1, teletrust_ellipticCurve) - DEFINE_OID(teletrust_ellipticCurve()+1+1, brainpoolP160r1) - DEFINE_OID(teletrust_ellipticCurve()+1+3, brainpoolP192r1) - DEFINE_OID(teletrust_ellipticCurve()+1+5, brainpoolP224r1) - DEFINE_OID(teletrust_ellipticCurve()+1+7, brainpoolP256r1) - DEFINE_OID(teletrust_ellipticCurve()+1+9, brainpoolP320r1) - DEFINE_OID(teletrust_ellipticCurve()+1+11, brainpoolP384r1) - DEFINE_OID(teletrust_ellipticCurve()+1+13, brainpoolP512r1) - - DEFINE_OID(identified_organization()+132, certicom); - DEFINE_OID(certicom()+0, certicom_ellipticCurve); - // these are sorted by curve type and then by OID - // first curves based on GF(p) - DEFINE_OID(certicom_ellipticCurve()+6, secp112r1); - DEFINE_OID(certicom_ellipticCurve()+7, secp112r2); - DEFINE_OID(certicom_ellipticCurve()+8, secp160r1); - DEFINE_OID(certicom_ellipticCurve()+9, secp160k1); - DEFINE_OID(certicom_ellipticCurve()+10, secp256k1); - DEFINE_OID(certicom_ellipticCurve()+28, secp128r1); - DEFINE_OID(certicom_ellipticCurve()+29, secp128r2); - DEFINE_OID(certicom_ellipticCurve()+30, secp160r2); - DEFINE_OID(certicom_ellipticCurve()+31, secp192k1); - DEFINE_OID(certicom_ellipticCurve()+32, secp224k1); - DEFINE_OID(certicom_ellipticCurve()+33, secp224r1); - DEFINE_OID(certicom_ellipticCurve()+34, secp384r1); - DEFINE_OID(certicom_ellipticCurve()+35, secp521r1); - // then curves based on GF(2^n) - DEFINE_OID(certicom_ellipticCurve()+1, sect163k1); - DEFINE_OID(certicom_ellipticCurve()+2, sect163r1); - DEFINE_OID(certicom_ellipticCurve()+3, sect239k1); - DEFINE_OID(certicom_ellipticCurve()+4, sect113r1); - DEFINE_OID(certicom_ellipticCurve()+5, sect113r2); - DEFINE_OID(certicom_ellipticCurve()+15, sect163r2); - DEFINE_OID(certicom_ellipticCurve()+16, sect283k1); - DEFINE_OID(certicom_ellipticCurve()+17, sect283r1); - DEFINE_OID(certicom_ellipticCurve()+22, sect131r1); - DEFINE_OID(certicom_ellipticCurve()+23, sect131r2); - DEFINE_OID(certicom_ellipticCurve()+24, sect193r1); - DEFINE_OID(certicom_ellipticCurve()+25, sect193r2); - DEFINE_OID(certicom_ellipticCurve()+26, sect233k1); - DEFINE_OID(certicom_ellipticCurve()+27, sect233r1); - DEFINE_OID(certicom_ellipticCurve()+36, sect409k1); - DEFINE_OID(certicom_ellipticCurve()+37, sect409r1); - DEFINE_OID(certicom_ellipticCurve()+38, sect571k1); - DEFINE_OID(certicom_ellipticCurve()+39, sect571r1); -DEFINE_OID(2, joint_iso_ccitt) - DEFINE_OID(joint_iso_ccitt()+16, country) - DEFINE_OID(country()+840, joint_iso_ccitt_us) - DEFINE_OID(joint_iso_ccitt_us()+1, us_organization) - DEFINE_OID(us_organization()+101, us_gov) - DEFINE_OID(us_gov()+3, csor) - DEFINE_OID(csor()+4, nistalgorithms) - DEFINE_OID(nistalgorithms()+1, aes) - DEFINE_OID(aes()+1, id_aes128_ECB) - DEFINE_OID(aes()+2, id_aes128_cbc) - DEFINE_OID(aes()+3, id_aes128_ofb) - DEFINE_OID(aes()+4, id_aes128_cfb) - DEFINE_OID(aes()+21, id_aes192_ECB) - DEFINE_OID(aes()+22, id_aes192_cbc) - DEFINE_OID(aes()+23, id_aes192_ofb) - DEFINE_OID(aes()+24, id_aes192_cfb) - DEFINE_OID(aes()+41, id_aes256_ECB) - DEFINE_OID(aes()+42, id_aes256_cbc) - DEFINE_OID(aes()+43, id_aes256_ofb) - DEFINE_OID(aes()+44, id_aes256_cfb) - DEFINE_OID(nistalgorithms()+2, nist_hashalgs) - DEFINE_OID(nist_hashalgs()+1, id_sha256) - DEFINE_OID(nist_hashalgs()+2, id_sha384) - DEFINE_OID(nist_hashalgs()+3, id_sha512) - -NAMESPACE_END - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/osrng.cpp b/lib/cryptopp/osrng.cpp deleted file mode 100644 index 76e486b4e..000000000 --- a/lib/cryptopp/osrng.cpp +++ /dev/null @@ -1,192 +0,0 @@ -// osrng.cpp - written and placed in the public domain by Wei Dai - -// Thanks to Leonard Janke for the suggestion for AutoSeededRandomPool. - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "osrng.h" - -#ifdef OS_RNG_AVAILABLE - -#include "rng.h" - -#ifdef CRYPTOPP_WIN32_AVAILABLE -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0400 -#endif -#include <windows.h> -#include <wincrypt.h> -#endif - -#ifdef CRYPTOPP_UNIX_AVAILABLE -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#endif - -NAMESPACE_BEGIN(CryptoPP) - -#if defined(NONBLOCKING_RNG_AVAILABLE) || defined(BLOCKING_RNG_AVAILABLE) -OS_RNG_Err::OS_RNG_Err(const std::string &operation) - : Exception(OTHER_ERROR, "OS_Rng: " + operation + " operation failed with error " + -#ifdef CRYPTOPP_WIN32_AVAILABLE - "0x" + IntToString(GetLastError(), 16) -#else - IntToString(errno) -#endif - ) -{ -} -#endif - -#ifdef NONBLOCKING_RNG_AVAILABLE - -#ifdef CRYPTOPP_WIN32_AVAILABLE - -MicrosoftCryptoProvider::MicrosoftCryptoProvider() -{ - if(!CryptAcquireContext(&m_hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) - throw OS_RNG_Err("CryptAcquireContext"); -} - -MicrosoftCryptoProvider::~MicrosoftCryptoProvider() -{ - CryptReleaseContext(m_hProvider, 0); -} - -#endif - -NonblockingRng::NonblockingRng() -{ -#ifndef CRYPTOPP_WIN32_AVAILABLE - m_fd = open("/dev/urandom",O_RDONLY); - if (m_fd == -1) - throw OS_RNG_Err("open /dev/urandom"); -#endif -} - -NonblockingRng::~NonblockingRng() -{ -#ifndef CRYPTOPP_WIN32_AVAILABLE - close(m_fd); -#endif -} - -void NonblockingRng::GenerateBlock(byte *output, size_t size) -{ -#ifdef CRYPTOPP_WIN32_AVAILABLE -# ifdef WORKAROUND_MS_BUG_Q258000 - const MicrosoftCryptoProvider &m_Provider = Singleton<MicrosoftCryptoProvider>().Ref(); -# endif - if (!CryptGenRandom(m_Provider.GetProviderHandle(), (DWORD)size, output)) - throw OS_RNG_Err("CryptGenRandom"); -#else - while (size) - { - ssize_t len = read(m_fd, output, size); - - if (len < 0) - { - // /dev/urandom reads CAN give EAGAIN errors! (maybe EINTR as well) - if (errno != EINTR && errno != EAGAIN) - throw OS_RNG_Err("read /dev/urandom"); - - continue; - } - - output += len; - size -= len; - } -#endif -} - -#endif - -// ************************************************************* - -#ifdef BLOCKING_RNG_AVAILABLE - -#ifndef CRYPTOPP_BLOCKING_RNG_FILENAME -#ifdef __OpenBSD__ -#define CRYPTOPP_BLOCKING_RNG_FILENAME "/dev/srandom" -#else -#define CRYPTOPP_BLOCKING_RNG_FILENAME "/dev/random" -#endif -#endif - -BlockingRng::BlockingRng() -{ - m_fd = open(CRYPTOPP_BLOCKING_RNG_FILENAME,O_RDONLY); - if (m_fd == -1) - throw OS_RNG_Err("open " CRYPTOPP_BLOCKING_RNG_FILENAME); -} - -BlockingRng::~BlockingRng() -{ - close(m_fd); -} - -void BlockingRng::GenerateBlock(byte *output, size_t size) -{ - while (size) - { - // on some systems /dev/random will block until all bytes - // are available, on others it returns immediately - ssize_t len = read(m_fd, output, size); - if (len < 0) - { - // /dev/random reads CAN give EAGAIN errors! (maybe EINTR as well) - if (errno != EINTR && errno != EAGAIN) - throw OS_RNG_Err("read " CRYPTOPP_BLOCKING_RNG_FILENAME); - - continue; - } - - size -= len; - output += len; - if (size) - sleep(1); - } -} - -#endif - -// ************************************************************* - -void OS_GenerateRandomBlock(bool blocking, byte *output, size_t size) -{ -#ifdef NONBLOCKING_RNG_AVAILABLE - if (blocking) -#endif - { -#ifdef BLOCKING_RNG_AVAILABLE - BlockingRng rng; - rng.GenerateBlock(output, size); -#endif - } - -#ifdef BLOCKING_RNG_AVAILABLE - if (!blocking) -#endif - { -#ifdef NONBLOCKING_RNG_AVAILABLE - NonblockingRng rng; - rng.GenerateBlock(output, size); -#endif - } -} - -void AutoSeededRandomPool::Reseed(bool blocking, unsigned int seedSize) -{ - SecByteBlock seed(seedSize); - OS_GenerateRandomBlock(blocking, seed, seedSize); - IncorporateEntropy(seed, seedSize); -} - -NAMESPACE_END - -#endif - -#endif diff --git a/lib/cryptopp/osrng.h b/lib/cryptopp/osrng.h deleted file mode 100644 index ae07d057b..000000000 --- a/lib/cryptopp/osrng.h +++ /dev/null @@ -1,156 +0,0 @@ -#ifndef CRYPTOPP_OSRNG_H -#define CRYPTOPP_OSRNG_H - -//! \file - -#include "config.h" - -#ifdef OS_RNG_AVAILABLE - -#include "randpool.h" -#include "rng.h" -#include "aes.h" -#include "sha.h" -#include "fips140.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! Exception class for Operating-System Random Number Generator. -class CRYPTOPP_DLL OS_RNG_Err : public Exception -{ -public: - OS_RNG_Err(const std::string &operation); -}; - -#ifdef NONBLOCKING_RNG_AVAILABLE - -#ifdef CRYPTOPP_WIN32_AVAILABLE -class CRYPTOPP_DLL MicrosoftCryptoProvider -{ -public: - MicrosoftCryptoProvider(); - ~MicrosoftCryptoProvider(); -#if defined(_WIN64) - typedef unsigned __int64 ProviderHandle; // type HCRYPTPROV, avoid #include <windows.h> -#else - typedef unsigned long ProviderHandle; -#endif - ProviderHandle GetProviderHandle() const {return m_hProvider;} -private: - ProviderHandle m_hProvider; -}; - -#pragma comment(lib, "advapi32.lib") -#endif - -//! encapsulate CryptoAPI's CryptGenRandom or /dev/urandom -class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator -{ -public: - NonblockingRng(); - ~NonblockingRng(); - void GenerateBlock(byte *output, size_t size); - -protected: -#ifdef CRYPTOPP_WIN32_AVAILABLE -# ifndef WORKAROUND_MS_BUG_Q258000 - MicrosoftCryptoProvider m_Provider; -# endif -#else - int m_fd; -#endif -}; - -#endif - -#ifdef BLOCKING_RNG_AVAILABLE - -//! encapsulate /dev/random, or /dev/srandom on OpenBSD -class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator -{ -public: - BlockingRng(); - ~BlockingRng(); - void GenerateBlock(byte *output, size_t size); - -protected: - int m_fd; -}; - -#endif - -CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *output, size_t size); - -//! Automaticly Seeded Randomness Pool -/*! This class seeds itself using an operating system provided RNG. */ -class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool -{ -public: - //! use blocking to choose seeding with BlockingRng or NonblockingRng. the parameter is ignored if only one of these is available - explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32) - {Reseed(blocking, seedSize);} - void Reseed(bool blocking = false, unsigned int seedSize = 32); -}; - -//! RNG from ANSI X9.17 Appendix C, seeded using an OS provided RNG -template <class BLOCK_CIPHER> -class AutoSeededX917RNG : public RandomNumberGenerator, public NotCopyable -{ -public: - //! use blocking to choose seeding with BlockingRng or NonblockingRng. the parameter is ignored if only one of these is available - explicit AutoSeededX917RNG(bool blocking = false, bool autoSeed = true) - {if (autoSeed) Reseed(blocking);} - void Reseed(bool blocking = false, const byte *additionalEntropy = NULL, size_t length = 0); - // exposed for testing - void Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector); - - bool CanIncorporateEntropy() const {return true;} - void IncorporateEntropy(const byte *input, size_t length) {Reseed(false, input, length);} - void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length) {m_rng->GenerateIntoBufferedTransformation(target, channel, length);} - -private: - member_ptr<RandomNumberGenerator> m_rng; -}; - -template <class BLOCK_CIPHER> -void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector) -{ - m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector)); -} - -template <class BLOCK_CIPHER> -void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking, const byte *input, size_t length) -{ - SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH); - const byte *key; - do - { - OS_GenerateRandomBlock(blocking, seed, seed.size()); - if (length > 0) - { - SHA256 hash; - hash.Update(seed, seed.size()); - hash.Update(input, length); - hash.TruncatedFinal(seed, UnsignedMin(hash.DigestSize(), seed.size())); - } - key = seed + BLOCK_CIPHER::BLOCKSIZE; - } // check that seed and key don't have same value - while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0); - - Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, NULL); -} - -CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG<AES>; - -//! this is AutoSeededX917RNG\<AES\> in FIPS mode, otherwise it's AutoSeededRandomPool -#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 -typedef AutoSeededX917RNG<AES> DefaultAutoSeededRNG; -#else -typedef AutoSeededRandomPool DefaultAutoSeededRNG; -#endif - -NAMESPACE_END - -#endif - -#endif diff --git a/lib/cryptopp/pch.cpp b/lib/cryptopp/pch.cpp deleted file mode 100644 index 1d9f38c57..000000000 --- a/lib/cryptopp/pch.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "pch.h" diff --git a/lib/cryptopp/pch.h b/lib/cryptopp/pch.h deleted file mode 100644 index 418c39076..000000000 --- a/lib/cryptopp/pch.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef CRYPTOPP_PCH_H -#define CRYPTOPP_PCH_H - -#ifdef CRYPTOPP_GENERATE_X64_MASM - - #include "cpu.h" - -#else - - #include "config.h" - - #ifdef USE_PRECOMPILED_HEADERS - #include "simple.h" - #include "secblock.h" - #include "misc.h" - #include "smartptr.h" - #endif - -#endif - -#endif diff --git a/lib/cryptopp/pkcspad.cpp b/lib/cryptopp/pkcspad.cpp deleted file mode 100644 index e1f1d1e23..000000000 --- a/lib/cryptopp/pkcspad.cpp +++ /dev/null @@ -1,124 +0,0 @@ -// pkcspad.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_PKCSPAD_CPP // SunCC workaround: compiler could cause this file to be included twice -#define CRYPTOPP_PKCSPAD_CPP - -#include "pkcspad.h" -#include <assert.h> - -NAMESPACE_BEGIN(CryptoPP) - -// more in dll.cpp -template<> const byte PKCS_DigestDecoration<Weak1::MD2>::decoration[] = {0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x02,0x05,0x00,0x04,0x10}; -template<> const unsigned int PKCS_DigestDecoration<Weak1::MD2>::length = sizeof(PKCS_DigestDecoration<Weak1::MD2>::decoration); - -template<> const byte PKCS_DigestDecoration<Weak1::MD5>::decoration[] = {0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x04,0x10}; -template<> const unsigned int PKCS_DigestDecoration<Weak1::MD5>::length = sizeof(PKCS_DigestDecoration<Weak1::MD5>::decoration); - -template<> const byte PKCS_DigestDecoration<RIPEMD160>::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x24,0x03,0x02,0x01,0x05,0x00,0x04,0x14}; -template<> const unsigned int PKCS_DigestDecoration<RIPEMD160>::length = sizeof(PKCS_DigestDecoration<RIPEMD160>::decoration); - -template<> const byte PKCS_DigestDecoration<Tiger>::decoration[] = {0x30,0x29,0x30,0x0D,0x06,0x09,0x2B,0x06,0x01,0x04,0x01,0xDA,0x47,0x0C,0x02,0x05,0x00,0x04,0x18}; -template<> const unsigned int PKCS_DigestDecoration<Tiger>::length = sizeof(PKCS_DigestDecoration<Tiger>::decoration); - -size_t PKCS_EncryptionPaddingScheme::MaxUnpaddedLength(size_t paddedLength) const -{ - return SaturatingSubtract(paddedLength/8, 10U); -} - -void PKCS_EncryptionPaddingScheme::Pad(RandomNumberGenerator &rng, const byte *input, size_t inputLen, byte *pkcsBlock, size_t pkcsBlockLen, const NameValuePairs ¶meters) const -{ - assert (inputLen <= MaxUnpaddedLength(pkcsBlockLen)); // this should be checked by caller - - // convert from bit length to byte length - if (pkcsBlockLen % 8 != 0) - { - pkcsBlock[0] = 0; - pkcsBlock++; - } - pkcsBlockLen /= 8; - - pkcsBlock[0] = 2; // block type 2 - - // pad with non-zero random bytes - for (unsigned i = 1; i < pkcsBlockLen-inputLen-1; i++) - pkcsBlock[i] = (byte)rng.GenerateWord32(1, 0xff); - - pkcsBlock[pkcsBlockLen-inputLen-1] = 0; // separator - memcpy(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen); -} - -DecodingResult PKCS_EncryptionPaddingScheme::Unpad(const byte *pkcsBlock, size_t pkcsBlockLen, byte *output, const NameValuePairs ¶meters) const -{ - bool invalid = false; - size_t maxOutputLen = MaxUnpaddedLength(pkcsBlockLen); - - // convert from bit length to byte length - if (pkcsBlockLen % 8 != 0) - { - invalid = (pkcsBlock[0] != 0) || invalid; - pkcsBlock++; - } - pkcsBlockLen /= 8; - - // Require block type 2. - invalid = (pkcsBlock[0] != 2) || invalid; - - // skip past the padding until we find the separator - size_t i=1; - while (i<pkcsBlockLen && pkcsBlock[i++]) { // null body - } - assert(i==pkcsBlockLen || pkcsBlock[i-1]==0); - - size_t outputLen = pkcsBlockLen - i; - invalid = (outputLen > maxOutputLen) || invalid; - - if (invalid) - return DecodingResult(); - - memcpy (output, pkcsBlock+i, outputLen); - return DecodingResult(outputLen); -} - -// ******************************************************** - -#ifndef CRYPTOPP_IMPORTS - -void PKCS1v15_SignatureMessageEncodingMethod::ComputeMessageRepresentative(RandomNumberGenerator &rng, - const byte *recoverableMessage, size_t recoverableMessageLength, - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const -{ - assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize())); - - size_t pkcsBlockLen = representativeBitLength; - // convert from bit length to byte length - if (pkcsBlockLen % 8 != 0) - { - representative[0] = 0; - representative++; - } - pkcsBlockLen /= 8; - - representative[0] = 1; // block type 1 - - unsigned int digestSize = hash.DigestSize(); - byte *pPadding = representative + 1; - byte *pDigest = representative + pkcsBlockLen - digestSize; - byte *pHashId = pDigest - hashIdentifier.second; - byte *pSeparator = pHashId - 1; - - // pad with 0xff - memset(pPadding, 0xff, pSeparator-pPadding); - *pSeparator = 0; - memcpy(pHashId, hashIdentifier.first, hashIdentifier.second); - hash.Final(pDigest); -} - -#endif - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/pkcspad.h b/lib/cryptopp/pkcspad.h deleted file mode 100644 index 6371c7698..000000000 --- a/lib/cryptopp/pkcspad.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef CRYPTOPP_PKCSPAD_H -#define CRYPTOPP_PKCSPAD_H - -#include "cryptlib.h" -#include "pubkey.h" - -#ifdef CRYPTOPP_IS_DLL -#include "sha.h" -#endif - -NAMESPACE_BEGIN(CryptoPP) - -//! <a href="http://www.weidai.com/scan-mirror/ca.html#cem_PKCS1-1.5">EME-PKCS1-v1_5</a> -class PKCS_EncryptionPaddingScheme : public PK_EncryptionMessageEncodingMethod -{ -public: - static const char * StaticAlgorithmName() {return "EME-PKCS1-v1_5";} - - size_t MaxUnpaddedLength(size_t paddedLength) const; - void Pad(RandomNumberGenerator &rng, const byte *raw, size_t inputLength, byte *padded, size_t paddedLength, const NameValuePairs ¶meters) const; - DecodingResult Unpad(const byte *padded, size_t paddedLength, byte *raw, const NameValuePairs ¶meters) const; -}; - -template <class H> class PKCS_DigestDecoration -{ -public: - static const byte decoration[]; - static const unsigned int length; -}; - -// PKCS_DigestDecoration can be instantiated with the following -// classes as specified in PKCS#1 v2.0 and P1363a -class SHA1; -class RIPEMD160; -class Tiger; -class SHA224; -class SHA256; -class SHA384; -class SHA512; -namespace Weak1 { -class MD2; -class MD5; -} -// end of list - -#ifdef CRYPTOPP_IS_DLL -CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA1>; -CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA224>; -CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA256>; -CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA384>; -CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration<SHA512>; -#endif - -//! <a href="http://www.weidai.com/scan-mirror/sig.html#sem_PKCS1-1.5">EMSA-PKCS1-v1_5</a> -class CRYPTOPP_DLL PKCS1v15_SignatureMessageEncodingMethod : public PK_DeterministicSignatureMessageEncodingMethod -{ -public: - static const char * CRYPTOPP_API StaticAlgorithmName() {return "EMSA-PKCS1-v1_5";} - - size_t MinRepresentativeBitLength(size_t hashIdentifierSize, size_t digestSize) const - {return 8 * (digestSize + hashIdentifierSize + 10);} - - void ComputeMessageRepresentative(RandomNumberGenerator &rng, - const byte *recoverableMessage, size_t recoverableMessageLength, - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const; - - struct HashIdentifierLookup - { - template <class H> struct HashIdentifierLookup2 - { - static HashIdentifier Lookup() - { - return HashIdentifier(PKCS_DigestDecoration<H>::decoration, PKCS_DigestDecoration<H>::length); - } - }; - }; -}; - -//! PKCS #1 version 1.5, for use with RSAES and RSASS -/*! Only the following hash functions are supported by this signature standard: - \dontinclude pkcspad.h - \skip can be instantiated - \until end of list -*/ -struct PKCS1v15 : public SignatureStandard, public EncryptionStandard -{ - typedef PKCS_EncryptionPaddingScheme EncryptionMessageEncodingMethod; - typedef PKCS1v15_SignatureMessageEncodingMethod SignatureMessageEncodingMethod; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/polynomi.cpp b/lib/cryptopp/polynomi.cpp deleted file mode 100644 index 734cae926..000000000 --- a/lib/cryptopp/polynomi.cpp +++ /dev/null @@ -1,577 +0,0 @@ -// polynomi.cpp - written and placed in the public domain by Wei Dai - -// Part of the code for polynomial evaluation and interpolation -// originally came from Hal Finney's public domain secsplit.c. - -#include "pch.h" -#include "polynomi.h" -#include "secblock.h" - -#include <sstream> -#include <iostream> - -NAMESPACE_BEGIN(CryptoPP) - -template <class T> -void PolynomialOver<T>::Randomize(RandomNumberGenerator &rng, const RandomizationParameter ¶meter, const Ring &ring) -{ - m_coefficients.resize(parameter.m_coefficientCount); - for (unsigned int i=0; i<m_coefficients.size(); ++i) - m_coefficients[i] = ring.RandomElement(rng, parameter.m_coefficientParameter); -} - -template <class T> -void PolynomialOver<T>::FromStr(const char *str, const Ring &ring) -{ - std::istringstream in((char *)str); - bool positive = true; - CoefficientType coef; - unsigned int power; - - while (in) - { - std::ws(in); - if (in.peek() == 'x') - coef = ring.MultiplicativeIdentity(); - else - in >> coef; - - std::ws(in); - if (in.peek() == 'x') - { - in.get(); - std::ws(in); - if (in.peek() == '^') - { - in.get(); - in >> power; - } - else - power = 1; - } - else - power = 0; - - if (!positive) - coef = ring.Inverse(coef); - - SetCoefficient(power, coef, ring); - - std::ws(in); - switch (in.get()) - { - case '+': - positive = true; - break; - case '-': - positive = false; - break; - default: - return; // something's wrong with the input string - } - } -} - -template <class T> -unsigned int PolynomialOver<T>::CoefficientCount(const Ring &ring) const -{ - unsigned count = m_coefficients.size(); - while (count && ring.Equal(m_coefficients[count-1], ring.Identity())) - count--; - const_cast<std::vector<CoefficientType> &>(m_coefficients).resize(count); - return count; -} - -template <class T> -typename PolynomialOver<T>::CoefficientType PolynomialOver<T>::GetCoefficient(unsigned int i, const Ring &ring) const -{ - return (i < m_coefficients.size()) ? m_coefficients[i] : ring.Identity(); -} - -template <class T> -PolynomialOver<T>& PolynomialOver<T>::operator=(const PolynomialOver<T>& t) -{ - if (this != &t) - { - m_coefficients.resize(t.m_coefficients.size()); - for (unsigned int i=0; i<m_coefficients.size(); i++) - m_coefficients[i] = t.m_coefficients[i]; - } - return *this; -} - -template <class T> -PolynomialOver<T>& PolynomialOver<T>::Accumulate(const PolynomialOver<T>& t, const Ring &ring) -{ - unsigned int count = t.CoefficientCount(ring); - - if (count > CoefficientCount(ring)) - m_coefficients.resize(count, ring.Identity()); - - for (unsigned int i=0; i<count; i++) - ring.Accumulate(m_coefficients[i], t.GetCoefficient(i, ring)); - - return *this; -} - -template <class T> -PolynomialOver<T>& PolynomialOver<T>::Reduce(const PolynomialOver<T>& t, const Ring &ring) -{ - unsigned int count = t.CoefficientCount(ring); - - if (count > CoefficientCount(ring)) - m_coefficients.resize(count, ring.Identity()); - - for (unsigned int i=0; i<count; i++) - ring.Reduce(m_coefficients[i], t.GetCoefficient(i, ring)); - - return *this; -} - -template <class T> -typename PolynomialOver<T>::CoefficientType PolynomialOver<T>::EvaluateAt(const CoefficientType &x, const Ring &ring) const -{ - int degree = Degree(ring); - - if (degree < 0) - return ring.Identity(); - - CoefficientType result = m_coefficients[degree]; - for (int j=degree-1; j>=0; j--) - { - result = ring.Multiply(result, x); - ring.Accumulate(result, m_coefficients[j]); - } - return result; -} - -template <class T> -PolynomialOver<T>& PolynomialOver<T>::ShiftLeft(unsigned int n, const Ring &ring) -{ - unsigned int i = CoefficientCount(ring) + n; - m_coefficients.resize(i, ring.Identity()); - while (i > n) - { - i--; - m_coefficients[i] = m_coefficients[i-n]; - } - while (i) - { - i--; - m_coefficients[i] = ring.Identity(); - } - return *this; -} - -template <class T> -PolynomialOver<T>& PolynomialOver<T>::ShiftRight(unsigned int n, const Ring &ring) -{ - unsigned int count = CoefficientCount(ring); - if (count > n) - { - for (unsigned int i=0; i<count-n; i++) - m_coefficients[i] = m_coefficients[i+n]; - m_coefficients.resize(count-n, ring.Identity()); - } - else - m_coefficients.resize(0, ring.Identity()); - return *this; -} - -template <class T> -void PolynomialOver<T>::SetCoefficient(unsigned int i, const CoefficientType &value, const Ring &ring) -{ - if (i >= m_coefficients.size()) - m_coefficients.resize(i+1, ring.Identity()); - m_coefficients[i] = value; -} - -template <class T> -void PolynomialOver<T>::Negate(const Ring &ring) -{ - unsigned int count = CoefficientCount(ring); - for (unsigned int i=0; i<count; i++) - m_coefficients[i] = ring.Inverse(m_coefficients[i]); -} - -template <class T> -void PolynomialOver<T>::swap(PolynomialOver<T> &t) -{ - m_coefficients.swap(t.m_coefficients); -} - -template <class T> -bool PolynomialOver<T>::Equals(const PolynomialOver<T>& t, const Ring &ring) const -{ - unsigned int count = CoefficientCount(ring); - - if (count != t.CoefficientCount(ring)) - return false; - - for (unsigned int i=0; i<count; i++) - if (!ring.Equal(m_coefficients[i], t.m_coefficients[i])) - return false; - - return true; -} - -template <class T> -PolynomialOver<T> PolynomialOver<T>::Plus(const PolynomialOver<T>& t, const Ring &ring) const -{ - unsigned int i; - unsigned int count = CoefficientCount(ring); - unsigned int tCount = t.CoefficientCount(ring); - - if (count > tCount) - { - PolynomialOver<T> result(ring, count); - - for (i=0; i<tCount; i++) - result.m_coefficients[i] = ring.Add(m_coefficients[i], t.m_coefficients[i]); - for (; i<count; i++) - result.m_coefficients[i] = m_coefficients[i]; - - return result; - } - else - { - PolynomialOver<T> result(ring, tCount); - - for (i=0; i<count; i++) - result.m_coefficients[i] = ring.Add(m_coefficients[i], t.m_coefficients[i]); - for (; i<tCount; i++) - result.m_coefficients[i] = t.m_coefficients[i]; - - return result; - } -} - -template <class T> -PolynomialOver<T> PolynomialOver<T>::Minus(const PolynomialOver<T>& t, const Ring &ring) const -{ - unsigned int i; - unsigned int count = CoefficientCount(ring); - unsigned int tCount = t.CoefficientCount(ring); - - if (count > tCount) - { - PolynomialOver<T> result(ring, count); - - for (i=0; i<tCount; i++) - result.m_coefficients[i] = ring.Subtract(m_coefficients[i], t.m_coefficients[i]); - for (; i<count; i++) - result.m_coefficients[i] = m_coefficients[i]; - - return result; - } - else - { - PolynomialOver<T> result(ring, tCount); - - for (i=0; i<count; i++) - result.m_coefficients[i] = ring.Subtract(m_coefficients[i], t.m_coefficients[i]); - for (; i<tCount; i++) - result.m_coefficients[i] = ring.Inverse(t.m_coefficients[i]); - - return result; - } -} - -template <class T> -PolynomialOver<T> PolynomialOver<T>::Inverse(const Ring &ring) const -{ - unsigned int count = CoefficientCount(ring); - PolynomialOver<T> result(ring, count); - - for (unsigned int i=0; i<count; i++) - result.m_coefficients[i] = ring.Inverse(m_coefficients[i]); - - return result; -} - -template <class T> -PolynomialOver<T> PolynomialOver<T>::Times(const PolynomialOver<T>& t, const Ring &ring) const -{ - if (IsZero(ring) || t.IsZero(ring)) - return PolynomialOver<T>(); - - unsigned int count1 = CoefficientCount(ring), count2 = t.CoefficientCount(ring); - PolynomialOver<T> result(ring, count1 + count2 - 1); - - for (unsigned int i=0; i<count1; i++) - for (unsigned int j=0; j<count2; j++) - ring.Accumulate(result.m_coefficients[i+j], ring.Multiply(m_coefficients[i], t.m_coefficients[j])); - - return result; -} - -template <class T> -PolynomialOver<T> PolynomialOver<T>::DividedBy(const PolynomialOver<T>& t, const Ring &ring) const -{ - PolynomialOver<T> remainder, quotient; - Divide(remainder, quotient, *this, t, ring); - return quotient; -} - -template <class T> -PolynomialOver<T> PolynomialOver<T>::Modulo(const PolynomialOver<T>& t, const Ring &ring) const -{ - PolynomialOver<T> remainder, quotient; - Divide(remainder, quotient, *this, t, ring); - return remainder; -} - -template <class T> -PolynomialOver<T> PolynomialOver<T>::MultiplicativeInverse(const Ring &ring) const -{ - return Degree(ring)==0 ? ring.MultiplicativeInverse(m_coefficients[0]) : ring.Identity(); -} - -template <class T> -bool PolynomialOver<T>::IsUnit(const Ring &ring) const -{ - return Degree(ring)==0 && ring.IsUnit(m_coefficients[0]); -} - -template <class T> -std::istream& PolynomialOver<T>::Input(std::istream &in, const Ring &ring) -{ - char c; - unsigned int length = 0; - SecBlock<char> str(length + 16); - bool paren = false; - - std::ws(in); - - if (in.peek() == '(') - { - paren = true; - in.get(); - } - - do - { - in.read(&c, 1); - str[length++] = c; - if (length >= str.size()) - str.Grow(length + 16); - } - // if we started with a left paren, then read until we find a right paren, - // otherwise read until the end of the line - while (in && ((paren && c != ')') || (!paren && c != '\n'))); - - str[length-1] = '\0'; - *this = PolynomialOver<T>(str, ring); - - return in; -} - -template <class T> -std::ostream& PolynomialOver<T>::Output(std::ostream &out, const Ring &ring) const -{ - unsigned int i = CoefficientCount(ring); - if (i) - { - bool firstTerm = true; - - while (i--) - { - if (m_coefficients[i] != ring.Identity()) - { - if (firstTerm) - { - firstTerm = false; - if (!i || !ring.Equal(m_coefficients[i], ring.MultiplicativeIdentity())) - out << m_coefficients[i]; - } - else - { - CoefficientType inverse = ring.Inverse(m_coefficients[i]); - std::ostringstream pstr, nstr; - - pstr << m_coefficients[i]; - nstr << inverse; - - if (pstr.str().size() <= nstr.str().size()) - { - out << " + "; - if (!i || !ring.Equal(m_coefficients[i], ring.MultiplicativeIdentity())) - out << m_coefficients[i]; - } - else - { - out << " - "; - if (!i || !ring.Equal(inverse, ring.MultiplicativeIdentity())) - out << inverse; - } - } - - switch (i) - { - case 0: - break; - case 1: - out << "x"; - break; - default: - out << "x^" << i; - } - } - } - } - else - { - out << ring.Identity(); - } - return out; -} - -template <class T> -void PolynomialOver<T>::Divide(PolynomialOver<T> &r, PolynomialOver<T> &q, const PolynomialOver<T> &a, const PolynomialOver<T> &d, const Ring &ring) -{ - unsigned int i = a.CoefficientCount(ring); - const int dDegree = d.Degree(ring); - - if (dDegree < 0) - throw DivideByZero(); - - r = a; - q.m_coefficients.resize(STDMAX(0, int(i - dDegree))); - - while (i > (unsigned int)dDegree) - { - --i; - q.m_coefficients[i-dDegree] = ring.Divide(r.m_coefficients[i], d.m_coefficients[dDegree]); - for (int j=0; j<=dDegree; j++) - ring.Reduce(r.m_coefficients[i-dDegree+j], ring.Multiply(q.m_coefficients[i-dDegree], d.m_coefficients[j])); - } - - r.CoefficientCount(ring); // resize r.m_coefficients -} - -// ******************************************************** - -// helper function for Interpolate() and InterpolateAt() -template <class T> -void RingOfPolynomialsOver<T>::CalculateAlpha(std::vector<CoefficientType> &alpha, const CoefficientType x[], const CoefficientType y[], unsigned int n) const -{ - for (unsigned int j=0; j<n; ++j) - alpha[j] = y[j]; - - for (unsigned int k=1; k<n; ++k) - { - for (unsigned int j=n-1; j>=k; --j) - { - m_ring.Reduce(alpha[j], alpha[j-1]); - - CoefficientType d = m_ring.Subtract(x[j], x[j-k]); - if (!m_ring.IsUnit(d)) - throw InterpolationFailed(); - alpha[j] = m_ring.Divide(alpha[j], d); - } - } -} - -template <class T> -typename RingOfPolynomialsOver<T>::Element RingOfPolynomialsOver<T>::Interpolate(const CoefficientType x[], const CoefficientType y[], unsigned int n) const -{ - assert(n > 0); - - std::vector<CoefficientType> alpha(n); - CalculateAlpha(alpha, x, y, n); - - std::vector<CoefficientType> coefficients((size_t)n, m_ring.Identity()); - coefficients[0] = alpha[n-1]; - - for (int j=n-2; j>=0; --j) - { - for (unsigned int i=n-j-1; i>0; i--) - coefficients[i] = m_ring.Subtract(coefficients[i-1], m_ring.Multiply(coefficients[i], x[j])); - - coefficients[0] = m_ring.Subtract(alpha[j], m_ring.Multiply(coefficients[0], x[j])); - } - - return PolynomialOver<T>(coefficients.begin(), coefficients.end()); -} - -template <class T> -typename RingOfPolynomialsOver<T>::CoefficientType RingOfPolynomialsOver<T>::InterpolateAt(const CoefficientType &position, const CoefficientType x[], const CoefficientType y[], unsigned int n) const -{ - assert(n > 0); - - std::vector<CoefficientType> alpha(n); - CalculateAlpha(alpha, x, y, n); - - CoefficientType result = alpha[n-1]; - for (int j=n-2; j>=0; --j) - { - result = m_ring.Multiply(result, m_ring.Subtract(position, x[j])); - m_ring.Accumulate(result, alpha[j]); - } - return result; -} - -template <class Ring, class Element> -void PrepareBulkPolynomialInterpolation(const Ring &ring, Element *w, const Element x[], unsigned int n) -{ - for (unsigned int i=0; i<n; i++) - { - Element t = ring.MultiplicativeIdentity(); - for (unsigned int j=0; j<n; j++) - if (i != j) - t = ring.Multiply(t, ring.Subtract(x[i], x[j])); - w[i] = ring.MultiplicativeInverse(t); - } -} - -template <class Ring, class Element> -void PrepareBulkPolynomialInterpolationAt(const Ring &ring, Element *v, const Element &position, const Element x[], const Element w[], unsigned int n) -{ - assert(n > 0); - - std::vector<Element> a(2*n-1); - unsigned int i; - - for (i=0; i<n; i++) - a[n-1+i] = ring.Subtract(position, x[i]); - - for (i=n-1; i>1; i--) - a[i-1] = ring.Multiply(a[2*i], a[2*i-1]); - - a[0] = ring.MultiplicativeIdentity(); - - for (i=0; i<n-1; i++) - { - std::swap(a[2*i+1], a[2*i+2]); - a[2*i+1] = ring.Multiply(a[i], a[2*i+1]); - a[2*i+2] = ring.Multiply(a[i], a[2*i+2]); - } - - for (i=0; i<n; i++) - v[i] = ring.Multiply(a[n-1+i], w[i]); -} - -template <class Ring, class Element> -Element BulkPolynomialInterpolateAt(const Ring &ring, const Element y[], const Element v[], unsigned int n) -{ - Element result = ring.Identity(); - for (unsigned int i=0; i<n; i++) - ring.Accumulate(result, ring.Multiply(y[i], v[i])); - return result; -} - -// ******************************************************** - -template <class T, int instance> -const PolynomialOverFixedRing<T, instance> &PolynomialOverFixedRing<T, instance>::Zero() -{ - return Singleton<ThisType>().Ref(); -} - -template <class T, int instance> -const PolynomialOverFixedRing<T, instance> &PolynomialOverFixedRing<T, instance>::One() -{ - return Singleton<ThisType, NewOnePolynomial>().Ref(); -} - -NAMESPACE_END diff --git a/lib/cryptopp/polynomi.h b/lib/cryptopp/polynomi.h deleted file mode 100644 index cddadaeaf..000000000 --- a/lib/cryptopp/polynomi.h +++ /dev/null @@ -1,459 +0,0 @@ -#ifndef CRYPTOPP_POLYNOMI_H -#define CRYPTOPP_POLYNOMI_H - -/*! \file */ - -#include "cryptlib.h" -#include "misc.h" -#include "algebra.h" - -#include <iosfwd> -#include <vector> - -NAMESPACE_BEGIN(CryptoPP) - -//! represents single-variable polynomials over arbitrary rings -/*! \nosubgrouping */ -template <class T> class PolynomialOver -{ -public: - //! \name ENUMS, EXCEPTIONS, and TYPEDEFS - //@{ - //! division by zero exception - class DivideByZero : public Exception - { - public: - DivideByZero() : Exception(OTHER_ERROR, "PolynomialOver<T>: division by zero") {} - }; - - //! specify the distribution for randomization functions - class RandomizationParameter - { - public: - RandomizationParameter(unsigned int coefficientCount, const typename T::RandomizationParameter &coefficientParameter ) - : m_coefficientCount(coefficientCount), m_coefficientParameter(coefficientParameter) {} - - private: - unsigned int m_coefficientCount; - typename T::RandomizationParameter m_coefficientParameter; - friend class PolynomialOver<T>; - }; - - typedef T Ring; - typedef typename T::Element CoefficientType; - //@} - - //! \name CREATORS - //@{ - //! creates the zero polynomial - PolynomialOver() {} - - //! - PolynomialOver(const Ring &ring, unsigned int count) - : m_coefficients((size_t)count, ring.Identity()) {} - - //! copy constructor - PolynomialOver(const PolynomialOver<Ring> &t) - : m_coefficients(t.m_coefficients.size()) {*this = t;} - - //! construct constant polynomial - PolynomialOver(const CoefficientType &element) - : m_coefficients(1, element) {} - - //! construct polynomial with specified coefficients, starting from coefficient of x^0 - template <typename Iterator> PolynomialOver(Iterator begin, Iterator end) - : m_coefficients(begin, end) {} - - //! convert from string - PolynomialOver(const char *str, const Ring &ring) {FromStr(str, ring);} - - //! convert from big-endian byte array - PolynomialOver(const byte *encodedPolynomialOver, unsigned int byteCount); - - //! convert from Basic Encoding Rules encoded byte array - explicit PolynomialOver(const byte *BEREncodedPolynomialOver); - - //! convert from BER encoded byte array stored in a BufferedTransformation object - explicit PolynomialOver(BufferedTransformation &bt); - - //! create a random PolynomialOver<T> - PolynomialOver(RandomNumberGenerator &rng, const RandomizationParameter ¶meter, const Ring &ring) - {Randomize(rng, parameter, ring);} - //@} - - //! \name ACCESSORS - //@{ - //! the zero polynomial will return a degree of -1 - int Degree(const Ring &ring) const {return int(CoefficientCount(ring))-1;} - //! - unsigned int CoefficientCount(const Ring &ring) const; - //! return coefficient for x^i - CoefficientType GetCoefficient(unsigned int i, const Ring &ring) const; - //@} - - //! \name MANIPULATORS - //@{ - //! - PolynomialOver<Ring>& operator=(const PolynomialOver<Ring>& t); - - //! - void Randomize(RandomNumberGenerator &rng, const RandomizationParameter ¶meter, const Ring &ring); - - //! set the coefficient for x^i to value - void SetCoefficient(unsigned int i, const CoefficientType &value, const Ring &ring); - - //! - void Negate(const Ring &ring); - - //! - void swap(PolynomialOver<Ring> &t); - //@} - - - //! \name BASIC ARITHMETIC ON POLYNOMIALS - //@{ - bool Equals(const PolynomialOver<Ring> &t, const Ring &ring) const; - bool IsZero(const Ring &ring) const {return CoefficientCount(ring)==0;} - - PolynomialOver<Ring> Plus(const PolynomialOver<Ring>& t, const Ring &ring) const; - PolynomialOver<Ring> Minus(const PolynomialOver<Ring>& t, const Ring &ring) const; - PolynomialOver<Ring> Inverse(const Ring &ring) const; - - PolynomialOver<Ring> Times(const PolynomialOver<Ring>& t, const Ring &ring) const; - PolynomialOver<Ring> DividedBy(const PolynomialOver<Ring>& t, const Ring &ring) const; - PolynomialOver<Ring> Modulo(const PolynomialOver<Ring>& t, const Ring &ring) const; - PolynomialOver<Ring> MultiplicativeInverse(const Ring &ring) const; - bool IsUnit(const Ring &ring) const; - - PolynomialOver<Ring>& Accumulate(const PolynomialOver<Ring>& t, const Ring &ring); - PolynomialOver<Ring>& Reduce(const PolynomialOver<Ring>& t, const Ring &ring); - - //! - PolynomialOver<Ring> Doubled(const Ring &ring) const {return Plus(*this, ring);} - //! - PolynomialOver<Ring> Squared(const Ring &ring) const {return Times(*this, ring);} - - CoefficientType EvaluateAt(const CoefficientType &x, const Ring &ring) const; - - PolynomialOver<Ring>& ShiftLeft(unsigned int n, const Ring &ring); - PolynomialOver<Ring>& ShiftRight(unsigned int n, const Ring &ring); - - //! calculate r and q such that (a == d*q + r) && (0 <= degree of r < degree of d) - static void Divide(PolynomialOver<Ring> &r, PolynomialOver<Ring> &q, const PolynomialOver<Ring> &a, const PolynomialOver<Ring> &d, const Ring &ring); - //@} - - //! \name INPUT/OUTPUT - //@{ - std::istream& Input(std::istream &in, const Ring &ring); - std::ostream& Output(std::ostream &out, const Ring &ring) const; - //@} - -private: - void FromStr(const char *str, const Ring &ring); - - std::vector<CoefficientType> m_coefficients; -}; - -//! Polynomials over a fixed ring -/*! Having a fixed ring allows overloaded operators */ -template <class T, int instance> class PolynomialOverFixedRing : private PolynomialOver<T> -{ - typedef PolynomialOver<T> B; - typedef PolynomialOverFixedRing<T, instance> ThisType; - -public: - typedef T Ring; - typedef typename T::Element CoefficientType; - typedef typename B::DivideByZero DivideByZero; - typedef typename B::RandomizationParameter RandomizationParameter; - - //! \name CREATORS - //@{ - //! creates the zero polynomial - PolynomialOverFixedRing(unsigned int count = 0) : B(ms_fixedRing, count) {} - - //! copy constructor - PolynomialOverFixedRing(const ThisType &t) : B(t) {} - - explicit PolynomialOverFixedRing(const B &t) : B(t) {} - - //! construct constant polynomial - PolynomialOverFixedRing(const CoefficientType &element) : B(element) {} - - //! construct polynomial with specified coefficients, starting from coefficient of x^0 - template <typename Iterator> PolynomialOverFixedRing(Iterator first, Iterator last) - : B(first, last) {} - - //! convert from string - explicit PolynomialOverFixedRing(const char *str) : B(str, ms_fixedRing) {} - - //! convert from big-endian byte array - PolynomialOverFixedRing(const byte *encodedPoly, unsigned int byteCount) : B(encodedPoly, byteCount) {} - - //! convert from Basic Encoding Rules encoded byte array - explicit PolynomialOverFixedRing(const byte *BEREncodedPoly) : B(BEREncodedPoly) {} - - //! convert from BER encoded byte array stored in a BufferedTransformation object - explicit PolynomialOverFixedRing(BufferedTransformation &bt) : B(bt) {} - - //! create a random PolynomialOverFixedRing - PolynomialOverFixedRing(RandomNumberGenerator &rng, const RandomizationParameter ¶meter) : B(rng, parameter, ms_fixedRing) {} - - static const ThisType &Zero(); - static const ThisType &One(); - //@} - - //! \name ACCESSORS - //@{ - //! the zero polynomial will return a degree of -1 - int Degree() const {return B::Degree(ms_fixedRing);} - //! degree + 1 - unsigned int CoefficientCount() const {return B::CoefficientCount(ms_fixedRing);} - //! return coefficient for x^i - CoefficientType GetCoefficient(unsigned int i) const {return B::GetCoefficient(i, ms_fixedRing);} - //! return coefficient for x^i - CoefficientType operator[](unsigned int i) const {return B::GetCoefficient(i, ms_fixedRing);} - //@} - - //! \name MANIPULATORS - //@{ - //! - ThisType& operator=(const ThisType& t) {B::operator=(t); return *this;} - //! - ThisType& operator+=(const ThisType& t) {Accumulate(t, ms_fixedRing); return *this;} - //! - ThisType& operator-=(const ThisType& t) {Reduce(t, ms_fixedRing); return *this;} - //! - ThisType& operator*=(const ThisType& t) {return *this = *this*t;} - //! - ThisType& operator/=(const ThisType& t) {return *this = *this/t;} - //! - ThisType& operator%=(const ThisType& t) {return *this = *this%t;} - - //! - ThisType& operator<<=(unsigned int n) {ShiftLeft(n, ms_fixedRing); return *this;} - //! - ThisType& operator>>=(unsigned int n) {ShiftRight(n, ms_fixedRing); return *this;} - - //! set the coefficient for x^i to value - void SetCoefficient(unsigned int i, const CoefficientType &value) {B::SetCoefficient(i, value, ms_fixedRing);} - - //! - void Randomize(RandomNumberGenerator &rng, const RandomizationParameter ¶meter) {B::Randomize(rng, parameter, ms_fixedRing);} - - //! - void Negate() {B::Negate(ms_fixedRing);} - - void swap(ThisType &t) {B::swap(t);} - //@} - - //! \name UNARY OPERATORS - //@{ - //! - bool operator!() const {return CoefficientCount()==0;} - //! - ThisType operator+() const {return *this;} - //! - ThisType operator-() const {return ThisType(Inverse(ms_fixedRing));} - //@} - - //! \name BINARY OPERATORS - //@{ - //! - friend ThisType operator>>(ThisType a, unsigned int n) {return ThisType(a>>=n);} - //! - friend ThisType operator<<(ThisType a, unsigned int n) {return ThisType(a<<=n);} - //@} - - //! \name OTHER ARITHMETIC FUNCTIONS - //@{ - //! - ThisType MultiplicativeInverse() const {return ThisType(B::MultiplicativeInverse(ms_fixedRing));} - //! - bool IsUnit() const {return B::IsUnit(ms_fixedRing);} - - //! - ThisType Doubled() const {return ThisType(B::Doubled(ms_fixedRing));} - //! - ThisType Squared() const {return ThisType(B::Squared(ms_fixedRing));} - - CoefficientType EvaluateAt(const CoefficientType &x) const {return B::EvaluateAt(x, ms_fixedRing);} - - //! calculate r and q such that (a == d*q + r) && (0 <= r < abs(d)) - static void Divide(ThisType &r, ThisType &q, const ThisType &a, const ThisType &d) - {B::Divide(r, q, a, d, ms_fixedRing);} - //@} - - //! \name INPUT/OUTPUT - //@{ - //! - friend std::istream& operator>>(std::istream& in, ThisType &a) - {return a.Input(in, ms_fixedRing);} - //! - friend std::ostream& operator<<(std::ostream& out, const ThisType &a) - {return a.Output(out, ms_fixedRing);} - //@} - -private: - struct NewOnePolynomial - { - ThisType * operator()() const - { - return new ThisType(ms_fixedRing.MultiplicativeIdentity()); - } - }; - - static const Ring ms_fixedRing; -}; - -//! Ring of polynomials over another ring -template <class T> class RingOfPolynomialsOver : public AbstractEuclideanDomain<PolynomialOver<T> > -{ -public: - typedef T CoefficientRing; - typedef PolynomialOver<T> Element; - typedef typename Element::CoefficientType CoefficientType; - typedef typename Element::RandomizationParameter RandomizationParameter; - - RingOfPolynomialsOver(const CoefficientRing &ring) : m_ring(ring) {} - - Element RandomElement(RandomNumberGenerator &rng, const RandomizationParameter ¶meter) - {return Element(rng, parameter, m_ring);} - - bool Equal(const Element &a, const Element &b) const - {return a.Equals(b, m_ring);} - - const Element& Identity() const - {return this->result = m_ring.Identity();} - - const Element& Add(const Element &a, const Element &b) const - {return this->result = a.Plus(b, m_ring);} - - Element& Accumulate(Element &a, const Element &b) const - {a.Accumulate(b, m_ring); return a;} - - const Element& Inverse(const Element &a) const - {return this->result = a.Inverse(m_ring);} - - const Element& Subtract(const Element &a, const Element &b) const - {return this->result = a.Minus(b, m_ring);} - - Element& Reduce(Element &a, const Element &b) const - {return a.Reduce(b, m_ring);} - - const Element& Double(const Element &a) const - {return this->result = a.Doubled(m_ring);} - - const Element& MultiplicativeIdentity() const - {return this->result = m_ring.MultiplicativeIdentity();} - - const Element& Multiply(const Element &a, const Element &b) const - {return this->result = a.Times(b, m_ring);} - - const Element& Square(const Element &a) const - {return this->result = a.Squared(m_ring);} - - bool IsUnit(const Element &a) const - {return a.IsUnit(m_ring);} - - const Element& MultiplicativeInverse(const Element &a) const - {return this->result = a.MultiplicativeInverse(m_ring);} - - const Element& Divide(const Element &a, const Element &b) const - {return this->result = a.DividedBy(b, m_ring);} - - const Element& Mod(const Element &a, const Element &b) const - {return this->result = a.Modulo(b, m_ring);} - - void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const - {Element::Divide(r, q, a, d, m_ring);} - - class InterpolationFailed : public Exception - { - public: - InterpolationFailed() : Exception(OTHER_ERROR, "RingOfPolynomialsOver<T>: interpolation failed") {} - }; - - Element Interpolate(const CoefficientType x[], const CoefficientType y[], unsigned int n) const; - - // a faster version of Interpolate(x, y, n).EvaluateAt(position) - CoefficientType InterpolateAt(const CoefficientType &position, const CoefficientType x[], const CoefficientType y[], unsigned int n) const; -/* - void PrepareBulkInterpolation(CoefficientType *w, const CoefficientType x[], unsigned int n) const; - void PrepareBulkInterpolationAt(CoefficientType *v, const CoefficientType &position, const CoefficientType x[], const CoefficientType w[], unsigned int n) const; - CoefficientType BulkInterpolateAt(const CoefficientType y[], const CoefficientType v[], unsigned int n) const; -*/ -protected: - void CalculateAlpha(std::vector<CoefficientType> &alpha, const CoefficientType x[], const CoefficientType y[], unsigned int n) const; - - CoefficientRing m_ring; -}; - -template <class Ring, class Element> -void PrepareBulkPolynomialInterpolation(const Ring &ring, Element *w, const Element x[], unsigned int n); -template <class Ring, class Element> -void PrepareBulkPolynomialInterpolationAt(const Ring &ring, Element *v, const Element &position, const Element x[], const Element w[], unsigned int n); -template <class Ring, class Element> -Element BulkPolynomialInterpolateAt(const Ring &ring, const Element y[], const Element v[], unsigned int n); - -//! -template <class T, int instance> -inline bool operator==(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) - {return a.Equals(b, a.ms_fixedRing);} -//! -template <class T, int instance> -inline bool operator!=(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) - {return !(a==b);} - -//! -template <class T, int instance> -inline bool operator> (const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) - {return a.Degree() > b.Degree();} -//! -template <class T, int instance> -inline bool operator>=(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) - {return a.Degree() >= b.Degree();} -//! -template <class T, int instance> -inline bool operator< (const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) - {return a.Degree() < b.Degree();} -//! -template <class T, int instance> -inline bool operator<=(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) - {return a.Degree() <= b.Degree();} - -//! -template <class T, int instance> -inline CryptoPP::PolynomialOverFixedRing<T, instance> operator+(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) - {return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Plus(b, a.ms_fixedRing));} -//! -template <class T, int instance> -inline CryptoPP::PolynomialOverFixedRing<T, instance> operator-(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) - {return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Minus(b, a.ms_fixedRing));} -//! -template <class T, int instance> -inline CryptoPP::PolynomialOverFixedRing<T, instance> operator*(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) - {return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Times(b, a.ms_fixedRing));} -//! -template <class T, int instance> -inline CryptoPP::PolynomialOverFixedRing<T, instance> operator/(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) - {return CryptoPP::PolynomialOverFixedRing<T, instance>(a.DividedBy(b, a.ms_fixedRing));} -//! -template <class T, int instance> -inline CryptoPP::PolynomialOverFixedRing<T, instance> operator%(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b) - {return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Modulo(b, a.ms_fixedRing));} - -NAMESPACE_END - -NAMESPACE_BEGIN(std) -template<class T> inline void swap(CryptoPP::PolynomialOver<T> &a, CryptoPP::PolynomialOver<T> &b) -{ - a.swap(b); -} -template<class T, int i> inline void swap(CryptoPP::PolynomialOverFixedRing<T,i> &a, CryptoPP::PolynomialOverFixedRing<T,i> &b) -{ - a.swap(b); -} -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/pssr.cpp b/lib/cryptopp/pssr.cpp deleted file mode 100644 index ccbe4ee27..000000000 --- a/lib/cryptopp/pssr.cpp +++ /dev/null @@ -1,145 +0,0 @@ -// pssr.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "pssr.h" -#include <functional> - -NAMESPACE_BEGIN(CryptoPP) - -// more in dll.cpp -template<> const byte EMSA2HashId<RIPEMD160>::id = 0x31; -template<> const byte EMSA2HashId<RIPEMD128>::id = 0x32; -template<> const byte EMSA2HashId<Whirlpool>::id = 0x37; - -#ifndef CRYPTOPP_IMPORTS - -size_t PSSR_MEM_Base::MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const -{ - size_t saltLen = SaltLen(digestLength); - size_t minPadLen = MinPadLen(digestLength); - return 9 + 8*(minPadLen + saltLen + digestLength + hashIdentifierLength); -} - -size_t PSSR_MEM_Base::MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const -{ - if (AllowRecovery()) - return SaturatingSubtract(representativeBitLength, MinRepresentativeBitLength(hashIdentifierLength, digestLength)) / 8; - return 0; -} - -bool PSSR_MEM_Base::IsProbabilistic() const -{ - return SaltLen(1) > 0; -} - -bool PSSR_MEM_Base::AllowNonrecoverablePart() const -{ - return true; -} - -bool PSSR_MEM_Base::RecoverablePartFirst() const -{ - return false; -} - -void PSSR_MEM_Base::ComputeMessageRepresentative(RandomNumberGenerator &rng, - const byte *recoverableMessage, size_t recoverableMessageLength, - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const -{ - assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize())); - - const size_t u = hashIdentifier.second + 1; - const size_t representativeByteLength = BitsToBytes(representativeBitLength); - const size_t digestSize = hash.DigestSize(); - const size_t saltSize = SaltLen(digestSize); - byte *const h = representative + representativeByteLength - u - digestSize; - - SecByteBlock digest(digestSize), salt(saltSize); - hash.Final(digest); - rng.GenerateBlock(salt, saltSize); - - // compute H = hash of M' - byte c[8]; - PutWord(false, BIG_ENDIAN_ORDER, c, (word32)SafeRightShift<29>(recoverableMessageLength)); - PutWord(false, BIG_ENDIAN_ORDER, c+4, word32(recoverableMessageLength << 3)); - hash.Update(c, 8); - hash.Update(recoverableMessage, recoverableMessageLength); - hash.Update(digest, digestSize); - hash.Update(salt, saltSize); - hash.Final(h); - - // compute representative - GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize, false); - byte *xorStart = representative + representativeByteLength - u - digestSize - salt.size() - recoverableMessageLength - 1; - xorStart[0] ^= 1; - xorbuf(xorStart + 1, recoverableMessage, recoverableMessageLength); - xorbuf(xorStart + 1 + recoverableMessageLength, salt, salt.size()); - memcpy(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second); - representative[representativeByteLength - 1] = hashIdentifier.second ? 0xcc : 0xbc; - if (representativeBitLength % 8 != 0) - representative[0] = (byte)Crop(representative[0], representativeBitLength % 8); -} - -DecodingResult PSSR_MEM_Base::RecoverMessageFromRepresentative( - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength, - byte *recoverableMessage) const -{ - assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize())); - - const size_t u = hashIdentifier.second + 1; - const size_t representativeByteLength = BitsToBytes(representativeBitLength); - const size_t digestSize = hash.DigestSize(); - const size_t saltSize = SaltLen(digestSize); - const byte *const h = representative + representativeByteLength - u - digestSize; - - SecByteBlock digest(digestSize); - hash.Final(digest); - - DecodingResult result(0); - bool &valid = result.isValidCoding; - size_t &recoverableMessageLength = result.messageLength; - - valid = (representative[representativeByteLength - 1] == (hashIdentifier.second ? 0xcc : 0xbc)) && valid; - valid = VerifyBufsEqual(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second) && valid; - - GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize); - if (representativeBitLength % 8 != 0) - representative[0] = (byte)Crop(representative[0], representativeBitLength % 8); - - // extract salt and recoverableMessage from DB = 00 ... || 01 || M || salt - byte *salt = representative + representativeByteLength - u - digestSize - saltSize; - byte *M = std::find_if(representative, salt-1, std::bind2nd(std::not_equal_to<byte>(), 0)); - recoverableMessageLength = salt-M-1; - if (*M == 0x01 - && (size_t)(M - representative - (representativeBitLength % 8 != 0)) >= MinPadLen(digestSize) - && recoverableMessageLength <= MaxRecoverableLength(representativeBitLength, hashIdentifier.second, digestSize)) - { - memcpy(recoverableMessage, M+1, recoverableMessageLength); - } - else - { - recoverableMessageLength = 0; - valid = false; - } - - // verify H = hash of M' - byte c[8]; - PutWord(false, BIG_ENDIAN_ORDER, c, (word32)SafeRightShift<29>(recoverableMessageLength)); - PutWord(false, BIG_ENDIAN_ORDER, c+4, word32(recoverableMessageLength << 3)); - hash.Update(c, 8); - hash.Update(recoverableMessage, recoverableMessageLength); - hash.Update(digest, digestSize); - hash.Update(salt, saltSize); - valid = hash.Verify(h) && valid; - - if (!AllowRecovery() && valid && recoverableMessageLength != 0) - {throw NotImplemented("PSSR_MEM: message recovery disabled");} - - return result; -} - -#endif - -NAMESPACE_END diff --git a/lib/cryptopp/pssr.h b/lib/cryptopp/pssr.h deleted file mode 100644 index 6ec6936e5..000000000 --- a/lib/cryptopp/pssr.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef CRYPTOPP_PSSR_H -#define CRYPTOPP_PSSR_H - -#include "pubkey.h" -#include "emsa2.h" - -#ifdef CRYPTOPP_IS_DLL -#include "sha.h" -#endif - -NAMESPACE_BEGIN(CryptoPP) - -class CRYPTOPP_DLL PSSR_MEM_Base : public PK_RecoverableSignatureMessageEncodingMethod -{ - virtual bool AllowRecovery() const =0; - virtual size_t SaltLen(size_t hashLen) const =0; - virtual size_t MinPadLen(size_t hashLen) const =0; - virtual const MaskGeneratingFunction & GetMGF() const =0; - -public: - size_t MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const; - size_t MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const; - bool IsProbabilistic() const; - bool AllowNonrecoverablePart() const; - bool RecoverablePartFirst() const; - void ComputeMessageRepresentative(RandomNumberGenerator &rng, - const byte *recoverableMessage, size_t recoverableMessageLength, - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const; - DecodingResult RecoverMessageFromRepresentative( - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength, - byte *recoverableMessage) const; -}; - -template <bool USE_HASH_ID> class PSSR_MEM_BaseWithHashId; -template<> class PSSR_MEM_BaseWithHashId<true> : public EMSA2HashIdLookup<PSSR_MEM_Base> {}; -template<> class PSSR_MEM_BaseWithHashId<false> : public PSSR_MEM_Base {}; - -template <bool ALLOW_RECOVERY, class MGF=P1363_MGF1, int SALT_LEN=-1, int MIN_PAD_LEN=0, bool USE_HASH_ID=false> -class PSSR_MEM : public PSSR_MEM_BaseWithHashId<USE_HASH_ID> -{ - virtual bool AllowRecovery() const {return ALLOW_RECOVERY;} - virtual size_t SaltLen(size_t hashLen) const {return SALT_LEN < 0 ? hashLen : SALT_LEN;} - virtual size_t MinPadLen(size_t hashLen) const {return MIN_PAD_LEN < 0 ? hashLen : MIN_PAD_LEN;} - virtual const MaskGeneratingFunction & GetMGF() const {static MGF mgf; return mgf;} - -public: - static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(ALLOW_RECOVERY ? "PSSR-" : "PSS-") + MGF::StaticAlgorithmName();} -}; - -//! <a href="http://www.weidai.com/scan-mirror/sig.html#sem_PSSR-MGF1">PSSR-MGF1</a> -struct PSSR : public SignatureStandard -{ - typedef PSSR_MEM<true> SignatureMessageEncodingMethod; -}; - -//! <a href="http://www.weidai.com/scan-mirror/sig.html#sem_PSS-MGF1">PSS-MGF1</a> -struct PSS : public SignatureStandard -{ - typedef PSSR_MEM<false> SignatureMessageEncodingMethod; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/pubkey.cpp b/lib/cryptopp/pubkey.cpp deleted file mode 100644 index 1159e5343..000000000 --- a/lib/cryptopp/pubkey.cpp +++ /dev/null @@ -1,165 +0,0 @@ -// pubkey.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "pubkey.h" - -NAMESPACE_BEGIN(CryptoPP) - -void P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength, bool mask, unsigned int counterStart) -{ - ArraySink *sink; - HashFilter filter(hash, sink = mask ? new ArrayXorSink(output, outputLength) : new ArraySink(output, outputLength)); - word32 counter = counterStart; - while (sink->AvailableSize() > 0) - { - filter.Put(input, inputLength); - filter.PutWord32(counter++); - filter.Put(derivationParams, derivationParamsLength); - filter.MessageEnd(); - } -} - -bool PK_DeterministicSignatureMessageEncodingMethod::VerifyMessageRepresentative( - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const -{ - SecByteBlock computedRepresentative(BitsToBytes(representativeBitLength)); - ComputeMessageRepresentative(NullRNG(), NULL, 0, hash, hashIdentifier, messageEmpty, computedRepresentative, representativeBitLength); - return VerifyBufsEqual(representative, computedRepresentative, computedRepresentative.size()); -} - -bool PK_RecoverableSignatureMessageEncodingMethod::VerifyMessageRepresentative( - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const -{ - SecByteBlock recoveredMessage(MaxRecoverableLength(representativeBitLength, hashIdentifier.second, hash.DigestSize())); - DecodingResult result = RecoverMessageFromRepresentative( - hash, hashIdentifier, messageEmpty, representative, representativeBitLength, recoveredMessage); - return result.isValidCoding && result.messageLength == 0; -} - -void TF_SignerBase::InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const -{ - PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator); - HashIdentifier id = GetHashIdentifier(); - const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); - - if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) - throw PK_SignatureScheme::KeyTooShort(); - - size_t maxRecoverableLength = encoding.MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, ma.AccessHash().DigestSize()); - - if (maxRecoverableLength == 0) - {throw NotImplemented("TF_SignerBase: this algorithm does not support messsage recovery or the key is too short");} - if (recoverableMessageLength > maxRecoverableLength) - throw InvalidArgument("TF_SignerBase: the recoverable message part is too long for the given key and algorithm"); - - ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength); - encoding.ProcessRecoverableMessage( - ma.AccessHash(), - recoverableMessage, recoverableMessageLength, - NULL, 0, ma.m_semisignature); -} - -size_t TF_SignerBase::SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const -{ - PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator); - HashIdentifier id = GetHashIdentifier(); - const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); - - if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) - throw PK_SignatureScheme::KeyTooShort(); - - SecByteBlock representative(MessageRepresentativeLength()); - encoding.ComputeMessageRepresentative(rng, - ma.m_recoverableMessage, ma.m_recoverableMessage.size(), - ma.AccessHash(), id, ma.m_empty, - representative, MessageRepresentativeBitLength()); - ma.m_empty = true; - - Integer r(representative, representative.size()); - size_t signatureLength = SignatureLength(); - GetTrapdoorFunctionInterface().CalculateRandomizedInverse(rng, r).Encode(signature, signatureLength); - return signatureLength; -} - -void TF_VerifierBase::InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const -{ - PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator); - HashIdentifier id = GetHashIdentifier(); - const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); - - if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) - throw PK_SignatureScheme::KeyTooShort(); - - ma.m_representative.New(MessageRepresentativeLength()); - Integer x = GetTrapdoorFunctionInterface().ApplyFunction(Integer(signature, signatureLength)); - if (x.BitCount() > MessageRepresentativeBitLength()) - x = Integer::Zero(); // don't return false here to prevent timing attack - x.Encode(ma.m_representative, ma.m_representative.size()); -} - -bool TF_VerifierBase::VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const -{ - PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator); - HashIdentifier id = GetHashIdentifier(); - const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); - - if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) - throw PK_SignatureScheme::KeyTooShort(); - - bool result = encoding.VerifyMessageRepresentative( - ma.AccessHash(), id, ma.m_empty, ma.m_representative, MessageRepresentativeBitLength()); - ma.m_empty = true; - return result; -} - -DecodingResult TF_VerifierBase::RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const -{ - PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator); - HashIdentifier id = GetHashIdentifier(); - const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); - - if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) - throw PK_SignatureScheme::KeyTooShort(); - - DecodingResult result = encoding.RecoverMessageFromRepresentative( - ma.AccessHash(), id, ma.m_empty, ma.m_representative, MessageRepresentativeBitLength(), recoveredMessage); - ma.m_empty = true; - return result; -} - -DecodingResult TF_DecryptorBase::Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters) const -{ - if (ciphertextLength != FixedCiphertextLength()) - throw InvalidArgument(AlgorithmName() + ": ciphertext length of " + IntToString(ciphertextLength) + " doesn't match the required length of " + IntToString(FixedCiphertextLength()) + " for this key"); - - SecByteBlock paddedBlock(PaddedBlockByteLength()); - Integer x = GetTrapdoorFunctionInterface().CalculateInverse(rng, Integer(ciphertext, ciphertextLength)); - if (x.ByteCount() > paddedBlock.size()) - x = Integer::Zero(); // don't return false here to prevent timing attack - x.Encode(paddedBlock, paddedBlock.size()); - return GetMessageEncodingInterface().Unpad(paddedBlock, PaddedBlockBitLength(), plaintext, parameters); -} - -void TF_EncryptorBase::Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const -{ - if (plaintextLength > FixedMaxPlaintextLength()) - { - if (FixedMaxPlaintextLength() < 1) - throw InvalidArgument(AlgorithmName() + ": this key is too short to encrypt any messages"); - else - throw InvalidArgument(AlgorithmName() + ": message length of " + IntToString(plaintextLength) + " exceeds the maximum of " + IntToString(FixedMaxPlaintextLength()) + " for this public key"); - } - - SecByteBlock paddedBlock(PaddedBlockByteLength()); - GetMessageEncodingInterface().Pad(rng, plaintext, plaintextLength, paddedBlock, PaddedBlockBitLength(), parameters); - GetTrapdoorFunctionInterface().ApplyRandomizedFunction(rng, Integer(paddedBlock, paddedBlock.size())).Encode(ciphertext, FixedCiphertextLength()); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/pubkey.h b/lib/cryptopp/pubkey.h deleted file mode 100644 index 3a3f3bcde..000000000 --- a/lib/cryptopp/pubkey.h +++ /dev/null @@ -1,1678 +0,0 @@ -// pubkey.h - written and placed in the public domain by Wei Dai - -#ifndef CRYPTOPP_PUBKEY_H -#define CRYPTOPP_PUBKEY_H - -/** \file - - This file contains helper classes/functions for implementing public key algorithms. - - The class hierachies in this .h file tend to look like this: -<pre> - x1 - / \ - y1 z1 - | | - x2<y1> x2<z1> - | | - y2 z2 - | | - x3<y2> x3<z2> - | | - y3 z3 -</pre> - - x1, y1, z1 are abstract interface classes defined in cryptlib.h - - x2, y2, z2 are implementations of the interfaces using "abstract policies", which - are pure virtual functions that should return interfaces to interchangeable algorithms. - These classes have "Base" suffixes. - - x3, y3, z3 hold actual algorithms and implement those virtual functions. - These classes have "Impl" suffixes. - - The "TF_" prefix means an implementation using trapdoor functions on integers. - The "DL_" prefix means an implementation using group operations (in groups where discrete log is hard). -*/ - -#include "modarith.h" -#include "filters.h" -#include "eprecomp.h" -#include "fips140.h" -#include "argnames.h" -#include <memory> - -// VC60 workaround: this macro is defined in shlobj.h and conflicts with a template parameter used in this file -#undef INTERFACE - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionBounds -{ -public: - virtual ~TrapdoorFunctionBounds() {} - - virtual Integer PreimageBound() const =0; - virtual Integer ImageBound() const =0; - virtual Integer MaxPreimage() const {return --PreimageBound();} - virtual Integer MaxImage() const {return --ImageBound();} -}; - -//! _ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction : public TrapdoorFunctionBounds -{ -public: - virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0; - virtual bool IsRandomized() const {return true;} -}; - -//! _ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunction : public RandomizedTrapdoorFunction -{ -public: - Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const - {return ApplyFunction(x);} - bool IsRandomized() const {return false;} - - virtual Integer ApplyFunction(const Integer &x) const =0; -}; - -//! _ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse -{ -public: - virtual ~RandomizedTrapdoorFunctionInverse() {} - - virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0; - virtual bool IsRandomized() const {return true;} -}; - -//! _ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse -{ -public: - virtual ~TrapdoorFunctionInverse() {} - - Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const - {return CalculateInverse(rng, x);} - bool IsRandomized() const {return false;} - - virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0; -}; - -// ******************************************************** - -//! message encoding method for public key encryption -class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod -{ -public: - virtual ~PK_EncryptionMessageEncodingMethod() {} - - virtual bool ParameterSupported(const char *name) const {return false;} - - //! max size of unpadded message in bytes, given max size of padded message in bits (1 less than size of modulus) - virtual size_t MaxUnpaddedLength(size_t paddedLength) const =0; - - virtual void Pad(RandomNumberGenerator &rng, const byte *raw, size_t inputLength, byte *padded, size_t paddedBitLength, const NameValuePairs ¶meters) const =0; - - virtual DecodingResult Unpad(const byte *padded, size_t paddedBitLength, byte *raw, const NameValuePairs ¶meters) const =0; -}; - -// ******************************************************** - -//! _ -template <class TFI, class MEI> -class CRYPTOPP_NO_VTABLE TF_Base -{ -protected: - virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0; - - typedef TFI TrapdoorFunctionInterface; - virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const =0; - - typedef MEI MessageEncodingInterface; - virtual const MessageEncodingInterface & GetMessageEncodingInterface() const =0; -}; - -// ******************************************************** - -//! _ -template <class BASE> -class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE -{ -public: - size_t MaxPlaintextLength(size_t ciphertextLength) const - {return ciphertextLength == FixedCiphertextLength() ? FixedMaxPlaintextLength() : 0;} - size_t CiphertextLength(size_t plaintextLength) const - {return plaintextLength <= FixedMaxPlaintextLength() ? FixedCiphertextLength() : 0;} - - virtual size_t FixedMaxPlaintextLength() const =0; - virtual size_t FixedCiphertextLength() const =0; -}; - -//! _ -template <class INTERFACE, class BASE> -class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public PK_FixedLengthCryptoSystemImpl<INTERFACE>, protected BASE -{ -public: - bool ParameterSupported(const char *name) const {return this->GetMessageEncodingInterface().ParameterSupported(name);} - size_t FixedMaxPlaintextLength() const {return this->GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());} - size_t FixedCiphertextLength() const {return this->GetTrapdoorFunctionBounds().MaxImage().ByteCount();} - -protected: - size_t PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());} - size_t PaddedBlockBitLength() const {return this->GetTrapdoorFunctionBounds().PreimageBound().BitCount()-1;} -}; - -//! _ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase<PK_Decryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> > -{ -public: - DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const; -}; - -//! _ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase<PK_Encryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> > -{ -public: - void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const; -}; - -// ******************************************************** - -typedef std::pair<const byte *, size_t> HashIdentifier; - -//! interface for message encoding method for public key signature schemes -class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod -{ -public: - virtual ~PK_SignatureMessageEncodingMethod() {} - - virtual size_t MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const - {return 0;} - virtual size_t MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const - {return 0;} - - bool IsProbabilistic() const - {return true;} - bool AllowNonrecoverablePart() const - {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");} - virtual bool RecoverablePartFirst() const - {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");} - - // for verification, DL - virtual void ProcessSemisignature(HashTransformation &hash, const byte *semisignature, size_t semisignatureLength) const {} - - // for signature - virtual void ProcessRecoverableMessage(HashTransformation &hash, - const byte *recoverableMessage, size_t recoverableMessageLength, - const byte *presignature, size_t presignatureLength, - SecByteBlock &semisignature) const - { - if (RecoverablePartFirst()) - assert(!"ProcessRecoverableMessage() not implemented"); - } - - virtual void ComputeMessageRepresentative(RandomNumberGenerator &rng, - const byte *recoverableMessage, size_t recoverableMessageLength, - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const =0; - - virtual bool VerifyMessageRepresentative( - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const =0; - - virtual DecodingResult RecoverMessageFromRepresentative( // for TF - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength, - byte *recoveredMessage) const - {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");} - - virtual DecodingResult RecoverMessageFromSemisignature( // for DL - HashTransformation &hash, HashIdentifier hashIdentifier, - const byte *presignature, size_t presignatureLength, - const byte *semisignature, size_t semisignatureLength, - byte *recoveredMessage) const - {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");} - - // VC60 workaround - struct HashIdentifierLookup - { - template <class H> struct HashIdentifierLookup2 - { - static HashIdentifier CRYPTOPP_API Lookup() - { - return HashIdentifier((const byte *)NULL, 0); - } - }; - }; -}; - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_DeterministicSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod -{ -public: - bool VerifyMessageRepresentative( - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const; -}; - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_RecoverableSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod -{ -public: - bool VerifyMessageRepresentative( - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const; -}; - -class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_DSA : public PK_DeterministicSignatureMessageEncodingMethod -{ -public: - void ComputeMessageRepresentative(RandomNumberGenerator &rng, - const byte *recoverableMessage, size_t recoverableMessageLength, - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const; -}; - -class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_NR : public PK_DeterministicSignatureMessageEncodingMethod -{ -public: - void ComputeMessageRepresentative(RandomNumberGenerator &rng, - const byte *recoverableMessage, size_t recoverableMessageLength, - HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, - byte *representative, size_t representativeBitLength) const; -}; - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulatorBase : public PK_MessageAccumulator -{ -public: - PK_MessageAccumulatorBase() : m_empty(true) {} - - virtual HashTransformation & AccessHash() =0; - - void Update(const byte *input, size_t length) - { - AccessHash().Update(input, length); - m_empty = m_empty && length == 0; - } - - SecByteBlock m_recoverableMessage, m_representative, m_presignature, m_semisignature; - Integer m_k, m_s; - bool m_empty; -}; - -template <class HASH_ALGORITHM> -class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder<HASH_ALGORITHM> -{ -public: - HashTransformation & AccessHash() {return this->m_object;} -}; - -//! _ -template <class INTERFACE, class BASE> -class CRYPTOPP_NO_VTABLE TF_SignatureSchemeBase : public INTERFACE, protected BASE -{ -public: - size_t SignatureLength() const - {return this->GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();} - size_t MaxRecoverableLength() const - {return this->GetMessageEncodingInterface().MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, GetDigestSize());} - size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const - {return this->MaxRecoverableLength();} - - bool IsProbabilistic() const - {return this->GetTrapdoorFunctionInterface().IsRandomized() || this->GetMessageEncodingInterface().IsProbabilistic();} - bool AllowNonrecoverablePart() const - {return this->GetMessageEncodingInterface().AllowNonrecoverablePart();} - bool RecoverablePartFirst() const - {return this->GetMessageEncodingInterface().RecoverablePartFirst();} - -protected: - size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());} - size_t MessageRepresentativeBitLength() const {return this->GetTrapdoorFunctionBounds().ImageBound().BitCount()-1;} - virtual HashIdentifier GetHashIdentifier() const =0; - virtual size_t GetDigestSize() const =0; -}; - -//! _ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_SignerBase : public TF_SignatureSchemeBase<PK_Signer, TF_Base<RandomizedTrapdoorFunctionInverse, PK_SignatureMessageEncodingMethod> > -{ -public: - void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const; - size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const; -}; - -//! _ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_VerifierBase : public TF_SignatureSchemeBase<PK_Verifier, TF_Base<TrapdoorFunction, PK_SignatureMessageEncodingMethod> > -{ -public: - void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const; - bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const; - DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &recoveryAccumulator) const; -}; - -// ******************************************************** - -//! _ -template <class T1, class T2, class T3> -struct TF_CryptoSchemeOptions -{ - typedef T1 AlgorithmInfo; - typedef T2 Keys; - typedef typename Keys::PrivateKey PrivateKey; - typedef typename Keys::PublicKey PublicKey; - typedef T3 MessageEncodingMethod; -}; - -//! _ -template <class T1, class T2, class T3, class T4> -struct TF_SignatureSchemeOptions : public TF_CryptoSchemeOptions<T1, T2, T3> -{ - typedef T4 HashFunction; -}; - -//! _ -template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS> -class CRYPTOPP_NO_VTABLE TF_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo> -{ -public: - typedef SCHEME_OPTIONS SchemeOptions; - typedef KEY_CLASS KeyClass; - - PublicKey & AccessPublicKey() {return AccessKey();} - const PublicKey & GetPublicKey() const {return GetKey();} - - PrivateKey & AccessPrivateKey() {return AccessKey();} - const PrivateKey & GetPrivateKey() const {return GetKey();} - - virtual const KeyClass & GetKey() const =0; - virtual KeyClass & AccessKey() =0; - - const KeyClass & GetTrapdoorFunction() const {return GetKey();} - - PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const - { - return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>; - } - PK_MessageAccumulator * NewVerificationAccumulator() const - { - return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>; - } - -protected: - const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface() const - {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::MessageEncodingMethod>().Ref();} - const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const - {return GetKey();} - const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const - {return GetKey();} - - // for signature scheme - HashIdentifier GetHashIdentifier() const - { - typedef CPP_TYPENAME SchemeOptions::MessageEncodingMethod::HashIdentifierLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction> L; - return L::Lookup(); - } - size_t GetDigestSize() const - { - typedef CPP_TYPENAME SchemeOptions::HashFunction H; - return H::DIGESTSIZE; - } -}; - -//! _ -template <class BASE, class SCHEME_OPTIONS, class KEY> -class TF_ObjectImplExtRef : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY> -{ -public: - TF_ObjectImplExtRef(const KEY *pKey = NULL) : m_pKey(pKey) {} - void SetKeyPtr(const KEY *pKey) {m_pKey = pKey;} - - const KEY & GetKey() const {return *m_pKey;} - KEY & AccessKey() {throw NotImplemented("TF_ObjectImplExtRef: cannot modify refererenced key");} - -private: - const KEY * m_pKey; -}; - -//! _ -template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS> -class CRYPTOPP_NO_VTABLE TF_ObjectImpl : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY_CLASS> -{ -public: - typedef KEY_CLASS KeyClass; - - const KeyClass & GetKey() const {return m_trapdoorFunction;} - KeyClass & AccessKey() {return m_trapdoorFunction;} - -private: - KeyClass m_trapdoorFunction; -}; - -//! _ -template <class SCHEME_OPTIONS> -class TF_DecryptorImpl : public TF_ObjectImpl<TF_DecryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey> -{ -}; - -//! _ -template <class SCHEME_OPTIONS> -class TF_EncryptorImpl : public TF_ObjectImpl<TF_EncryptorBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey> -{ -}; - -//! _ -template <class SCHEME_OPTIONS> -class TF_SignerImpl : public TF_ObjectImpl<TF_SignerBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey> -{ -}; - -//! _ -template <class SCHEME_OPTIONS> -class TF_VerifierImpl : public TF_ObjectImpl<TF_VerifierBase, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey> -{ -}; - -// ******************************************************** - -//! _ -class CRYPTOPP_NO_VTABLE MaskGeneratingFunction -{ -public: - virtual ~MaskGeneratingFunction() {} - virtual void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const =0; -}; - -CRYPTOPP_DLL void CRYPTOPP_API P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength, bool mask, unsigned int counterStart); - -//! _ -class P1363_MGF1 : public MaskGeneratingFunction -{ -public: - static const char * CRYPTOPP_API StaticAlgorithmName() {return "MGF1";} - void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const - { - P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, NULL, 0, mask, 0); - } -}; - -// ******************************************************** - -//! _ -template <class H> -class P1363_KDF2 -{ -public: - static void CRYPTOPP_API DeriveKey(byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength) - { - H h; - P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, derivationParams, derivationParamsLength, false, 1); - } -}; - -// ******************************************************** - -//! to be thrown by DecodeElement and AgreeWithStaticPrivateKey -class DL_BadElement : public InvalidDataFormat -{ -public: - DL_BadElement() : InvalidDataFormat("CryptoPP: invalid group element") {} -}; - -//! interface for DL group parameters -template <class T> -class CRYPTOPP_NO_VTABLE DL_GroupParameters : public CryptoParameters -{ - typedef DL_GroupParameters<T> ThisClass; - -public: - typedef T Element; - - DL_GroupParameters() : m_validationLevel(0) {} - - // CryptoMaterial - bool Validate(RandomNumberGenerator &rng, unsigned int level) const - { - if (!GetBasePrecomputation().IsInitialized()) - return false; - - if (m_validationLevel > level) - return true; - - bool pass = ValidateGroup(rng, level); - pass = pass && ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation()); - - m_validationLevel = pass ? level+1 : 0; - - return pass; - } - - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const - { - return GetValueHelper(this, name, valueType, pValue) - CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder) - CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator) - ; - } - - bool SupportsPrecomputation() const {return true;} - - void Precompute(unsigned int precomputationStorage=16) - { - AccessBasePrecomputation().Precompute(GetGroupPrecomputation(), GetSubgroupOrder().BitCount(), precomputationStorage); - } - - void LoadPrecomputation(BufferedTransformation &storedPrecomputation) - { - AccessBasePrecomputation().Load(GetGroupPrecomputation(), storedPrecomputation); - m_validationLevel = 0; - } - - void SavePrecomputation(BufferedTransformation &storedPrecomputation) const - { - GetBasePrecomputation().Save(GetGroupPrecomputation(), storedPrecomputation); - } - - // non-inherited - virtual const Element & GetSubgroupGenerator() const {return GetBasePrecomputation().GetBase(GetGroupPrecomputation());} - virtual void SetSubgroupGenerator(const Element &base) {AccessBasePrecomputation().SetBase(GetGroupPrecomputation(), base);} - virtual Element ExponentiateBase(const Integer &exponent) const - { - return GetBasePrecomputation().Exponentiate(GetGroupPrecomputation(), exponent); - } - virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const - { - Element result; - SimultaneousExponentiate(&result, base, &exponent, 1); - return result; - } - - virtual const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const =0; - virtual const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const =0; - virtual DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() =0; - virtual const Integer & GetSubgroupOrder() const =0; // order of subgroup generated by base element - virtual Integer GetMaxExponent() const =0; - virtual Integer GetGroupOrder() const {return GetSubgroupOrder()*GetCofactor();} // one of these two needs to be overriden - virtual Integer GetCofactor() const {return GetGroupOrder()/GetSubgroupOrder();} - virtual unsigned int GetEncodedElementSize(bool reversible) const =0; - virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0; - virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0; - virtual Integer ConvertElementToInteger(const Element &element) const =0; - virtual bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const =0; - virtual bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const =0; - virtual bool FastSubgroupCheckAvailable() const =0; - virtual bool IsIdentity(const Element &element) const =0; - virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0; - -protected: - void ParametersChanged() {m_validationLevel = 0;} - -private: - mutable unsigned int m_validationLevel; -}; - -//! _ -template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<CPP_TYPENAME GROUP_PRECOMP::Element>, class BASE = DL_GroupParameters<CPP_TYPENAME GROUP_PRECOMP::Element> > -class DL_GroupParametersImpl : public BASE -{ -public: - typedef GROUP_PRECOMP GroupPrecomputation; - typedef typename GROUP_PRECOMP::Element Element; - typedef BASE_PRECOMP BasePrecomputation; - - const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const {return m_groupPrecomputation;} - const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return m_gpc;} - DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return m_gpc;} - -protected: - GROUP_PRECOMP m_groupPrecomputation; - BASE_PRECOMP m_gpc; -}; - -//! _ -template <class T> -class CRYPTOPP_NO_VTABLE DL_Key -{ -public: - virtual const DL_GroupParameters<T> & GetAbstractGroupParameters() const =0; - virtual DL_GroupParameters<T> & AccessAbstractGroupParameters() =0; -}; - -//! interface for DL public keys -template <class T> -class CRYPTOPP_NO_VTABLE DL_PublicKey : public DL_Key<T> -{ - typedef DL_PublicKey<T> ThisClass; - -public: - typedef T Element; - - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const - { - return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters()) - CRYPTOPP_GET_FUNCTION_ENTRY(PublicElement); - } - - void AssignFrom(const NameValuePairs &source); - - // non-inherited - virtual const Element & GetPublicElement() const {return GetPublicPrecomputation().GetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation());} - virtual void SetPublicElement(const Element &y) {AccessPublicPrecomputation().SetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation(), y);} - virtual Element ExponentiatePublicElement(const Integer &exponent) const - { - const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters(); - return GetPublicPrecomputation().Exponentiate(params.GetGroupPrecomputation(), exponent); - } - virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const - { - const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters(); - return params.GetBasePrecomputation().CascadeExponentiate(params.GetGroupPrecomputation(), baseExp, GetPublicPrecomputation(), publicExp); - } - - virtual const DL_FixedBasePrecomputation<T> & GetPublicPrecomputation() const =0; - virtual DL_FixedBasePrecomputation<T> & AccessPublicPrecomputation() =0; -}; - -//! interface for DL private keys -template <class T> -class CRYPTOPP_NO_VTABLE DL_PrivateKey : public DL_Key<T> -{ - typedef DL_PrivateKey<T> ThisClass; - -public: - typedef T Element; - - void MakePublicKey(DL_PublicKey<T> &pub) const - { - pub.AccessAbstractGroupParameters().AssignFrom(this->GetAbstractGroupParameters()); - pub.SetPublicElement(this->GetAbstractGroupParameters().ExponentiateBase(GetPrivateExponent())); - } - - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const - { - return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters()) - CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent); - } - - void AssignFrom(const NameValuePairs &source) - { - this->AccessAbstractGroupParameters().AssignFrom(source); - AssignFromHelper(this, source) - CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent); - } - - virtual const Integer & GetPrivateExponent() const =0; - virtual void SetPrivateExponent(const Integer &x) =0; -}; - -template <class T> -void DL_PublicKey<T>::AssignFrom(const NameValuePairs &source) -{ - DL_PrivateKey<T> *pPrivateKey = NULL; - if (source.GetThisPointer(pPrivateKey)) - pPrivateKey->MakePublicKey(*this); - else - { - this->AccessAbstractGroupParameters().AssignFrom(source); - AssignFromHelper(this, source) - CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement); - } -} - -class OID; - -//! _ -template <class PK, class GP, class O = OID> -class DL_KeyImpl : public PK -{ -public: - typedef GP GroupParameters; - - O GetAlgorithmID() const {return GetGroupParameters().GetAlgorithmID();} -// void BERDecode(BufferedTransformation &bt) -// {PK::BERDecode(bt);} -// void DEREncode(BufferedTransformation &bt) const -// {PK::DEREncode(bt);} - bool BERDecodeAlgorithmParameters(BufferedTransformation &bt) - {AccessGroupParameters().BERDecode(bt); return true;} - bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const - {GetGroupParameters().DEREncode(bt); return true;} - - const GP & GetGroupParameters() const {return m_groupParameters;} - GP & AccessGroupParameters() {return m_groupParameters;} - -private: - GP m_groupParameters; -}; - -class X509PublicKey; -class PKCS8PrivateKey; - -//! _ -template <class GP> -class DL_PrivateKeyImpl : public DL_PrivateKey<CPP_TYPENAME GP::Element>, public DL_KeyImpl<PKCS8PrivateKey, GP> -{ -public: - typedef typename GP::Element Element; - - // GeneratableCryptoMaterial - bool Validate(RandomNumberGenerator &rng, unsigned int level) const - { - bool pass = GetAbstractGroupParameters().Validate(rng, level); - - const Integer &q = GetAbstractGroupParameters().GetSubgroupOrder(); - const Integer &x = GetPrivateExponent(); - - pass = pass && x.IsPositive() && x < q; - if (level >= 1) - pass = pass && Integer::Gcd(x, q) == Integer::One(); - return pass; - } - - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const - { - return GetValueHelper<DL_PrivateKey<Element> >(this, name, valueType, pValue).Assignable(); - } - - void AssignFrom(const NameValuePairs &source) - { - AssignFromHelper<DL_PrivateKey<Element> >(this, source); - } - - void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms) - { - if (!params.GetThisObject(this->AccessGroupParameters())) - this->AccessGroupParameters().GenerateRandom(rng, params); -// std::pair<const byte *, int> seed; - Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); -// Integer::ANY, Integer::Zero(), Integer::One(), -// params.GetValue("DeterministicKeyGenerationSeed", seed) ? &seed : NULL); - SetPrivateExponent(x); - } - - bool SupportsPrecomputation() const {return true;} - - void Precompute(unsigned int precomputationStorage=16) - {AccessAbstractGroupParameters().Precompute(precomputationStorage);} - - void LoadPrecomputation(BufferedTransformation &storedPrecomputation) - {AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);} - - void SavePrecomputation(BufferedTransformation &storedPrecomputation) const - {GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);} - - // DL_Key - const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();} - DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();} - - // DL_PrivateKey - const Integer & GetPrivateExponent() const {return m_x;} - void SetPrivateExponent(const Integer &x) {m_x = x;} - - // PKCS8PrivateKey - void BERDecodePrivateKey(BufferedTransformation &bt, bool, size_t) - {m_x.BERDecode(bt);} - void DEREncodePrivateKey(BufferedTransformation &bt) const - {m_x.DEREncode(bt);} - -private: - Integer m_x; -}; - -//! _ -template <class BASE, class SIGNATURE_SCHEME> -class DL_PrivateKey_WithSignaturePairwiseConsistencyTest : public BASE -{ -public: - void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms) - { - BASE::GenerateRandom(rng, params); - - if (FIPS_140_2_ComplianceEnabled()) - { - typename SIGNATURE_SCHEME::Signer signer(*this); - typename SIGNATURE_SCHEME::Verifier verifier(signer); - SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier); - } - } -}; - -//! _ -template <class GP> -class DL_PublicKeyImpl : public DL_PublicKey<typename GP::Element>, public DL_KeyImpl<X509PublicKey, GP> -{ -public: - typedef typename GP::Element Element; - - // CryptoMaterial - bool Validate(RandomNumberGenerator &rng, unsigned int level) const - { - bool pass = GetAbstractGroupParameters().Validate(rng, level); - pass = pass && GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation()); - return pass; - } - - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const - { - return GetValueHelper<DL_PublicKey<Element> >(this, name, valueType, pValue).Assignable(); - } - - void AssignFrom(const NameValuePairs &source) - { - AssignFromHelper<DL_PublicKey<Element> >(this, source); - } - - bool SupportsPrecomputation() const {return true;} - - void Precompute(unsigned int precomputationStorage=16) - { - AccessAbstractGroupParameters().Precompute(precomputationStorage); - AccessPublicPrecomputation().Precompute(GetAbstractGroupParameters().GetGroupPrecomputation(), GetAbstractGroupParameters().GetSubgroupOrder().BitCount(), precomputationStorage); - } - - void LoadPrecomputation(BufferedTransformation &storedPrecomputation) - { - AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation); - AccessPublicPrecomputation().Load(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation); - } - - void SavePrecomputation(BufferedTransformation &storedPrecomputation) const - { - GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation); - GetPublicPrecomputation().Save(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation); - } - - // DL_Key - const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return this->GetGroupParameters();} - DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return this->AccessGroupParameters();} - - // DL_PublicKey - const DL_FixedBasePrecomputation<Element> & GetPublicPrecomputation() const {return m_ypc;} - DL_FixedBasePrecomputation<Element> & AccessPublicPrecomputation() {return m_ypc;} - - // non-inherited - bool operator==(const DL_PublicKeyImpl<GP> &rhs) const - {return this->GetGroupParameters() == rhs.GetGroupParameters() && this->GetPublicElement() == rhs.GetPublicElement();} - -private: - typename GP::BasePrecomputation m_ypc; -}; - -//! interface for Elgamal-like signature algorithms -template <class T> -class CRYPTOPP_NO_VTABLE DL_ElgamalLikeSignatureAlgorithm -{ -public: - virtual void Sign(const DL_GroupParameters<T> ¶ms, const Integer &privateKey, const Integer &k, const Integer &e, Integer &r, Integer &s) const =0; - virtual bool Verify(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const =0; - virtual Integer RecoverPresignature(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &r, const Integer &s) const - {throw NotImplemented("DL_ElgamalLikeSignatureAlgorithm: this signature scheme does not support message recovery");} - virtual size_t RLen(const DL_GroupParameters<T> ¶ms) const - {return params.GetSubgroupOrder().ByteCount();} - virtual size_t SLen(const DL_GroupParameters<T> ¶ms) const - {return params.GetSubgroupOrder().ByteCount();} -}; - -//! interface for DL key agreement algorithms -template <class T> -class CRYPTOPP_NO_VTABLE DL_KeyAgreementAlgorithm -{ -public: - typedef T Element; - - virtual Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> ¶ms, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const =0; - virtual Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> ¶ms, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const =0; -}; - -//! interface for key derivation algorithms used in DL cryptosystems -template <class T> -class CRYPTOPP_NO_VTABLE DL_KeyDerivationAlgorithm -{ -public: - virtual bool ParameterSupported(const char *name) const {return false;} - virtual void Derive(const DL_GroupParameters<T> &groupParams, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &derivationParams) const =0; -}; - -//! interface for symmetric encryption algorithms used in DL cryptosystems -class CRYPTOPP_NO_VTABLE DL_SymmetricEncryptionAlgorithm -{ -public: - virtual bool ParameterSupported(const char *name) const {return false;} - virtual size_t GetSymmetricKeyLength(size_t plaintextLength) const =0; - virtual size_t GetSymmetricCiphertextLength(size_t plaintextLength) const =0; - virtual size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const =0; - virtual void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const =0; - virtual DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters) const =0; -}; - -//! _ -template <class KI> -class CRYPTOPP_NO_VTABLE DL_Base -{ -protected: - typedef KI KeyInterface; - typedef typename KI::Element Element; - - const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return GetKeyInterface().GetAbstractGroupParameters();} - DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return AccessKeyInterface().AccessAbstractGroupParameters();} - - virtual KeyInterface & AccessKeyInterface() =0; - virtual const KeyInterface & GetKeyInterface() const =0; -}; - -//! _ -template <class INTERFACE, class KEY_INTERFACE> -class CRYPTOPP_NO_VTABLE DL_SignatureSchemeBase : public INTERFACE, public DL_Base<KEY_INTERFACE> -{ -public: - size_t SignatureLength() const - { - return GetSignatureAlgorithm().RLen(this->GetAbstractGroupParameters()) - + GetSignatureAlgorithm().SLen(this->GetAbstractGroupParameters()); - } - size_t MaxRecoverableLength() const - {return GetMessageEncodingInterface().MaxRecoverableLength(0, GetHashIdentifier().second, GetDigestSize());} - size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const - {assert(false); return 0;} // TODO - - bool IsProbabilistic() const - {return true;} - bool AllowNonrecoverablePart() const - {return GetMessageEncodingInterface().AllowNonrecoverablePart();} - bool RecoverablePartFirst() const - {return GetMessageEncodingInterface().RecoverablePartFirst();} - -protected: - size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());} - size_t MessageRepresentativeBitLength() const {return this->GetAbstractGroupParameters().GetSubgroupOrder().BitCount();} - - virtual const DL_ElgamalLikeSignatureAlgorithm<CPP_TYPENAME KEY_INTERFACE::Element> & GetSignatureAlgorithm() const =0; - virtual const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const =0; - virtual HashIdentifier GetHashIdentifier() const =0; - virtual size_t GetDigestSize() const =0; -}; - -//! _ -template <class T> -class CRYPTOPP_NO_VTABLE DL_SignerBase : public DL_SignatureSchemeBase<PK_Signer, DL_PrivateKey<T> > -{ -public: - // for validation testing - void RawSign(const Integer &k, const Integer &e, Integer &r, Integer &s) const - { - const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm(); - const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters(); - const DL_PrivateKey<T> &key = this->GetKeyInterface(); - - r = params.ConvertElementToInteger(params.ExponentiateBase(k)); - alg.Sign(params, key.GetPrivateExponent(), k, e, r, s); - } - - void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const - { - PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator); - ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength); - this->GetMessageEncodingInterface().ProcessRecoverableMessage(ma.AccessHash(), - recoverableMessage, recoverableMessageLength, - ma.m_presignature, ma.m_presignature.size(), - ma.m_semisignature); - } - - size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const - { - this->GetMaterial().DoQuickSanityCheck(); - - PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator); - const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm(); - const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters(); - const DL_PrivateKey<T> &key = this->GetKeyInterface(); - - SecByteBlock representative(this->MessageRepresentativeLength()); - this->GetMessageEncodingInterface().ComputeMessageRepresentative( - rng, - ma.m_recoverableMessage, ma.m_recoverableMessage.size(), - ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty, - representative, this->MessageRepresentativeBitLength()); - ma.m_empty = true; - Integer e(representative, representative.size()); - - // hash message digest into random number k to prevent reusing the same k on a different messages - // after virtual machine rollback - if (rng.CanIncorporateEntropy()) - rng.IncorporateEntropy(representative, representative.size()); - Integer k(rng, 1, params.GetSubgroupOrder()-1); - Integer r, s; - r = params.ConvertElementToInteger(params.ExponentiateBase(k)); - alg.Sign(params, key.GetPrivateExponent(), k, e, r, s); - - /* - Integer r, s; - if (this->MaxRecoverableLength() > 0) - r.Decode(ma.m_semisignature, ma.m_semisignature.size()); - else - r.Decode(ma.m_presignature, ma.m_presignature.size()); - alg.Sign(params, key.GetPrivateExponent(), ma.m_k, e, r, s); - */ - - size_t rLen = alg.RLen(params); - r.Encode(signature, rLen); - s.Encode(signature+rLen, alg.SLen(params)); - - if (restart) - RestartMessageAccumulator(rng, ma); - - return this->SignatureLength(); - } - -protected: - void RestartMessageAccumulator(RandomNumberGenerator &rng, PK_MessageAccumulatorBase &ma) const - { - // k needs to be generated before hashing for signature schemes with recovery - // but to defend against VM rollbacks we need to generate k after hashing. - // so this code is commented out, since no DL-based signature scheme with recovery - // has been implemented in Crypto++ anyway - /* - const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm(); - const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters(); - ma.m_k.Randomize(rng, 1, params.GetSubgroupOrder()-1); - ma.m_presignature.New(params.GetEncodedElementSize(false)); - params.ConvertElementToInteger(params.ExponentiateBase(ma.m_k)).Encode(ma.m_presignature, ma.m_presignature.size()); - */ - } -}; - -//! _ -template <class T> -class CRYPTOPP_NO_VTABLE DL_VerifierBase : public DL_SignatureSchemeBase<PK_Verifier, DL_PublicKey<T> > -{ -public: - void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const - { - PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator); - const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm(); - const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters(); - - size_t rLen = alg.RLen(params); - ma.m_semisignature.Assign(signature, rLen); - ma.m_s.Decode(signature+rLen, alg.SLen(params)); - - this->GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size()); - } - - bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const - { - this->GetMaterial().DoQuickSanityCheck(); - - PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator); - const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm(); - const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters(); - const DL_PublicKey<T> &key = this->GetKeyInterface(); - - SecByteBlock representative(this->MessageRepresentativeLength()); - this->GetMessageEncodingInterface().ComputeMessageRepresentative(NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(), - ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty, - representative, this->MessageRepresentativeBitLength()); - ma.m_empty = true; - Integer e(representative, representative.size()); - - Integer r(ma.m_semisignature, ma.m_semisignature.size()); - return alg.Verify(params, key, e, r, ma.m_s); - } - - DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const - { - this->GetMaterial().DoQuickSanityCheck(); - - PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator); - const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm(); - const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters(); - const DL_PublicKey<T> &key = this->GetKeyInterface(); - - SecByteBlock representative(this->MessageRepresentativeLength()); - this->GetMessageEncodingInterface().ComputeMessageRepresentative( - NullRNG(), - ma.m_recoverableMessage, ma.m_recoverableMessage.size(), - ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty, - representative, this->MessageRepresentativeBitLength()); - ma.m_empty = true; - Integer e(representative, representative.size()); - - ma.m_presignature.New(params.GetEncodedElementSize(false)); - Integer r(ma.m_semisignature, ma.m_semisignature.size()); - alg.RecoverPresignature(params, key, r, ma.m_s).Encode(ma.m_presignature, ma.m_presignature.size()); - - return this->GetMessageEncodingInterface().RecoverMessageFromSemisignature( - ma.AccessHash(), this->GetHashIdentifier(), - ma.m_presignature, ma.m_presignature.size(), - ma.m_semisignature, ma.m_semisignature.size(), - recoveredMessage); - } -}; - -//! _ -template <class PK, class KI> -class CRYPTOPP_NO_VTABLE DL_CryptoSystemBase : public PK, public DL_Base<KI> -{ -public: - typedef typename DL_Base<KI>::Element Element; - - size_t MaxPlaintextLength(size_t ciphertextLength) const - { - unsigned int minLen = this->GetAbstractGroupParameters().GetEncodedElementSize(true); - return ciphertextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(ciphertextLength - minLen); - } - - size_t CiphertextLength(size_t plaintextLength) const - { - size_t len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plaintextLength); - return len == 0 ? 0 : this->GetAbstractGroupParameters().GetEncodedElementSize(true) + len; - } - - bool ParameterSupported(const char *name) const - {return GetKeyDerivationAlgorithm().ParameterSupported(name) || GetSymmetricEncryptionAlgorithm().ParameterSupported(name);} - -protected: - virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0; - virtual const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const =0; - virtual const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const =0; -}; - -//! _ -template <class T> -class CRYPTOPP_NO_VTABLE DL_DecryptorBase : public DL_CryptoSystemBase<PK_Decryptor, DL_PrivateKey<T> > -{ -public: - typedef T Element; - - DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const - { - try - { - const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm(); - const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm(); - const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm(); - const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters(); - const DL_PrivateKey<T> &key = this->GetKeyInterface(); - - Element q = params.DecodeElement(ciphertext, true); - size_t elementSize = params.GetEncodedElementSize(true); - ciphertext += elementSize; - ciphertextLength -= elementSize; - - Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q, true, key.GetPrivateExponent()); - - SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(ciphertextLength))); - derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters); - - return encAlg.SymmetricDecrypt(derivedKey, ciphertext, ciphertextLength, plaintext, parameters); - } - catch (DL_BadElement &) - { - return DecodingResult(); - } - } -}; - -//! _ -template <class T> -class CRYPTOPP_NO_VTABLE DL_EncryptorBase : public DL_CryptoSystemBase<PK_Encryptor, DL_PublicKey<T> > -{ -public: - typedef T Element; - - void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const - { - const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm(); - const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm(); - const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm(); - const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters(); - const DL_PublicKey<T> &key = this->GetKeyInterface(); - - Integer x(rng, Integer::One(), params.GetMaxExponent()); - Element q = params.ExponentiateBase(x); - params.EncodeElement(true, q, ciphertext); - unsigned int elementSize = params.GetEncodedElementSize(true); - ciphertext += elementSize; - - Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x); - - SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plaintextLength)); - derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters); - - encAlg.SymmetricEncrypt(rng, derivedKey, plaintext, plaintextLength, ciphertext, parameters); - } -}; - -//! _ -template <class T1, class T2> -struct DL_SchemeOptionsBase -{ - typedef T1 AlgorithmInfo; - typedef T2 GroupParameters; - typedef typename GroupParameters::Element Element; -}; - -//! _ -template <class T1, class T2> -struct DL_KeyedSchemeOptions : public DL_SchemeOptionsBase<T1, typename T2::PublicKey::GroupParameters> -{ - typedef T2 Keys; - typedef typename Keys::PrivateKey PrivateKey; - typedef typename Keys::PublicKey PublicKey; -}; - -//! _ -template <class T1, class T2, class T3, class T4, class T5> -struct DL_SignatureSchemeOptions : public DL_KeyedSchemeOptions<T1, T2> -{ - typedef T3 SignatureAlgorithm; - typedef T4 MessageEncodingMethod; - typedef T5 HashFunction; -}; - -//! _ -template <class T1, class T2, class T3, class T4, class T5> -struct DL_CryptoSchemeOptions : public DL_KeyedSchemeOptions<T1, T2> -{ - typedef T3 KeyAgreementAlgorithm; - typedef T4 KeyDerivationAlgorithm; - typedef T5 SymmetricEncryptionAlgorithm; -}; - -//! _ -template <class BASE, class SCHEME_OPTIONS, class KEY> -class CRYPTOPP_NO_VTABLE DL_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo> -{ -public: - typedef SCHEME_OPTIONS SchemeOptions; - typedef typename KEY::Element Element; - - PrivateKey & AccessPrivateKey() {return m_key;} - PublicKey & AccessPublicKey() {return m_key;} - - // KeyAccessor - const KEY & GetKey() const {return m_key;} - KEY & AccessKey() {return m_key;} - -protected: - typename BASE::KeyInterface & AccessKeyInterface() {return m_key;} - const typename BASE::KeyInterface & GetKeyInterface() const {return m_key;} - - // for signature scheme - HashIdentifier GetHashIdentifier() const - { - typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup HashLookup; - return HashLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction>::Lookup(); - } - size_t GetDigestSize() const - { - typedef CPP_TYPENAME SchemeOptions::HashFunction H; - return H::DIGESTSIZE; - } - -private: - KEY m_key; -}; - -//! _ -template <class BASE, class SCHEME_OPTIONS, class KEY> -class CRYPTOPP_NO_VTABLE DL_ObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY> -{ -public: - typedef typename KEY::Element Element; - -protected: - const DL_ElgamalLikeSignatureAlgorithm<Element> & GetSignatureAlgorithm() const - {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SignatureAlgorithm>().Ref();} - const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const - {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyAgreementAlgorithm>().Ref();} - const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const - {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyDerivationAlgorithm>().Ref();} - const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const - {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SymmetricEncryptionAlgorithm>().Ref();} - HashIdentifier GetHashIdentifier() const - {return HashIdentifier();} - const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const - {return Singleton<CPP_TYPENAME SCHEME_OPTIONS::MessageEncodingMethod>().Ref();} -}; - -//! _ -template <class SCHEME_OPTIONS> -class DL_SignerImpl : public DL_ObjectImpl<DL_SignerBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey> -{ -public: - PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const - { - std::auto_ptr<PK_MessageAccumulatorBase> p(new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>); - this->RestartMessageAccumulator(rng, *p); - return p.release(); - } -}; - -//! _ -template <class SCHEME_OPTIONS> -class DL_VerifierImpl : public DL_ObjectImpl<DL_VerifierBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey> -{ -public: - PK_MessageAccumulator * NewVerificationAccumulator() const - { - return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>; - } -}; - -//! _ -template <class SCHEME_OPTIONS> -class DL_EncryptorImpl : public DL_ObjectImpl<DL_EncryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey> -{ -}; - -//! _ -template <class SCHEME_OPTIONS> -class DL_DecryptorImpl : public DL_ObjectImpl<DL_DecryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey> -{ -}; - -// ******************************************************** - -//! _ -template <class T> -class CRYPTOPP_NO_VTABLE DL_SimpleKeyAgreementDomainBase : public SimpleKeyAgreementDomain -{ -public: - typedef T Element; - - CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();} - unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} - unsigned int PrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} - unsigned int PublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);} - - void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const - { - Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); - x.Encode(privateKey, PrivateKeyLength()); - } - - void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const - { - const DL_GroupParameters<T> ¶ms = GetAbstractGroupParameters(); - Integer x(privateKey, PrivateKeyLength()); - Element y = params.ExponentiateBase(x); - params.EncodeElement(true, y, publicKey); - } - - bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const - { - try - { - const DL_GroupParameters<T> ¶ms = GetAbstractGroupParameters(); - Integer x(privateKey, PrivateKeyLength()); - Element w = params.DecodeElement(otherPublicKey, validateOtherPublicKey); - - Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey( - GetAbstractGroupParameters(), w, validateOtherPublicKey, x); - params.EncodeElement(false, z, agreedValue); - } - catch (DL_BadElement &) - { - return false; - } - return true; - } - - const Element &GetGenerator() const {return GetAbstractGroupParameters().GetSubgroupGenerator();} - -protected: - virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0; - virtual DL_GroupParameters<Element> & AccessAbstractGroupParameters() =0; - const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return const_cast<DL_SimpleKeyAgreementDomainBase<Element> *>(this)->AccessAbstractGroupParameters();} -}; - -enum CofactorMultiplicationOption {NO_COFACTOR_MULTIPLICTION, COMPATIBLE_COFACTOR_MULTIPLICTION, INCOMPATIBLE_COFACTOR_MULTIPLICTION}; -typedef EnumToType<CofactorMultiplicationOption, NO_COFACTOR_MULTIPLICTION> NoCofactorMultiplication; -typedef EnumToType<CofactorMultiplicationOption, COMPATIBLE_COFACTOR_MULTIPLICTION> CompatibleCofactorMultiplication; -typedef EnumToType<CofactorMultiplicationOption, INCOMPATIBLE_COFACTOR_MULTIPLICTION> IncompatibleCofactorMultiplication; - -//! DH key agreement algorithm -template <class ELEMENT, class COFACTOR_OPTION> -class DL_KeyAgreementAlgorithm_DH : public DL_KeyAgreementAlgorithm<ELEMENT> -{ -public: - typedef ELEMENT Element; - - static const char * CRYPTOPP_API StaticAlgorithmName() - {return COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? "DHC" : "DH";} - - Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> ¶ms, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const - { - return publicPrecomputation.Exponentiate(params.GetGroupPrecomputation(), - COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.GetCofactor() : privateExponent); - } - - Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> ¶ms, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const - { - if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION) - { - const Integer &k = params.GetCofactor(); - return params.ExponentiateElement(publicElement, - ModularArithmetic(params.GetSubgroupOrder()).Divide(privateExponent, k)*k); - } - else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION) - return params.ExponentiateElement(publicElement, privateExponent*params.GetCofactor()); - else - { - assert(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION); - - if (!validateOtherPublicKey) - return params.ExponentiateElement(publicElement, privateExponent); - - if (params.FastSubgroupCheckAvailable()) - { - if (!params.ValidateElement(2, publicElement, NULL)) - throw DL_BadElement(); - return params.ExponentiateElement(publicElement, privateExponent); - } - else - { - const Integer e[2] = {params.GetSubgroupOrder(), privateExponent}; - Element r[2]; - params.SimultaneousExponentiate(r, publicElement, e, 2); - if (!params.IsIdentity(r[0])) - throw DL_BadElement(); - return r[1]; - } - } - } -}; - -// ******************************************************** - -//! A template implementing constructors for public key algorithm classes -template <class BASE> -class CRYPTOPP_NO_VTABLE PK_FinalTemplate : public BASE -{ -public: - PK_FinalTemplate() {} - - PK_FinalTemplate(const CryptoMaterial &key) - {this->AccessKey().AssignFrom(key);} - - PK_FinalTemplate(BufferedTransformation &bt) - {this->AccessKey().BERDecode(bt);} - - PK_FinalTemplate(const AsymmetricAlgorithm &algorithm) - {this->AccessKey().AssignFrom(algorithm.GetMaterial());} - - PK_FinalTemplate(const Integer &v1) - {this->AccessKey().Initialize(v1);} - -#if (defined(_MSC_VER) && _MSC_VER < 1300) - - template <class T1, class T2> - PK_FinalTemplate(T1 &v1, T2 &v2) - {this->AccessKey().Initialize(v1, v2);} - - template <class T1, class T2, class T3> - PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3) - {this->AccessKey().Initialize(v1, v2, v3);} - - template <class T1, class T2, class T3, class T4> - PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4) - {this->AccessKey().Initialize(v1, v2, v3, v4);} - - template <class T1, class T2, class T3, class T4, class T5> - PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5) - {this->AccessKey().Initialize(v1, v2, v3, v4, v5);} - - template <class T1, class T2, class T3, class T4, class T5, class T6> - PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6) - {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);} - - template <class T1, class T2, class T3, class T4, class T5, class T6, class T7> - PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7) - {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);} - - template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8> - PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7, T8 &v8) - {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);} - -#else - - template <class T1, class T2> - PK_FinalTemplate(const T1 &v1, const T2 &v2) - {this->AccessKey().Initialize(v1, v2);} - - template <class T1, class T2, class T3> - PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3) - {this->AccessKey().Initialize(v1, v2, v3);} - - template <class T1, class T2, class T3, class T4> - PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) - {this->AccessKey().Initialize(v1, v2, v3, v4);} - - template <class T1, class T2, class T3, class T4, class T5> - PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5) - {this->AccessKey().Initialize(v1, v2, v3, v4, v5);} - - template <class T1, class T2, class T3, class T4, class T5, class T6> - PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6) - {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);} - - template <class T1, class T2, class T3, class T4, class T5, class T6, class T7> - PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7) - {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);} - - template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8> - PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8) - {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);} - - template <class T1, class T2> - PK_FinalTemplate(T1 &v1, const T2 &v2) - {this->AccessKey().Initialize(v1, v2);} - - template <class T1, class T2, class T3> - PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3) - {this->AccessKey().Initialize(v1, v2, v3);} - - template <class T1, class T2, class T3, class T4> - PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) - {this->AccessKey().Initialize(v1, v2, v3, v4);} - - template <class T1, class T2, class T3, class T4, class T5> - PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5) - {this->AccessKey().Initialize(v1, v2, v3, v4, v5);} - - template <class T1, class T2, class T3, class T4, class T5, class T6> - PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6) - {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);} - - template <class T1, class T2, class T3, class T4, class T5, class T6, class T7> - PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7) - {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);} - - template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8> - PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8) - {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);} - -#endif -}; - -//! Base class for public key encryption standard classes. These classes are used to select from variants of algorithms. Note that not all standards apply to all algorithms. -struct EncryptionStandard {}; - -//! Base class for public key signature standard classes. These classes are used to select from variants of algorithms. Note that not all standards apply to all algorithms. -struct SignatureStandard {}; - -template <class STANDARD, class KEYS, class ALG_INFO> -class TF_ES; - -//! Trapdoor Function Based Encryption Scheme -template <class STANDARD, class KEYS, class ALG_INFO = TF_ES<STANDARD, KEYS, int> > -class TF_ES : public KEYS -{ - typedef typename STANDARD::EncryptionMessageEncodingMethod MessageEncodingMethod; - -public: - //! see EncryptionStandard for a list of standards - typedef STANDARD Standard; - typedef TF_CryptoSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod> SchemeOptions; - - static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName();} - - //! implements PK_Decryptor interface - typedef PK_FinalTemplate<TF_DecryptorImpl<SchemeOptions> > Decryptor; - //! implements PK_Encryptor interface - typedef PK_FinalTemplate<TF_EncryptorImpl<SchemeOptions> > Encryptor; -}; - -template <class STANDARD, class H, class KEYS, class ALG_INFO> // VC60 workaround: doesn't work if KEYS is first parameter -class TF_SS; - -//! Trapdoor Function Based Signature Scheme -template <class STANDARD, class H, class KEYS, class ALG_INFO = TF_SS<STANDARD, H, KEYS, int> > // VC60 workaround: doesn't work if KEYS is first parameter -class TF_SS : public KEYS -{ -public: - //! see SignatureStandard for a list of standards - typedef STANDARD Standard; - typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod; - typedef TF_SignatureSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod, H> SchemeOptions; - - static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";} - - //! implements PK_Signer interface - typedef PK_FinalTemplate<TF_SignerImpl<SchemeOptions> > Signer; - //! implements PK_Verifier interface - typedef PK_FinalTemplate<TF_VerifierImpl<SchemeOptions> > Verifier; -}; - -template <class KEYS, class SA, class MEM, class H, class ALG_INFO> -class DL_SS; - -//! Discrete Log Based Signature Scheme -template <class KEYS, class SA, class MEM, class H, class ALG_INFO = DL_SS<KEYS, SA, MEM, H, int> > -class DL_SS : public KEYS -{ - typedef DL_SignatureSchemeOptions<ALG_INFO, KEYS, SA, MEM, H> SchemeOptions; - -public: - static std::string StaticAlgorithmName() {return SA::StaticAlgorithmName() + std::string("/EMSA1(") + H::StaticAlgorithmName() + ")";} - - //! implements PK_Signer interface - typedef PK_FinalTemplate<DL_SignerImpl<SchemeOptions> > Signer; - //! implements PK_Verifier interface - typedef PK_FinalTemplate<DL_VerifierImpl<SchemeOptions> > Verifier; -}; - -//! Discrete Log Based Encryption Scheme -template <class KEYS, class AA, class DA, class EA, class ALG_INFO> -class DL_ES : public KEYS -{ - typedef DL_CryptoSchemeOptions<ALG_INFO, KEYS, AA, DA, EA> SchemeOptions; - -public: - //! implements PK_Decryptor interface - typedef PK_FinalTemplate<DL_DecryptorImpl<SchemeOptions> > Decryptor; - //! implements PK_Encryptor interface - typedef PK_FinalTemplate<DL_EncryptorImpl<SchemeOptions> > Encryptor; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/pwdbased.h b/lib/cryptopp/pwdbased.h deleted file mode 100644 index f755724b1..000000000 --- a/lib/cryptopp/pwdbased.h +++ /dev/null @@ -1,214 +0,0 @@ -// pwdbased.h - written and placed in the public domain by Wei Dai - -#ifndef CRYPTOPP_PWDBASED_H -#define CRYPTOPP_PWDBASED_H - -#include "cryptlib.h" -#include "hmac.h" -#include "hrtimer.h" -#include "integer.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! abstract base class for password based key derivation function -class PasswordBasedKeyDerivationFunction -{ -public: - virtual size_t MaxDerivedKeyLength() const =0; - virtual bool UsesPurposeByte() const =0; - //! derive key from password - /*! If timeInSeconds != 0, will iterate until time elapsed, as measured by ThreadUserTimer - Returns actual iteration count, which is equal to iterations if timeInSeconds == 0, and not less than iterations otherwise. */ - virtual unsigned int DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds=0) const =0; -}; - -//! PBKDF1 from PKCS #5, T should be a HashTransformation class -template <class T> -class PKCS5_PBKDF1 : public PasswordBasedKeyDerivationFunction -{ -public: - size_t MaxDerivedKeyLength() const {return T::DIGESTSIZE;} - bool UsesPurposeByte() const {return false;} - // PKCS #5 says PBKDF1 should only take 8-byte salts. This implementation allows salts of any length. - unsigned int DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds=0) const; -}; - -//! PBKDF2 from PKCS #5, T should be a HashTransformation class -template <class T> -class PKCS5_PBKDF2_HMAC : public PasswordBasedKeyDerivationFunction -{ -public: - size_t MaxDerivedKeyLength() const {return 0xffffffffU;} // should multiply by T::DIGESTSIZE, but gets overflow that way - bool UsesPurposeByte() const {return false;} - unsigned int DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds=0) const; -}; - -/* -class PBKDF2Params -{ -public: - SecByteBlock m_salt; - unsigned int m_interationCount; - ASNOptional<ASNUnsignedWrapper<word32> > m_keyLength; -}; -*/ - -template <class T> -unsigned int PKCS5_PBKDF1<T>::DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const -{ - assert(derivedLen <= MaxDerivedKeyLength()); - assert(iterations > 0 || timeInSeconds > 0); - - if (!iterations) - iterations = 1; - - T hash; - hash.Update(password, passwordLen); - hash.Update(salt, saltLen); - - SecByteBlock buffer(hash.DigestSize()); - hash.Final(buffer); - - unsigned int i; - ThreadUserTimer timer; - - if (timeInSeconds) - timer.StartTimer(); - - for (i=1; i<iterations || (timeInSeconds && (i%128!=0 || timer.ElapsedTimeAsDouble() < timeInSeconds)); i++) - hash.CalculateDigest(buffer, buffer, buffer.size()); - - memcpy(derived, buffer, derivedLen); - return i; -} - -template <class T> -unsigned int PKCS5_PBKDF2_HMAC<T>::DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const -{ - assert(derivedLen <= MaxDerivedKeyLength()); - assert(iterations > 0 || timeInSeconds > 0); - - if (!iterations) - iterations = 1; - - HMAC<T> hmac(password, passwordLen); - SecByteBlock buffer(hmac.DigestSize()); - ThreadUserTimer timer; - - unsigned int i=1; - while (derivedLen > 0) - { - hmac.Update(salt, saltLen); - unsigned int j; - for (j=0; j<4; j++) - { - byte b = byte(i >> ((3-j)*8)); - hmac.Update(&b, 1); - } - hmac.Final(buffer); - - size_t segmentLen = STDMIN(derivedLen, buffer.size()); - memcpy(derived, buffer, segmentLen); - - if (timeInSeconds) - { - timeInSeconds = timeInSeconds / ((derivedLen + buffer.size() - 1) / buffer.size()); - timer.StartTimer(); - } - - for (j=1; j<iterations || (timeInSeconds && (j%128!=0 || timer.ElapsedTimeAsDouble() < timeInSeconds)); j++) - { - hmac.CalculateDigest(buffer, buffer, buffer.size()); - xorbuf(derived, buffer, segmentLen); - } - - if (timeInSeconds) - { - iterations = j; - timeInSeconds = 0; - } - - derived += segmentLen; - derivedLen -= segmentLen; - i++; - } - - return iterations; -} - -//! PBKDF from PKCS #12, appendix B, T should be a HashTransformation class -template <class T> -class PKCS12_PBKDF : public PasswordBasedKeyDerivationFunction -{ -public: - size_t MaxDerivedKeyLength() const {return size_t(0)-1;} - bool UsesPurposeByte() const {return true;} - unsigned int DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const; -}; - -template <class T> -unsigned int PKCS12_PBKDF<T>::DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const -{ - assert(derivedLen <= MaxDerivedKeyLength()); - assert(iterations > 0 || timeInSeconds > 0); - - if (!iterations) - iterations = 1; - - const size_t v = T::BLOCKSIZE; // v is in bytes rather than bits as in PKCS #12 - const size_t DLen = v, SLen = RoundUpToMultipleOf(saltLen, v); - const size_t PLen = RoundUpToMultipleOf(passwordLen, v), ILen = SLen + PLen; - SecByteBlock buffer(DLen + SLen + PLen); - byte *D = buffer, *S = buffer+DLen, *P = buffer+DLen+SLen, *I = S; - - memset(D, purpose, DLen); - size_t i; - for (i=0; i<SLen; i++) - S[i] = salt[i % saltLen]; - for (i=0; i<PLen; i++) - P[i] = password[i % passwordLen]; - - - T hash; - SecByteBlock Ai(T::DIGESTSIZE), B(v); - ThreadUserTimer timer; - - while (derivedLen > 0) - { - hash.CalculateDigest(Ai, buffer, buffer.size()); - - if (timeInSeconds) - { - timeInSeconds = timeInSeconds / ((derivedLen + Ai.size() - 1) / Ai.size()); - timer.StartTimer(); - } - - for (i=1; i<iterations || (timeInSeconds && (i%128!=0 || timer.ElapsedTimeAsDouble() < timeInSeconds)); i++) - hash.CalculateDigest(Ai, Ai, Ai.size()); - - if (timeInSeconds) - { - iterations = (unsigned int)i; - timeInSeconds = 0; - } - - for (i=0; i<B.size(); i++) - B[i] = Ai[i % Ai.size()]; - - Integer B1(B, B.size()); - ++B1; - for (i=0; i<ILen; i+=v) - (Integer(I+i, v) + B1).Encode(I+i, v); - - size_t segmentLen = STDMIN(derivedLen, Ai.size()); - memcpy(derived, Ai, segmentLen); - derived += segmentLen; - derivedLen -= segmentLen; - } - - return iterations; -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/queue.cpp b/lib/cryptopp/queue.cpp deleted file mode 100644 index ff2f0d316..000000000 --- a/lib/cryptopp/queue.cpp +++ /dev/null @@ -1,565 +0,0 @@ -// queue.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "queue.h" -#include "filters.h" - -NAMESPACE_BEGIN(CryptoPP) - -static const unsigned int s_maxAutoNodeSize = 16*1024; - -// this class for use by ByteQueue only -class ByteQueueNode -{ -public: - ByteQueueNode(size_t maxSize) - : buf(maxSize) - { - m_head = m_tail = 0; - next = 0; - } - - inline size_t MaxSize() const {return buf.size();} - - inline size_t CurrentSize() const - { - return m_tail-m_head; - } - - inline bool UsedUp() const - { - return (m_head==MaxSize()); - } - - inline void Clear() - { - m_head = m_tail = 0; - } - - inline size_t Put(const byte *begin, size_t length) - { - size_t l = STDMIN(length, MaxSize()-m_tail); - if (buf+m_tail != begin) - memcpy(buf+m_tail, begin, l); - m_tail += l; - return l; - } - - inline size_t Peek(byte &outByte) const - { - if (m_tail==m_head) - return 0; - - outByte=buf[m_head]; - return 1; - } - - inline size_t Peek(byte *target, size_t copyMax) const - { - size_t len = STDMIN(copyMax, m_tail-m_head); - memcpy(target, buf+m_head, len); - return len; - } - - inline size_t CopyTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL) const - { - size_t len = m_tail-m_head; - target.ChannelPut(channel, buf+m_head, len); - return len; - } - - inline size_t CopyTo(BufferedTransformation &target, size_t copyMax, const std::string &channel=DEFAULT_CHANNEL) const - { - size_t len = STDMIN(copyMax, m_tail-m_head); - target.ChannelPut(channel, buf+m_head, len); - return len; - } - - inline size_t Get(byte &outByte) - { - size_t len = Peek(outByte); - m_head += len; - return len; - } - - inline size_t Get(byte *outString, size_t getMax) - { - size_t len = Peek(outString, getMax); - m_head += len; - return len; - } - - inline size_t TransferTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL) - { - size_t len = m_tail-m_head; - target.ChannelPutModifiable(channel, buf+m_head, len); - m_head = m_tail; - return len; - } - - inline size_t TransferTo(BufferedTransformation &target, lword transferMax, const std::string &channel=DEFAULT_CHANNEL) - { - size_t len = UnsignedMin(m_tail-m_head, transferMax); - target.ChannelPutModifiable(channel, buf+m_head, len); - m_head += len; - return len; - } - - inline size_t Skip(size_t skipMax) - { - size_t len = STDMIN(skipMax, m_tail-m_head); - m_head += len; - return len; - } - - inline byte operator[](size_t i) const - { - return buf[m_head+i]; - } - - ByteQueueNode *next; - - SecByteBlock buf; - size_t m_head, m_tail; -}; - -// ******************************************************** - -ByteQueue::ByteQueue(size_t nodeSize) - : m_lazyString(NULL), m_lazyLength(0) -{ - SetNodeSize(nodeSize); - m_head = m_tail = new ByteQueueNode(m_nodeSize); -} - -void ByteQueue::SetNodeSize(size_t nodeSize) -{ - m_autoNodeSize = !nodeSize; - m_nodeSize = m_autoNodeSize ? 256 : nodeSize; -} - -ByteQueue::ByteQueue(const ByteQueue ©) - : m_lazyString(NULL) -{ - CopyFrom(copy); -} - -void ByteQueue::CopyFrom(const ByteQueue ©) -{ - m_lazyLength = 0; - m_autoNodeSize = copy.m_autoNodeSize; - m_nodeSize = copy.m_nodeSize; - m_head = m_tail = new ByteQueueNode(*copy.m_head); - - for (ByteQueueNode *current=copy.m_head->next; current; current=current->next) - { - m_tail->next = new ByteQueueNode(*current); - m_tail = m_tail->next; - } - - m_tail->next = NULL; - - Put(copy.m_lazyString, copy.m_lazyLength); -} - -ByteQueue::~ByteQueue() -{ - Destroy(); -} - -void ByteQueue::Destroy() -{ - for (ByteQueueNode *next, *current=m_head; current; current=next) - { - next=current->next; - delete current; - } -} - -void ByteQueue::IsolatedInitialize(const NameValuePairs ¶meters) -{ - m_nodeSize = parameters.GetIntValueWithDefault("NodeSize", 256); - Clear(); -} - -lword ByteQueue::CurrentSize() const -{ - lword size=0; - - for (ByteQueueNode *current=m_head; current; current=current->next) - size += current->CurrentSize(); - - return size + m_lazyLength; -} - -bool ByteQueue::IsEmpty() const -{ - return m_head==m_tail && m_head->CurrentSize()==0 && m_lazyLength==0; -} - -void ByteQueue::Clear() -{ - for (ByteQueueNode *next, *current=m_head->next; current; current=next) - { - next=current->next; - delete current; - } - - m_tail = m_head; - m_head->Clear(); - m_head->next = NULL; - m_lazyLength = 0; -} - -size_t ByteQueue::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) -{ - if (m_lazyLength > 0) - FinalizeLazyPut(); - - size_t len; - while ((len=m_tail->Put(inString, length)) < length) - { - inString += len; - length -= len; - if (m_autoNodeSize && m_nodeSize < s_maxAutoNodeSize) - do - { - m_nodeSize *= 2; - } - while (m_nodeSize < length && m_nodeSize < s_maxAutoNodeSize); - m_tail->next = new ByteQueueNode(STDMAX(m_nodeSize, length)); - m_tail = m_tail->next; - } - - return 0; -} - -void ByteQueue::CleanupUsedNodes() -{ - while (m_head != m_tail && m_head->UsedUp()) - { - ByteQueueNode *temp=m_head; - m_head=m_head->next; - delete temp; - } - - if (m_head->CurrentSize() == 0) - m_head->Clear(); -} - -void ByteQueue::LazyPut(const byte *inString, size_t size) -{ - if (m_lazyLength > 0) - FinalizeLazyPut(); - - if (inString == m_tail->buf+m_tail->m_tail) - Put(inString, size); - else - { - m_lazyString = const_cast<byte *>(inString); - m_lazyLength = size; - m_lazyStringModifiable = false; - } -} - -void ByteQueue::LazyPutModifiable(byte *inString, size_t size) -{ - if (m_lazyLength > 0) - FinalizeLazyPut(); - m_lazyString = inString; - m_lazyLength = size; - m_lazyStringModifiable = true; -} - -void ByteQueue::UndoLazyPut(size_t size) -{ - if (m_lazyLength < size) - throw InvalidArgument("ByteQueue: size specified for UndoLazyPut is too large"); - - m_lazyLength -= size; -} - -void ByteQueue::FinalizeLazyPut() -{ - size_t len = m_lazyLength; - m_lazyLength = 0; - if (len) - Put(m_lazyString, len); -} - -size_t ByteQueue::Get(byte &outByte) -{ - if (m_head->Get(outByte)) - { - if (m_head->UsedUp()) - CleanupUsedNodes(); - return 1; - } - else if (m_lazyLength > 0) - { - outByte = *m_lazyString++; - m_lazyLength--; - return 1; - } - else - return 0; -} - -size_t ByteQueue::Get(byte *outString, size_t getMax) -{ - ArraySink sink(outString, getMax); - return (size_t)TransferTo(sink, getMax); -} - -size_t ByteQueue::Peek(byte &outByte) const -{ - if (m_head->Peek(outByte)) - return 1; - else if (m_lazyLength > 0) - { - outByte = *m_lazyString; - return 1; - } - else - return 0; -} - -size_t ByteQueue::Peek(byte *outString, size_t peekMax) const -{ - ArraySink sink(outString, peekMax); - return (size_t)CopyTo(sink, peekMax); -} - -size_t ByteQueue::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) -{ - if (blocking) - { - lword bytesLeft = transferBytes; - for (ByteQueueNode *current=m_head; bytesLeft && current; current=current->next) - bytesLeft -= current->TransferTo(target, bytesLeft, channel); - CleanupUsedNodes(); - - size_t len = (size_t)STDMIN(bytesLeft, (lword)m_lazyLength); - if (len) - { - if (m_lazyStringModifiable) - target.ChannelPutModifiable(channel, m_lazyString, len); - else - target.ChannelPut(channel, m_lazyString, len); - m_lazyString += len; - m_lazyLength -= len; - bytesLeft -= len; - } - transferBytes -= bytesLeft; - return 0; - } - else - { - Walker walker(*this); - size_t blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking); - Skip(transferBytes); - return blockedBytes; - } -} - -size_t ByteQueue::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const -{ - Walker walker(*this); - walker.Skip(begin); - lword transferBytes = end-begin; - size_t blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking); - begin += transferBytes; - return blockedBytes; -} - -void ByteQueue::Unget(byte inByte) -{ - Unget(&inByte, 1); -} - -void ByteQueue::Unget(const byte *inString, size_t length) -{ - size_t len = STDMIN(length, m_head->m_head); - length -= len; - m_head->m_head -= len; - memcpy(m_head->buf + m_head->m_head, inString + length, len); - - if (length > 0) - { - ByteQueueNode *newHead = new ByteQueueNode(length); - newHead->next = m_head; - m_head = newHead; - m_head->Put(inString, length); - } -} - -const byte * ByteQueue::Spy(size_t &contiguousSize) const -{ - contiguousSize = m_head->m_tail - m_head->m_head; - if (contiguousSize == 0 && m_lazyLength > 0) - { - contiguousSize = m_lazyLength; - return m_lazyString; - } - else - return m_head->buf + m_head->m_head; -} - -byte * ByteQueue::CreatePutSpace(size_t &size) -{ - if (m_lazyLength > 0) - FinalizeLazyPut(); - - if (m_tail->m_tail == m_tail->MaxSize()) - { - m_tail->next = new ByteQueueNode(STDMAX(m_nodeSize, size)); - m_tail = m_tail->next; - } - - size = m_tail->MaxSize() - m_tail->m_tail; - return m_tail->buf + m_tail->m_tail; -} - -ByteQueue & ByteQueue::operator=(const ByteQueue &rhs) -{ - Destroy(); - CopyFrom(rhs); - return *this; -} - -bool ByteQueue::operator==(const ByteQueue &rhs) const -{ - const lword currentSize = CurrentSize(); - - if (currentSize != rhs.CurrentSize()) - return false; - - Walker walker1(*this), walker2(rhs); - byte b1, b2; - - while (walker1.Get(b1) && walker2.Get(b2)) - if (b1 != b2) - return false; - - return true; -} - -byte ByteQueue::operator[](lword i) const -{ - for (ByteQueueNode *current=m_head; current; current=current->next) - { - if (i < current->CurrentSize()) - return (*current)[(size_t)i]; - - i -= current->CurrentSize(); - } - - assert(i < m_lazyLength); - return m_lazyString[i]; -} - -void ByteQueue::swap(ByteQueue &rhs) -{ - std::swap(m_autoNodeSize, rhs.m_autoNodeSize); - std::swap(m_nodeSize, rhs.m_nodeSize); - std::swap(m_head, rhs.m_head); - std::swap(m_tail, rhs.m_tail); - std::swap(m_lazyString, rhs.m_lazyString); - std::swap(m_lazyLength, rhs.m_lazyLength); - std::swap(m_lazyStringModifiable, rhs.m_lazyStringModifiable); -} - -// ******************************************************** - -void ByteQueue::Walker::IsolatedInitialize(const NameValuePairs ¶meters) -{ - m_node = m_queue.m_head; - m_position = 0; - m_offset = 0; - m_lazyString = m_queue.m_lazyString; - m_lazyLength = m_queue.m_lazyLength; -} - -size_t ByteQueue::Walker::Get(byte &outByte) -{ - ArraySink sink(&outByte, 1); - return (size_t)TransferTo(sink, 1); -} - -size_t ByteQueue::Walker::Get(byte *outString, size_t getMax) -{ - ArraySink sink(outString, getMax); - return (size_t)TransferTo(sink, getMax); -} - -size_t ByteQueue::Walker::Peek(byte &outByte) const -{ - ArraySink sink(&outByte, 1); - return (size_t)CopyTo(sink, 1); -} - -size_t ByteQueue::Walker::Peek(byte *outString, size_t peekMax) const -{ - ArraySink sink(outString, peekMax); - return (size_t)CopyTo(sink, peekMax); -} - -size_t ByteQueue::Walker::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) -{ - lword bytesLeft = transferBytes; - size_t blockedBytes = 0; - - while (m_node) - { - size_t len = (size_t)STDMIN(bytesLeft, (lword)m_node->CurrentSize()-m_offset); - blockedBytes = target.ChannelPut2(channel, m_node->buf+m_node->m_head+m_offset, len, 0, blocking); - - if (blockedBytes) - goto done; - - m_position += len; - bytesLeft -= len; - - if (!bytesLeft) - { - m_offset += len; - goto done; - } - - m_node = m_node->next; - m_offset = 0; - } - - if (bytesLeft && m_lazyLength) - { - size_t len = (size_t)STDMIN(bytesLeft, (lword)m_lazyLength); - blockedBytes = target.ChannelPut2(channel, m_lazyString, len, 0, blocking); - if (blockedBytes) - goto done; - - m_lazyString += len; - m_lazyLength -= len; - bytesLeft -= len; - } - -done: - transferBytes -= bytesLeft; - return blockedBytes; -} - -size_t ByteQueue::Walker::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const -{ - Walker walker(*this); - walker.Skip(begin); - lword transferBytes = end-begin; - size_t blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking); - begin += transferBytes; - return blockedBytes; -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/queue.h b/lib/cryptopp/queue.h deleted file mode 100644 index ab89dbdf1..000000000 --- a/lib/cryptopp/queue.h +++ /dev/null @@ -1,144 +0,0 @@ -// specification file for an unlimited queue for storing bytes - -#ifndef CRYPTOPP_QUEUE_H -#define CRYPTOPP_QUEUE_H - -#include "simple.h" -//#include <algorithm> - -NAMESPACE_BEGIN(CryptoPP) - -/** The queue is implemented as a linked list of byte arrays, but you don't need to - know about that. So just ignore this next line. :) */ -class ByteQueueNode; - -//! Byte Queue -class CRYPTOPP_DLL ByteQueue : public Bufferless<BufferedTransformation> -{ -public: - ByteQueue(size_t nodeSize=0); - ByteQueue(const ByteQueue ©); - ~ByteQueue(); - - lword MaxRetrievable() const - {return CurrentSize();} - bool AnyRetrievable() const - {return !IsEmpty();} - - void IsolatedInitialize(const NameValuePairs ¶meters); - byte * CreatePutSpace(size_t &size); - size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); - - size_t Get(byte &outByte); - size_t Get(byte *outString, size_t getMax); - - size_t Peek(byte &outByte) const; - size_t Peek(byte *outString, size_t peekMax) const; - - size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); - size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; - - // these member functions are not inherited - void SetNodeSize(size_t nodeSize); - - lword CurrentSize() const; - bool IsEmpty() const; - - void Clear(); - - void Unget(byte inByte); - void Unget(const byte *inString, size_t length); - - const byte * Spy(size_t &contiguousSize) const; - - void LazyPut(const byte *inString, size_t size); - void LazyPutModifiable(byte *inString, size_t size); - void UndoLazyPut(size_t size); - void FinalizeLazyPut(); - - ByteQueue & operator=(const ByteQueue &rhs); - bool operator==(const ByteQueue &rhs) const; - bool operator!=(const ByteQueue &rhs) const {return !operator==(rhs);} - byte operator[](lword i) const; - void swap(ByteQueue &rhs); - - class Walker : public InputRejecting<BufferedTransformation> - { - public: - Walker(const ByteQueue &queue) - : m_queue(queue) {Initialize();} - - lword GetCurrentPosition() {return m_position;} - - lword MaxRetrievable() const - {return m_queue.CurrentSize() - m_position;} - - void IsolatedInitialize(const NameValuePairs ¶meters); - - size_t Get(byte &outByte); - size_t Get(byte *outString, size_t getMax); - - size_t Peek(byte &outByte) const; - size_t Peek(byte *outString, size_t peekMax) const; - - size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); - size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; - - private: - const ByteQueue &m_queue; - const ByteQueueNode *m_node; - lword m_position; - size_t m_offset; - const byte *m_lazyString; - size_t m_lazyLength; - }; - - friend class Walker; - -private: - void CleanupUsedNodes(); - void CopyFrom(const ByteQueue ©); - void Destroy(); - - bool m_autoNodeSize; - size_t m_nodeSize; - ByteQueueNode *m_head, *m_tail; - byte *m_lazyString; - size_t m_lazyLength; - bool m_lazyStringModifiable; -}; - -//! use this to make sure LazyPut is finalized in event of exception -class CRYPTOPP_DLL LazyPutter -{ -public: - LazyPutter(ByteQueue &bq, const byte *inString, size_t size) - : m_bq(bq) {bq.LazyPut(inString, size);} - ~LazyPutter() - {try {m_bq.FinalizeLazyPut();} catch(...) {}} -protected: - LazyPutter(ByteQueue &bq) : m_bq(bq) {} -private: - ByteQueue &m_bq; -}; - -//! like LazyPutter, but does a LazyPutModifiable instead -class LazyPutterModifiable : public LazyPutter -{ -public: - LazyPutterModifiable(ByteQueue &bq, byte *inString, size_t size) - : LazyPutter(bq) {bq.LazyPutModifiable(inString, size);} -}; - -NAMESPACE_END - -#ifndef __BORLANDC__ -NAMESPACE_BEGIN(std) -template<> inline void swap(CryptoPP::ByteQueue &a, CryptoPP::ByteQueue &b) -{ - a.swap(b); -} -NAMESPACE_END -#endif - -#endif diff --git a/lib/cryptopp/rabin.cpp b/lib/cryptopp/rabin.cpp deleted file mode 100644 index d496333b5..000000000 --- a/lib/cryptopp/rabin.cpp +++ /dev/null @@ -1,221 +0,0 @@ -// rabin.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "rabin.h" -#include "nbtheory.h" -#include "asn.h" -#include "sha.h" -#include "modarith.h" - -NAMESPACE_BEGIN(CryptoPP) - -void RabinFunction::BERDecode(BufferedTransformation &bt) -{ - BERSequenceDecoder seq(bt); - m_n.BERDecode(seq); - m_r.BERDecode(seq); - m_s.BERDecode(seq); - seq.MessageEnd(); -} - -void RabinFunction::DEREncode(BufferedTransformation &bt) const -{ - DERSequenceEncoder seq(bt); - m_n.DEREncode(seq); - m_r.DEREncode(seq); - m_s.DEREncode(seq); - seq.MessageEnd(); -} - -Integer RabinFunction::ApplyFunction(const Integer &in) const -{ - DoQuickSanityCheck(); - - Integer out = in.Squared()%m_n; - if (in.IsOdd()) - out = out*m_r%m_n; - if (Jacobi(in, m_n)==-1) - out = out*m_s%m_n; - return out; -} - -bool RabinFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const -{ - bool pass = true; - pass = pass && m_n > Integer::One() && m_n%4 == 1; - pass = pass && m_r > Integer::One() && m_r < m_n; - pass = pass && m_s > Integer::One() && m_s < m_n; - if (level >= 1) - pass = pass && Jacobi(m_r, m_n) == -1 && Jacobi(m_s, m_n) == -1; - return pass; -} - -bool RabinFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const -{ - return GetValueHelper(this, name, valueType, pValue).Assignable() - CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) - CRYPTOPP_GET_FUNCTION_ENTRY(QuadraticResidueModPrime1) - CRYPTOPP_GET_FUNCTION_ENTRY(QuadraticResidueModPrime2) - ; -} - -void RabinFunction::AssignFrom(const NameValuePairs &source) -{ - AssignFromHelper(this, source) - CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) - CRYPTOPP_SET_FUNCTION_ENTRY(QuadraticResidueModPrime1) - CRYPTOPP_SET_FUNCTION_ENTRY(QuadraticResidueModPrime2) - ; -} - -// ***************************************************************************** -// private key operations: - -// generate a random private key -void InvertibleRabinFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) -{ - int modulusSize = 2048; - alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize); - - if (modulusSize < 16) - throw InvalidArgument("InvertibleRabinFunction: specified modulus size is too small"); - - // VC70 workaround: putting these after primeParam causes overlapped stack allocation - bool rFound=false, sFound=false; - Integer t=2; - - AlgorithmParameters primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize) - ("EquivalentTo", 3)("Mod", 4); - m_p.GenerateRandom(rng, primeParam); - m_q.GenerateRandom(rng, primeParam); - - while (!(rFound && sFound)) - { - int jp = Jacobi(t, m_p); - int jq = Jacobi(t, m_q); - - if (!rFound && jp==1 && jq==-1) - { - m_r = t; - rFound = true; - } - - if (!sFound && jp==-1 && jq==1) - { - m_s = t; - sFound = true; - } - - ++t; - } - - m_n = m_p * m_q; - m_u = m_q.InverseMod(m_p); -} - -void InvertibleRabinFunction::BERDecode(BufferedTransformation &bt) -{ - BERSequenceDecoder seq(bt); - m_n.BERDecode(seq); - m_r.BERDecode(seq); - m_s.BERDecode(seq); - m_p.BERDecode(seq); - m_q.BERDecode(seq); - m_u.BERDecode(seq); - seq.MessageEnd(); -} - -void InvertibleRabinFunction::DEREncode(BufferedTransformation &bt) const -{ - DERSequenceEncoder seq(bt); - m_n.DEREncode(seq); - m_r.DEREncode(seq); - m_s.DEREncode(seq); - m_p.DEREncode(seq); - m_q.DEREncode(seq); - m_u.DEREncode(seq); - seq.MessageEnd(); -} - -Integer InvertibleRabinFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &in) const -{ - DoQuickSanityCheck(); - - ModularArithmetic modn(m_n); - Integer r(rng, Integer::One(), m_n - Integer::One()); - r = modn.Square(r); - Integer r2 = modn.Square(r); - Integer c = modn.Multiply(in, r2); // blind - - Integer cp=c%m_p, cq=c%m_q; - - int jp = Jacobi(cp, m_p); - int jq = Jacobi(cq, m_q); - - if (jq==-1) - { - cp = cp*EuclideanMultiplicativeInverse(m_r, m_p)%m_p; - cq = cq*EuclideanMultiplicativeInverse(m_r, m_q)%m_q; - } - - if (jp==-1) - { - cp = cp*EuclideanMultiplicativeInverse(m_s, m_p)%m_p; - cq = cq*EuclideanMultiplicativeInverse(m_s, m_q)%m_q; - } - - cp = ModularSquareRoot(cp, m_p); - cq = ModularSquareRoot(cq, m_q); - - if (jp==-1) - cp = m_p-cp; - - Integer out = CRT(cq, m_q, cp, m_p, m_u); - - out = modn.Divide(out, r); // unblind - - if ((jq==-1 && out.IsEven()) || (jq==1 && out.IsOdd())) - out = m_n-out; - - return out; -} - -bool InvertibleRabinFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const -{ - bool pass = RabinFunction::Validate(rng, level); - pass = pass && m_p > Integer::One() && m_p%4 == 3 && m_p < m_n; - pass = pass && m_q > Integer::One() && m_q%4 == 3 && m_q < m_n; - pass = pass && m_u.IsPositive() && m_u < m_p; - if (level >= 1) - { - pass = pass && m_p * m_q == m_n; - pass = pass && m_u * m_q % m_p == 1; - pass = pass && Jacobi(m_r, m_p) == 1; - pass = pass && Jacobi(m_r, m_q) == -1; - pass = pass && Jacobi(m_s, m_p) == -1; - pass = pass && Jacobi(m_s, m_q) == 1; - } - if (level >= 2) - pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); - return pass; -} - -bool InvertibleRabinFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const -{ - return GetValueHelper<RabinFunction>(this, name, valueType, pValue).Assignable() - CRYPTOPP_GET_FUNCTION_ENTRY(Prime1) - CRYPTOPP_GET_FUNCTION_ENTRY(Prime2) - CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) - ; -} - -void InvertibleRabinFunction::AssignFrom(const NameValuePairs &source) -{ - AssignFromHelper<RabinFunction>(this, source) - CRYPTOPP_SET_FUNCTION_ENTRY(Prime1) - CRYPTOPP_SET_FUNCTION_ENTRY(Prime2) - CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) - ; -} - -NAMESPACE_END diff --git a/lib/cryptopp/rabin.h b/lib/cryptopp/rabin.h deleted file mode 100644 index 1c9bcbb49..000000000 --- a/lib/cryptopp/rabin.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef CRYPTOPP_RABIN_H -#define CRYPTOPP_RABIN_H - -/** \file -*/ - -#include "oaep.h" -#include "pssr.h" -#include "integer.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -class RabinFunction : public TrapdoorFunction, public PublicKey -{ - typedef RabinFunction ThisClass; - -public: - void Initialize(const Integer &n, const Integer &r, const Integer &s) - {m_n = n; m_r = r; m_s = s;} - - void BERDecode(BufferedTransformation &bt); - void DEREncode(BufferedTransformation &bt) const; - - Integer ApplyFunction(const Integer &x) const; - Integer PreimageBound() const {return m_n;} - Integer ImageBound() const {return m_n;} - - bool Validate(RandomNumberGenerator &rng, unsigned int level) const; - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; - void AssignFrom(const NameValuePairs &source); - - const Integer& GetModulus() const {return m_n;} - const Integer& GetQuadraticResidueModPrime1() const {return m_r;} - const Integer& GetQuadraticResidueModPrime2() const {return m_s;} - - void SetModulus(const Integer &n) {m_n = n;} - void SetQuadraticResidueModPrime1(const Integer &r) {m_r = r;} - void SetQuadraticResidueModPrime2(const Integer &s) {m_s = s;} - -protected: - Integer m_n, m_r, m_s; -}; - -//! _ -class InvertibleRabinFunction : public RabinFunction, public TrapdoorFunctionInverse, public PrivateKey -{ - typedef InvertibleRabinFunction ThisClass; - -public: - void Initialize(const Integer &n, const Integer &r, const Integer &s, - const Integer &p, const Integer &q, const Integer &u) - {m_n = n; m_r = r; m_s = s; m_p = p; m_q = q; m_u = u;} - void Initialize(RandomNumberGenerator &rng, unsigned int keybits) - {GenerateRandomWithKeySize(rng, keybits);} - - void BERDecode(BufferedTransformation &bt); - void DEREncode(BufferedTransformation &bt) const; - - Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; - - bool Validate(RandomNumberGenerator &rng, unsigned int level) const; - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; - void AssignFrom(const NameValuePairs &source); - /*! parameters: (ModulusSize) */ - void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); - - const Integer& GetPrime1() const {return m_p;} - const Integer& GetPrime2() const {return m_q;} - const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const {return m_u;} - - void SetPrime1(const Integer &p) {m_p = p;} - void SetPrime2(const Integer &q) {m_q = q;} - void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer &u) {m_u = u;} - -protected: - Integer m_p, m_q, m_u; -}; - -//! Rabin -struct Rabin -{ - static std::string StaticAlgorithmName() {return "Rabin-Crypto++Variant";} - typedef RabinFunction PublicKey; - typedef InvertibleRabinFunction PrivateKey; -}; - -//! Rabin encryption -template <class STANDARD> -struct RabinES : public TF_ES<STANDARD, Rabin> -{ -}; - -//! Rabin signature -template <class STANDARD, class H> -struct RabinSS : public TF_SS<STANDARD, H, Rabin> -{ -}; - -// More typedefs for backwards compatibility -class SHA1; -typedef RabinES<OAEP<SHA1> >::Decryptor RabinDecryptor; -typedef RabinES<OAEP<SHA1> >::Encryptor RabinEncryptor; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/randpool.cpp b/lib/cryptopp/randpool.cpp deleted file mode 100644 index a063c8996..000000000 --- a/lib/cryptopp/randpool.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// randpool.cpp - written and placed in the public domain by Wei Dai -// RandomPool used to follow the design of randpool in PGP 2.6.x, -// but as of version 5.5 it has been redesigned to reduce the risk -// of reusing random numbers after state rollback (which may occur -// when running in a virtual machine like VMware). - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "randpool.h" -#include "aes.h" -#include "sha.h" -#include "hrtimer.h" -#include <time.h> - -NAMESPACE_BEGIN(CryptoPP) - -RandomPool::RandomPool() - : m_pCipher(new AES::Encryption), m_keySet(false) -{ - memset(m_key, 0, m_key.SizeInBytes()); - memset(m_seed, 0, m_seed.SizeInBytes()); -} - -void RandomPool::IncorporateEntropy(const byte *input, size_t length) -{ - SHA256 hash; - hash.Update(m_key, 32); - hash.Update(input, length); - hash.Final(m_key); - m_keySet = false; -} - -void RandomPool::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size) -{ - if (size > 0) - { - if (!m_keySet) - m_pCipher->SetKey(m_key, 32); - - Timer timer; - TimerWord tw = timer.GetCurrentTimerValue(); - CRYPTOPP_COMPILE_ASSERT(sizeof(tw) <= 16); - *(TimerWord *)m_seed.data() += tw; - - time_t t = time(NULL); - CRYPTOPP_COMPILE_ASSERT(sizeof(t) <= 8); - *(time_t *)(m_seed.data()+8) += t; - - do - { - m_pCipher->ProcessBlock(m_seed); - size_t len = UnsignedMin(16, size); - target.ChannelPut(channel, m_seed, len); - size -= len; - } while (size > 0); - } -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/randpool.h b/lib/cryptopp/randpool.h deleted file mode 100644 index c25bc9bb1..000000000 --- a/lib/cryptopp/randpool.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef CRYPTOPP_RANDPOOL_H -#define CRYPTOPP_RANDPOOL_H - -#include "cryptlib.h" -#include "filters.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! Randomness Pool -/*! This class can be used to generate cryptographic quality - pseudorandom bytes after seeding the pool with IncorporateEntropy() */ -class CRYPTOPP_DLL RandomPool : public RandomNumberGenerator, public NotCopyable -{ -public: - RandomPool(); - - bool CanIncorporateEntropy() const {return true;} - void IncorporateEntropy(const byte *input, size_t length); - void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size); - - // for backwards compatibility. use RandomNumberSource, RandomNumberStore, and RandomNumberSink for other BufferTransformation functionality - void Put(const byte *input, size_t length) {IncorporateEntropy(input, length);} - -private: - FixedSizeSecBlock<byte, 32> m_key; - FixedSizeSecBlock<byte, 16> m_seed; - member_ptr<BlockCipher> m_pCipher; - bool m_keySet; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/rdtables.cpp b/lib/cryptopp/rdtables.cpp deleted file mode 100644 index 493793252..000000000 --- a/lib/cryptopp/rdtables.cpp +++ /dev/null @@ -1,172 +0,0 @@ -// Rijndael tables - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "rijndael.h" - -// VC60 workaround: gives a C4786 warning without this function -// when runtime lib is set to multithread debug DLL -// even though warning 4786 is disabled! -void Rijndael_VC60Workaround() -{ -} - -NAMESPACE_BEGIN(CryptoPP) - -/* -Te0[x] = S [x].[02, 01, 01, 03]; -Te1[x] = S [x].[03, 02, 01, 01]; -Te2[x] = S [x].[01, 03, 02, 01]; -Te3[x] = S [x].[01, 01, 03, 02]; - -Td0[x] = Si[x].[0e, 09, 0d, 0b]; -Td1[x] = Si[x].[0b, 0e, 09, 0d]; -Td2[x] = Si[x].[0d, 0b, 0e, 09]; -Td3[x] = Si[x].[09, 0d, 0b, 0e]; -*/ - -const byte Rijndael::Base::Se[256] = { - 0x63, 0x7c, 0x77, 0x7b, - 0xf2, 0x6b, 0x6f, 0xc5, - 0x30, 0x01, 0x67, 0x2b, - 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, - 0xfa, 0x59, 0x47, 0xf0, - 0xad, 0xd4, 0xa2, 0xaf, - 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, - 0x36, 0x3f, 0xf7, 0xcc, - 0x34, 0xa5, 0xe5, 0xf1, - 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, - 0x18, 0x96, 0x05, 0x9a, - 0x07, 0x12, 0x80, 0xe2, - 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, - 0x1b, 0x6e, 0x5a, 0xa0, - 0x52, 0x3b, 0xd6, 0xb3, - 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, - 0x20, 0xfc, 0xb1, 0x5b, - 0x6a, 0xcb, 0xbe, 0x39, - 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, - 0x43, 0x4d, 0x33, 0x85, - 0x45, 0xf9, 0x02, 0x7f, - 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, - 0x92, 0x9d, 0x38, 0xf5, - 0xbc, 0xb6, 0xda, 0x21, - 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, - 0x5f, 0x97, 0x44, 0x17, - 0xc4, 0xa7, 0x7e, 0x3d, - 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, - 0x22, 0x2a, 0x90, 0x88, - 0x46, 0xee, 0xb8, 0x14, - 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, - 0x49, 0x06, 0x24, 0x5c, - 0xc2, 0xd3, 0xac, 0x62, - 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, - 0x8d, 0xd5, 0x4e, 0xa9, - 0x6c, 0x56, 0xf4, 0xea, - 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, - 0x1c, 0xa6, 0xb4, 0xc6, - 0xe8, 0xdd, 0x74, 0x1f, - 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, - 0x48, 0x03, 0xf6, 0x0e, - 0x61, 0x35, 0x57, 0xb9, - 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, - 0x69, 0xd9, 0x8e, 0x94, - 0x9b, 0x1e, 0x87, 0xe9, - 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, - 0xbf, 0xe6, 0x42, 0x68, - 0x41, 0x99, 0x2d, 0x0f, - 0xb0, 0x54, 0xbb, 0x16, -}; - -const byte Rijndael::Base::Sd[256] = { - 0x52, 0x09, 0x6a, 0xd5, - 0x30, 0x36, 0xa5, 0x38, - 0xbf, 0x40, 0xa3, 0x9e, - 0x81, 0xf3, 0xd7, 0xfb, - 0x7c, 0xe3, 0x39, 0x82, - 0x9b, 0x2f, 0xff, 0x87, - 0x34, 0x8e, 0x43, 0x44, - 0xc4, 0xde, 0xe9, 0xcb, - 0x54, 0x7b, 0x94, 0x32, - 0xa6, 0xc2, 0x23, 0x3d, - 0xee, 0x4c, 0x95, 0x0b, - 0x42, 0xfa, 0xc3, 0x4e, - 0x08, 0x2e, 0xa1, 0x66, - 0x28, 0xd9, 0x24, 0xb2, - 0x76, 0x5b, 0xa2, 0x49, - 0x6d, 0x8b, 0xd1, 0x25, - 0x72, 0xf8, 0xf6, 0x64, - 0x86, 0x68, 0x98, 0x16, - 0xd4, 0xa4, 0x5c, 0xcc, - 0x5d, 0x65, 0xb6, 0x92, - 0x6c, 0x70, 0x48, 0x50, - 0xfd, 0xed, 0xb9, 0xda, - 0x5e, 0x15, 0x46, 0x57, - 0xa7, 0x8d, 0x9d, 0x84, - 0x90, 0xd8, 0xab, 0x00, - 0x8c, 0xbc, 0xd3, 0x0a, - 0xf7, 0xe4, 0x58, 0x05, - 0xb8, 0xb3, 0x45, 0x06, - 0xd0, 0x2c, 0x1e, 0x8f, - 0xca, 0x3f, 0x0f, 0x02, - 0xc1, 0xaf, 0xbd, 0x03, - 0x01, 0x13, 0x8a, 0x6b, - 0x3a, 0x91, 0x11, 0x41, - 0x4f, 0x67, 0xdc, 0xea, - 0x97, 0xf2, 0xcf, 0xce, - 0xf0, 0xb4, 0xe6, 0x73, - 0x96, 0xac, 0x74, 0x22, - 0xe7, 0xad, 0x35, 0x85, - 0xe2, 0xf9, 0x37, 0xe8, - 0x1c, 0x75, 0xdf, 0x6e, - 0x47, 0xf1, 0x1a, 0x71, - 0x1d, 0x29, 0xc5, 0x89, - 0x6f, 0xb7, 0x62, 0x0e, - 0xaa, 0x18, 0xbe, 0x1b, - 0xfc, 0x56, 0x3e, 0x4b, - 0xc6, 0xd2, 0x79, 0x20, - 0x9a, 0xdb, 0xc0, 0xfe, - 0x78, 0xcd, 0x5a, 0xf4, - 0x1f, 0xdd, 0xa8, 0x33, - 0x88, 0x07, 0xc7, 0x31, - 0xb1, 0x12, 0x10, 0x59, - 0x27, 0x80, 0xec, 0x5f, - 0x60, 0x51, 0x7f, 0xa9, - 0x19, 0xb5, 0x4a, 0x0d, - 0x2d, 0xe5, 0x7a, 0x9f, - 0x93, 0xc9, 0x9c, 0xef, - 0xa0, 0xe0, 0x3b, 0x4d, - 0xae, 0x2a, 0xf5, 0xb0, - 0xc8, 0xeb, 0xbb, 0x3c, - 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2b, 0x04, 0x7e, - 0xba, 0x77, 0xd6, 0x26, - 0xe1, 0x69, 0x14, 0x63, - 0x55, 0x21, 0x0c, 0x7d, -}; - -const word32 Rijndael::Base::rcon[] = { - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/resource.h b/lib/cryptopp/resource.h deleted file mode 100644 index 861e22ba3..000000000 --- a/lib/cryptopp/resource.h +++ /dev/null @@ -1,15 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by cryptopp.rc -// - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/lib/cryptopp/rijndael.cpp b/lib/cryptopp/rijndael.cpp deleted file mode 100644 index c185032cf..000000000 --- a/lib/cryptopp/rijndael.cpp +++ /dev/null @@ -1,1261 +0,0 @@ -// rijndael.cpp - modified by Chris Morgan <cmorgan@wpi.edu> -// and Wei Dai from Paulo Baretto's Rijndael implementation -// The original code and all modifications are in the public domain. - -// use "cl /EP /P /DCRYPTOPP_GENERATE_X64_MASM rijndael.cpp" to generate MASM code - -/* -July 2010: Added support for AES-NI instructions via compiler intrinsics. -*/ - -/* -Feb 2009: The x86/x64 assembly code was rewritten in by Wei Dai to do counter mode -caching, which was invented by Hongjun Wu and popularized by Daniel J. Bernstein -and Peter Schwabe in their paper "New AES software speed records". The round -function was also modified to include a trick similar to one in Brian Gladman's -x86 assembly code, doing an 8-bit register move to minimize the number of -register spills. Also switched to compressed tables and copying round keys to -the stack. - -The C++ implementation now uses compressed tables if -CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS is defined. -*/ - -/* -July 2006: Defense against timing attacks was added in by Wei Dai. - -The code now uses smaller tables in the first and last rounds, -and preloads them into L1 cache before usage (by loading at least -one element in each cache line). - -We try to delay subsequent accesses to each table (used in the first -and last rounds) until all of the table has been preloaded. Hopefully -the compiler isn't smart enough to optimize that code away. - -After preloading the table, we also try not to access any memory location -other than the table and the stack, in order to prevent table entries from -being unloaded from L1 cache, until that round is finished. -(Some popular CPUs have 2-way associative caches.) -*/ - -// This is the original introductory comment: - -/** - * version 3.0 (December 2000) - * - * Optimised ANSI C code for the Rijndael cipher (now AES) - * - * author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> - * author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> - * author Paulo Barreto <paulo.barreto@terra.com.br> - * - * This code is hereby placed in the public domain. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS -#ifndef CRYPTOPP_GENERATE_X64_MASM - -#include "rijndael.h" -#include "misc.h" -#include "cpu.h" - -NAMESPACE_BEGIN(CryptoPP) - -#ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) -namespace rdtable {CRYPTOPP_ALIGN_DATA(16) word64 Te[256+2];} -using namespace rdtable; -#else -static word64 Te[256]; -#endif -static word64 Td[256]; -#else -static word32 Te[256*4], Td[256*4]; -#endif -static volatile bool s_TeFilled = false, s_TdFilled = false; - -// ************************* Portable Code ************************************ - -#define QUARTER_ROUND(L, T, t, a, b, c, d) \ - a ^= L(T, 3, byte(t)); t >>= 8;\ - b ^= L(T, 2, byte(t)); t >>= 8;\ - c ^= L(T, 1, byte(t)); t >>= 8;\ - d ^= L(T, 0, t); - -#define QUARTER_ROUND_LE(t, a, b, c, d) \ - tempBlock[a] = ((byte *)(Te+byte(t)))[1]; t >>= 8;\ - tempBlock[b] = ((byte *)(Te+byte(t)))[1]; t >>= 8;\ - tempBlock[c] = ((byte *)(Te+byte(t)))[1]; t >>= 8;\ - tempBlock[d] = ((byte *)(Te+t))[1]; - -#ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS - #define QUARTER_ROUND_LD(t, a, b, c, d) \ - tempBlock[a] = ((byte *)(Td+byte(t)))[GetNativeByteOrder()*7]; t >>= 8;\ - tempBlock[b] = ((byte *)(Td+byte(t)))[GetNativeByteOrder()*7]; t >>= 8;\ - tempBlock[c] = ((byte *)(Td+byte(t)))[GetNativeByteOrder()*7]; t >>= 8;\ - tempBlock[d] = ((byte *)(Td+t))[GetNativeByteOrder()*7]; -#else - #define QUARTER_ROUND_LD(t, a, b, c, d) \ - tempBlock[a] = Sd[byte(t)]; t >>= 8;\ - tempBlock[b] = Sd[byte(t)]; t >>= 8;\ - tempBlock[c] = Sd[byte(t)]; t >>= 8;\ - tempBlock[d] = Sd[t]; -#endif - -#define QUARTER_ROUND_E(t, a, b, c, d) QUARTER_ROUND(TL_M, Te, t, a, b, c, d) -#define QUARTER_ROUND_D(t, a, b, c, d) QUARTER_ROUND(TL_M, Td, t, a, b, c, d) - -#ifdef IS_LITTLE_ENDIAN - #define QUARTER_ROUND_FE(t, a, b, c, d) QUARTER_ROUND(TL_F, Te, t, d, c, b, a) - #define QUARTER_ROUND_FD(t, a, b, c, d) QUARTER_ROUND(TL_F, Td, t, d, c, b, a) - #ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS - #define TL_F(T, i, x) (*(word32 *)((byte *)T + x*8 + (6-i)%4+1)) - #define TL_M(T, i, x) (*(word32 *)((byte *)T + x*8 + (i+3)%4+1)) - #else - #define TL_F(T, i, x) rotrFixed(T[x], (3-i)*8) - #define TL_M(T, i, x) T[i*256 + x] - #endif -#else - #define QUARTER_ROUND_FE(t, a, b, c, d) QUARTER_ROUND(TL_F, Te, t, a, b, c, d) - #define QUARTER_ROUND_FD(t, a, b, c, d) QUARTER_ROUND(TL_F, Td, t, a, b, c, d) - #ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS - #define TL_F(T, i, x) (*(word32 *)((byte *)T + x*8 + (4-i)%4)) - #define TL_M TL_F - #else - #define TL_F(T, i, x) rotrFixed(T[x], i*8) - #define TL_M(T, i, x) T[i*256 + x] - #endif -#endif - - -#define f2(x) ((x<<1)^(((x>>7)&1)*0x11b)) -#define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b)) -#define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b)) - -#define f3(x) (f2(x) ^ x) -#define f9(x) (f8(x) ^ x) -#define fb(x) (f8(x) ^ f2(x) ^ x) -#define fd(x) (f8(x) ^ f4(x) ^ x) -#define fe(x) (f8(x) ^ f4(x) ^ f2(x)) - -void Rijndael::Base::FillEncTable() -{ - for (int i=0; i<256; i++) - { - byte x = Se[i]; -#ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS - word32 y = word32(x)<<8 | word32(x)<<16 | word32(f2(x))<<24; - Te[i] = word64(y | f3(x))<<32 | y; -#else - word32 y = f3(x) | word32(x)<<8 | word32(x)<<16 | word32(f2(x))<<24; - for (int j=0; j<4; j++) - { - Te[i+j*256] = y; - y = rotrFixed(y, 8); - } -#endif - } -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) - Te[256] = Te[257] = 0; -#endif - s_TeFilled = true; -} - -void Rijndael::Base::FillDecTable() -{ - for (int i=0; i<256; i++) - { - byte x = Sd[i]; -#ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS - word32 y = word32(fd(x))<<8 | word32(f9(x))<<16 | word32(fe(x))<<24; - Td[i] = word64(y | fb(x))<<32 | y | x; -#else - word32 y = fb(x) | word32(fd(x))<<8 | word32(f9(x))<<16 | word32(fe(x))<<24;; - for (int j=0; j<4; j++) - { - Td[i+j*256] = y; - y = rotrFixed(y, 8); - } -#endif - } - s_TdFilled = true; -} - -void Rijndael::Base::UncheckedSetKey(const byte *userKey, unsigned int keylen, const NameValuePairs &) -{ - AssertValidKeyLength(keylen); - - m_rounds = keylen/4 + 6; - m_key.New(4*(m_rounds+1)); - - word32 *rk = m_key; - -#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE && (!defined(_MSC_VER) || _MSC_VER >= 1600 || CRYPTOPP_BOOL_X86) - // MSVC 2008 SP1 generates bad code for _mm_extract_epi32() when compiling for X64 - if (HasAESNI()) - { - static const word32 rcLE[] = { - 0x01, 0x02, 0x04, 0x08, - 0x10, 0x20, 0x40, 0x80, - 0x1B, 0x36, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ - }; - const word32 *rc = rcLE; - - __m128i temp = _mm_loadu_si128((__m128i *)(userKey+keylen-16)); - memcpy(rk, userKey, keylen); - - while (true) - { - rk[keylen/4] = rk[0] ^ _mm_extract_epi32(_mm_aeskeygenassist_si128(temp, 0), 3) ^ *(rc++); - rk[keylen/4+1] = rk[1] ^ rk[keylen/4]; - rk[keylen/4+2] = rk[2] ^ rk[keylen/4+1]; - rk[keylen/4+3] = rk[3] ^ rk[keylen/4+2]; - - if (rk + keylen/4 + 4 == m_key.end()) - break; - - if (keylen == 24) - { - rk[10] = rk[ 4] ^ rk[ 9]; - rk[11] = rk[ 5] ^ rk[10]; - temp = _mm_insert_epi32(temp, rk[11], 3); - } - else if (keylen == 32) - { - temp = _mm_insert_epi32(temp, rk[11], 3); - rk[12] = rk[ 4] ^ _mm_extract_epi32(_mm_aeskeygenassist_si128(temp, 0), 2); - rk[13] = rk[ 5] ^ rk[12]; - rk[14] = rk[ 6] ^ rk[13]; - rk[15] = rk[ 7] ^ rk[14]; - temp = _mm_insert_epi32(temp, rk[15], 3); - } - else - temp = _mm_insert_epi32(temp, rk[7], 3); - - rk += keylen/4; - } - - if (!IsForwardTransformation()) - { - rk = m_key; - unsigned int i, j; - - std::swap(*(__m128i *)(rk), *(__m128i *)(rk+4*m_rounds)); - - for (i = 4, j = 4*m_rounds-4; i < j; i += 4, j -= 4) - { - temp = _mm_aesimc_si128(*(__m128i *)(rk+i)); - *(__m128i *)(rk+i) = _mm_aesimc_si128(*(__m128i *)(rk+j)); - *(__m128i *)(rk+j) = temp; - } - - *(__m128i *)(rk+i) = _mm_aesimc_si128(*(__m128i *)(rk+i)); - } - - return; - } -#endif - - GetUserKey(BIG_ENDIAN_ORDER, rk, keylen/4, userKey, keylen); - const word32 *rc = rcon; - word32 temp; - - while (true) - { - temp = rk[keylen/4-1]; - word32 x = (word32(Se[GETBYTE(temp, 2)]) << 24) ^ (word32(Se[GETBYTE(temp, 1)]) << 16) ^ (word32(Se[GETBYTE(temp, 0)]) << 8) ^ Se[GETBYTE(temp, 3)]; - rk[keylen/4] = rk[0] ^ x ^ *(rc++); - rk[keylen/4+1] = rk[1] ^ rk[keylen/4]; - rk[keylen/4+2] = rk[2] ^ rk[keylen/4+1]; - rk[keylen/4+3] = rk[3] ^ rk[keylen/4+2]; - - if (rk + keylen/4 + 4 == m_key.end()) - break; - - if (keylen == 24) - { - rk[10] = rk[ 4] ^ rk[ 9]; - rk[11] = rk[ 5] ^ rk[10]; - } - else if (keylen == 32) - { - temp = rk[11]; - rk[12] = rk[ 4] ^ (word32(Se[GETBYTE(temp, 3)]) << 24) ^ (word32(Se[GETBYTE(temp, 2)]) << 16) ^ (word32(Se[GETBYTE(temp, 1)]) << 8) ^ Se[GETBYTE(temp, 0)]; - rk[13] = rk[ 5] ^ rk[12]; - rk[14] = rk[ 6] ^ rk[13]; - rk[15] = rk[ 7] ^ rk[14]; - } - rk += keylen/4; - } - - rk = m_key; - - if (IsForwardTransformation()) - { - if (!s_TeFilled) - FillEncTable(); - - ConditionalByteReverse(BIG_ENDIAN_ORDER, rk, rk, 16); - ConditionalByteReverse(BIG_ENDIAN_ORDER, rk + m_rounds*4, rk + m_rounds*4, 16); - } - else - { - if (!s_TdFilled) - FillDecTable(); - - unsigned int i, j; - -#define InverseMixColumn(x) TL_M(Td, 0, Se[GETBYTE(x, 3)]) ^ TL_M(Td, 1, Se[GETBYTE(x, 2)]) ^ TL_M(Td, 2, Se[GETBYTE(x, 1)]) ^ TL_M(Td, 3, Se[GETBYTE(x, 0)]) - - for (i = 4, j = 4*m_rounds-4; i < j; i += 4, j -= 4) - { - temp = InverseMixColumn(rk[i ]); rk[i ] = InverseMixColumn(rk[j ]); rk[j ] = temp; - temp = InverseMixColumn(rk[i + 1]); rk[i + 1] = InverseMixColumn(rk[j + 1]); rk[j + 1] = temp; - temp = InverseMixColumn(rk[i + 2]); rk[i + 2] = InverseMixColumn(rk[j + 2]); rk[j + 2] = temp; - temp = InverseMixColumn(rk[i + 3]); rk[i + 3] = InverseMixColumn(rk[j + 3]); rk[j + 3] = temp; - } - - rk[i+0] = InverseMixColumn(rk[i+0]); - rk[i+1] = InverseMixColumn(rk[i+1]); - rk[i+2] = InverseMixColumn(rk[i+2]); - rk[i+3] = InverseMixColumn(rk[i+3]); - - temp = ConditionalByteReverse(BIG_ENDIAN_ORDER, rk[0]); rk[0] = ConditionalByteReverse(BIG_ENDIAN_ORDER, rk[4*m_rounds+0]); rk[4*m_rounds+0] = temp; - temp = ConditionalByteReverse(BIG_ENDIAN_ORDER, rk[1]); rk[1] = ConditionalByteReverse(BIG_ENDIAN_ORDER, rk[4*m_rounds+1]); rk[4*m_rounds+1] = temp; - temp = ConditionalByteReverse(BIG_ENDIAN_ORDER, rk[2]); rk[2] = ConditionalByteReverse(BIG_ENDIAN_ORDER, rk[4*m_rounds+2]); rk[4*m_rounds+2] = temp; - temp = ConditionalByteReverse(BIG_ENDIAN_ORDER, rk[3]); rk[3] = ConditionalByteReverse(BIG_ENDIAN_ORDER, rk[4*m_rounds+3]); rk[4*m_rounds+3] = temp; - } - -#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE - if (HasAESNI()) - ConditionalByteReverse(BIG_ENDIAN_ORDER, rk+4, rk+4, (m_rounds-1)*16); -#endif -} - -void Rijndael::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) || CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) - if (HasSSE2()) -#else - if (HasAESNI()) -#endif - { - Rijndael::Enc::AdvancedProcessBlocks(inBlock, xorBlock, outBlock, 16, 0); - return; - } -#endif - - typedef BlockGetAndPut<word32, NativeByteOrder> Block; - - word32 s0, s1, s2, s3, t0, t1, t2, t3; - Block::Get(inBlock)(s0)(s1)(s2)(s3); - - const word32 *rk = m_key; - s0 ^= rk[0]; - s1 ^= rk[1]; - s2 ^= rk[2]; - s3 ^= rk[3]; - t0 = rk[4]; - t1 = rk[5]; - t2 = rk[6]; - t3 = rk[7]; - rk += 8; - - // timing attack countermeasure. see comments at top for more details - const int cacheLineSize = GetCacheLineSize(); - unsigned int i; - word32 u = 0; -#ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS - for (i=0; i<2048; i+=cacheLineSize) -#else - for (i=0; i<1024; i+=cacheLineSize) -#endif - u &= *(const word32 *)(((const byte *)Te)+i); - u &= Te[255]; - s0 |= u; s1 |= u; s2 |= u; s3 |= u; - - QUARTER_ROUND_FE(s3, t0, t1, t2, t3) - QUARTER_ROUND_FE(s2, t3, t0, t1, t2) - QUARTER_ROUND_FE(s1, t2, t3, t0, t1) - QUARTER_ROUND_FE(s0, t1, t2, t3, t0) - - // Nr - 2 full rounds: - unsigned int r = m_rounds/2 - 1; - do - { - s0 = rk[0]; s1 = rk[1]; s2 = rk[2]; s3 = rk[3]; - - QUARTER_ROUND_E(t3, s0, s1, s2, s3) - QUARTER_ROUND_E(t2, s3, s0, s1, s2) - QUARTER_ROUND_E(t1, s2, s3, s0, s1) - QUARTER_ROUND_E(t0, s1, s2, s3, s0) - - t0 = rk[4]; t1 = rk[5]; t2 = rk[6]; t3 = rk[7]; - - QUARTER_ROUND_E(s3, t0, t1, t2, t3) - QUARTER_ROUND_E(s2, t3, t0, t1, t2) - QUARTER_ROUND_E(s1, t2, t3, t0, t1) - QUARTER_ROUND_E(s0, t1, t2, t3, t0) - - rk += 8; - } while (--r); - - word32 tbw[4]; - byte *const tempBlock = (byte *)tbw; - - QUARTER_ROUND_LE(t2, 15, 2, 5, 8) - QUARTER_ROUND_LE(t1, 11, 14, 1, 4) - QUARTER_ROUND_LE(t0, 7, 10, 13, 0) - QUARTER_ROUND_LE(t3, 3, 6, 9, 12) - - Block::Put(xorBlock, outBlock)(tbw[0]^rk[0])(tbw[1]^rk[1])(tbw[2]^rk[2])(tbw[3]^rk[3]); -} - -void Rijndael::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ -#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE - if (HasAESNI()) - { - Rijndael::Dec::AdvancedProcessBlocks(inBlock, xorBlock, outBlock, 16, 0); - return; - } -#endif - - typedef BlockGetAndPut<word32, NativeByteOrder> Block; - - word32 s0, s1, s2, s3, t0, t1, t2, t3; - Block::Get(inBlock)(s0)(s1)(s2)(s3); - - const word32 *rk = m_key; - s0 ^= rk[0]; - s1 ^= rk[1]; - s2 ^= rk[2]; - s3 ^= rk[3]; - t0 = rk[4]; - t1 = rk[5]; - t2 = rk[6]; - t3 = rk[7]; - rk += 8; - - // timing attack countermeasure. see comments at top for more details - const int cacheLineSize = GetCacheLineSize(); - unsigned int i; - word32 u = 0; -#ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS - for (i=0; i<2048; i+=cacheLineSize) -#else - for (i=0; i<1024; i+=cacheLineSize) -#endif - u &= *(const word32 *)(((const byte *)Td)+i); - u &= Td[255]; - s0 |= u; s1 |= u; s2 |= u; s3 |= u; - - QUARTER_ROUND_FD(s3, t2, t1, t0, t3) - QUARTER_ROUND_FD(s2, t1, t0, t3, t2) - QUARTER_ROUND_FD(s1, t0, t3, t2, t1) - QUARTER_ROUND_FD(s0, t3, t2, t1, t0) - - // Nr - 2 full rounds: - unsigned int r = m_rounds/2 - 1; - do - { - s0 = rk[0]; s1 = rk[1]; s2 = rk[2]; s3 = rk[3]; - - QUARTER_ROUND_D(t3, s2, s1, s0, s3) - QUARTER_ROUND_D(t2, s1, s0, s3, s2) - QUARTER_ROUND_D(t1, s0, s3, s2, s1) - QUARTER_ROUND_D(t0, s3, s2, s1, s0) - - t0 = rk[4]; t1 = rk[5]; t2 = rk[6]; t3 = rk[7]; - - QUARTER_ROUND_D(s3, t2, t1, t0, t3) - QUARTER_ROUND_D(s2, t1, t0, t3, t2) - QUARTER_ROUND_D(s1, t0, t3, t2, t1) - QUARTER_ROUND_D(s0, t3, t2, t1, t0) - - rk += 8; - } while (--r); - -#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS - // timing attack countermeasure. see comments at top for more details - // If CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS is defined, - // QUARTER_ROUND_LD will use Td, which is already preloaded. - u = 0; - for (i=0; i<256; i+=cacheLineSize) - u &= *(const word32 *)(Sd+i); - u &= *(const word32 *)(Sd+252); - t0 |= u; t1 |= u; t2 |= u; t3 |= u; -#endif - - word32 tbw[4]; - byte *const tempBlock = (byte *)tbw; - - QUARTER_ROUND_LD(t2, 7, 2, 13, 8) - QUARTER_ROUND_LD(t1, 3, 14, 9, 4) - QUARTER_ROUND_LD(t0, 15, 10, 5, 0) - QUARTER_ROUND_LD(t3, 11, 6, 1, 12) - - Block::Put(xorBlock, outBlock)(tbw[0]^rk[0])(tbw[1]^rk[1])(tbw[2]^rk[2])(tbw[3]^rk[3]); -} - -// ************************* Assembly Code ************************************ - -#pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code - -#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM - -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - -CRYPTOPP_NAKED void CRYPTOPP_FASTCALL Rijndael_Enc_AdvancedProcessBlocks(void *locals, const word32 *k) -{ -#if CRYPTOPP_BOOL_X86 - -#define L_REG esp -#define L_INDEX(i) (L_REG+768+i) -#define L_INXORBLOCKS L_INBLOCKS+4 -#define L_OUTXORBLOCKS L_INBLOCKS+8 -#define L_OUTBLOCKS L_INBLOCKS+12 -#define L_INCREMENTS L_INDEX(16*15) -#define L_SP L_INDEX(16*16) -#define L_LENGTH L_INDEX(16*16+4) -#define L_KEYS_BEGIN L_INDEX(16*16+8) - -#define MOVD movd -#define MM(i) mm##i - -#define MXOR(a,b,c) \ - AS2( movzx esi, b)\ - AS2( movd mm7, DWORD PTR [AS_REG_7+8*WORD_REG(si)+MAP0TO4(c)])\ - AS2( pxor MM(a), mm7)\ - -#define MMOV(a,b,c) \ - AS2( movzx esi, b)\ - AS2( movd MM(a), DWORD PTR [AS_REG_7+8*WORD_REG(si)+MAP0TO4(c)])\ - -#else - -#define L_REG r8 -#define L_INDEX(i) (L_REG+i) -#define L_INXORBLOCKS L_INBLOCKS+8 -#define L_OUTXORBLOCKS L_INBLOCKS+16 -#define L_OUTBLOCKS L_INBLOCKS+24 -#define L_INCREMENTS L_INDEX(16*16) -#define L_LENGTH L_INDEX(16*18+8) -#define L_KEYS_BEGIN L_INDEX(16*19) - -#define MOVD mov -#define MM_0 r9d -#define MM_1 r12d -#ifdef __GNUC__ -#define MM_2 r11d -#else -#define MM_2 r10d -#endif -#define MM(i) MM_##i - -#define MXOR(a,b,c) \ - AS2( movzx esi, b)\ - AS2( xor MM(a), DWORD PTR [AS_REG_7+8*WORD_REG(si)+MAP0TO4(c)])\ - -#define MMOV(a,b,c) \ - AS2( movzx esi, b)\ - AS2( mov MM(a), DWORD PTR [AS_REG_7+8*WORD_REG(si)+MAP0TO4(c)])\ - -#endif - -#define L_SUBKEYS L_INDEX(0) -#define L_SAVED_X L_SUBKEYS -#define L_KEY12 L_INDEX(16*12) -#define L_LASTROUND L_INDEX(16*13) -#define L_INBLOCKS L_INDEX(16*14) -#define MAP0TO4(i) (ASM_MOD(i+3,4)+1) - -#define XOR(a,b,c) \ - AS2( movzx esi, b)\ - AS2( xor a, DWORD PTR [AS_REG_7+8*WORD_REG(si)+MAP0TO4(c)])\ - -#define MOV(a,b,c) \ - AS2( movzx esi, b)\ - AS2( mov a, DWORD PTR [AS_REG_7+8*WORD_REG(si)+MAP0TO4(c)])\ - -#ifdef CRYPTOPP_GENERATE_X64_MASM - ALIGN 8 - Rijndael_Enc_AdvancedProcessBlocks PROC FRAME - rex_push_reg rsi - push_reg rdi - push_reg rbx - push_reg r12 - .endprolog - mov L_REG, rcx - mov AS_REG_7, ?Te@rdtable@CryptoPP@@3PA_KA - mov edi, DWORD PTR [?g_cacheLineSize@CryptoPP@@3IA] -#elif defined(__GNUC__) - __asm__ __volatile__ - ( - ".intel_syntax noprefix;" - #if CRYPTOPP_BOOL_X64 - AS2( mov L_REG, rcx) - #endif - AS_PUSH_IF86(bx) - AS_PUSH_IF86(bp) - AS2( mov AS_REG_7, WORD_REG(si)) -#else - AS_PUSH_IF86(si) - AS_PUSH_IF86(di) - AS_PUSH_IF86(bx) - AS_PUSH_IF86(bp) - AS2( lea AS_REG_7, [Te]) - AS2( mov edi, [g_cacheLineSize]) -#endif - -#if CRYPTOPP_BOOL_X86 - AS2( mov [ecx+16*12+16*4], esp) // save esp to L_SP - AS2( lea esp, [ecx-768]) -#endif - - // copy subkeys to stack - AS2( mov WORD_REG(si), [L_KEYS_BEGIN]) - AS2( mov WORD_REG(ax), 16) - AS2( and WORD_REG(ax), WORD_REG(si)) - AS2( movdqa xmm3, XMMWORD_PTR [WORD_REG(dx)+16+WORD_REG(ax)]) // subkey 1 (non-counter) or 2 (counter) - AS2( movdqa [L_KEY12], xmm3) - AS2( lea WORD_REG(ax), [WORD_REG(dx)+WORD_REG(ax)+2*16]) - AS2( sub WORD_REG(ax), WORD_REG(si)) - ASL(0) - AS2( movdqa xmm0, [WORD_REG(ax)+WORD_REG(si)]) - AS2( movdqa XMMWORD_PTR [L_SUBKEYS+WORD_REG(si)], xmm0) - AS2( add WORD_REG(si), 16) - AS2( cmp WORD_REG(si), 16*12) - ASJ( jl, 0, b) - - // read subkeys 0, 1 and last - AS2( movdqa xmm4, [WORD_REG(ax)+WORD_REG(si)]) // last subkey - AS2( movdqa xmm1, [WORD_REG(dx)]) // subkey 0 - AS2( MOVD MM(1), [WORD_REG(dx)+4*4]) // 0,1,2,3 - AS2( mov ebx, [WORD_REG(dx)+5*4]) // 4,5,6,7 - AS2( mov ecx, [WORD_REG(dx)+6*4]) // 8,9,10,11 - AS2( mov edx, [WORD_REG(dx)+7*4]) // 12,13,14,15 - - // load table into cache - AS2( xor WORD_REG(ax), WORD_REG(ax)) - ASL(9) - AS2( mov esi, [AS_REG_7+WORD_REG(ax)]) - AS2( add WORD_REG(ax), WORD_REG(di)) - AS2( mov esi, [AS_REG_7+WORD_REG(ax)]) - AS2( add WORD_REG(ax), WORD_REG(di)) - AS2( mov esi, [AS_REG_7+WORD_REG(ax)]) - AS2( add WORD_REG(ax), WORD_REG(di)) - AS2( mov esi, [AS_REG_7+WORD_REG(ax)]) - AS2( add WORD_REG(ax), WORD_REG(di)) - AS2( cmp WORD_REG(ax), 2048) - ASJ( jl, 9, b) - AS1( lfence) - - AS2( test DWORD PTR [L_LENGTH], 1) - ASJ( jz, 8, f) - - // counter mode one-time setup - AS2( mov WORD_REG(si), [L_INBLOCKS]) - AS2( movdqu xmm2, [WORD_REG(si)]) // counter - AS2( pxor xmm2, xmm1) - AS2( psrldq xmm1, 14) - AS2( movd eax, xmm1) - AS2( mov al, BYTE PTR [WORD_REG(si)+15]) - AS2( MOVD MM(2), eax) -#if CRYPTOPP_BOOL_X86 - AS2( mov eax, 1) - AS2( movd mm3, eax) -#endif - - // partial first round, in: xmm2(15,14,13,12;11,10,9,8;7,6,5,4;3,2,1,0), out: mm1, ebx, ecx, edx - AS2( movd eax, xmm2) - AS2( psrldq xmm2, 4) - AS2( movd edi, xmm2) - AS2( psrldq xmm2, 4) - MXOR( 1, al, 0) // 0 - XOR( edx, ah, 1) // 1 - AS2( shr eax, 16) - XOR( ecx, al, 2) // 2 - XOR( ebx, ah, 3) // 3 - AS2( mov eax, edi) - AS2( movd edi, xmm2) - AS2( psrldq xmm2, 4) - XOR( ebx, al, 0) // 4 - MXOR( 1, ah, 1) // 5 - AS2( shr eax, 16) - XOR( edx, al, 2) // 6 - XOR( ecx, ah, 3) // 7 - AS2( mov eax, edi) - AS2( movd edi, xmm2) - XOR( ecx, al, 0) // 8 - XOR( ebx, ah, 1) // 9 - AS2( shr eax, 16) - MXOR( 1, al, 2) // 10 - XOR( edx, ah, 3) // 11 - AS2( mov eax, edi) - XOR( edx, al, 0) // 12 - XOR( ecx, ah, 1) // 13 - AS2( shr eax, 16) - XOR( ebx, al, 2) // 14 - AS2( psrldq xmm2, 3) - - // partial second round, in: ebx(4,5,6,7), ecx(8,9,10,11), edx(12,13,14,15), out: eax, ebx, edi, mm0 - AS2( mov eax, [L_KEY12+0*4]) - AS2( mov edi, [L_KEY12+2*4]) - AS2( MOVD MM(0), [L_KEY12+3*4]) - MXOR( 0, cl, 3) /* 11 */ - XOR( edi, bl, 3) /* 7 */ - MXOR( 0, bh, 2) /* 6 */ - AS2( shr ebx, 16) /* 4,5 */ - XOR( eax, bl, 1) /* 5 */ - MOV( ebx, bh, 0) /* 4 */ - AS2( xor ebx, [L_KEY12+1*4]) - XOR( eax, ch, 2) /* 10 */ - AS2( shr ecx, 16) /* 8,9 */ - XOR( eax, dl, 3) /* 15 */ - XOR( ebx, dh, 2) /* 14 */ - AS2( shr edx, 16) /* 12,13 */ - XOR( edi, ch, 0) /* 8 */ - XOR( ebx, cl, 1) /* 9 */ - XOR( edi, dl, 1) /* 13 */ - MXOR( 0, dh, 0) /* 12 */ - - AS2( movd ecx, xmm2) - AS2( MOVD edx, MM(1)) - AS2( MOVD [L_SAVED_X+3*4], MM(0)) - AS2( mov [L_SAVED_X+0*4], eax) - AS2( mov [L_SAVED_X+1*4], ebx) - AS2( mov [L_SAVED_X+2*4], edi) - ASJ( jmp, 5, f) - - ASL(3) - // non-counter mode per-block setup - AS2( MOVD MM(1), [L_KEY12+0*4]) // 0,1,2,3 - AS2( mov ebx, [L_KEY12+1*4]) // 4,5,6,7 - AS2( mov ecx, [L_KEY12+2*4]) // 8,9,10,11 - AS2( mov edx, [L_KEY12+3*4]) // 12,13,14,15 - ASL(8) - AS2( mov WORD_REG(ax), [L_INBLOCKS]) - AS2( movdqu xmm2, [WORD_REG(ax)]) - AS2( mov WORD_REG(si), [L_INXORBLOCKS]) - AS2( movdqu xmm5, [WORD_REG(si)]) - AS2( pxor xmm2, xmm1) - AS2( pxor xmm2, xmm5) - - // first round, in: xmm2(15,14,13,12;11,10,9,8;7,6,5,4;3,2,1,0), out: eax, ebx, ecx, edx - AS2( movd eax, xmm2) - AS2( psrldq xmm2, 4) - AS2( movd edi, xmm2) - AS2( psrldq xmm2, 4) - MXOR( 1, al, 0) // 0 - XOR( edx, ah, 1) // 1 - AS2( shr eax, 16) - XOR( ecx, al, 2) // 2 - XOR( ebx, ah, 3) // 3 - AS2( mov eax, edi) - AS2( movd edi, xmm2) - AS2( psrldq xmm2, 4) - XOR( ebx, al, 0) // 4 - MXOR( 1, ah, 1) // 5 - AS2( shr eax, 16) - XOR( edx, al, 2) // 6 - XOR( ecx, ah, 3) // 7 - AS2( mov eax, edi) - AS2( movd edi, xmm2) - XOR( ecx, al, 0) // 8 - XOR( ebx, ah, 1) // 9 - AS2( shr eax, 16) - MXOR( 1, al, 2) // 10 - XOR( edx, ah, 3) // 11 - AS2( mov eax, edi) - XOR( edx, al, 0) // 12 - XOR( ecx, ah, 1) // 13 - AS2( shr eax, 16) - XOR( ebx, al, 2) // 14 - MXOR( 1, ah, 3) // 15 - AS2( MOVD eax, MM(1)) - - AS2( add L_REG, [L_KEYS_BEGIN]) - AS2( add L_REG, 4*16) - ASJ( jmp, 2, f) - - ASL(1) - // counter-mode per-block setup - AS2( MOVD ecx, MM(2)) - AS2( MOVD edx, MM(1)) - AS2( mov eax, [L_SAVED_X+0*4]) - AS2( mov ebx, [L_SAVED_X+1*4]) - AS2( xor cl, ch) - AS2( and WORD_REG(cx), 255) - ASL(5) -#if CRYPTOPP_BOOL_X86 - AS2( paddb MM(2), mm3) -#else - AS2( add MM(2), 1) -#endif - // remaining part of second round, in: edx(previous round),esi(keyed counter byte) eax,ebx,[L_SAVED_X+2*4],[L_SAVED_X+3*4], out: eax,ebx,ecx,edx - AS2( xor edx, DWORD PTR [AS_REG_7+WORD_REG(cx)*8+3]) - XOR( ebx, dl, 3) - MOV( ecx, dh, 2) - AS2( shr edx, 16) - AS2( xor ecx, [L_SAVED_X+2*4]) - XOR( eax, dh, 0) - MOV( edx, dl, 1) - AS2( xor edx, [L_SAVED_X+3*4]) - - AS2( add L_REG, [L_KEYS_BEGIN]) - AS2( add L_REG, 3*16) - ASJ( jmp, 4, f) - -// in: eax(0,1,2,3), ebx(4,5,6,7), ecx(8,9,10,11), edx(12,13,14,15) -// out: eax, ebx, edi, mm0 -#define ROUND() \ - MXOR( 0, cl, 3) /* 11 */\ - AS2( mov cl, al) /* 8,9,10,3 */\ - XOR( edi, ah, 2) /* 2 */\ - AS2( shr eax, 16) /* 0,1 */\ - XOR( edi, bl, 3) /* 7 */\ - MXOR( 0, bh, 2) /* 6 */\ - AS2( shr ebx, 16) /* 4,5 */\ - MXOR( 0, al, 1) /* 1 */\ - MOV( eax, ah, 0) /* 0 */\ - XOR( eax, bl, 1) /* 5 */\ - MOV( ebx, bh, 0) /* 4 */\ - XOR( eax, ch, 2) /* 10 */\ - XOR( ebx, cl, 3) /* 3 */\ - AS2( shr ecx, 16) /* 8,9 */\ - XOR( eax, dl, 3) /* 15 */\ - XOR( ebx, dh, 2) /* 14 */\ - AS2( shr edx, 16) /* 12,13 */\ - XOR( edi, ch, 0) /* 8 */\ - XOR( ebx, cl, 1) /* 9 */\ - XOR( edi, dl, 1) /* 13 */\ - MXOR( 0, dh, 0) /* 12 */\ - - ASL(2) // 2-round loop - AS2( MOVD MM(0), [L_SUBKEYS-4*16+3*4]) - AS2( mov edi, [L_SUBKEYS-4*16+2*4]) - ROUND() - AS2( mov ecx, edi) - AS2( xor eax, [L_SUBKEYS-4*16+0*4]) - AS2( xor ebx, [L_SUBKEYS-4*16+1*4]) - AS2( MOVD edx, MM(0)) - - ASL(4) - AS2( MOVD MM(0), [L_SUBKEYS-4*16+7*4]) - AS2( mov edi, [L_SUBKEYS-4*16+6*4]) - ROUND() - AS2( mov ecx, edi) - AS2( xor eax, [L_SUBKEYS-4*16+4*4]) - AS2( xor ebx, [L_SUBKEYS-4*16+5*4]) - AS2( MOVD edx, MM(0)) - - AS2( add L_REG, 32) - AS2( test L_REG, 255) - ASJ( jnz, 2, b) - AS2( sub L_REG, 16*16) - -#define LAST(a, b, c) \ - AS2( movzx esi, a )\ - AS2( movzx edi, BYTE PTR [AS_REG_7+WORD_REG(si)*8+1] )\ - AS2( movzx esi, b )\ - AS2( xor edi, DWORD PTR [AS_REG_7+WORD_REG(si)*8+0] )\ - AS2( mov WORD PTR [L_LASTROUND+c], di )\ - - // last round - LAST(ch, dl, 2) - LAST(dh, al, 6) - AS2( shr edx, 16) - LAST(ah, bl, 10) - AS2( shr eax, 16) - LAST(bh, cl, 14) - AS2( shr ebx, 16) - LAST(dh, al, 12) - AS2( shr ecx, 16) - LAST(ah, bl, 0) - LAST(bh, cl, 4) - LAST(ch, dl, 8) - - AS2( mov WORD_REG(ax), [L_OUTXORBLOCKS]) - AS2( mov WORD_REG(bx), [L_OUTBLOCKS]) - - AS2( mov WORD_REG(cx), [L_LENGTH]) - AS2( sub WORD_REG(cx), 16) - - AS2( movdqu xmm2, [WORD_REG(ax)]) - AS2( pxor xmm2, xmm4) - -#if CRYPTOPP_BOOL_X86 - AS2( movdqa xmm0, [L_INCREMENTS]) - AS2( paddd xmm0, [L_INBLOCKS]) - AS2( movdqa [L_INBLOCKS], xmm0) -#else - AS2( movdqa xmm0, [L_INCREMENTS+16]) - AS2( paddq xmm0, [L_INBLOCKS+16]) - AS2( movdqa [L_INBLOCKS+16], xmm0) -#endif - - AS2( pxor xmm2, [L_LASTROUND]) - AS2( movdqu [WORD_REG(bx)], xmm2) - - ASJ( jle, 7, f) - AS2( mov [L_LENGTH], WORD_REG(cx)) - AS2( test WORD_REG(cx), 1) - ASJ( jnz, 1, b) -#if CRYPTOPP_BOOL_X64 - AS2( movdqa xmm0, [L_INCREMENTS]) - AS2( paddq xmm0, [L_INBLOCKS]) - AS2( movdqa [L_INBLOCKS], xmm0) -#endif - ASJ( jmp, 3, b) - - ASL(7) - // erase keys on stack - AS2( xorps xmm0, xmm0) - AS2( lea WORD_REG(ax), [L_SUBKEYS+7*16]) - AS2( movaps [WORD_REG(ax)-7*16], xmm0) - AS2( movaps [WORD_REG(ax)-6*16], xmm0) - AS2( movaps [WORD_REG(ax)-5*16], xmm0) - AS2( movaps [WORD_REG(ax)-4*16], xmm0) - AS2( movaps [WORD_REG(ax)-3*16], xmm0) - AS2( movaps [WORD_REG(ax)-2*16], xmm0) - AS2( movaps [WORD_REG(ax)-1*16], xmm0) - AS2( movaps [WORD_REG(ax)+0*16], xmm0) - AS2( movaps [WORD_REG(ax)+1*16], xmm0) - AS2( movaps [WORD_REG(ax)+2*16], xmm0) - AS2( movaps [WORD_REG(ax)+3*16], xmm0) - AS2( movaps [WORD_REG(ax)+4*16], xmm0) - AS2( movaps [WORD_REG(ax)+5*16], xmm0) - AS2( movaps [WORD_REG(ax)+6*16], xmm0) -#if CRYPTOPP_BOOL_X86 - AS2( mov esp, [L_SP]) - AS1( emms) -#endif - AS_POP_IF86(bp) - AS_POP_IF86(bx) -#if defined(_MSC_VER) && CRYPTOPP_BOOL_X86 - AS_POP_IF86(di) - AS_POP_IF86(si) - AS1(ret) -#endif -#ifdef CRYPTOPP_GENERATE_X64_MASM - pop r12 - pop rbx - pop rdi - pop rsi - ret - Rijndael_Enc_AdvancedProcessBlocks ENDP -#endif -#ifdef __GNUC__ - ".att_syntax prefix;" - : - : "c" (locals), "d" (k), "S" (Te), "D" (g_cacheLineSize) - : "memory", "cc", "%eax" - #if CRYPTOPP_BOOL_X64 - , "%rbx", "%r8", "%r9", "%r10", "%r11", "%r12" - #endif - ); -#endif -} - -#endif - -#ifndef CRYPTOPP_GENERATE_X64_MASM - -#ifdef CRYPTOPP_X64_MASM_AVAILABLE -extern "C" { -void Rijndael_Enc_AdvancedProcessBlocks(void *locals, const word32 *k); -} -#endif - -#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 - -static inline bool AliasedWithTable(const byte *begin, const byte *end) -{ - size_t s0 = size_t(begin)%4096, s1 = size_t(end)%4096; - size_t t0 = size_t(Te)%4096, t1 = (size_t(Te)+sizeof(Te))%4096; - if (t1 > t0) - return (s0 >= t0 && s0 < t1) || (s1 > t0 && s1 <= t1); - else - return (s0 < t1 || s1 <= t1) || (s0 >= t0 || s1 > t0); -} - -#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE - -inline void AESNI_Enc_Block(__m128i &block, const __m128i *subkeys, unsigned int rounds) -{ - block = _mm_xor_si128(block, subkeys[0]); - for (unsigned int i=1; i<rounds-1; i+=2) - { - block = _mm_aesenc_si128(block, subkeys[i]); - block = _mm_aesenc_si128(block, subkeys[i+1]); - } - block = _mm_aesenc_si128(block, subkeys[rounds-1]); - block = _mm_aesenclast_si128(block, subkeys[rounds]); -} - -inline void AESNI_Enc_4_Blocks(__m128i &block0, __m128i &block1, __m128i &block2, __m128i &block3, const __m128i *subkeys, unsigned int rounds) -{ - __m128i rk = subkeys[0]; - block0 = _mm_xor_si128(block0, rk); - block1 = _mm_xor_si128(block1, rk); - block2 = _mm_xor_si128(block2, rk); - block3 = _mm_xor_si128(block3, rk); - for (unsigned int i=1; i<rounds; i++) - { - rk = subkeys[i]; - block0 = _mm_aesenc_si128(block0, rk); - block1 = _mm_aesenc_si128(block1, rk); - block2 = _mm_aesenc_si128(block2, rk); - block3 = _mm_aesenc_si128(block3, rk); - } - rk = subkeys[rounds]; - block0 = _mm_aesenclast_si128(block0, rk); - block1 = _mm_aesenclast_si128(block1, rk); - block2 = _mm_aesenclast_si128(block2, rk); - block3 = _mm_aesenclast_si128(block3, rk); -} - -inline void AESNI_Dec_Block(__m128i &block, const __m128i *subkeys, unsigned int rounds) -{ - block = _mm_xor_si128(block, subkeys[0]); - for (unsigned int i=1; i<rounds-1; i+=2) - { - block = _mm_aesdec_si128(block, subkeys[i]); - block = _mm_aesdec_si128(block, subkeys[i+1]); - } - block = _mm_aesdec_si128(block, subkeys[rounds-1]); - block = _mm_aesdeclast_si128(block, subkeys[rounds]); -} - -inline void AESNI_Dec_4_Blocks(__m128i &block0, __m128i &block1, __m128i &block2, __m128i &block3, const __m128i *subkeys, unsigned int rounds) -{ - __m128i rk = subkeys[0]; - block0 = _mm_xor_si128(block0, rk); - block1 = _mm_xor_si128(block1, rk); - block2 = _mm_xor_si128(block2, rk); - block3 = _mm_xor_si128(block3, rk); - for (unsigned int i=1; i<rounds; i++) - { - rk = subkeys[i]; - block0 = _mm_aesdec_si128(block0, rk); - block1 = _mm_aesdec_si128(block1, rk); - block2 = _mm_aesdec_si128(block2, rk); - block3 = _mm_aesdec_si128(block3, rk); - } - rk = subkeys[rounds]; - block0 = _mm_aesdeclast_si128(block0, rk); - block1 = _mm_aesdeclast_si128(block1, rk); - block2 = _mm_aesdeclast_si128(block2, rk); - block3 = _mm_aesdeclast_si128(block3, rk); -} - -static CRYPTOPP_ALIGN_DATA(16) const word32 s_one[] = {0, 0, 0, 1<<24}; - -template <typename F1, typename F4> -inline size_t AESNI_AdvancedProcessBlocks(F1 func1, F4 func4, const __m128i *subkeys, unsigned int rounds, const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) -{ - size_t blockSize = 16; - size_t inIncrement = (flags & (BlockTransformation::BT_InBlockIsCounter|BlockTransformation::BT_DontIncrementInOutPointers)) ? 0 : blockSize; - size_t xorIncrement = xorBlocks ? blockSize : 0; - size_t outIncrement = (flags & BlockTransformation::BT_DontIncrementInOutPointers) ? 0 : blockSize; - - if (flags & BlockTransformation::BT_ReverseDirection) - { - assert(length % blockSize == 0); - inBlocks += length - blockSize; - xorBlocks += length - blockSize; - outBlocks += length - blockSize; - inIncrement = 0-inIncrement; - xorIncrement = 0-xorIncrement; - outIncrement = 0-outIncrement; - } - - if (flags & BlockTransformation::BT_AllowParallel) - { - while (length >= 4*blockSize) - { - __m128i block0 = _mm_loadu_si128((const __m128i *)inBlocks), block1, block2, block3; - if (flags & BlockTransformation::BT_InBlockIsCounter) - { - const __m128i be1 = *(const __m128i *)s_one; - block1 = _mm_add_epi32(block0, be1); - block2 = _mm_add_epi32(block1, be1); - block3 = _mm_add_epi32(block2, be1); - _mm_storeu_si128((__m128i *)inBlocks, _mm_add_epi32(block3, be1)); - } - else - { - inBlocks += inIncrement; - block1 = _mm_loadu_si128((const __m128i *)inBlocks); - inBlocks += inIncrement; - block2 = _mm_loadu_si128((const __m128i *)inBlocks); - inBlocks += inIncrement; - block3 = _mm_loadu_si128((const __m128i *)inBlocks); - inBlocks += inIncrement; - } - - if (flags & BlockTransformation::BT_XorInput) - { - block0 = _mm_xor_si128(block0, _mm_loadu_si128((const __m128i *)xorBlocks)); - xorBlocks += xorIncrement; - block1 = _mm_xor_si128(block1, _mm_loadu_si128((const __m128i *)xorBlocks)); - xorBlocks += xorIncrement; - block2 = _mm_xor_si128(block2, _mm_loadu_si128((const __m128i *)xorBlocks)); - xorBlocks += xorIncrement; - block3 = _mm_xor_si128(block3, _mm_loadu_si128((const __m128i *)xorBlocks)); - xorBlocks += xorIncrement; - } - - func4(block0, block1, block2, block3, subkeys, rounds); - - if (xorBlocks && !(flags & BlockTransformation::BT_XorInput)) - { - block0 = _mm_xor_si128(block0, _mm_loadu_si128((const __m128i *)xorBlocks)); - xorBlocks += xorIncrement; - block1 = _mm_xor_si128(block1, _mm_loadu_si128((const __m128i *)xorBlocks)); - xorBlocks += xorIncrement; - block2 = _mm_xor_si128(block2, _mm_loadu_si128((const __m128i *)xorBlocks)); - xorBlocks += xorIncrement; - block3 = _mm_xor_si128(block3, _mm_loadu_si128((const __m128i *)xorBlocks)); - xorBlocks += xorIncrement; - } - - _mm_storeu_si128((__m128i *)outBlocks, block0); - outBlocks += outIncrement; - _mm_storeu_si128((__m128i *)outBlocks, block1); - outBlocks += outIncrement; - _mm_storeu_si128((__m128i *)outBlocks, block2); - outBlocks += outIncrement; - _mm_storeu_si128((__m128i *)outBlocks, block3); - outBlocks += outIncrement; - - length -= 4*blockSize; - } - } - - while (length >= blockSize) - { - __m128i block = _mm_loadu_si128((const __m128i *)inBlocks); - - if (flags & BlockTransformation::BT_XorInput) - block = _mm_xor_si128(block, _mm_loadu_si128((const __m128i *)xorBlocks)); - - if (flags & BlockTransformation::BT_InBlockIsCounter) - const_cast<byte *>(inBlocks)[15]++; - - func1(block, subkeys, rounds); - - if (xorBlocks && !(flags & BlockTransformation::BT_XorInput)) - block = _mm_xor_si128(block, _mm_loadu_si128((const __m128i *)xorBlocks)); - - _mm_storeu_si128((__m128i *)outBlocks, block); - - inBlocks += inIncrement; - outBlocks += outIncrement; - xorBlocks += xorIncrement; - length -= blockSize; - } - - return length; -} -#endif - -size_t Rijndael::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const -{ -#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE - if (HasAESNI()) - return AESNI_AdvancedProcessBlocks(AESNI_Enc_Block, AESNI_Enc_4_Blocks, (const __m128i *)m_key.begin(), m_rounds, inBlocks, xorBlocks, outBlocks, length, flags); -#endif - -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) - if (HasSSE2()) - { - if (length < BLOCKSIZE) - return length; - - struct Locals - { - word32 subkeys[4*12], workspace[8]; - const byte *inBlocks, *inXorBlocks, *outXorBlocks; - byte *outBlocks; - size_t inIncrement, inXorIncrement, outXorIncrement, outIncrement; - size_t regSpill, lengthAndCounterFlag, keysBegin; - }; - - size_t increment = BLOCKSIZE; - const byte* zeros = (byte *)(Te+256); - byte *space; - - do { - space = (byte *)alloca(255+sizeof(Locals)); - space += (256-(size_t)space%256)%256; - } - while (AliasedWithTable(space, space+sizeof(Locals))); - - if (flags & BT_ReverseDirection) - { - assert(length % BLOCKSIZE == 0); - inBlocks += length - BLOCKSIZE; - xorBlocks += length - BLOCKSIZE; - outBlocks += length - BLOCKSIZE; - increment = 0-increment; - } - - Locals &locals = *(Locals *)space; - - locals.inBlocks = inBlocks; - locals.inXorBlocks = (flags & BT_XorInput) && xorBlocks ? xorBlocks : zeros; - locals.outXorBlocks = (flags & BT_XorInput) || !xorBlocks ? zeros : xorBlocks; - locals.outBlocks = outBlocks; - - locals.inIncrement = (flags & BT_DontIncrementInOutPointers) ? 0 : increment; - locals.inXorIncrement = (flags & BT_XorInput) && xorBlocks ? increment : 0; - locals.outXorIncrement = (flags & BT_XorInput) || !xorBlocks ? 0 : increment; - locals.outIncrement = (flags & BT_DontIncrementInOutPointers) ? 0 : increment; - - locals.lengthAndCounterFlag = length - (length%16) - bool(flags & BT_InBlockIsCounter); - int keysToCopy = m_rounds - (flags & BT_InBlockIsCounter ? 3 : 2); - locals.keysBegin = (12-keysToCopy)*16; - - Rijndael_Enc_AdvancedProcessBlocks(&locals, m_key); - return length % BLOCKSIZE; - } -#endif - - return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags); -} - -#endif - -#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE - -size_t Rijndael::Dec::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const -{ - if (HasAESNI()) - return AESNI_AdvancedProcessBlocks(AESNI_Dec_Block, AESNI_Dec_4_Blocks, (const __m128i *)m_key.begin(), m_rounds, inBlocks, xorBlocks, outBlocks, length, flags); - - return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags); -} - -#endif // #if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE - -NAMESPACE_END - -#endif -#endif diff --git a/lib/cryptopp/rijndael.h b/lib/cryptopp/rijndael.h deleted file mode 100644 index 64c784b07..000000000 --- a/lib/cryptopp/rijndael.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef CRYPTOPP_RIJNDAEL_H -#define CRYPTOPP_RIJNDAEL_H - -/** \file -*/ - -#include "seckey.h" -#include "secblock.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -struct Rijndael_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 16, 32, 8> -{ - CRYPTOPP_DLL static const char * CRYPTOPP_API StaticAlgorithmName() {return CRYPTOPP_RIJNDAEL_NAME;} -}; - -/// <a href="http://www.weidai.com/scan-mirror/cs.html#Rijndael">Rijndael</a> -class CRYPTOPP_DLL Rijndael : public Rijndael_Info, public BlockCipherDocumentation -{ - class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<Rijndael_Info> - { - public: - void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); - - protected: - static void FillEncTable(); - static void FillDecTable(); - - // VS2005 workaround: have to put these on seperate lines, or error C2487 is triggered in DLL build - static const byte Se[256]; - static const byte Sd[256]; - - static const word32 rcon[]; - - unsigned int m_rounds; - FixedSizeAlignedSecBlock<word32, 4*15> m_key; - }; - - class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Enc : public Base - { - public: - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; -#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 - size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; -#endif - }; - - class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Dec : public Base - { - public: - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; -#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE - size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; -#endif - }; - -public: - typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption; - typedef BlockCipherFinal<DECRYPTION, Dec> Decryption; -}; - -typedef Rijndael::Encryption RijndaelEncryption; -typedef Rijndael::Decryption RijndaelDecryption; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/rng.cpp b/lib/cryptopp/rng.cpp deleted file mode 100644 index 9866cd831..000000000 --- a/lib/cryptopp/rng.cpp +++ /dev/null @@ -1,155 +0,0 @@ -// rng.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#include "rng.h" -#include "fips140.h" - -#include <time.h> -#include <math.h> - -NAMESPACE_BEGIN(CryptoPP) - -// linear congruential generator -// originally by William S. England - -// do not use for cryptographic purposes - -/* -** Original_numbers are the original published m and q in the -** ACM article above. John Burton has furnished numbers for -** a reportedly better generator. The new numbers are now -** used in this program by default. -*/ - -#ifndef LCRNG_ORIGINAL_NUMBERS -const word32 LC_RNG::m=2147483647L; -const word32 LC_RNG::q=44488L; - -const word16 LC_RNG::a=(unsigned int)48271L; -const word16 LC_RNG::r=3399; -#else -const word32 LC_RNG::m=2147483647L; -const word32 LC_RNG::q=127773L; - -const word16 LC_RNG::a=16807; -const word16 LC_RNG::r=2836; -#endif - -void LC_RNG::GenerateBlock(byte *output, size_t size) -{ - while (size--) - { - word32 hi = seed/q; - word32 lo = seed%q; - - long test = a*lo - r*hi; - - if (test > 0) - seed = test; - else - seed = test+ m; - - *output++ = (GETBYTE(seed, 0) ^ GETBYTE(seed, 1) ^ GETBYTE(seed, 2) ^ GETBYTE(seed, 3)); - } -} - -// ******************************************************** - -#ifndef CRYPTOPP_IMPORTS - -X917RNG::X917RNG(BlockTransformation *c, const byte *seed, const byte *deterministicTimeVector) - : cipher(c), - S(cipher->BlockSize()), - dtbuf(S), - randseed(seed, S), - m_lastBlock(S), - m_deterministicTimeVector(deterministicTimeVector, deterministicTimeVector ? S : 0) -{ - if (!deterministicTimeVector) - { - time_t tstamp1 = time(0); - xorbuf(dtbuf, (byte *)&tstamp1, UnsignedMin(sizeof(tstamp1), S)); - cipher->ProcessBlock(dtbuf); - clock_t tstamp2 = clock(); - xorbuf(dtbuf, (byte *)&tstamp2, UnsignedMin(sizeof(tstamp2), S)); - cipher->ProcessBlock(dtbuf); - } - - // for FIPS 140-2 - GenerateBlock(m_lastBlock, S); -} - -void X917RNG::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size) -{ - while (size > 0) - { - // calculate new enciphered timestamp - if (m_deterministicTimeVector.size()) - { - cipher->ProcessBlock(m_deterministicTimeVector, dtbuf); - IncrementCounterByOne(m_deterministicTimeVector, S); - } - else - { - clock_t c = clock(); - xorbuf(dtbuf, (byte *)&c, UnsignedMin(sizeof(c), S)); - time_t t = time(NULL); - xorbuf(dtbuf+S-UnsignedMin(sizeof(t), S), (byte *)&t, UnsignedMin(sizeof(t), S)); - cipher->ProcessBlock(dtbuf); - } - - // combine enciphered timestamp with seed - xorbuf(randseed, dtbuf, S); - - // generate a new block of random bytes - cipher->ProcessBlock(randseed); - if (memcmp(m_lastBlock, randseed, S) == 0) - throw SelfTestFailure("X917RNG: Continuous random number generator test failed."); - - // output random bytes - size_t len = UnsignedMin(S, size); - target.ChannelPut(channel, randseed, len); - size -= len; - - // compute new seed vector - memcpy(m_lastBlock, randseed, S); - xorbuf(randseed, dtbuf, S); - cipher->ProcessBlock(randseed); - } -} - -#endif - -MaurerRandomnessTest::MaurerRandomnessTest() - : sum(0.0), n(0) -{ - for (unsigned i=0; i<V; i++) - tab[i] = 0; -} - -size_t MaurerRandomnessTest::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) -{ - while (length--) - { - byte inByte = *inString++; - if (n >= Q) - sum += log(double(n - tab[inByte])); - tab[inByte] = n; - n++; - } - return 0; -} - -double MaurerRandomnessTest::GetTestValue() const -{ - if (BytesNeeded() > 0) - throw Exception(Exception::OTHER_ERROR, "MaurerRandomnessTest: " + IntToString(BytesNeeded()) + " more bytes of input needed"); - - double fTu = (sum/(n-Q))/log(2.0); // this is the test value defined by Maurer - - double value = fTu * 0.1392; // arbitrarily normalize it to - return value > 1.0 ? 1.0 : value; // a number between 0 and 1 -} - -NAMESPACE_END diff --git a/lib/cryptopp/rng.h b/lib/cryptopp/rng.h deleted file mode 100644 index 2439dee69..000000000 --- a/lib/cryptopp/rng.h +++ /dev/null @@ -1,77 +0,0 @@ -// rng.h - misc RNG related classes, see also osrng.h, randpool.h - -#ifndef CRYPTOPP_RNG_H -#define CRYPTOPP_RNG_H - -#include "cryptlib.h" -#include "filters.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! linear congruential generator -/*! originally by William S. England, do not use for cryptographic purposes */ -class LC_RNG : public RandomNumberGenerator -{ -public: - LC_RNG(word32 init_seed) - : seed(init_seed) {} - - void GenerateBlock(byte *output, size_t size); - - word32 GetSeed() {return seed;} - -private: - word32 seed; - - static const word32 m; - static const word32 q; - static const word16 a; - static const word16 r; -}; - -//! RNG derived from ANSI X9.17 Appendix C - -class CRYPTOPP_DLL X917RNG : public RandomNumberGenerator, public NotCopyable -{ -public: - // cipher will be deleted by destructor, deterministicTimeVector = 0 means obtain time vector from system - X917RNG(BlockTransformation *cipher, const byte *seed, const byte *deterministicTimeVector = 0); - - void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size); - -private: - member_ptr<BlockTransformation> cipher; - unsigned int S; // blocksize of cipher - SecByteBlock dtbuf; // buffer for enciphered timestamp - SecByteBlock randseed, m_lastBlock, m_deterministicTimeVector; -}; - -/** This class implements Maurer's Universal Statistical Test for Random Bit Generators - it is intended for measuring the randomness of *PHYSICAL* RNGs. - For more details see his paper in Journal of Cryptology, 1992. */ - -class MaurerRandomnessTest : public Bufferless<Sink> -{ -public: - MaurerRandomnessTest(); - - size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); - - // BytesNeeded() returns how many more bytes of input is needed by the test - // GetTestValue() should not be called before BytesNeeded()==0 - unsigned int BytesNeeded() const {return n >= (Q+K) ? 0 : Q+K-n;} - - // returns a number between 0.0 and 1.0, describing the quality of the - // random numbers entered - double GetTestValue() const; - -private: - enum {L=8, V=256, Q=2000, K=2000}; - double sum; - unsigned int n; - unsigned int tab[V]; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/rsa.cpp b/lib/cryptopp/rsa.cpp deleted file mode 100644 index 59449c40e..000000000 --- a/lib/cryptopp/rsa.cpp +++ /dev/null @@ -1,304 +0,0 @@ -// rsa.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "rsa.h" -#include "asn.h" -#include "oids.h" -#include "modarith.h" -#include "nbtheory.h" -#include "sha.h" -#include "algparam.h" -#include "fips140.h" - -#if !defined(NDEBUG) && !defined(CRYPTOPP_IS_DLL) -#include "pssr.h" -NAMESPACE_BEGIN(CryptoPP) -void RSA_TestInstantiations() -{ - RSASS<PKCS1v15, SHA>::Verifier x1(1, 1); - RSASS<PKCS1v15, SHA>::Signer x2(NullRNG(), 1); - RSASS<PKCS1v15, SHA>::Verifier x3(x2); - RSASS<PKCS1v15, SHA>::Verifier x4(x2.GetKey()); - RSASS<PSS, SHA>::Verifier x5(x3); -#ifndef __MWERKS__ - RSASS<PSSR, SHA>::Signer x6 = x2; - x3 = x2; - x6 = x2; -#endif - RSAES<PKCS1v15>::Encryptor x7(x2); -#ifndef __GNUC__ - RSAES<PKCS1v15>::Encryptor x8(x3); -#endif - RSAES<OAEP<SHA> >::Encryptor x9(x2); - - x4 = x2.GetKey(); -} -NAMESPACE_END -#endif - -#ifndef CRYPTOPP_IMPORTS - -NAMESPACE_BEGIN(CryptoPP) - -OID RSAFunction::GetAlgorithmID() const -{ - return ASN1::rsaEncryption(); -} - -void RSAFunction::BERDecodePublicKey(BufferedTransformation &bt, bool, size_t) -{ - BERSequenceDecoder seq(bt); - m_n.BERDecode(seq); - m_e.BERDecode(seq); - seq.MessageEnd(); -} - -void RSAFunction::DEREncodePublicKey(BufferedTransformation &bt) const -{ - DERSequenceEncoder seq(bt); - m_n.DEREncode(seq); - m_e.DEREncode(seq); - seq.MessageEnd(); -} - -Integer RSAFunction::ApplyFunction(const Integer &x) const -{ - DoQuickSanityCheck(); - return a_exp_b_mod_c(x, m_e, m_n); -} - -bool RSAFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const -{ - bool pass = true; - pass = pass && m_n > Integer::One() && m_n.IsOdd(); - pass = pass && m_e > Integer::One() && m_e.IsOdd() && m_e < m_n; - return pass; -} - -bool RSAFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const -{ - return GetValueHelper(this, name, valueType, pValue).Assignable() - CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) - CRYPTOPP_GET_FUNCTION_ENTRY(PublicExponent) - ; -} - -void RSAFunction::AssignFrom(const NameValuePairs &source) -{ - AssignFromHelper(this, source) - CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) - CRYPTOPP_SET_FUNCTION_ENTRY(PublicExponent) - ; -} - -// ***************************************************************************** - -class RSAPrimeSelector : public PrimeSelector -{ -public: - RSAPrimeSelector(const Integer &e) : m_e(e) {} - bool IsAcceptable(const Integer &candidate) const {return RelativelyPrime(m_e, candidate-Integer::One());} - Integer m_e; -}; - -void InvertibleRSAFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) -{ - int modulusSize = 2048; - alg.GetIntValue(Name::ModulusSize(), modulusSize) || alg.GetIntValue(Name::KeySize(), modulusSize); - - if (modulusSize < 16) - throw InvalidArgument("InvertibleRSAFunction: specified modulus size is too small"); - - m_e = alg.GetValueWithDefault(Name::PublicExponent(), Integer(17)); - - if (m_e < 3 || m_e.IsEven()) - throw InvalidArgument("InvertibleRSAFunction: invalid public exponent"); - - RSAPrimeSelector selector(m_e); - AlgorithmParameters primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize) - (Name::PointerToPrimeSelector(), selector.GetSelectorPointer()); - m_p.GenerateRandom(rng, primeParam); - m_q.GenerateRandom(rng, primeParam); - - m_d = m_e.InverseMod(LCM(m_p-1, m_q-1)); - assert(m_d.IsPositive()); - - m_dp = m_d % (m_p-1); - m_dq = m_d % (m_q-1); - m_n = m_p * m_q; - m_u = m_q.InverseMod(m_p); - - if (FIPS_140_2_ComplianceEnabled()) - { - RSASS<PKCS1v15, SHA>::Signer signer(*this); - RSASS<PKCS1v15, SHA>::Verifier verifier(signer); - SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier); - - RSAES<OAEP<SHA> >::Decryptor decryptor(*this); - RSAES<OAEP<SHA> >::Encryptor encryptor(decryptor); - EncryptionPairwiseConsistencyTest_FIPS_140_Only(encryptor, decryptor); - } -} - -void InvertibleRSAFunction::Initialize(RandomNumberGenerator &rng, unsigned int keybits, const Integer &e) -{ - GenerateRandom(rng, MakeParameters(Name::ModulusSize(), (int)keybits)(Name::PublicExponent(), e+e.IsEven())); -} - -void InvertibleRSAFunction::Initialize(const Integer &n, const Integer &e, const Integer &d) -{ - if (n.IsEven() || e.IsEven() | d.IsEven()) - throw InvalidArgument("InvertibleRSAFunction: input is not a valid RSA private key"); - - m_n = n; - m_e = e; - m_d = d; - - Integer r = --(d*e); - unsigned int s = 0; - while (r.IsEven()) - { - r >>= 1; - s++; - } - - ModularArithmetic modn(n); - for (Integer i = 2; ; ++i) - { - Integer a = modn.Exponentiate(i, r); - if (a == 1) - continue; - Integer b; - unsigned int j = 0; - while (a != n-1) - { - b = modn.Square(a); - if (b == 1) - { - m_p = GCD(a-1, n); - m_q = n/m_p; - m_dp = m_d % (m_p-1); - m_dq = m_d % (m_q-1); - m_u = m_q.InverseMod(m_p); - return; - } - if (++j == s) - throw InvalidArgument("InvertibleRSAFunction: input is not a valid RSA private key"); - a = b; - } - } -} - -void InvertibleRSAFunction::BERDecodePrivateKey(BufferedTransformation &bt, bool, size_t) -{ - BERSequenceDecoder privateKey(bt); - word32 version; - BERDecodeUnsigned<word32>(privateKey, version, INTEGER, 0, 0); // check version - m_n.BERDecode(privateKey); - m_e.BERDecode(privateKey); - m_d.BERDecode(privateKey); - m_p.BERDecode(privateKey); - m_q.BERDecode(privateKey); - m_dp.BERDecode(privateKey); - m_dq.BERDecode(privateKey); - m_u.BERDecode(privateKey); - privateKey.MessageEnd(); -} - -void InvertibleRSAFunction::DEREncodePrivateKey(BufferedTransformation &bt) const -{ - DERSequenceEncoder privateKey(bt); - DEREncodeUnsigned<word32>(privateKey, 0); // version - m_n.DEREncode(privateKey); - m_e.DEREncode(privateKey); - m_d.DEREncode(privateKey); - m_p.DEREncode(privateKey); - m_q.DEREncode(privateKey); - m_dp.DEREncode(privateKey); - m_dq.DEREncode(privateKey); - m_u.DEREncode(privateKey); - privateKey.MessageEnd(); -} - -Integer InvertibleRSAFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const -{ - DoQuickSanityCheck(); - ModularArithmetic modn(m_n); - Integer r, rInv; - do { // do this in a loop for people using small numbers for testing - r.Randomize(rng, Integer::One(), m_n - Integer::One()); - rInv = modn.MultiplicativeInverse(r); - } while (rInv.IsZero()); - Integer re = modn.Exponentiate(r, m_e); - re = modn.Multiply(re, x); // blind - // here we follow the notation of PKCS #1 and let u=q inverse mod p - // but in ModRoot, u=p inverse mod q, so we reverse the order of p and q - Integer y = ModularRoot(re, m_dq, m_dp, m_q, m_p, m_u); - y = modn.Multiply(y, rInv); // unblind - if (modn.Exponentiate(y, m_e) != x) // check - throw Exception(Exception::OTHER_ERROR, "InvertibleRSAFunction: computational error during private key operation"); - return y; -} - -bool InvertibleRSAFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const -{ - bool pass = RSAFunction::Validate(rng, level); - pass = pass && m_p > Integer::One() && m_p.IsOdd() && m_p < m_n; - pass = pass && m_q > Integer::One() && m_q.IsOdd() && m_q < m_n; - pass = pass && m_d > Integer::One() && m_d.IsOdd() && m_d < m_n; - pass = pass && m_dp > Integer::One() && m_dp.IsOdd() && m_dp < m_p; - pass = pass && m_dq > Integer::One() && m_dq.IsOdd() && m_dq < m_q; - pass = pass && m_u.IsPositive() && m_u < m_p; - if (level >= 1) - { - pass = pass && m_p * m_q == m_n; - pass = pass && m_e*m_d % LCM(m_p-1, m_q-1) == 1; - pass = pass && m_dp == m_d%(m_p-1) && m_dq == m_d%(m_q-1); - pass = pass && m_u * m_q % m_p == 1; - } - if (level >= 2) - pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); - return pass; -} - -bool InvertibleRSAFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const -{ - return GetValueHelper<RSAFunction>(this, name, valueType, pValue).Assignable() - CRYPTOPP_GET_FUNCTION_ENTRY(Prime1) - CRYPTOPP_GET_FUNCTION_ENTRY(Prime2) - CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent) - CRYPTOPP_GET_FUNCTION_ENTRY(ModPrime1PrivateExponent) - CRYPTOPP_GET_FUNCTION_ENTRY(ModPrime2PrivateExponent) - CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) - ; -} - -void InvertibleRSAFunction::AssignFrom(const NameValuePairs &source) -{ - AssignFromHelper<RSAFunction>(this, source) - CRYPTOPP_SET_FUNCTION_ENTRY(Prime1) - CRYPTOPP_SET_FUNCTION_ENTRY(Prime2) - CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent) - CRYPTOPP_SET_FUNCTION_ENTRY(ModPrime1PrivateExponent) - CRYPTOPP_SET_FUNCTION_ENTRY(ModPrime2PrivateExponent) - CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) - ; -} - -// ***************************************************************************** - -Integer RSAFunction_ISO::ApplyFunction(const Integer &x) const -{ - Integer t = RSAFunction::ApplyFunction(x); - return t % 16 == 12 ? t : m_n - t; -} - -Integer InvertibleRSAFunction_ISO::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const -{ - Integer t = InvertibleRSAFunction::CalculateInverse(rng, x); - return STDMIN(t, m_n-t); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/rsa.h b/lib/cryptopp/rsa.h deleted file mode 100644 index 6a8b18525..000000000 --- a/lib/cryptopp/rsa.h +++ /dev/null @@ -1,174 +0,0 @@ -#ifndef CRYPTOPP_RSA_H -#define CRYPTOPP_RSA_H - -/** \file - This file contains classes that implement the RSA - ciphers and signature schemes as defined in PKCS #1 v2.0. -*/ - -#include "pubkey.h" -#include "asn.h" -#include "pkcspad.h" -#include "oaep.h" -#include "emsa2.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -class CRYPTOPP_DLL RSAFunction : public TrapdoorFunction, public X509PublicKey -{ - typedef RSAFunction ThisClass; - -public: - void Initialize(const Integer &n, const Integer &e) - {m_n = n; m_e = e;} - - // X509PublicKey - OID GetAlgorithmID() const; - void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size); - void DEREncodePublicKey(BufferedTransformation &bt) const; - - // CryptoMaterial - bool Validate(RandomNumberGenerator &rng, unsigned int level) const; - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; - void AssignFrom(const NameValuePairs &source); - - // TrapdoorFunction - Integer ApplyFunction(const Integer &x) const; - Integer PreimageBound() const {return m_n;} - Integer ImageBound() const {return m_n;} - - // non-derived - const Integer & GetModulus() const {return m_n;} - const Integer & GetPublicExponent() const {return m_e;} - - void SetModulus(const Integer &n) {m_n = n;} - void SetPublicExponent(const Integer &e) {m_e = e;} - -protected: - Integer m_n, m_e; -}; - -//! _ -class CRYPTOPP_DLL InvertibleRSAFunction : public RSAFunction, public TrapdoorFunctionInverse, public PKCS8PrivateKey -{ - typedef InvertibleRSAFunction ThisClass; - -public: - void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits, const Integer &e = 17); - void Initialize(const Integer &n, const Integer &e, const Integer &d, const Integer &p, const Integer &q, const Integer &dp, const Integer &dq, const Integer &u) - {m_n = n; m_e = e; m_d = d; m_p = p; m_q = q; m_dp = dp; m_dq = dq; m_u = u;} - //! factor n given private exponent - void Initialize(const Integer &n, const Integer &e, const Integer &d); - - // PKCS8PrivateKey - void BERDecode(BufferedTransformation &bt) - {PKCS8PrivateKey::BERDecode(bt);} - void DEREncode(BufferedTransformation &bt) const - {PKCS8PrivateKey::DEREncode(bt);} - void Load(BufferedTransformation &bt) - {PKCS8PrivateKey::BERDecode(bt);} - void Save(BufferedTransformation &bt) const - {PKCS8PrivateKey::DEREncode(bt);} - OID GetAlgorithmID() const {return RSAFunction::GetAlgorithmID();} - void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size); - void DEREncodePrivateKey(BufferedTransformation &bt) const; - - // TrapdoorFunctionInverse - Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; - - // GeneratableCryptoMaterial - bool Validate(RandomNumberGenerator &rng, unsigned int level) const; - /*! parameters: (ModulusSize, PublicExponent (default 17)) */ - void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; - void AssignFrom(const NameValuePairs &source); - - // non-derived interface - const Integer& GetPrime1() const {return m_p;} - const Integer& GetPrime2() const {return m_q;} - const Integer& GetPrivateExponent() const {return m_d;} - const Integer& GetModPrime1PrivateExponent() const {return m_dp;} - const Integer& GetModPrime2PrivateExponent() const {return m_dq;} - const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const {return m_u;} - - void SetPrime1(const Integer &p) {m_p = p;} - void SetPrime2(const Integer &q) {m_q = q;} - void SetPrivateExponent(const Integer &d) {m_d = d;} - void SetModPrime1PrivateExponent(const Integer &dp) {m_dp = dp;} - void SetModPrime2PrivateExponent(const Integer &dq) {m_dq = dq;} - void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer &u) {m_u = u;} - -protected: - Integer m_d, m_p, m_q, m_dp, m_dq, m_u; -}; - -class CRYPTOPP_DLL RSAFunction_ISO : public RSAFunction -{ -public: - Integer ApplyFunction(const Integer &x) const; - Integer PreimageBound() const {return ++(m_n>>1);} -}; - -class CRYPTOPP_DLL InvertibleRSAFunction_ISO : public InvertibleRSAFunction -{ -public: - Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; - Integer PreimageBound() const {return ++(m_n>>1);} -}; - -//! RSA -struct CRYPTOPP_DLL RSA -{ - static const char * CRYPTOPP_API StaticAlgorithmName() {return "RSA";} - typedef RSAFunction PublicKey; - typedef InvertibleRSAFunction PrivateKey; -}; - -//! <a href="http://www.weidai.com/scan-mirror/ca.html#RSA">RSA cryptosystem</a> -template <class STANDARD> -struct RSAES : public TF_ES<STANDARD, RSA> -{ -}; - -//! <a href="http://www.weidai.com/scan-mirror/sig.html#RSA">RSA signature scheme with appendix</a> -/*! See documentation of PKCS1v15 for a list of hash functions that can be used with it. */ -template <class STANDARD, class H> -struct RSASS : public TF_SS<STANDARD, H, RSA> -{ -}; - -struct CRYPTOPP_DLL RSA_ISO -{ - static const char * CRYPTOPP_API StaticAlgorithmName() {return "RSA-ISO";} - typedef RSAFunction_ISO PublicKey; - typedef InvertibleRSAFunction_ISO PrivateKey; -}; - -template <class H> -struct RSASS_ISO : public TF_SS<P1363_EMSA2, H, RSA_ISO> -{ -}; - -// The two RSA encryption schemes defined in PKCS #1 v2.0 -typedef RSAES<PKCS1v15>::Decryptor RSAES_PKCS1v15_Decryptor; -typedef RSAES<PKCS1v15>::Encryptor RSAES_PKCS1v15_Encryptor; - -typedef RSAES<OAEP<SHA> >::Decryptor RSAES_OAEP_SHA_Decryptor; -typedef RSAES<OAEP<SHA> >::Encryptor RSAES_OAEP_SHA_Encryptor; - -// The three RSA signature schemes defined in PKCS #1 v2.0 -typedef RSASS<PKCS1v15, SHA>::Signer RSASSA_PKCS1v15_SHA_Signer; -typedef RSASS<PKCS1v15, SHA>::Verifier RSASSA_PKCS1v15_SHA_Verifier; - -namespace Weak { -typedef RSASS<PKCS1v15, Weak1::MD2>::Signer RSASSA_PKCS1v15_MD2_Signer; -typedef RSASS<PKCS1v15, Weak1::MD2>::Verifier RSASSA_PKCS1v15_MD2_Verifier; - -typedef RSASS<PKCS1v15, Weak1::MD5>::Signer RSASSA_PKCS1v15_MD5_Signer; -typedef RSASS<PKCS1v15, Weak1::MD5>::Verifier RSASSA_PKCS1v15_MD5_Verifier; -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/rw.cpp b/lib/cryptopp/rw.cpp deleted file mode 100644 index cdd9f2d22..000000000 --- a/lib/cryptopp/rw.cpp +++ /dev/null @@ -1,196 +0,0 @@ -// rw.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "rw.h" -#include "nbtheory.h" -#include "asn.h" - -#ifndef CRYPTOPP_IMPORTS - -NAMESPACE_BEGIN(CryptoPP) - -void RWFunction::BERDecode(BufferedTransformation &bt) -{ - BERSequenceDecoder seq(bt); - m_n.BERDecode(seq); - seq.MessageEnd(); -} - -void RWFunction::DEREncode(BufferedTransformation &bt) const -{ - DERSequenceEncoder seq(bt); - m_n.DEREncode(seq); - seq.MessageEnd(); -} - -Integer RWFunction::ApplyFunction(const Integer &in) const -{ - DoQuickSanityCheck(); - - Integer out = in.Squared()%m_n; - const word r = 12; - // this code was written to handle both r = 6 and r = 12, - // but now only r = 12 is used in P1363 - const word r2 = r/2; - const word r3a = (16 + 5 - r) % 16; // n%16 could be 5 or 13 - const word r3b = (16 + 13 - r) % 16; - const word r4 = (8 + 5 - r/2) % 8; // n%8 == 5 - switch (out % 16) - { - case r: - break; - case r2: - case r2+8: - out <<= 1; - break; - case r3a: - case r3b: - out.Negate(); - out += m_n; - break; - case r4: - case r4+8: - out.Negate(); - out += m_n; - out <<= 1; - break; - default: - out = Integer::Zero(); - } - return out; -} - -bool RWFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const -{ - bool pass = true; - pass = pass && m_n > Integer::One() && m_n%8 == 5; - return pass; -} - -bool RWFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const -{ - return GetValueHelper(this, name, valueType, pValue).Assignable() - CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) - ; -} - -void RWFunction::AssignFrom(const NameValuePairs &source) -{ - AssignFromHelper(this, source) - CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) - ; -} - -// ***************************************************************************** -// private key operations: - -// generate a random private key -void InvertibleRWFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) -{ - int modulusSize = 2048; - alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize); - - if (modulusSize < 16) - throw InvalidArgument("InvertibleRWFunction: specified modulus length is too small"); - - AlgorithmParameters primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize); - m_p.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("EquivalentTo", 3)("Mod", 8))); - m_q.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("EquivalentTo", 7)("Mod", 8))); - - m_n = m_p * m_q; - m_u = m_q.InverseMod(m_p); -} - -void InvertibleRWFunction::BERDecode(BufferedTransformation &bt) -{ - BERSequenceDecoder seq(bt); - m_n.BERDecode(seq); - m_p.BERDecode(seq); - m_q.BERDecode(seq); - m_u.BERDecode(seq); - seq.MessageEnd(); -} - -void InvertibleRWFunction::DEREncode(BufferedTransformation &bt) const -{ - DERSequenceEncoder seq(bt); - m_n.DEREncode(seq); - m_p.DEREncode(seq); - m_q.DEREncode(seq); - m_u.DEREncode(seq); - seq.MessageEnd(); -} - -Integer InvertibleRWFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const -{ - DoQuickSanityCheck(); - ModularArithmetic modn(m_n); - Integer r, rInv; - do { // do this in a loop for people using small numbers for testing - r.Randomize(rng, Integer::One(), m_n - Integer::One()); - rInv = modn.MultiplicativeInverse(r); - } while (rInv.IsZero()); - Integer re = modn.Square(r); - re = modn.Multiply(re, x); // blind - - Integer cp=re%m_p, cq=re%m_q; - if (Jacobi(cp, m_p) * Jacobi(cq, m_q) != 1) - { - cp = cp.IsOdd() ? (cp+m_p) >> 1 : cp >> 1; - cq = cq.IsOdd() ? (cq+m_q) >> 1 : cq >> 1; - } - - #pragma omp parallel - #pragma omp sections - { - #pragma omp section - cp = ModularSquareRoot(cp, m_p); - #pragma omp section - cq = ModularSquareRoot(cq, m_q); - } - - Integer y = CRT(cq, m_q, cp, m_p, m_u); - y = modn.Multiply(y, rInv); // unblind - y = STDMIN(y, m_n-y); - if (ApplyFunction(y) != x) // check - throw Exception(Exception::OTHER_ERROR, "InvertibleRWFunction: computational error during private key operation"); - return y; -} - -bool InvertibleRWFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const -{ - bool pass = RWFunction::Validate(rng, level); - pass = pass && m_p > Integer::One() && m_p%8 == 3 && m_p < m_n; - pass = pass && m_q > Integer::One() && m_q%8 == 7 && m_q < m_n; - pass = pass && m_u.IsPositive() && m_u < m_p; - if (level >= 1) - { - pass = pass && m_p * m_q == m_n; - pass = pass && m_u * m_q % m_p == 1; - } - if (level >= 2) - pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); - return pass; -} - -bool InvertibleRWFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const -{ - return GetValueHelper<RWFunction>(this, name, valueType, pValue).Assignable() - CRYPTOPP_GET_FUNCTION_ENTRY(Prime1) - CRYPTOPP_GET_FUNCTION_ENTRY(Prime2) - CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) - ; -} - -void InvertibleRWFunction::AssignFrom(const NameValuePairs &source) -{ - AssignFromHelper<RWFunction>(this, source) - CRYPTOPP_SET_FUNCTION_ENTRY(Prime1) - CRYPTOPP_SET_FUNCTION_ENTRY(Prime2) - CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) - ; -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/rw.h b/lib/cryptopp/rw.h deleted file mode 100644 index 6820251e8..000000000 --- a/lib/cryptopp/rw.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef CRYPTOPP_RW_H -#define CRYPTOPP_RW_H - -/** \file - This file contains classes that implement the - Rabin-Williams signature schemes as defined in IEEE P1363. -*/ - -#include "pubkey.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -class CRYPTOPP_DLL RWFunction : public TrapdoorFunction, public PublicKey -{ - typedef RWFunction ThisClass; - -public: - void Initialize(const Integer &n) - {m_n = n;} - - void BERDecode(BufferedTransformation &bt); - void DEREncode(BufferedTransformation &bt) const; - - void Save(BufferedTransformation &bt) const - {DEREncode(bt);} - void Load(BufferedTransformation &bt) - {BERDecode(bt);} - - Integer ApplyFunction(const Integer &x) const; - Integer PreimageBound() const {return ++(m_n>>1);} - Integer ImageBound() const {return m_n;} - - bool Validate(RandomNumberGenerator &rng, unsigned int level) const; - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; - void AssignFrom(const NameValuePairs &source); - - const Integer& GetModulus() const {return m_n;} - void SetModulus(const Integer &n) {m_n = n;} - -protected: - Integer m_n; -}; - -//! _ -class CRYPTOPP_DLL InvertibleRWFunction : public RWFunction, public TrapdoorFunctionInverse, public PrivateKey -{ - typedef InvertibleRWFunction ThisClass; - -public: - void Initialize(const Integer &n, const Integer &p, const Integer &q, const Integer &u) - {m_n = n; m_p = p; m_q = q; m_u = u;} - // generate a random private key - void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits) - {GenerateRandomWithKeySize(rng, modulusBits);} - - void BERDecode(BufferedTransformation &bt); - void DEREncode(BufferedTransformation &bt) const; - - void Save(BufferedTransformation &bt) const - {DEREncode(bt);} - void Load(BufferedTransformation &bt) - {BERDecode(bt);} - - Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; - - // GeneratibleCryptoMaterial - bool Validate(RandomNumberGenerator &rng, unsigned int level) const; - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; - void AssignFrom(const NameValuePairs &source); - /*! parameters: (ModulusSize) */ - void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); - - const Integer& GetPrime1() const {return m_p;} - const Integer& GetPrime2() const {return m_q;} - const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const {return m_u;} - - void SetPrime1(const Integer &p) {m_p = p;} - void SetPrime2(const Integer &q) {m_q = q;} - void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer &u) {m_u = u;} - -protected: - Integer m_p, m_q, m_u; -}; - -//! RW -struct RW -{ - static std::string StaticAlgorithmName() {return "RW";} - typedef RWFunction PublicKey; - typedef InvertibleRWFunction PrivateKey; -}; - -//! RWSS -template <class STANDARD, class H> -struct RWSS : public TF_SS<STANDARD, H, RW> -{ -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/safer.cpp b/lib/cryptopp/safer.cpp deleted file mode 100644 index d46ca6417..000000000 --- a/lib/cryptopp/safer.cpp +++ /dev/null @@ -1,153 +0,0 @@ -// safer.cpp - modified by by Wei Dai from Richard De Moliner's safer.c - -#include "pch.h" -#include "safer.h" -#include "misc.h" -#include "argnames.h" - -NAMESPACE_BEGIN(CryptoPP) - -const byte SAFER::Base::exp_tab[256] = - {1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63, - 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247, - 64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, - 255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, - 241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, - 129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, - 4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, - 32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217, - 0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194, - 249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10, - 193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80, - 2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126, - 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237, - 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97, - 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5, - 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40}; - -const byte SAFER::Base::log_tab[256] = - {128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248, - 192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130, - 112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37, - 201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15, - 32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198, - 175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84, - 121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188, - 189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217, - 208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158, - 210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42, - 95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219, - 164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29, - 41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14, - 122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104, - 109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66, - 184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48}; - -#define EXP(x) exp_tab[(x)] -#define LOG(x) log_tab[(x)] -#define PHT(x, y) { y += x; x += y; } -#define IPHT(x, y) { x -= y; y -= x; } - -static const unsigned int BLOCKSIZE = 8; -static const unsigned int MAX_ROUNDS = 13; - -void SAFER::Base::UncheckedSetKey(const byte *userkey_1, unsigned int length, const NameValuePairs ¶ms) -{ - bool strengthened = Strengthened(); - unsigned int nof_rounds = params.GetIntValueWithDefault(Name::Rounds(), length == 8 ? (strengthened ? 8 : 6) : 10); - - const byte *userkey_2 = length == 8 ? userkey_1 : userkey_1 + 8; - keySchedule.New(1 + BLOCKSIZE * (1 + 2 * nof_rounds)); - - unsigned int i, j; - byte *key = keySchedule; - SecByteBlock ka(BLOCKSIZE + 1), kb(BLOCKSIZE + 1); - - if (MAX_ROUNDS < nof_rounds) - nof_rounds = MAX_ROUNDS; - *key++ = (unsigned char)nof_rounds; - ka[BLOCKSIZE] = 0; - kb[BLOCKSIZE] = 0; - for (j = 0; j < BLOCKSIZE; j++) - { - ka[BLOCKSIZE] ^= ka[j] = rotlFixed(userkey_1[j], 5U); - kb[BLOCKSIZE] ^= kb[j] = *key++ = userkey_2[j]; - } - - for (i = 1; i <= nof_rounds; i++) - { - for (j = 0; j < BLOCKSIZE + 1; j++) - { - ka[j] = rotlFixed(ka[j], 6U); - kb[j] = rotlFixed(kb[j], 6U); - } - for (j = 0; j < BLOCKSIZE; j++) - if (strengthened) - *key++ = (ka[(j + 2 * i - 1) % (BLOCKSIZE + 1)] - + exp_tab[exp_tab[18 * i + j + 1]]) & 0xFF; - else - *key++ = (ka[j] + exp_tab[exp_tab[18 * i + j + 1]]) & 0xFF; - for (j = 0; j < BLOCKSIZE; j++) - if (strengthened) - *key++ = (kb[(j + 2 * i) % (BLOCKSIZE + 1)] - + exp_tab[exp_tab[18 * i + j + 10]]) & 0xFF; - else - *key++ = (kb[j] + exp_tab[exp_tab[18 * i + j + 10]]) & 0xFF; - } -} - -typedef BlockGetAndPut<byte, BigEndian> Block; - -void SAFER::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - byte a, b, c, d, e, f, g, h, t; - const byte *key = keySchedule+1; - unsigned int round = keySchedule[0]; - - Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h); - while(round--) - { - a ^= key[0]; b += key[1]; c += key[2]; d ^= key[3]; - e ^= key[4]; f += key[5]; g += key[6]; h ^= key[7]; - a = EXP(a) + key[ 8]; b = LOG(b) ^ key[ 9]; - c = LOG(c) ^ key[10]; d = EXP(d) + key[11]; - e = EXP(e) + key[12]; f = LOG(f) ^ key[13]; - g = LOG(g) ^ key[14]; h = EXP(h) + key[15]; - key += 16; - PHT(a, b); PHT(c, d); PHT(e, f); PHT(g, h); - PHT(a, c); PHT(e, g); PHT(b, d); PHT(f, h); - PHT(a, e); PHT(b, f); PHT(c, g); PHT(d, h); - t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t; - } - a ^= key[0]; b += key[1]; c += key[2]; d ^= key[3]; - e ^= key[4]; f += key[5]; g += key[6]; h ^= key[7]; - Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h); -} - -void SAFER::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - byte a, b, c, d, e, f, g, h, t; - unsigned int round = keySchedule[0]; - const byte *key = keySchedule + BLOCKSIZE * (1 + 2 * round) - 7; - - Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h); - h ^= key[7]; g -= key[6]; f -= key[5]; e ^= key[4]; - d ^= key[3]; c -= key[2]; b -= key[1]; a ^= key[0]; - while (round--) - { - key -= 16; - t = e; e = b; b = c; c = t; t = f; f = d; d = g; g = t; - IPHT(a, e); IPHT(b, f); IPHT(c, g); IPHT(d, h); - IPHT(a, c); IPHT(e, g); IPHT(b, d); IPHT(f, h); - IPHT(a, b); IPHT(c, d); IPHT(e, f); IPHT(g, h); - h -= key[15]; g ^= key[14]; f ^= key[13]; e -= key[12]; - d -= key[11]; c ^= key[10]; b ^= key[9]; a -= key[8]; - h = LOG(h) ^ key[7]; g = EXP(g) - key[6]; - f = EXP(f) - key[5]; e = LOG(e) ^ key[4]; - d = LOG(d) ^ key[3]; c = EXP(c) - key[2]; - b = EXP(b) - key[1]; a = LOG(a) ^ key[0]; - } - Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h); -} - -NAMESPACE_END diff --git a/lib/cryptopp/safer.h b/lib/cryptopp/safer.h deleted file mode 100644 index f9a3c9e1f..000000000 --- a/lib/cryptopp/safer.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef CRYPTOPP_SAFER_H -#define CRYPTOPP_SAFER_H - -/** \file -*/ - -#include "seckey.h" -#include "secblock.h" - -NAMESPACE_BEGIN(CryptoPP) - -/// base class, do not use directly -class SAFER -{ -public: - class CRYPTOPP_NO_VTABLE Base : public BlockCipher - { - public: - unsigned int OptimalDataAlignment() const {return 1;} - void UncheckedSetKey(const byte *userkey, unsigned int length, const NameValuePairs ¶ms); - - protected: - virtual bool Strengthened() const =0; - - SecByteBlock keySchedule; - static const byte exp_tab[256]; - static const byte log_tab[256]; - }; - - class CRYPTOPP_NO_VTABLE Enc : public Base - { - public: - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - }; - - class CRYPTOPP_NO_VTABLE Dec : public Base - { - public: - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - }; -}; - -template <class BASE, class INFO, bool STR> -class CRYPTOPP_NO_VTABLE SAFER_Impl : public BlockCipherImpl<INFO, BASE> -{ -protected: - bool Strengthened() const {return STR;} -}; - -//! _ -struct SAFER_K_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 8, 16, 8>, public VariableRounds<10, 1, 13> -{ - static const char *StaticAlgorithmName() {return "SAFER-K";} -}; - -/// <a href="http://www.weidai.com/scan-mirror/cs.html#SAFER-K">SAFER-K</a> -class SAFER_K : public SAFER_K_Info, public SAFER, public BlockCipherDocumentation -{ -public: - typedef BlockCipherFinal<ENCRYPTION, SAFER_Impl<Enc, SAFER_K_Info, false> > Encryption; - typedef BlockCipherFinal<DECRYPTION, SAFER_Impl<Dec, SAFER_K_Info, false> > Decryption; -}; - -//! _ -struct SAFER_SK_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 8, 16, 8>, public VariableRounds<10, 1, 13> -{ - static const char *StaticAlgorithmName() {return "SAFER-SK";} -}; - -/// <a href="http://www.weidai.com/scan-mirror/cs.html#SAFER-SK">SAFER-SK</a> -class SAFER_SK : public SAFER_SK_Info, public SAFER, public BlockCipherDocumentation -{ -public: - typedef BlockCipherFinal<ENCRYPTION, SAFER_Impl<Enc, SAFER_SK_Info, true> > Encryption; - typedef BlockCipherFinal<DECRYPTION, SAFER_Impl<Dec, SAFER_SK_Info, true> > Decryption; -}; - -typedef SAFER_K::Encryption SAFER_K_Encryption; -typedef SAFER_K::Decryption SAFER_K_Decryption; - -typedef SAFER_SK::Encryption SAFER_SK_Encryption; -typedef SAFER_SK::Decryption SAFER_SK_Decryption; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/seal.cpp b/lib/cryptopp/seal.cpp deleted file mode 100644 index f49b52203..000000000 --- a/lib/cryptopp/seal.cpp +++ /dev/null @@ -1,213 +0,0 @@ -// seal.cpp - written and placed in the public domain by Wei Dai -// updated to SEAL 3.0 by Leonard Janke - -#include "pch.h" - -#include "seal.h" -#include "sha.h" -#include "misc.h" - -NAMESPACE_BEGIN(CryptoPP) - -void SEAL_TestInstantiations() -{ - SEAL<>::Encryption x; -} - -struct SEAL_Gamma -{ - SEAL_Gamma(const byte *key) - : H(5), Z(5), D(16), lastIndex(0xffffffff) - { - GetUserKey(BIG_ENDIAN_ORDER, H.begin(), 5, key, 20); - memset(D, 0, 64); - } - - word32 Apply(word32 i); - - SecBlock<word32> H, Z, D; - word32 lastIndex; -}; - -word32 SEAL_Gamma::Apply(word32 i) -{ - word32 shaIndex = i/5; - if (shaIndex != lastIndex) - { - memcpy(Z, H, 20); - D[0] = shaIndex; - SHA::Transform(Z, D); - lastIndex = shaIndex; - } - return Z[i%5]; -} - -template <class B> -void SEAL_Policy<B>::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) -{ - m_insideCounter = m_outsideCounter = m_startCount = 0; - - unsigned int L = params.GetIntValueWithDefault("NumberOfOutputBitsPerPositionIndex", 32*1024); - m_iterationsPerCount = L / 8192; - - SEAL_Gamma gamma(key); - unsigned int i; - - for (i=0; i<512; i++) - m_T[i] = gamma.Apply(i); - - for (i=0; i<256; i++) - m_S[i] = gamma.Apply(0x1000+i); - - m_R.New(4*(L/8192)); - - for (i=0; i<m_R.size(); i++) - m_R[i] = gamma.Apply(0x2000+i); -} - -template <class B> -void SEAL_Policy<B>::CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length) -{ - assert(length==4); - m_outsideCounter = IV ? GetWord<word32>(false, BIG_ENDIAN_ORDER, IV) : 0; - m_startCount = m_outsideCounter; - m_insideCounter = 0; -} - -template <class B> -void SEAL_Policy<B>::SeekToIteration(lword iterationCount) -{ - m_outsideCounter = m_startCount + (unsigned int)(iterationCount / m_iterationsPerCount); - m_insideCounter = (unsigned int)(iterationCount % m_iterationsPerCount); -} - -template <class B> -void SEAL_Policy<B>::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) -{ - word32 a, b, c, d, n1, n2, n3, n4; - unsigned int p, q; - - for (size_t iteration = 0; iteration < iterationCount; ++iteration) - { -#define Ttab(x) *(word32 *)((byte *)m_T.begin()+x) - - a = m_outsideCounter ^ m_R[4*m_insideCounter]; - b = rotrFixed(m_outsideCounter, 8U) ^ m_R[4*m_insideCounter+1]; - c = rotrFixed(m_outsideCounter, 16U) ^ m_R[4*m_insideCounter+2]; - d = rotrFixed(m_outsideCounter, 24U) ^ m_R[4*m_insideCounter+3]; - - for (unsigned int j=0; j<2; j++) - { - p = a & 0x7fc; - b += Ttab(p); - a = rotrFixed(a, 9U); - - p = b & 0x7fc; - c += Ttab(p); - b = rotrFixed(b, 9U); - - p = c & 0x7fc; - d += Ttab(p); - c = rotrFixed(c, 9U); - - p = d & 0x7fc; - a += Ttab(p); - d = rotrFixed(d, 9U); - } - - n1 = d, n2 = b, n3 = a, n4 = c; - - p = a & 0x7fc; - b += Ttab(p); - a = rotrFixed(a, 9U); - - p = b & 0x7fc; - c += Ttab(p); - b = rotrFixed(b, 9U); - - p = c & 0x7fc; - d += Ttab(p); - c = rotrFixed(c, 9U); - - p = d & 0x7fc; - a += Ttab(p); - d = rotrFixed(d, 9U); - - // generate 8192 bits - for (unsigned int i=0; i<64; i++) - { - p = a & 0x7fc; - a = rotrFixed(a, 9U); - b += Ttab(p); - b ^= a; - - q = b & 0x7fc; - b = rotrFixed(b, 9U); - c ^= Ttab(q); - c += b; - - p = (p+c) & 0x7fc; - c = rotrFixed(c, 9U); - d += Ttab(p); - d ^= c; - - q = (q+d) & 0x7fc; - d = rotrFixed(d, 9U); - a ^= Ttab(q); - a += d; - - p = (p+a) & 0x7fc; - b ^= Ttab(p); - a = rotrFixed(a, 9U); - - q = (q+b) & 0x7fc; - c += Ttab(q); - b = rotrFixed(b, 9U); - - p = (p+c) & 0x7fc; - d ^= Ttab(p); - c = rotrFixed(c, 9U); - - q = (q+d) & 0x7fc; - d = rotrFixed(d, 9U); - a += Ttab(q); - -#define SEAL_OUTPUT(x) \ - CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 0, b + m_S[4*i+0]);\ - CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 1, c ^ m_S[4*i+1]);\ - CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 2, d + m_S[4*i+2]);\ - CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 3, a ^ m_S[4*i+3]); - - CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(SEAL_OUTPUT, 4*4); - - if (i & 1) - { - a += n3; - b += n4; - c ^= n3; - d ^= n4; - } - else - { - a += n1; - b += n2; - c ^= n1; - d ^= n2; - } - } - - if (++m_insideCounter == m_iterationsPerCount) - { - ++m_outsideCounter; - m_insideCounter = 0; - } - } - - a = b = c = d = n1 = n2 = n3 = n4 = 0; - p = q = 0; -} - -template class SEAL_Policy<BigEndian>; -template class SEAL_Policy<LittleEndian>; - -NAMESPACE_END diff --git a/lib/cryptopp/seal.h b/lib/cryptopp/seal.h deleted file mode 100644 index e14ae1caf..000000000 --- a/lib/cryptopp/seal.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef CRYPTOPP_SEAL_H -#define CRYPTOPP_SEAL_H - -#include "strciphr.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -template <class B = BigEndian> -struct SEAL_Info : public FixedKeyLength<20, SimpleKeyingInterface::INTERNALLY_GENERATED_IV, 4> -{ - static const char *StaticAlgorithmName() {return B::ToEnum() == LITTLE_ENDIAN_ORDER ? "SEAL-3.0-LE" : "SEAL-3.0-BE";} -}; - -template <class B = BigEndian> -class CRYPTOPP_NO_VTABLE SEAL_Policy : public AdditiveCipherConcretePolicy<word32, 256>, public SEAL_Info<B> -{ -protected: - void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); - void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); - void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length); - bool CipherIsRandomAccess() const {return true;} - void SeekToIteration(lword iterationCount); - -private: - FixedSizeSecBlock<word32, 512> m_T; - FixedSizeSecBlock<word32, 256> m_S; - SecBlock<word32> m_R; - - word32 m_startCount, m_iterationsPerCount; - word32 m_outsideCounter, m_insideCounter; -}; - -//! <a href="http://www.weidai.com/scan-mirror/cs.html#SEAL-3.0-BE">SEAL</a> -template <class B = BigEndian> -struct SEAL : public SEAL_Info<B>, public SymmetricCipherDocumentation -{ - typedef SymmetricCipherFinal<ConcretePolicyHolder<SEAL_Policy<B>, AdditiveCipherTemplate<> >, SEAL_Info<B> > Encryption; - typedef Encryption Decryption; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/secblock.h b/lib/cryptopp/secblock.h deleted file mode 100644 index 40cce3341..000000000 --- a/lib/cryptopp/secblock.h +++ /dev/null @@ -1,467 +0,0 @@ -// secblock.h - written and placed in the public domain by Wei Dai - -#ifndef CRYPTOPP_SECBLOCK_H -#define CRYPTOPP_SECBLOCK_H - -#include "config.h" -#include "misc.h" -#include <assert.h> - -NAMESPACE_BEGIN(CryptoPP) - -// ************** secure memory allocation *************** - -template<class T> -class AllocatorBase -{ -public: - typedef T value_type; - typedef size_t size_type; -#ifdef CRYPTOPP_MSVCRT6 - typedef ptrdiff_t difference_type; -#else - typedef std::ptrdiff_t difference_type; -#endif - typedef T * pointer; - typedef const T * const_pointer; - typedef T & reference; - typedef const T & const_reference; - - pointer address(reference r) const {return (&r);} - const_pointer address(const_reference r) const {return (&r); } - void construct(pointer p, const T& val) {new (p) T(val);} - void destroy(pointer p) {p->~T();} - size_type max_size() const {return ~size_type(0)/sizeof(T);} // switch to std::numeric_limits<T>::max later - -protected: - static void CheckSize(size_t n) - { - if (n > ~size_t(0) / sizeof(T)) - throw InvalidArgument("AllocatorBase: requested size would cause integer overflow"); - } -}; - -#define CRYPTOPP_INHERIT_ALLOCATOR_TYPES \ -typedef typename AllocatorBase<T>::value_type value_type;\ -typedef typename AllocatorBase<T>::size_type size_type;\ -typedef typename AllocatorBase<T>::difference_type difference_type;\ -typedef typename AllocatorBase<T>::pointer pointer;\ -typedef typename AllocatorBase<T>::const_pointer const_pointer;\ -typedef typename AllocatorBase<T>::reference reference;\ -typedef typename AllocatorBase<T>::const_reference const_reference; - -#if defined(_MSC_VER) && (_MSC_VER < 1300) -// this pragma causes an internal compiler error if placed immediately before std::swap(a, b) -#pragma warning(push) -#pragma warning(disable: 4700) // VC60 workaround: don't know how to get rid of this warning -#endif - -template <class T, class A> -typename A::pointer StandardReallocate(A& a, T *p, typename A::size_type oldSize, typename A::size_type newSize, bool preserve) -{ - if (oldSize == newSize) - return p; - - if (preserve) - { - typename A::pointer newPointer = a.allocate(newSize, NULL); - memcpy_s(newPointer, sizeof(T)*newSize, p, sizeof(T)*STDMIN(oldSize, newSize)); - a.deallocate(p, oldSize); - return newPointer; - } - else - { - a.deallocate(p, oldSize); - return a.allocate(newSize, NULL); - } -} - -#if defined(_MSC_VER) && (_MSC_VER < 1300) -#pragma warning(pop) -#endif - -template <class T, bool T_Align16 = false> -class AllocatorWithCleanup : public AllocatorBase<T> -{ -public: - CRYPTOPP_INHERIT_ALLOCATOR_TYPES - - pointer allocate(size_type n, const void * = NULL) - { - this->CheckSize(n); - if (n == 0) - return NULL; - -#if CRYPTOPP_BOOL_ALIGN16_ENABLED - if (T_Align16 && n*sizeof(T) >= 16) - return (pointer)AlignedAllocate(n*sizeof(T)); -#endif - - return (pointer)UnalignedAllocate(n*sizeof(T)); - } - - void deallocate(void *p, size_type n) - { - SecureWipeArray((pointer)p, n); - -#if CRYPTOPP_BOOL_ALIGN16_ENABLED - if (T_Align16 && n*sizeof(T) >= 16) - return AlignedDeallocate(p); -#endif - - UnalignedDeallocate(p); - } - - pointer reallocate(T *p, size_type oldSize, size_type newSize, bool preserve) - { - return StandardReallocate(*this, p, oldSize, newSize, preserve); - } - - // VS.NET STL enforces the policy of "All STL-compliant allocators have to provide a - // template class member called rebind". - template <class U> struct rebind { typedef AllocatorWithCleanup<U, T_Align16> other; }; -#if _MSC_VER >= 1500 - AllocatorWithCleanup() {} - template <class U, bool A> AllocatorWithCleanup(const AllocatorWithCleanup<U, A> &) {} -#endif -}; - -CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<byte>; -CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word16>; -CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word32>; -CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word64>; -#if CRYPTOPP_BOOL_X86 -CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word, true>; // for Integer -#endif - -template <class T> -class NullAllocator : public AllocatorBase<T> -{ -public: - CRYPTOPP_INHERIT_ALLOCATOR_TYPES - - pointer allocate(size_type n, const void * = NULL) - { - assert(false); - return NULL; - } - - void deallocate(void *p, size_type n) - { - assert(false); - } - - size_type max_size() const {return 0;} -}; - -// This allocator can't be used with standard collections because -// they require that all objects of the same allocator type are equivalent. -// So this is for use with SecBlock only. -template <class T, size_t S, class A = NullAllocator<T>, bool T_Align16 = false> -class FixedSizeAllocatorWithCleanup : public AllocatorBase<T> -{ -public: - CRYPTOPP_INHERIT_ALLOCATOR_TYPES - - FixedSizeAllocatorWithCleanup() : m_allocated(false) {} - - pointer allocate(size_type n) - { - assert(IsAlignedOn(m_array, 8)); - - if (n <= S && !m_allocated) - { - m_allocated = true; - return GetAlignedArray(); - } - else - return m_fallbackAllocator.allocate(n); - } - - pointer allocate(size_type n, const void *hint) - { - if (n <= S && !m_allocated) - { - m_allocated = true; - return GetAlignedArray(); - } - else - return m_fallbackAllocator.allocate(n, hint); - } - - void deallocate(void *p, size_type n) - { - if (p == GetAlignedArray()) - { - assert(n <= S); - assert(m_allocated); - m_allocated = false; - SecureWipeArray((pointer)p, n); - } - else - m_fallbackAllocator.deallocate(p, n); - } - - pointer reallocate(pointer p, size_type oldSize, size_type newSize, bool preserve) - { - if (p == GetAlignedArray() && newSize <= S) - { - assert(oldSize <= S); - if (oldSize > newSize) - SecureWipeArray(p+newSize, oldSize-newSize); - return p; - } - - pointer newPointer = allocate(newSize, NULL); - if (preserve) - memcpy(newPointer, p, sizeof(T)*STDMIN(oldSize, newSize)); - deallocate(p, oldSize); - return newPointer; - } - - size_type max_size() const {return STDMAX(m_fallbackAllocator.max_size(), S);} - -private: -#ifdef __BORLANDC__ - T* GetAlignedArray() {return m_array;} - T m_array[S]; -#else - T* GetAlignedArray() {return (CRYPTOPP_BOOL_ALIGN16_ENABLED && T_Align16) ? (T*)(((byte *)m_array) + (0-(size_t)m_array)%16) : m_array;} - CRYPTOPP_ALIGN_DATA(8) T m_array[(CRYPTOPP_BOOL_ALIGN16_ENABLED && T_Align16) ? S+8/sizeof(T) : S]; -#endif - A m_fallbackAllocator; - bool m_allocated; -}; - -//! a block of memory allocated using A -template <class T, class A = AllocatorWithCleanup<T> > -class SecBlock -{ -public: - typedef typename A::value_type value_type; - typedef typename A::pointer iterator; - typedef typename A::const_pointer const_iterator; - typedef typename A::size_type size_type; - - explicit SecBlock(size_type size=0) - : m_size(size) {m_ptr = m_alloc.allocate(size, NULL);} - SecBlock(const SecBlock<T, A> &t) - : m_size(t.m_size) {m_ptr = m_alloc.allocate(m_size, NULL); memcpy_s(m_ptr, m_size*sizeof(T), t.m_ptr, m_size*sizeof(T));} - SecBlock(const T *t, size_type len) - : m_size(len) - { - m_ptr = m_alloc.allocate(len, NULL); - if (t == NULL) - memset_z(m_ptr, 0, len*sizeof(T)); - else - memcpy(m_ptr, t, len*sizeof(T)); - } - - ~SecBlock() - {m_alloc.deallocate(m_ptr, m_size);} - -#ifdef __BORLANDC__ - operator T *() const - {return (T*)m_ptr;} -#else - operator const void *() const - {return m_ptr;} - operator void *() - {return m_ptr;} - - operator const T *() const - {return m_ptr;} - operator T *() - {return m_ptr;} -#endif - -// T *operator +(size_type offset) -// {return m_ptr+offset;} - -// const T *operator +(size_type offset) const -// {return m_ptr+offset;} - -// T& operator[](size_type index) -// {assert(index >= 0 && index < m_size); return m_ptr[index];} - -// const T& operator[](size_type index) const -// {assert(index >= 0 && index < m_size); return m_ptr[index];} - - iterator begin() - {return m_ptr;} - const_iterator begin() const - {return m_ptr;} - iterator end() - {return m_ptr+m_size;} - const_iterator end() const - {return m_ptr+m_size;} - - typename A::pointer data() {return m_ptr;} - typename A::const_pointer data() const {return m_ptr;} - - size_type size() const {return m_size;} - bool empty() const {return m_size == 0;} - - byte * BytePtr() {return (byte *)m_ptr;} - const byte * BytePtr() const {return (const byte *)m_ptr;} - size_type SizeInBytes() const {return m_size*sizeof(T);} - - //! set contents and size - void Assign(const T *t, size_type len) - { - New(len); - memcpy_s(m_ptr, m_size*sizeof(T), t, len*sizeof(T)); - } - - //! copy contents and size from another SecBlock - void Assign(const SecBlock<T, A> &t) - { - if (this != &t) - { - New(t.m_size); - memcpy_s(m_ptr, m_size*sizeof(T), t.m_ptr, m_size*sizeof(T)); - } - } - - SecBlock<T, A>& operator=(const SecBlock<T, A> &t) - { - Assign(t); - return *this; - } - - // append to this object - SecBlock<T, A>& operator+=(const SecBlock<T, A> &t) - { - size_type oldSize = m_size; - Grow(m_size+t.m_size); - memcpy_s(m_ptr+oldSize, m_size*sizeof(T), t.m_ptr, t.m_size*sizeof(T)); - return *this; - } - - // append operator - SecBlock<T, A> operator+(const SecBlock<T, A> &t) - { - SecBlock<T, A> result(m_size+t.m_size); - memcpy_s(result.m_ptr, result.m_size*sizeof(T), m_ptr, m_size*sizeof(T)); - memcpy_s(result.m_ptr+m_size, t.m_size*sizeof(T), t.m_ptr, t.m_size*sizeof(T)); - return result; - } - - bool operator==(const SecBlock<T, A> &t) const - { - return m_size == t.m_size && VerifyBufsEqual(m_ptr, t.m_ptr, m_size*sizeof(T)); - } - - bool operator!=(const SecBlock<T, A> &t) const - { - return !operator==(t); - } - - //! change size, without preserving contents - void New(size_type newSize) - { - m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, false); - m_size = newSize; - } - - //! change size and set contents to 0 - void CleanNew(size_type newSize) - { - New(newSize); - memset_z(m_ptr, 0, m_size*sizeof(T)); - } - - //! change size only if newSize > current size. contents are preserved - void Grow(size_type newSize) - { - if (newSize > m_size) - { - m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true); - m_size = newSize; - } - } - - //! change size only if newSize > current size. contents are preserved and additional area is set to 0 - void CleanGrow(size_type newSize) - { - if (newSize > m_size) - { - m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true); - memset(m_ptr+m_size, 0, (newSize-m_size)*sizeof(T)); - m_size = newSize; - } - } - - //! change size and preserve contents - void resize(size_type newSize) - { - m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true); - m_size = newSize; - } - - //! swap contents and size with another SecBlock - void swap(SecBlock<T, A> &b) - { - std::swap(m_alloc, b.m_alloc); - std::swap(m_size, b.m_size); - std::swap(m_ptr, b.m_ptr); - } - -//private: - A m_alloc; - size_type m_size; - T *m_ptr; -}; - -typedef SecBlock<byte> SecByteBlock; -typedef SecBlock<byte, AllocatorWithCleanup<byte, true> > AlignedSecByteBlock; -typedef SecBlock<word> SecWordBlock; - -//! a SecBlock with fixed size, allocated statically -template <class T, unsigned int S, class A = FixedSizeAllocatorWithCleanup<T, S> > -class FixedSizeSecBlock : public SecBlock<T, A> -{ -public: - explicit FixedSizeSecBlock() : SecBlock<T, A>(S) {} -}; - -template <class T, unsigned int S, bool T_Align16 = true> -class FixedSizeAlignedSecBlock : public FixedSizeSecBlock<T, S, FixedSizeAllocatorWithCleanup<T, S, NullAllocator<T>, T_Align16> > -{ -}; - -//! a SecBlock that preallocates size S statically, and uses the heap when this size is exceeded -template <class T, unsigned int S, class A = FixedSizeAllocatorWithCleanup<T, S, AllocatorWithCleanup<T> > > -class SecBlockWithHint : public SecBlock<T, A> -{ -public: - explicit SecBlockWithHint(size_t size) : SecBlock<T, A>(size) {} -}; - -template<class T, bool A, class U, bool B> -inline bool operator==(const CryptoPP::AllocatorWithCleanup<T, A>&, const CryptoPP::AllocatorWithCleanup<U, B>&) {return (true);} -template<class T, bool A, class U, bool B> -inline bool operator!=(const CryptoPP::AllocatorWithCleanup<T, A>&, const CryptoPP::AllocatorWithCleanup<U, B>&) {return (false);} - -NAMESPACE_END - -NAMESPACE_BEGIN(std) -template <class T, class A> -inline void swap(CryptoPP::SecBlock<T, A> &a, CryptoPP::SecBlock<T, A> &b) -{ - a.swap(b); -} - -#if defined(_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) || (defined(_STLPORT_VERSION) && !defined(_STLP_MEMBER_TEMPLATE_CLASSES)) -// working for STLport 5.1.3 and MSVC 6 SP5 -template <class _Tp1, class _Tp2> -inline CryptoPP::AllocatorWithCleanup<_Tp2>& -__stl_alloc_rebind(CryptoPP::AllocatorWithCleanup<_Tp1>& __a, const _Tp2*) -{ - return (CryptoPP::AllocatorWithCleanup<_Tp2>&)(__a); -} -#endif - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/seckey.h b/lib/cryptopp/seckey.h deleted file mode 100644 index 35046a61b..000000000 --- a/lib/cryptopp/seckey.h +++ /dev/null @@ -1,221 +0,0 @@ -// seckey.h - written and placed in the public domain by Wei Dai - -// This file contains helper classes/functions for implementing secret key algorithms. - -#ifndef CRYPTOPP_SECKEY_H -#define CRYPTOPP_SECKEY_H - -#include "cryptlib.h" -#include "misc.h" -#include "simple.h" - -NAMESPACE_BEGIN(CryptoPP) - -inline CipherDir ReverseCipherDir(CipherDir dir) -{ - return (dir == ENCRYPTION) ? DECRYPTION : ENCRYPTION; -} - -//! to be inherited by block ciphers with fixed block size -template <unsigned int N> -class FixedBlockSize -{ -public: - CRYPTOPP_CONSTANT(BLOCKSIZE = N) -}; - -// ************** rounds *************** - -//! to be inherited by ciphers with fixed number of rounds -template <unsigned int R> -class FixedRounds -{ -public: - CRYPTOPP_CONSTANT(ROUNDS = R) -}; - -//! to be inherited by ciphers with variable number of rounds -template <unsigned int D, unsigned int N=1, unsigned int M=INT_MAX> // use INT_MAX here because enums are treated as signed ints -class VariableRounds -{ -public: - CRYPTOPP_CONSTANT(DEFAULT_ROUNDS = D) - CRYPTOPP_CONSTANT(MIN_ROUNDS = N) - CRYPTOPP_CONSTANT(MAX_ROUNDS = M) - static unsigned int StaticGetDefaultRounds(size_t keylength) {return DEFAULT_ROUNDS;} - -protected: - inline void ThrowIfInvalidRounds(int rounds, const Algorithm *alg) - { - if (rounds < MIN_ROUNDS || rounds > MAX_ROUNDS) - throw InvalidRounds(alg->AlgorithmName(), rounds); - } - - inline unsigned int GetRoundsAndThrowIfInvalid(const NameValuePairs ¶m, const Algorithm *alg) - { - int rounds = param.GetIntValueWithDefault("Rounds", DEFAULT_ROUNDS); - ThrowIfInvalidRounds(rounds, alg); - return (unsigned int)rounds; - } -}; - -// ************** key length *************** - -//! to be inherited by keyed algorithms with fixed key length -template <unsigned int N, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0> -class FixedKeyLength -{ -public: - CRYPTOPP_CONSTANT(KEYLENGTH=N) - CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N) - CRYPTOPP_CONSTANT(MAX_KEYLENGTH=N) - CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=N) - CRYPTOPP_CONSTANT(IV_REQUIREMENT = IV_REQ) - CRYPTOPP_CONSTANT(IV_LENGTH = IV_L) - static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t) {return KEYLENGTH;} -}; - -/// support query of variable key length, template parameters are default, min, max, multiple (default multiple 1) -template <unsigned int D, unsigned int N, unsigned int M, unsigned int Q = 1, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0> -class VariableKeyLength -{ - // make these private to avoid Doxygen documenting them in all derived classes - CRYPTOPP_COMPILE_ASSERT(Q > 0); - CRYPTOPP_COMPILE_ASSERT(N % Q == 0); - CRYPTOPP_COMPILE_ASSERT(M % Q == 0); - CRYPTOPP_COMPILE_ASSERT(N < M); - CRYPTOPP_COMPILE_ASSERT(D >= N); - CRYPTOPP_COMPILE_ASSERT(M >= D); - -public: - CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N) - CRYPTOPP_CONSTANT(MAX_KEYLENGTH=M) - CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=D) - CRYPTOPP_CONSTANT(KEYLENGTH_MULTIPLE=Q) - CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ) - CRYPTOPP_CONSTANT(IV_LENGTH=IV_L) - - static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t n) - { - if (n < (size_t)MIN_KEYLENGTH) - return MIN_KEYLENGTH; - else if (n > (size_t)MAX_KEYLENGTH) - return (size_t)MAX_KEYLENGTH; - else - { - n += KEYLENGTH_MULTIPLE-1; - return n - n%KEYLENGTH_MULTIPLE; - } - } -}; - -/// support query of key length that's the same as another class -template <class T, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0> -class SameKeyLengthAs -{ -public: - CRYPTOPP_CONSTANT(MIN_KEYLENGTH=T::MIN_KEYLENGTH) - CRYPTOPP_CONSTANT(MAX_KEYLENGTH=T::MAX_KEYLENGTH) - CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH) - CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ) - CRYPTOPP_CONSTANT(IV_LENGTH=IV_L) - - static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength) - {return T::StaticGetValidKeyLength(keylength);} -}; - -// ************** implementation helper for SimpleKeyed *************** - -//! _ -template <class BASE, class INFO = BASE> -class CRYPTOPP_NO_VTABLE SimpleKeyingInterfaceImpl : public BASE -{ -public: - size_t MinKeyLength() const {return INFO::MIN_KEYLENGTH;} - size_t MaxKeyLength() const {return (size_t)INFO::MAX_KEYLENGTH;} - size_t DefaultKeyLength() const {return INFO::DEFAULT_KEYLENGTH;} - size_t GetValidKeyLength(size_t n) const {return INFO::StaticGetValidKeyLength(n);} - SimpleKeyingInterface::IV_Requirement IVRequirement() const {return (SimpleKeyingInterface::IV_Requirement)INFO::IV_REQUIREMENT;} - unsigned int IVSize() const {return INFO::IV_LENGTH;} -}; - -template <class INFO, class BASE = BlockCipher> -class CRYPTOPP_NO_VTABLE BlockCipherImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<TwoBases<BASE, INFO> > > -{ -public: - unsigned int BlockSize() const {return this->BLOCKSIZE;} -}; - -//! _ -template <CipherDir DIR, class BASE> -class BlockCipherFinal : public ClonableImpl<BlockCipherFinal<DIR, BASE>, BASE> -{ -public: - BlockCipherFinal() {} - BlockCipherFinal(const byte *key) - {this->SetKey(key, this->DEFAULT_KEYLENGTH);} - BlockCipherFinal(const byte *key, size_t length) - {this->SetKey(key, length);} - BlockCipherFinal(const byte *key, size_t length, unsigned int rounds) - {this->SetKeyWithRounds(key, length, rounds);} - - bool IsForwardTransformation() const {return DIR == ENCRYPTION;} -}; - -//! _ -template <class BASE, class INFO = BASE> -class MessageAuthenticationCodeImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO> -{ -}; - -//! _ -template <class BASE> -class MessageAuthenticationCodeFinal : public ClonableImpl<MessageAuthenticationCodeFinal<BASE>, MessageAuthenticationCodeImpl<BASE> > -{ -public: - MessageAuthenticationCodeFinal() {} - MessageAuthenticationCodeFinal(const byte *key) - {this->SetKey(key, this->DEFAULT_KEYLENGTH);} - MessageAuthenticationCodeFinal(const byte *key, size_t length) - {this->SetKey(key, length);} -}; - -// ************** documentation *************** - -//! These objects usually should not be used directly. See CipherModeDocumentation instead. -/*! Each class derived from this one defines two types, Encryption and Decryption, - both of which implement the BlockCipher interface. */ -struct BlockCipherDocumentation -{ - //! implements the BlockCipher interface - typedef BlockCipher Encryption; - //! implements the BlockCipher interface - typedef BlockCipher Decryption; -}; - -/*! \brief Each class derived from this one defines two types, Encryption and Decryption, - both of which implement the SymmetricCipher interface. Two types of classes derive - from this class: stream ciphers and block cipher modes. Stream ciphers can be used - alone, cipher mode classes need to be used with a block cipher. See CipherModeDocumentation - for more for information about using cipher modes and block ciphers. */ -struct SymmetricCipherDocumentation -{ - //! implements the SymmetricCipher interface - typedef SymmetricCipher Encryption; - //! implements the SymmetricCipher interface - typedef SymmetricCipher Decryption; -}; - -/*! \brief Each class derived from this one defines two types, Encryption and Decryption, - both of which implement the AuthenticatedSymmetricCipher interface. */ -struct AuthenticatedSymmetricCipherDocumentation -{ - //! implements the AuthenticatedSymmetricCipher interface - typedef AuthenticatedSymmetricCipher Encryption; - //! implements the AuthenticatedSymmetricCipher interface - typedef AuthenticatedSymmetricCipher Decryption; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/seed.cpp b/lib/cryptopp/seed.cpp deleted file mode 100644 index 101902dce..000000000 --- a/lib/cryptopp/seed.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// seed.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "seed.h" -#include "misc.h" - -NAMESPACE_BEGIN(CryptoPP) - -static const word32 s_kc[16] = { - 0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc, 0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf, - 0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1, 0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b}; - -static const byte s_s0[256] = { - 0xA9, 0x85, 0xD6, 0xD3, 0x54, 0x1D, 0xAC, 0x25, 0x5D, 0x43, 0x18, 0x1E, 0x51, 0xFC, 0xCA, 0x63, 0x28, - 0x44, 0x20, 0x9D, 0xE0, 0xE2, 0xC8, 0x17, 0xA5, 0x8F, 0x03, 0x7B, 0xBB, 0x13, 0xD2, 0xEE, 0x70, 0x8C, - 0x3F, 0xA8, 0x32, 0xDD, 0xF6, 0x74, 0xEC, 0x95, 0x0B, 0x57, 0x5C, 0x5B, 0xBD, 0x01, 0x24, 0x1C, 0x73, - 0x98, 0x10, 0xCC, 0xF2, 0xD9, 0x2C, 0xE7, 0x72, 0x83, 0x9B, 0xD1, 0x86, 0xC9, 0x60, 0x50, 0xA3, 0xEB, - 0x0D, 0xB6, 0x9E, 0x4F, 0xB7, 0x5A, 0xC6, 0x78, 0xA6, 0x12, 0xAF, 0xD5, 0x61, 0xC3, 0xB4, 0x41, 0x52, - 0x7D, 0x8D, 0x08, 0x1F, 0x99, 0x00, 0x19, 0x04, 0x53, 0xF7, 0xE1, 0xFD, 0x76, 0x2F, 0x27, 0xB0, 0x8B, - 0x0E, 0xAB, 0xA2, 0x6E, 0x93, 0x4D, 0x69, 0x7C, 0x09, 0x0A, 0xBF, 0xEF, 0xF3, 0xC5, 0x87, 0x14, 0xFE, - 0x64, 0xDE, 0x2E, 0x4B, 0x1A, 0x06, 0x21, 0x6B, 0x66, 0x02, 0xF5, 0x92, 0x8A, 0x0C, 0xB3, 0x7E, 0xD0, - 0x7A, 0x47, 0x96, 0xE5, 0x26, 0x80, 0xAD, 0xDF, 0xA1, 0x30, 0x37, 0xAE, 0x36, 0x15, 0x22, 0x38, 0xF4, - 0xA7, 0x45, 0x4C, 0x81, 0xE9, 0x84, 0x97, 0x35, 0xCB, 0xCE, 0x3C, 0x71, 0x11, 0xC7, 0x89, 0x75, 0xFB, - 0xDA, 0xF8, 0x94, 0x59, 0x82, 0xC4, 0xFF, 0x49, 0x39, 0x67, 0xC0, 0xCF, 0xD7, 0xB8, 0x0F, 0x8E, 0x42, - 0x23, 0x91, 0x6C, 0xDB, 0xA4, 0x34, 0xF1, 0x48, 0xC2, 0x6F, 0x3D, 0x2D, 0x40, 0xBE, 0x3E, 0xBC, 0xC1, - 0xAA, 0xBA, 0x4E, 0x55, 0x3B, 0xDC, 0x68, 0x7F, 0x9C, 0xD8, 0x4A, 0x56, 0x77, 0xA0, 0xED, 0x46, 0xB5, - 0x2B, 0x65, 0xFA, 0xE3, 0xB9, 0xB1, 0x9F, 0x5E, 0xF9, 0xE6, 0xB2, 0x31, 0xEA, 0x6D, 0x5F, 0xE4, 0xF0, - 0xCD, 0x88, 0x16, 0x3A, 0x58, 0xD4, 0x62, 0x29, 0x07, 0x33, 0xE8, 0x1B, 0x05, 0x79, 0x90, 0x6A, 0x2A, - 0x9A}; - -static const byte s_s1[256] = { - 0x38, 0xE8, 0x2D, 0xA6, 0xCF, 0xDE, 0xB3, 0xB8, 0xAF, 0x60, 0x55, 0xC7, 0x44, 0x6F, 0x6B, 0x5B, 0xC3, - 0x62, 0x33, 0xB5, 0x29, 0xA0, 0xE2, 0xA7, 0xD3, 0x91, 0x11, 0x06, 0x1C, 0xBC, 0x36, 0x4B, 0xEF, 0x88, - 0x6C, 0xA8, 0x17, 0xC4, 0x16, 0xF4, 0xC2, 0x45, 0xE1, 0xD6, 0x3F, 0x3D, 0x8E, 0x98, 0x28, 0x4E, 0xF6, - 0x3E, 0xA5, 0xF9, 0x0D, 0xDF, 0xD8, 0x2B, 0x66, 0x7A, 0x27, 0x2F, 0xF1, 0x72, 0x42, 0xD4, 0x41, 0xC0, - 0x73, 0x67, 0xAC, 0x8B, 0xF7, 0xAD, 0x80, 0x1F, 0xCA, 0x2C, 0xAA, 0x34, 0xD2, 0x0B, 0xEE, 0xE9, 0x5D, - 0x94, 0x18, 0xF8, 0x57, 0xAE, 0x08, 0xC5, 0x13, 0xCD, 0x86, 0xB9, 0xFF, 0x7D, 0xC1, 0x31, 0xF5, 0x8A, - 0x6A, 0xB1, 0xD1, 0x20, 0xD7, 0x02, 0x22, 0x04, 0x68, 0x71, 0x07, 0xDB, 0x9D, 0x99, 0x61, 0xBE, 0xE6, - 0x59, 0xDD, 0x51, 0x90, 0xDC, 0x9A, 0xA3, 0xAB, 0xD0, 0x81, 0x0F, 0x47, 0x1A, 0xE3, 0xEC, 0x8D, 0xBF, - 0x96, 0x7B, 0x5C, 0xA2, 0xA1, 0x63, 0x23, 0x4D, 0xC8, 0x9E, 0x9C, 0x3A, 0x0C, 0x2E, 0xBA, 0x6E, 0x9F, - 0x5A, 0xF2, 0x92, 0xF3, 0x49, 0x78, 0xCC, 0x15, 0xFB, 0x70, 0x75, 0x7F, 0x35, 0x10, 0x03, 0x64, 0x6D, - 0xC6, 0x74, 0xD5, 0xB4, 0xEA, 0x09, 0x76, 0x19, 0xFE, 0x40, 0x12, 0xE0, 0xBD, 0x05, 0xFA, 0x01, 0xF0, - 0x2A, 0x5E, 0xA9, 0x56, 0x43, 0x85, 0x14, 0x89, 0x9B, 0xB0, 0xE5, 0x48, 0x79, 0x97, 0xFC, 0x1E, 0x82, - 0x21, 0x8C, 0x1B, 0x5F, 0x77, 0x54, 0xB2, 0x1D, 0x25, 0x4F, 0x00, 0x46, 0xED, 0x58, 0x52, 0xEB, 0x7E, - 0xDA, 0xC9, 0xFD, 0x30, 0x95, 0x65, 0x3C, 0xB6, 0xE4, 0xBB, 0x7C, 0x0E, 0x50, 0x39, 0x26, 0x32, 0x84, - 0x69, 0x93, 0x37, 0xE7, 0x24, 0xA4, 0xCB, 0x53, 0x0A, 0x87, 0xD9, 0x4C, 0x83, 0x8F, 0xCE, 0x3B, 0x4A, - 0xB7}; - -#define SS0(x) ((s_s0[x]*0x01010101UL) & 0x3FCFF3FC) -#define SS1(x) ((s_s1[x]*0x01010101UL) & 0xFC3FCFF3) -#define SS2(x) ((s_s0[x]*0x01010101UL) & 0xF3FC3FCF) -#define SS3(x) ((s_s1[x]*0x01010101UL) & 0xCFF3FC3F) -#define G(x) (SS0(GETBYTE(x, 0)) ^ SS1(GETBYTE(x, 1)) ^ SS2(GETBYTE(x, 2)) ^ SS3(GETBYTE(x, 3))) - -void SEED::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) -{ - AssertValidKeyLength(length); - - word64 key01, key23; - GetBlock<word64, BigEndian> get(userKey); - get(key01)(key23); - word32 *k = m_k; - size_t kInc = 2; - if (!IsForwardTransformation()) - { - k = k+30; - kInc = 0-kInc; - } - - for (int i=0; i<ROUNDS; i++) - { - word32 t0 = word32(key01>>32) + word32(key23>>32) - s_kc[i]; - word32 t1 = word32(key01) - word32(key23) + s_kc[i]; - k[0] = G(t0); - k[1] = G(t1); - k+=kInc; - if (i&1) - key23 = rotlFixed<word64>(key23, 8); - else - key01 = rotrFixed<word64>(key01, 8); - } -} - -void SEED::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - typedef BlockGetAndPut<word32, BigEndian> Block; - word32 a0, a1, b0, b1, t0, t1; - Block::Get(inBlock)(a0)(a1)(b0)(b1); - - for (int i=0; i<ROUNDS; i+=2) - { - t0 = b0 ^ m_k[2*i+0]; t1 = b1 ^ m_k[2*i+1] ^ t0; - t1 = G(t1); t0 += t1; t0 = G(t0); t1 += t0; t1 = G(t1); - a0 ^= t0 + t1; a1 ^= t1; - - t0 = a0 ^ m_k[2*i+2]; t1 = a1 ^ m_k[2*i+3] ^ t0; - t1 = G(t1); t0 += t1; t0 = G(t0); t1 += t0; t1 = G(t1); - b0 ^= t0 + t1; b1 ^= t1; - } - - Block::Put(xorBlock, outBlock)(b0)(b1)(a0)(a1); -} - -NAMESPACE_END diff --git a/lib/cryptopp/seed.h b/lib/cryptopp/seed.h deleted file mode 100644 index 871284de7..000000000 --- a/lib/cryptopp/seed.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef CRYPTOPP_SEED_H -#define CRYPTOPP_SEED_H - -/** \file -*/ - -#include "seckey.h" -#include "secblock.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -struct SEED_Info : public FixedBlockSize<16>, public FixedKeyLength<16>, public FixedRounds<16> -{ - static const char *StaticAlgorithmName() {return "SEED";} -}; - -/// <a href="http://www.cryptolounge.org/wiki/SEED">SEED</a> -class SEED : public SEED_Info, public BlockCipherDocumentation -{ - class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<SEED_Info> - { - public: - void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - - protected: - FixedSizeSecBlock<word32, 32> m_k; - }; - -public: - typedef BlockCipherFinal<ENCRYPTION, Base> Encryption; - typedef BlockCipherFinal<DECRYPTION, Base> Decryption; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/sha.cpp b/lib/cryptopp/sha.cpp deleted file mode 100644 index df947ad16..000000000 --- a/lib/cryptopp/sha.cpp +++ /dev/null @@ -1,900 +0,0 @@ -// sha.cpp - modified by Wei Dai from Steve Reid's public domain sha1.c - -// Steve Reid implemented SHA-1. Wei Dai implemented SHA-2. -// Both are in the public domain. - -// use "cl /EP /P /DCRYPTOPP_GENERATE_X64_MASM sha.cpp" to generate MASM code - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS -#ifndef CRYPTOPP_GENERATE_X64_MASM - -#include "sha.h" -#include "misc.h" -#include "cpu.h" - -NAMESPACE_BEGIN(CryptoPP) - -// start of Steve Reid's code - -#define blk0(i) (W[i] = data[i]) -#define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1)) - -void SHA1::InitState(HashWordType *state) -{ - state[0] = 0x67452301L; - state[1] = 0xEFCDAB89L; - state[2] = 0x98BADCFEL; - state[3] = 0x10325476L; - state[4] = 0xC3D2E1F0L; -} - -#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); - -void SHA1::Transform(word32 *state, const word32 *data) -{ - word32 W[16]; - /* Copy context->state[] to working vars */ - word32 a = state[0]; - word32 b = state[1]; - word32 c = state[2]; - word32 d = state[3]; - word32 e = state[4]; - /* 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 context.state[] */ - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; -} - -// end of Steve Reid's code - -// ************************************************************* - -void SHA224::InitState(HashWordType *state) -{ - static const word32 s[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}; - memcpy(state, s, sizeof(s)); -} - -void SHA256::InitState(HashWordType *state) -{ - static const word32 s[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; - memcpy(state, s, sizeof(s)); -} - -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE -CRYPTOPP_ALIGN_DATA(16) extern const word32 SHA256_K[64] CRYPTOPP_SECTION_ALIGN16 = { -#else -extern const word32 SHA256_K[64] = { -#endif - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, - 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, - 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, - 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -}; - -#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM - -#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_GENERATE_X64_MASM) - -#pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code - -static void CRYPTOPP_FASTCALL X86_SHA256_HashBlocks(word32 *state, const word32 *data, size_t len -#if defined(_MSC_VER) && (_MSC_VER == 1200) - , ... // VC60 workaround: prevent VC 6 from inlining this function -#endif - ) -{ -#if defined(_MSC_VER) && (_MSC_VER == 1200) - AS2(mov ecx, [state]) - AS2(mov edx, [data]) -#endif - - #define LOCALS_SIZE 8*4 + 16*4 + 4*WORD_SZ - #define H(i) [BASE+ASM_MOD(1024+7-(i),8)*4] - #define G(i) H(i+1) - #define F(i) H(i+2) - #define E(i) H(i+3) - #define D(i) H(i+4) - #define C(i) H(i+5) - #define B(i) H(i+6) - #define A(i) H(i+7) - #define Wt(i) BASE+8*4+ASM_MOD(1024+15-(i),16)*4 - #define Wt_2(i) Wt((i)-2) - #define Wt_15(i) Wt((i)-15) - #define Wt_7(i) Wt((i)-7) - #define K_END [BASE+8*4+16*4+0*WORD_SZ] - #define STATE_SAVE [BASE+8*4+16*4+1*WORD_SZ] - #define DATA_SAVE [BASE+8*4+16*4+2*WORD_SZ] - #define DATA_END [BASE+8*4+16*4+3*WORD_SZ] - #define Kt(i) WORD_REG(si)+(i)*4 -#if CRYPTOPP_BOOL_X86 - #define BASE esp+4 -#elif defined(__GNUC__) - #define BASE r8 -#else - #define BASE rsp -#endif - -#define RA0(i, edx, edi) \ - AS2( add edx, [Kt(i)] )\ - AS2( add edx, [Wt(i)] )\ - AS2( add edx, H(i) )\ - -#define RA1(i, edx, edi) - -#define RB0(i, edx, edi) - -#define RB1(i, edx, edi) \ - AS2( mov AS_REG_7d, [Wt_2(i)] )\ - AS2( mov edi, [Wt_15(i)])\ - AS2( mov ebx, AS_REG_7d )\ - AS2( shr AS_REG_7d, 10 )\ - AS2( ror ebx, 17 )\ - AS2( xor AS_REG_7d, ebx )\ - AS2( ror ebx, 2 )\ - AS2( xor ebx, AS_REG_7d )/* s1(W_t-2) */\ - AS2( add ebx, [Wt_7(i)])\ - AS2( mov AS_REG_7d, edi )\ - AS2( shr AS_REG_7d, 3 )\ - AS2( ror edi, 7 )\ - AS2( add ebx, [Wt(i)])/* s1(W_t-2) + W_t-7 + W_t-16 */\ - AS2( xor AS_REG_7d, edi )\ - AS2( add edx, [Kt(i)])\ - AS2( ror edi, 11 )\ - AS2( add edx, H(i) )\ - AS2( xor AS_REG_7d, edi )/* s0(W_t-15) */\ - AS2( add AS_REG_7d, ebx )/* W_t = s1(W_t-2) + W_t-7 + s0(W_t-15) W_t-16*/\ - AS2( mov [Wt(i)], AS_REG_7d)\ - AS2( add edx, AS_REG_7d )\ - -#define ROUND(i, r, eax, ecx, edi, edx)\ - /* in: edi = E */\ - /* unused: eax, ecx, temp: ebx, AS_REG_7d, out: edx = T1 */\ - AS2( mov edx, F(i) )\ - AS2( xor edx, G(i) )\ - AS2( and edx, edi )\ - AS2( xor edx, G(i) )/* Ch(E,F,G) = (G^(E&(F^G))) */\ - AS2( mov AS_REG_7d, edi )\ - AS2( ror edi, 6 )\ - AS2( ror AS_REG_7d, 25 )\ - RA##r(i, edx, edi )/* H + Wt + Kt + Ch(E,F,G) */\ - AS2( xor AS_REG_7d, edi )\ - AS2( ror edi, 5 )\ - AS2( xor AS_REG_7d, edi )/* S1(E) */\ - AS2( add edx, AS_REG_7d )/* T1 = S1(E) + Ch(E,F,G) + H + Wt + Kt */\ - RB##r(i, edx, edi )/* H + Wt + Kt + Ch(E,F,G) */\ - /* in: ecx = A, eax = B^C, edx = T1 */\ - /* unused: edx, temp: ebx, AS_REG_7d, out: eax = A, ecx = B^C, edx = E */\ - AS2( mov ebx, ecx )\ - AS2( xor ecx, B(i) )/* A^B */\ - AS2( and eax, ecx )\ - AS2( xor eax, B(i) )/* Maj(A,B,C) = B^((A^B)&(B^C) */\ - AS2( mov AS_REG_7d, ebx )\ - AS2( ror ebx, 2 )\ - AS2( add eax, edx )/* T1 + Maj(A,B,C) */\ - AS2( add edx, D(i) )\ - AS2( mov D(i), edx )\ - AS2( ror AS_REG_7d, 22 )\ - AS2( xor AS_REG_7d, ebx )\ - AS2( ror ebx, 11 )\ - AS2( xor AS_REG_7d, ebx )\ - AS2( add eax, AS_REG_7d )/* T1 + S0(A) + Maj(A,B,C) */\ - AS2( mov H(i), eax )\ - -#define SWAP_COPY(i) \ - AS2( mov WORD_REG(bx), [WORD_REG(dx)+i*WORD_SZ])\ - AS1( bswap WORD_REG(bx))\ - AS2( mov [Wt(i*(1+CRYPTOPP_BOOL_X64)+CRYPTOPP_BOOL_X64)], WORD_REG(bx)) - -#if defined(__GNUC__) - #if CRYPTOPP_BOOL_X64 - FixedSizeAlignedSecBlock<byte, LOCALS_SIZE> workspace; - #endif - __asm__ __volatile__ - ( - #if CRYPTOPP_BOOL_X64 - "lea %4, %%r8;" - #endif - ".intel_syntax noprefix;" -#elif defined(CRYPTOPP_GENERATE_X64_MASM) - ALIGN 8 - X86_SHA256_HashBlocks PROC FRAME - rex_push_reg rsi - push_reg rdi - push_reg rbx - push_reg rbp - alloc_stack(LOCALS_SIZE+8) - .endprolog - mov rdi, r8 - lea rsi, [?SHA256_K@CryptoPP@@3QBIB + 48*4] -#endif - -#if CRYPTOPP_BOOL_X86 - #ifndef __GNUC__ - AS2( mov edi, [len]) - AS2( lea WORD_REG(si), [SHA256_K+48*4]) - #endif - #if !defined(_MSC_VER) || (_MSC_VER < 1400) - AS_PUSH_IF86(bx) - #endif - - AS_PUSH_IF86(bp) - AS2( mov ebx, esp) - AS2( and esp, -16) - AS2( sub WORD_REG(sp), LOCALS_SIZE) - AS_PUSH_IF86(bx) -#endif - AS2( mov STATE_SAVE, WORD_REG(cx)) - AS2( mov DATA_SAVE, WORD_REG(dx)) - AS2( lea WORD_REG(ax), [WORD_REG(di) + WORD_REG(dx)]) - AS2( mov DATA_END, WORD_REG(ax)) - AS2( mov K_END, WORD_REG(si)) - -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE -#if CRYPTOPP_BOOL_X86 - AS2( test edi, 1) - ASJ( jnz, 2, f) - AS1( dec DWORD PTR K_END) -#endif - AS2( movdqa xmm0, XMMWORD_PTR [WORD_REG(cx)+0*16]) - AS2( movdqa xmm1, XMMWORD_PTR [WORD_REG(cx)+1*16]) -#endif - -#if CRYPTOPP_BOOL_X86 -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - ASJ( jmp, 0, f) -#endif - ASL(2) // non-SSE2 - AS2( mov esi, ecx) - AS2( lea edi, A(0)) - AS2( mov ecx, 8) - AS1( rep movsd) - AS2( mov esi, K_END) - ASJ( jmp, 3, f) -#endif - -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - ASL(0) - AS2( movdqa E(0), xmm1) - AS2( movdqa A(0), xmm0) -#endif -#if CRYPTOPP_BOOL_X86 - ASL(3) -#endif - AS2( sub WORD_REG(si), 48*4) - SWAP_COPY(0) SWAP_COPY(1) SWAP_COPY(2) SWAP_COPY(3) - SWAP_COPY(4) SWAP_COPY(5) SWAP_COPY(6) SWAP_COPY(7) -#if CRYPTOPP_BOOL_X86 - SWAP_COPY(8) SWAP_COPY(9) SWAP_COPY(10) SWAP_COPY(11) - SWAP_COPY(12) SWAP_COPY(13) SWAP_COPY(14) SWAP_COPY(15) -#endif - AS2( mov edi, E(0)) // E - AS2( mov eax, B(0)) // B - AS2( xor eax, C(0)) // B^C - AS2( mov ecx, A(0)) // A - - ROUND(0, 0, eax, ecx, edi, edx) - ROUND(1, 0, ecx, eax, edx, edi) - ROUND(2, 0, eax, ecx, edi, edx) - ROUND(3, 0, ecx, eax, edx, edi) - ROUND(4, 0, eax, ecx, edi, edx) - ROUND(5, 0, ecx, eax, edx, edi) - ROUND(6, 0, eax, ecx, edi, edx) - ROUND(7, 0, ecx, eax, edx, edi) - ROUND(8, 0, eax, ecx, edi, edx) - ROUND(9, 0, ecx, eax, edx, edi) - ROUND(10, 0, eax, ecx, edi, edx) - ROUND(11, 0, ecx, eax, edx, edi) - ROUND(12, 0, eax, ecx, edi, edx) - ROUND(13, 0, ecx, eax, edx, edi) - ROUND(14, 0, eax, ecx, edi, edx) - ROUND(15, 0, ecx, eax, edx, edi) - - ASL(1) - AS2(add WORD_REG(si), 4*16) - ROUND(0, 1, eax, ecx, edi, edx) - ROUND(1, 1, ecx, eax, edx, edi) - ROUND(2, 1, eax, ecx, edi, edx) - ROUND(3, 1, ecx, eax, edx, edi) - ROUND(4, 1, eax, ecx, edi, edx) - ROUND(5, 1, ecx, eax, edx, edi) - ROUND(6, 1, eax, ecx, edi, edx) - ROUND(7, 1, ecx, eax, edx, edi) - ROUND(8, 1, eax, ecx, edi, edx) - ROUND(9, 1, ecx, eax, edx, edi) - ROUND(10, 1, eax, ecx, edi, edx) - ROUND(11, 1, ecx, eax, edx, edi) - ROUND(12, 1, eax, ecx, edi, edx) - ROUND(13, 1, ecx, eax, edx, edi) - ROUND(14, 1, eax, ecx, edi, edx) - ROUND(15, 1, ecx, eax, edx, edi) - AS2( cmp WORD_REG(si), K_END) - ASJ( jb, 1, b) - - AS2( mov WORD_REG(dx), DATA_SAVE) - AS2( add WORD_REG(dx), 64) - AS2( mov AS_REG_7, STATE_SAVE) - AS2( mov DATA_SAVE, WORD_REG(dx)) - -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE -#if CRYPTOPP_BOOL_X86 - AS2( test DWORD PTR K_END, 1) - ASJ( jz, 4, f) -#endif - AS2( movdqa xmm1, XMMWORD_PTR [AS_REG_7+1*16]) - AS2( movdqa xmm0, XMMWORD_PTR [AS_REG_7+0*16]) - AS2( paddd xmm1, E(0)) - AS2( paddd xmm0, A(0)) - AS2( movdqa [AS_REG_7+1*16], xmm1) - AS2( movdqa [AS_REG_7+0*16], xmm0) - AS2( cmp WORD_REG(dx), DATA_END) - ASJ( jb, 0, b) -#endif - -#if CRYPTOPP_BOOL_X86 -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - ASJ( jmp, 5, f) - ASL(4) // non-SSE2 -#endif - AS2( add [AS_REG_7+0*4], ecx) // A - AS2( add [AS_REG_7+4*4], edi) // E - AS2( mov eax, B(0)) - AS2( mov ebx, C(0)) - AS2( mov ecx, D(0)) - AS2( add [AS_REG_7+1*4], eax) - AS2( add [AS_REG_7+2*4], ebx) - AS2( add [AS_REG_7+3*4], ecx) - AS2( mov eax, F(0)) - AS2( mov ebx, G(0)) - AS2( mov ecx, H(0)) - AS2( add [AS_REG_7+5*4], eax) - AS2( add [AS_REG_7+6*4], ebx) - AS2( add [AS_REG_7+7*4], ecx) - AS2( mov ecx, AS_REG_7d) - AS2( cmp WORD_REG(dx), DATA_END) - ASJ( jb, 2, b) -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - ASL(5) -#endif -#endif - - AS_POP_IF86(sp) - AS_POP_IF86(bp) - #if !defined(_MSC_VER) || (_MSC_VER < 1400) - AS_POP_IF86(bx) - #endif - -#ifdef CRYPTOPP_GENERATE_X64_MASM - add rsp, LOCALS_SIZE+8 - pop rbp - pop rbx - pop rdi - pop rsi - ret - X86_SHA256_HashBlocks ENDP -#endif - -#ifdef __GNUC__ - ".att_syntax prefix;" - : - : "c" (state), "d" (data), "S" (SHA256_K+48), "D" (len) - #if CRYPTOPP_BOOL_X64 - , "m" (workspace[0]) - #endif - : "memory", "cc", "%eax" - #if CRYPTOPP_BOOL_X64 - , "%rbx", "%r8", "%r10" - #endif - ); -#endif -} - -#endif // #if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_GENERATE_X64_MASM) - -#ifndef CRYPTOPP_GENERATE_X64_MASM - -#ifdef CRYPTOPP_X64_MASM_AVAILABLE -extern "C" { -void CRYPTOPP_FASTCALL X86_SHA256_HashBlocks(word32 *state, const word32 *data, size_t len); -} -#endif - -#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE) - -size_t SHA256::HashMultipleBlocks(const word32 *input, size_t length) -{ - X86_SHA256_HashBlocks(m_state, input, (length&(size_t(0)-BLOCKSIZE)) - !HasSSE2()); - return length % BLOCKSIZE; -} - -size_t SHA224::HashMultipleBlocks(const word32 *input, size_t length) -{ - X86_SHA256_HashBlocks(m_state, input, (length&(size_t(0)-BLOCKSIZE)) - !HasSSE2()); - return length % BLOCKSIZE; -} - -#endif - -#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) (y^((x^y)&(y^z))) - -#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 R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\ - d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) - -// for SHA256 -#define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22)) -#define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25)) -#define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3)) -#define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10)) - -void SHA256::Transform(word32 *state, const word32 *data) -{ - word32 W[16]; -#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE) - // this byte reverse is a waste of time, but this function is only called by MDC - ByteReverse(W, data, BLOCKSIZE); - X86_SHA256_HashBlocks(state, W, BLOCKSIZE - !HasSSE2()); -#else - word32 T[8]; - /* Copy context->state[] to working vars */ - memcpy(T, state, sizeof(T)); - /* 64 operations, partially loop unrolled */ - for (unsigned int j=0; j<64; 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 context.state[] */ - state[0] += a(0); - state[1] += b(0); - state[2] += c(0); - state[3] += d(0); - state[4] += e(0); - state[5] += f(0); - state[6] += g(0); - state[7] += h(0); -#endif -} - -/* -// smaller but slower -void SHA256::Transform(word32 *state, const word32 *data) -{ - word32 T[20]; - word32 W[32]; - unsigned int i = 0, j = 0; - word32 *t = T+8; - - memcpy(t, state, 8*4); - word32 e = t[4], a = t[0]; - - do - { - word32 w = data[j]; - W[j] = w; - w += SHA256_K[j]; - w += t[7]; - w += S1(e); - w += Ch(e, t[5], t[6]); - e = t[3] + w; - t[3] = t[3+8] = e; - w += S0(t[0]); - a = w + Maj(a, t[1], t[2]); - t[-1] = t[7] = a; - --t; - ++j; - if (j%8 == 0) - t += 8; - } while (j<16); - - do - { - i = j&0xf; - word32 w = s1(W[i+16-2]) + s0(W[i+16-15]) + W[i] + W[i+16-7]; - W[i+16] = W[i] = w; - w += SHA256_K[j]; - w += t[7]; - w += S1(e); - w += Ch(e, t[5], t[6]); - e = t[3] + w; - t[3] = t[3+8] = e; - w += S0(t[0]); - a = w + Maj(a, t[1], t[2]); - t[-1] = t[7] = a; - - w = s1(W[(i+1)+16-2]) + s0(W[(i+1)+16-15]) + W[(i+1)] + W[(i+1)+16-7]; - W[(i+1)+16] = W[(i+1)] = w; - w += SHA256_K[j+1]; - w += (t-1)[7]; - w += S1(e); - w += Ch(e, (t-1)[5], (t-1)[6]); - e = (t-1)[3] + w; - (t-1)[3] = (t-1)[3+8] = e; - w += S0((t-1)[0]); - a = w + Maj(a, (t-1)[1], (t-1)[2]); - (t-1)[-1] = (t-1)[7] = a; - - t-=2; - j+=2; - if (j%8 == 0) - t += 8; - } while (j<64); - - state[0] += a; - state[1] += t[1]; - state[2] += t[2]; - state[3] += t[3]; - state[4] += e; - state[5] += t[5]; - state[6] += t[6]; - state[7] += t[7]; -} -*/ - -#undef S0 -#undef S1 -#undef s0 -#undef s1 -#undef R - -// ************************************************************* - -void SHA384::InitState(HashWordType *state) -{ - static const word64 s[8] = { - W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507), - W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939), - W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511), - W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4)}; - memcpy(state, s, sizeof(s)); -} - -void SHA512::InitState(HashWordType *state) -{ - static const word64 s[8] = { - W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b), - W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1), - W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f), - W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)}; - memcpy(state, s, sizeof(s)); -} - -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 -CRYPTOPP_ALIGN_DATA(16) static const word64 SHA512_K[80] CRYPTOPP_SECTION_ALIGN16 = { -#else -static const word64 SHA512_K[80] = { -#endif - 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) -}; - -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 -// put assembly version in separate function, otherwise MSVC 2005 SP1 doesn't generate correct code for the non-assembly version -CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state, const word64 *data) -{ -#ifdef __GNUC__ - __asm__ __volatile__ - ( - ".intel_syntax noprefix;" - AS1( push ebx) - AS2( mov ebx, eax) -#else - AS1( push ebx) - AS1( push esi) - AS1( push edi) - AS2( lea ebx, SHA512_K) -#endif - - AS2( mov eax, esp) - AS2( and esp, 0xfffffff0) - AS2( sub esp, 27*16) // 17*16 for expanded data, 20*8 for state - AS1( push eax) - AS2( xor eax, eax) - AS2( lea edi, [esp+4+8*8]) // start at middle of state buffer. will decrement pointer each round to avoid copying - AS2( lea esi, [esp+4+20*8+8]) // 16-byte alignment, then add 8 - - AS2( movdqa xmm0, [ecx+0*16]) - AS2( movdq2q mm4, xmm0) - AS2( movdqa [edi+0*16], xmm0) - AS2( movdqa xmm0, [ecx+1*16]) - AS2( movdqa [edi+1*16], xmm0) - AS2( movdqa xmm0, [ecx+2*16]) - AS2( movdq2q mm5, xmm0) - AS2( movdqa [edi+2*16], xmm0) - AS2( movdqa xmm0, [ecx+3*16]) - AS2( movdqa [edi+3*16], xmm0) - ASJ( jmp, 0, f) - -#define SSE2_S0_S1(r, a, b, c) \ - AS2( movq mm6, r)\ - AS2( psrlq r, a)\ - AS2( movq mm7, r)\ - AS2( psllq mm6, 64-c)\ - AS2( pxor mm7, mm6)\ - AS2( psrlq r, b-a)\ - AS2( pxor mm7, r)\ - AS2( psllq mm6, c-b)\ - AS2( pxor mm7, mm6)\ - AS2( psrlq r, c-b)\ - AS2( pxor r, mm7)\ - AS2( psllq mm6, b-a)\ - AS2( pxor r, mm6) - -#define SSE2_s0(r, a, b, c) \ - AS2( movdqa xmm6, r)\ - AS2( psrlq r, a)\ - AS2( movdqa xmm7, r)\ - AS2( psllq xmm6, 64-c)\ - AS2( pxor xmm7, xmm6)\ - AS2( psrlq r, b-a)\ - AS2( pxor xmm7, r)\ - AS2( psrlq r, c-b)\ - AS2( pxor r, xmm7)\ - AS2( psllq xmm6, c-a)\ - AS2( pxor r, xmm6) - -#define SSE2_s1(r, a, b, c) \ - AS2( movdqa xmm6, r)\ - AS2( psrlq r, a)\ - AS2( movdqa xmm7, r)\ - AS2( psllq xmm6, 64-c)\ - AS2( pxor xmm7, xmm6)\ - AS2( psrlq r, b-a)\ - AS2( pxor xmm7, r)\ - AS2( psllq xmm6, c-b)\ - AS2( pxor xmm7, xmm6)\ - AS2( psrlq r, c-b)\ - AS2( pxor r, xmm7) - - ASL(SHA512_Round) - // k + w is in mm0, a is in mm4, e is in mm5 - AS2( paddq mm0, [edi+7*8]) // h - AS2( movq mm2, [edi+5*8]) // f - AS2( movq mm3, [edi+6*8]) // g - AS2( pxor mm2, mm3) - AS2( pand mm2, mm5) - SSE2_S0_S1(mm5,14,18,41) - AS2( pxor mm2, mm3) - AS2( paddq mm0, mm2) // h += Ch(e,f,g) - AS2( paddq mm5, mm0) // h += S1(e) - AS2( movq mm2, [edi+1*8]) // b - AS2( movq mm1, mm2) - AS2( por mm2, mm4) - AS2( pand mm2, [edi+2*8]) // c - AS2( pand mm1, mm4) - AS2( por mm1, mm2) - AS2( paddq mm1, mm5) // temp = h + Maj(a,b,c) - AS2( paddq mm5, [edi+3*8]) // e = d + h - AS2( movq [edi+3*8], mm5) - AS2( movq [edi+11*8], mm5) - SSE2_S0_S1(mm4,28,34,39) // S0(a) - AS2( paddq mm4, mm1) // a = temp + S0(a) - AS2( movq [edi-8], mm4) - AS2( movq [edi+7*8], mm4) - AS1( ret) - - // first 16 rounds - ASL(0) - AS2( movq mm0, [edx+eax*8]) - AS2( movq [esi+eax*8], mm0) - AS2( movq [esi+eax*8+16*8], mm0) - AS2( paddq mm0, [ebx+eax*8]) - ASC( call, SHA512_Round) - AS1( inc eax) - AS2( sub edi, 8) - AS2( test eax, 7) - ASJ( jnz, 0, b) - AS2( add edi, 8*8) - AS2( cmp eax, 16) - ASJ( jne, 0, b) - - // rest of the rounds - AS2( movdqu xmm0, [esi+(16-2)*8]) - ASL(1) - // data expansion, W[i-2] already in xmm0 - AS2( movdqu xmm3, [esi]) - AS2( paddq xmm3, [esi+(16-7)*8]) - AS2( movdqa xmm2, [esi+(16-15)*8]) - SSE2_s1(xmm0, 6, 19, 61) - AS2( paddq xmm0, xmm3) - SSE2_s0(xmm2, 1, 7, 8) - AS2( paddq xmm0, xmm2) - AS2( movdq2q mm0, xmm0) - AS2( movhlps xmm1, xmm0) - AS2( paddq mm0, [ebx+eax*8]) - AS2( movlps [esi], xmm0) - AS2( movlps [esi+8], xmm1) - AS2( movlps [esi+8*16], xmm0) - AS2( movlps [esi+8*17], xmm1) - // 2 rounds - ASC( call, SHA512_Round) - AS2( sub edi, 8) - AS2( movdq2q mm0, xmm1) - AS2( paddq mm0, [ebx+eax*8+8]) - ASC( call, SHA512_Round) - // update indices and loop - AS2( add esi, 16) - AS2( add eax, 2) - AS2( sub edi, 8) - AS2( test eax, 7) - ASJ( jnz, 1, b) - // do housekeeping every 8 rounds - AS2( mov esi, 0xf) - AS2( and esi, eax) - AS2( lea esi, [esp+4+20*8+8+esi*8]) - AS2( add edi, 8*8) - AS2( cmp eax, 80) - ASJ( jne, 1, b) - -#define SSE2_CombineState(i) \ - AS2( movdqa xmm0, [edi+i*16])\ - AS2( paddq xmm0, [ecx+i*16])\ - AS2( movdqa [ecx+i*16], xmm0) - - SSE2_CombineState(0) - SSE2_CombineState(1) - SSE2_CombineState(2) - SSE2_CombineState(3) - - AS1( pop esp) - AS1( emms) - -#if defined(__GNUC__) - AS1( pop ebx) - ".att_syntax prefix;" - : - : "a" (SHA512_K), "c" (state), "d" (data) - : "%esi", "%edi", "memory", "cc" - ); -#else - AS1( pop edi) - AS1( pop esi) - AS1( pop ebx) - AS1( ret) -#endif -} -#endif // #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - -void SHA512::Transform(word64 *state, const word64 *data) -{ -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 - if (HasSSE2()) - { - SHA512_SSE2_Transform(state, data); - return; - } -#endif - -#define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39)) -#define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41)) -#define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7)) -#define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6)) - -#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA512_K[i+j]+(j?blk2(i):blk0(i));\ - d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) - - word64 W[16]; - word64 T[8]; - /* Copy context->state[] to working vars */ - memcpy(T, state, sizeof(T)); - /* 80 operations, partially loop unrolled */ - for (unsigned int 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 context.state[] */ - state[0] += a(0); - state[1] += b(0); - state[2] += c(0); - state[3] += d(0); - state[4] += e(0); - state[5] += f(0); - state[6] += g(0); - state[7] += h(0); -} - -NAMESPACE_END - -#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM -#endif // #ifndef CRYPTOPP_IMPORTS diff --git a/lib/cryptopp/sha.h b/lib/cryptopp/sha.h deleted file mode 100644 index 679081e8f..000000000 --- a/lib/cryptopp/sha.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef CRYPTOPP_SHA_H -#define CRYPTOPP_SHA_H - -#include "iterhash.h" - -NAMESPACE_BEGIN(CryptoPP) - -/// <a href="http://www.weidai.com/scan-mirror/md.html#SHA-1">SHA-1</a> -class CRYPTOPP_DLL SHA1 : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 20, SHA1> -{ -public: - static void CRYPTOPP_API InitState(HashWordType *state); - static void CRYPTOPP_API Transform(word32 *digest, const word32 *data); - static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-1";} -}; - -typedef SHA1 SHA; // for backwards compatibility - -//! implements the SHA-256 standard -class CRYPTOPP_DLL SHA256 : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 32, SHA256, 32, true> -{ -public: -#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE) - size_t HashMultipleBlocks(const word32 *input, size_t length); -#endif - static void CRYPTOPP_API InitState(HashWordType *state); - static void CRYPTOPP_API Transform(word32 *digest, const word32 *data); - static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-256";} -}; - -//! implements the SHA-224 standard -class CRYPTOPP_DLL SHA224 : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 32, SHA224, 28, true> -{ -public: -#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE) - size_t HashMultipleBlocks(const word32 *input, size_t length); -#endif - static void CRYPTOPP_API InitState(HashWordType *state); - static void CRYPTOPP_API Transform(word32 *digest, const word32 *data) {SHA256::Transform(digest, data);} - static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-224";} -}; - -//! implements the SHA-512 standard -class CRYPTOPP_DLL SHA512 : public IteratedHashWithStaticTransform<word64, BigEndian, 128, 64, SHA512, 64, CRYPTOPP_BOOL_X86> -{ -public: - static void CRYPTOPP_API InitState(HashWordType *state); - static void CRYPTOPP_API Transform(word64 *digest, const word64 *data); - static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-512";} -}; - -//! implements the SHA-384 standard -class CRYPTOPP_DLL SHA384 : public IteratedHashWithStaticTransform<word64, BigEndian, 128, 64, SHA384, 48, CRYPTOPP_BOOL_X86> -{ -public: - static void CRYPTOPP_API InitState(HashWordType *state); - static void CRYPTOPP_API Transform(word64 *digest, const word64 *data) {SHA512::Transform(digest, data);} - static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-384";} -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/shacal2.cpp b/lib/cryptopp/shacal2.cpp deleted file mode 100644 index b0360e404..000000000 --- a/lib/cryptopp/shacal2.cpp +++ /dev/null @@ -1,140 +0,0 @@ -// shacal2.cpp - by Kevin Springle, 2003 -// -// Portions of this code were derived from -// Wei Dai's implementation of SHA-2 -// -// The original code and all modifications are in the public domain. - -#include "pch.h" -#include "shacal2.h" -#include "misc.h" - -NAMESPACE_BEGIN(CryptoPP) - -// SHACAL-2 function and round definitions - -#define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22)) -#define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25)) -#define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3)) -#define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10)) - -#define Ch(x,y,z) (z^(x&(y^z))) -#define Maj(x,y,z) ((x&y)|(z&(x|y))) - -/* R is the SHA-256 round function. */ -/* This macro increments the k argument as a side effect. */ -#define R(a,b,c,d,e,f,g,h,k) \ - h+=S1(e)+Ch(e,f,g)+*k++;d+=h;h+=S0(a)+Maj(a,b,c); - -/* P is the inverse of the SHA-256 round function. */ -/* This macro decrements the k argument as a side effect. */ -#define P(a,b,c,d,e,f,g,h,k) \ - h-=S0(a)+Maj(a,b,c);d-=h;h-=S1(e)+Ch(e,f,g)+*--k; - -void SHACAL2::Base::UncheckedSetKey(const byte *userKey, unsigned int keylen, const NameValuePairs &) -{ - AssertValidKeyLength(keylen); - - word32 *rk = m_key; - unsigned int i; - - GetUserKey(BIG_ENDIAN_ORDER, rk, m_key.size(), userKey, keylen); - for (i = 0; i < 48; i++, rk++) - { - rk[16] = rk[0] + s0(rk[1]) + rk[9] + s1(rk[14]); - rk[0] += K[i]; - } - for (i = 48; i < 64; i++, rk++) - { - rk[0] += K[i]; - } -} - -typedef BlockGetAndPut<word32, BigEndian> Block; - -void SHACAL2::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - word32 a, b, c, d, e, f, g, h; - const word32 *rk = m_key; - - /* - * map byte array block to cipher state: - */ - Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h); - - // Perform SHA-256 transformation. - - /* 64 operations, partially loop unrolled */ - for (unsigned int j=0; j<64; j+=8) - { - R(a,b,c,d,e,f,g,h,rk); - R(h,a,b,c,d,e,f,g,rk); - R(g,h,a,b,c,d,e,f,rk); - R(f,g,h,a,b,c,d,e,rk); - R(e,f,g,h,a,b,c,d,rk); - R(d,e,f,g,h,a,b,c,rk); - R(c,d,e,f,g,h,a,b,rk); - R(b,c,d,e,f,g,h,a,rk); - } - - /* - * map cipher state to byte array block: - */ - - Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h); -} - -void SHACAL2::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - word32 a, b, c, d, e, f, g, h; - const word32 *rk = m_key + 64; - - /* - * map byte array block to cipher state: - */ - Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h); - - // Perform inverse SHA-256 transformation. - - /* 64 operations, partially loop unrolled */ - for (unsigned int j=0; j<64; j+=8) - { - P(b,c,d,e,f,g,h,a,rk); - P(c,d,e,f,g,h,a,b,rk); - P(d,e,f,g,h,a,b,c,rk); - P(e,f,g,h,a,b,c,d,rk); - P(f,g,h,a,b,c,d,e,rk); - P(g,h,a,b,c,d,e,f,rk); - P(h,a,b,c,d,e,f,g,rk); - P(a,b,c,d,e,f,g,h,rk); - } - - /* - * map cipher state to byte array block: - */ - - Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h); -} - -// The SHACAL-2 round constants are identical to the SHA-256 round constants. -const word32 SHACAL2::Base::K[64] = -{ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, - 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, - 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, - 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -}; - -NAMESPACE_END diff --git a/lib/cryptopp/shacal2.h b/lib/cryptopp/shacal2.h deleted file mode 100644 index 66c987fd7..000000000 --- a/lib/cryptopp/shacal2.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef CRYPTOPP_SHACAL2_H -#define CRYPTOPP_SHACAL2_H - -/** \file -*/ - -#include "seckey.h" -#include "secblock.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -struct SHACAL2_Info : public FixedBlockSize<32>, public VariableKeyLength<16, 16, 64> -{ - static const char *StaticAlgorithmName() {return "SHACAL-2";} -}; - -/// <a href="http://www.weidai.com/scan-mirror/cs.html#SHACAL-2">SHACAL-2</a> -class SHACAL2 : public SHACAL2_Info, public BlockCipherDocumentation -{ - class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<SHACAL2_Info> - { - public: - void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); - - protected: - FixedSizeSecBlock<word32, 64> m_key; - - static const word32 K[64]; - }; - - class CRYPTOPP_NO_VTABLE Enc : public Base - { - public: - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - }; - - class CRYPTOPP_NO_VTABLE Dec : public Base - { - public: - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - }; - -public: - typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption; - typedef BlockCipherFinal<DECRYPTION, Dec> Decryption; -}; - -typedef SHACAL2::Encryption SHACAL2Encryption; -typedef SHACAL2::Decryption SHACAL2Decryption; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/simple.cpp b/lib/cryptopp/simple.cpp deleted file mode 100644 index 96f256b40..000000000 --- a/lib/cryptopp/simple.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// simple.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "simple.h" -#include "secblock.h" - -NAMESPACE_BEGIN(CryptoPP) - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/simple.h b/lib/cryptopp/simple.h deleted file mode 100644 index 35fd65ae4..000000000 --- a/lib/cryptopp/simple.h +++ /dev/null @@ -1,209 +0,0 @@ -// simple.h - written and placed in the public domain by Wei Dai -/*! \file - Simple non-interface classes derived from classes in cryptlib.h. -*/ - -#ifndef CRYPTOPP_SIMPLE_H -#define CRYPTOPP_SIMPLE_H - -#include "cryptlib.h" -#include "misc.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -template <class DERIVED, class BASE> -class CRYPTOPP_NO_VTABLE ClonableImpl : public BASE -{ -public: - Clonable * Clone() const {return new DERIVED(*static_cast<const DERIVED *>(this));} -}; - -//! _ -template <class BASE, class ALGORITHM_INFO=BASE> -class CRYPTOPP_NO_VTABLE AlgorithmImpl : public BASE -{ -public: - static std::string CRYPTOPP_API StaticAlgorithmName() {return ALGORITHM_INFO::StaticAlgorithmName();} - std::string AlgorithmName() const {return ALGORITHM_INFO::StaticAlgorithmName();} -}; - -//! _ -class CRYPTOPP_DLL InvalidKeyLength : public InvalidArgument -{ -public: - explicit InvalidKeyLength(const std::string &algorithm, size_t length) : InvalidArgument(algorithm + ": " + IntToString(length) + " is not a valid key length") {} -}; - -//! _ -class CRYPTOPP_DLL InvalidRounds : public InvalidArgument -{ -public: - explicit InvalidRounds(const std::string &algorithm, unsigned int rounds) : InvalidArgument(algorithm + ": " + IntToString(rounds) + " is not a valid number of rounds") {} -}; - -// ***************************** - -//! _ -template <class T> -class CRYPTOPP_NO_VTABLE Bufferless : public T -{ -public: - bool IsolatedFlush(bool hardFlush, bool blocking) {return false;} -}; - -//! _ -template <class T> -class CRYPTOPP_NO_VTABLE Unflushable : public T -{ -public: - bool Flush(bool completeFlush, int propagation=-1, bool blocking=true) - {return ChannelFlush(DEFAULT_CHANNEL, completeFlush, propagation, blocking);} - bool IsolatedFlush(bool hardFlush, bool blocking) - {assert(false); return false;} - bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true) - { - if (hardFlush && !InputBufferIsEmpty()) - throw CannotFlush("Unflushable<T>: this object has buffered input that cannot be flushed"); - else - { - BufferedTransformation *attached = this->AttachedTransformation(); - return attached && propagation ? attached->ChannelFlush(channel, hardFlush, propagation-1, blocking) : false; - } - } - -protected: - virtual bool InputBufferIsEmpty() const {return false;} -}; - -//! _ -template <class T> -class CRYPTOPP_NO_VTABLE InputRejecting : public T -{ -public: - struct InputRejected : public NotImplemented - {InputRejected() : NotImplemented("BufferedTransformation: this object doesn't allow input") {}}; - - // shouldn't be calling these functions on this class - size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) - {throw InputRejected();} - bool IsolatedFlush(bool, bool) {return false;} - bool IsolatedMessageSeriesEnd(bool) {throw InputRejected();} - - size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) - {throw InputRejected();} - bool ChannelMessageSeriesEnd(const std::string &, int, bool) {throw InputRejected();} -}; - -//! _ -template <class T> -class CRYPTOPP_NO_VTABLE CustomFlushPropagation : public T -{ -public: - virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) =0; - -private: - bool IsolatedFlush(bool hardFlush, bool blocking) {assert(false); return false;} -}; - -//! _ -template <class T> -class CRYPTOPP_NO_VTABLE CustomSignalPropagation : public CustomFlushPropagation<T> -{ -public: - virtual void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1) =0; - -private: - void IsolatedInitialize(const NameValuePairs ¶meters) {assert(false);} -}; - -//! _ -template <class T> -class CRYPTOPP_NO_VTABLE Multichannel : public CustomFlushPropagation<T> -{ -public: - bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) - {return this->ChannelFlush(DEFAULT_CHANNEL, hardFlush, propagation, blocking);} - bool MessageSeriesEnd(int propagation=-1, bool blocking=true) - {return this->ChannelMessageSeriesEnd(DEFAULT_CHANNEL, propagation, blocking);} - byte * CreatePutSpace(size_t &size) - {return this->ChannelCreatePutSpace(DEFAULT_CHANNEL, size);} - size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) - {return this->ChannelPut2(DEFAULT_CHANNEL, begin, length, messageEnd, blocking);} - size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking) - {return this->ChannelPutModifiable2(DEFAULT_CHANNEL, inString, length, messageEnd, blocking);} - -// void ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1) -// {PropagateMessageSeriesEnd(propagation, channel);} - byte * ChannelCreatePutSpace(const std::string &channel, size_t &size) - {size = 0; return NULL;} - bool ChannelPutModifiable(const std::string &channel, byte *inString, size_t length) - {this->ChannelPut(channel, inString, length); return false;} - - virtual size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) =0; - size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking) - {return ChannelPut2(channel, begin, length, messageEnd, blocking);} - - virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true) =0; -}; - -//! _ -template <class T> -class CRYPTOPP_NO_VTABLE AutoSignaling : public T -{ -public: - AutoSignaling(int propagation=-1) : m_autoSignalPropagation(propagation) {} - - void SetAutoSignalPropagation(int propagation) - {m_autoSignalPropagation = propagation;} - int GetAutoSignalPropagation() const - {return m_autoSignalPropagation;} - -private: - int m_autoSignalPropagation; -}; - -//! A BufferedTransformation that only contains pre-existing data as "output" -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Store : public AutoSignaling<InputRejecting<BufferedTransformation> > -{ -public: - Store() : m_messageEnd(false) {} - - void IsolatedInitialize(const NameValuePairs ¶meters) - { - m_messageEnd = false; - StoreInitialize(parameters); - } - - unsigned int NumberOfMessages() const {return m_messageEnd ? 0 : 1;} - bool GetNextMessage(); - unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) const; - -protected: - virtual void StoreInitialize(const NameValuePairs ¶meters) =0; - - bool m_messageEnd; -}; - -//! A BufferedTransformation that doesn't produce any retrievable output -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Sink : public BufferedTransformation -{ -public: - size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) - {transferBytes = 0; return 0;} - size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const - {return 0;} -}; - -class CRYPTOPP_DLL BitBucket : public Bufferless<Sink> -{ -public: - std::string AlgorithmName() const {return "BitBucket";} - void IsolatedInitialize(const NameValuePairs ¶meters) {} - size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) - {return 0;} -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/smartptr.h b/lib/cryptopp/smartptr.h deleted file mode 100644 index a0a727edc..000000000 --- a/lib/cryptopp/smartptr.h +++ /dev/null @@ -1,223 +0,0 @@ -#ifndef CRYPTOPP_SMARTPTR_H -#define CRYPTOPP_SMARTPTR_H - -#include "config.h" -#include <algorithm> - -NAMESPACE_BEGIN(CryptoPP) - -template <class T> class simple_ptr -{ -public: - simple_ptr(T *p = NULL) : m_p(p) {} - ~simple_ptr() {delete m_p; m_p = NULL;} // set m_p to NULL so double destruction (which might occur in Singleton) will be harmless - T *m_p; -}; - -template <class T> class member_ptr -{ -public: - explicit member_ptr(T *p = NULL) : m_p(p) {} - - ~member_ptr(); - - const T& operator*() const { return *m_p; } - T& operator*() { return *m_p; } - - const T* operator->() const { return m_p; } - T* operator->() { return m_p; } - - const T* get() const { return m_p; } - T* get() { return m_p; } - - T* release() - { - T *old_p = m_p; - m_p = 0; - return old_p; - } - - void reset(T *p = 0); - -protected: - member_ptr(const member_ptr<T>& rhs); // copy not allowed - void operator=(const member_ptr<T>& rhs); // assignment not allowed - - T *m_p; -}; - -template <class T> member_ptr<T>::~member_ptr() {delete m_p;} -template <class T> void member_ptr<T>::reset(T *p) {delete m_p; m_p = p;} - -// ******************************************************** - -template<class T> class value_ptr : public member_ptr<T> -{ -public: - value_ptr(const T &obj) : member_ptr<T>(new T(obj)) {} - value_ptr(T *p = NULL) : member_ptr<T>(p) {} - value_ptr(const value_ptr<T>& rhs) - : member_ptr<T>(rhs.m_p ? new T(*rhs.m_p) : NULL) {} - - value_ptr<T>& operator=(const value_ptr<T>& rhs); - bool operator==(const value_ptr<T>& rhs) - { - return (!this->m_p && !rhs.m_p) || (this->m_p && rhs.m_p && *this->m_p == *rhs.m_p); - } -}; - -template <class T> value_ptr<T>& value_ptr<T>::operator=(const value_ptr<T>& rhs) -{ - T *old_p = this->m_p; - this->m_p = rhs.m_p ? new T(*rhs.m_p) : NULL; - delete old_p; - return *this; -} - -// ******************************************************** - -template<class T> class clonable_ptr : public member_ptr<T> -{ -public: - clonable_ptr(const T &obj) : member_ptr<T>(obj.Clone()) {} - clonable_ptr(T *p = NULL) : member_ptr<T>(p) {} - clonable_ptr(const clonable_ptr<T>& rhs) - : member_ptr<T>(rhs.m_p ? rhs.m_p->Clone() : NULL) {} - - clonable_ptr<T>& operator=(const clonable_ptr<T>& rhs); -}; - -template <class T> clonable_ptr<T>& clonable_ptr<T>::operator=(const clonable_ptr<T>& rhs) -{ - T *old_p = this->m_p; - this->m_p = rhs.m_p ? rhs.m_p->Clone() : NULL; - delete old_p; - return *this; -} - -// ******************************************************** - -template<class T> class counted_ptr -{ -public: - explicit counted_ptr(T *p = 0); - counted_ptr(const T &r) : m_p(0) {attach(r);} - counted_ptr(const counted_ptr<T>& rhs); - - ~counted_ptr(); - - const T& operator*() const { return *m_p; } - T& operator*() { return *m_p; } - - const T* operator->() const { return m_p; } - T* operator->() { return get(); } - - const T* get() const { return m_p; } - T* get(); - - void attach(const T &p); - - counted_ptr<T> & operator=(const counted_ptr<T>& rhs); - -private: - T *m_p; -}; - -template <class T> counted_ptr<T>::counted_ptr(T *p) - : m_p(p) -{ - if (m_p) - m_p->m_referenceCount = 1; -} - -template <class T> counted_ptr<T>::counted_ptr(const counted_ptr<T>& rhs) - : m_p(rhs.m_p) -{ - if (m_p) - m_p->m_referenceCount++; -} - -template <class T> counted_ptr<T>::~counted_ptr() -{ - if (m_p && --m_p->m_referenceCount == 0) - delete m_p; -} - -template <class T> void counted_ptr<T>::attach(const T &r) -{ - if (m_p && --m_p->m_referenceCount == 0) - delete m_p; - if (r.m_referenceCount == 0) - { - m_p = r.clone(); - m_p->m_referenceCount = 1; - } - else - { - m_p = const_cast<T *>(&r); - m_p->m_referenceCount++; - } -} - -template <class T> T* counted_ptr<T>::get() -{ - if (m_p && m_p->m_referenceCount > 1) - { - T *temp = m_p->clone(); - m_p->m_referenceCount--; - m_p = temp; - m_p->m_referenceCount = 1; - } - return m_p; -} - -template <class T> counted_ptr<T> & counted_ptr<T>::operator=(const counted_ptr<T>& rhs) -{ - if (m_p != rhs.m_p) - { - if (m_p && --m_p->m_referenceCount == 0) - delete m_p; - m_p = rhs.m_p; - if (m_p) - m_p->m_referenceCount++; - } - return *this; -} - -// ******************************************************** - -template <class T> class vector_member_ptrs -{ -public: - vector_member_ptrs(size_t size=0) - : m_size(size), m_ptr(new member_ptr<T>[size]) {} - ~vector_member_ptrs() - {delete [] this->m_ptr;} - - member_ptr<T>& operator[](size_t index) - {assert(index<this->m_size); return this->m_ptr[index];} - const member_ptr<T>& operator[](size_t index) const - {assert(index<this->m_size); return this->m_ptr[index];} - - size_t size() const {return this->m_size;} - void resize(size_t newSize) - { - member_ptr<T> *newPtr = new member_ptr<T>[newSize]; - for (size_t i=0; i<this->m_size && i<newSize; i++) - newPtr[i].reset(this->m_ptr[i].release()); - delete [] this->m_ptr; - this->m_size = newSize; - this->m_ptr = newPtr; - } - -private: - vector_member_ptrs(const vector_member_ptrs<T> &c); // copy not allowed - void operator=(const vector_member_ptrs<T> &x); // assignment not allowed - - size_t m_size; - member_ptr<T> *m_ptr; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/socketft.cpp b/lib/cryptopp/socketft.cpp deleted file mode 100644 index 6c5a8ff9d..000000000 --- a/lib/cryptopp/socketft.cpp +++ /dev/null @@ -1,531 +0,0 @@ -// socketft.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "socketft.h" - -#ifdef SOCKETS_AVAILABLE - -#include "wait.h" - -#ifdef USE_BERKELEY_STYLE_SOCKETS -#include <errno.h> -#include <netdb.h> -#include <unistd.h> -#include <arpa/inet.h> -#include <netinet/in.h> -#include <sys/ioctl.h> -#endif - -NAMESPACE_BEGIN(CryptoPP) - -#ifdef USE_WINDOWS_STYLE_SOCKETS -const int SOCKET_EINVAL = WSAEINVAL; -const int SOCKET_EWOULDBLOCK = WSAEWOULDBLOCK; -typedef int socklen_t; -#else -const int SOCKET_EINVAL = EINVAL; -const int SOCKET_EWOULDBLOCK = EWOULDBLOCK; -#endif - -Socket::Err::Err(socket_t s, const std::string& operation, int error) - : OS_Error(IO_ERROR, "Socket: " + operation + " operation failed with error " + IntToString(error), operation, error) - , m_s(s) -{ -} - -Socket::~Socket() -{ - if (m_own) - { - try - { - CloseSocket(); - } - catch (...) - { - } - } -} - -void Socket::AttachSocket(socket_t s, bool own) -{ - if (m_own) - CloseSocket(); - - m_s = s; - m_own = own; - SocketChanged(); -} - -socket_t Socket::DetachSocket() -{ - socket_t s = m_s; - m_s = INVALID_SOCKET; - SocketChanged(); - return s; -} - -void Socket::Create(int nType) -{ - assert(m_s == INVALID_SOCKET); - m_s = socket(AF_INET, nType, 0); - CheckAndHandleError("socket", m_s); - m_own = true; - SocketChanged(); -} - -void Socket::CloseSocket() -{ - if (m_s != INVALID_SOCKET) - { -#ifdef USE_WINDOWS_STYLE_SOCKETS - CancelIo((HANDLE) m_s); - CheckAndHandleError_int("closesocket", closesocket(m_s)); -#else - CheckAndHandleError_int("close", close(m_s)); -#endif - m_s = INVALID_SOCKET; - SocketChanged(); - } -} - -void Socket::Bind(unsigned int port, const char *addr) -{ - sockaddr_in sa; - memset(&sa, 0, sizeof(sa)); - sa.sin_family = AF_INET; - - if (addr == NULL) - sa.sin_addr.s_addr = htonl(INADDR_ANY); - else - { - unsigned long result = inet_addr(addr); - if (result == -1) // Solaris doesn't have INADDR_NONE - { - SetLastError(SOCKET_EINVAL); - CheckAndHandleError_int("inet_addr", SOCKET_ERROR); - } - sa.sin_addr.s_addr = result; - } - - sa.sin_port = htons((u_short)port); - - Bind((sockaddr *)&sa, sizeof(sa)); -} - -void Socket::Bind(const sockaddr *psa, socklen_t saLen) -{ - assert(m_s != INVALID_SOCKET); - // cygwin workaround: needs const_cast - CheckAndHandleError_int("bind", bind(m_s, const_cast<sockaddr *>(psa), saLen)); -} - -void Socket::Listen(int backlog) -{ - assert(m_s != INVALID_SOCKET); - CheckAndHandleError_int("listen", listen(m_s, backlog)); -} - -bool Socket::Connect(const char *addr, unsigned int port) -{ - assert(addr != NULL); - - sockaddr_in sa; - memset(&sa, 0, sizeof(sa)); - sa.sin_family = AF_INET; - sa.sin_addr.s_addr = inet_addr(addr); - - if (sa.sin_addr.s_addr == -1) // Solaris doesn't have INADDR_NONE - { - hostent *lphost = gethostbyname(addr); - if (lphost == NULL) - { - SetLastError(SOCKET_EINVAL); - CheckAndHandleError_int("gethostbyname", SOCKET_ERROR); - } - - sa.sin_addr.s_addr = ((in_addr *)lphost->h_addr)->s_addr; - } - - sa.sin_port = htons((u_short)port); - - return Connect((const sockaddr *)&sa, sizeof(sa)); -} - -bool Socket::Connect(const sockaddr* psa, socklen_t saLen) -{ - assert(m_s != INVALID_SOCKET); - int result = connect(m_s, const_cast<sockaddr*>(psa), saLen); - if (result == SOCKET_ERROR && GetLastError() == SOCKET_EWOULDBLOCK) - return false; - CheckAndHandleError_int("connect", result); - return true; -} - -bool Socket::Accept(Socket& target, sockaddr *psa, socklen_t *psaLen) -{ - assert(m_s != INVALID_SOCKET); - socket_t s = accept(m_s, psa, psaLen); - if (s == INVALID_SOCKET && GetLastError() == SOCKET_EWOULDBLOCK) - return false; - CheckAndHandleError("accept", s); - target.AttachSocket(s, true); - return true; -} - -void Socket::GetSockName(sockaddr *psa, socklen_t *psaLen) -{ - assert(m_s != INVALID_SOCKET); - CheckAndHandleError_int("getsockname", getsockname(m_s, psa, psaLen)); -} - -void Socket::GetPeerName(sockaddr *psa, socklen_t *psaLen) -{ - assert(m_s != INVALID_SOCKET); - CheckAndHandleError_int("getpeername", getpeername(m_s, psa, psaLen)); -} - -unsigned int Socket::Send(const byte* buf, size_t bufLen, int flags) -{ - assert(m_s != INVALID_SOCKET); - int result = send(m_s, (const char *)buf, UnsignedMin(INT_MAX, bufLen), flags); - CheckAndHandleError_int("send", result); - return result; -} - -unsigned int Socket::Receive(byte* buf, size_t bufLen, int flags) -{ - assert(m_s != INVALID_SOCKET); - int result = recv(m_s, (char *)buf, UnsignedMin(INT_MAX, bufLen), flags); - CheckAndHandleError_int("recv", result); - return result; -} - -void Socket::ShutDown(int how) -{ - assert(m_s != INVALID_SOCKET); - int result = shutdown(m_s, how); - CheckAndHandleError_int("shutdown", result); -} - -void Socket::IOCtl(long cmd, unsigned long *argp) -{ - assert(m_s != INVALID_SOCKET); -#ifdef USE_WINDOWS_STYLE_SOCKETS - CheckAndHandleError_int("ioctlsocket", ioctlsocket(m_s, cmd, argp)); -#else - CheckAndHandleError_int("ioctl", ioctl(m_s, cmd, argp)); -#endif -} - -bool Socket::SendReady(const timeval *timeout) -{ - fd_set fds; - FD_ZERO(&fds); - FD_SET(m_s, &fds); - int ready; - if (timeout == NULL) - ready = select((int)m_s+1, NULL, &fds, NULL, NULL); - else - { - timeval timeoutCopy = *timeout; // select() modified timeout on Linux - ready = select((int)m_s+1, NULL, &fds, NULL, &timeoutCopy); - } - CheckAndHandleError_int("select", ready); - return ready > 0; -} - -bool Socket::ReceiveReady(const timeval *timeout) -{ - fd_set fds; - FD_ZERO(&fds); - FD_SET(m_s, &fds); - int ready; - if (timeout == NULL) - ready = select((int)m_s+1, &fds, NULL, NULL, NULL); - else - { - timeval timeoutCopy = *timeout; // select() modified timeout on Linux - ready = select((int)m_s+1, &fds, NULL, NULL, &timeoutCopy); - } - CheckAndHandleError_int("select", ready); - return ready > 0; -} - -unsigned int Socket::PortNameToNumber(const char *name, const char *protocol) -{ - int port = atoi(name); - if (IntToString(port) == name) - return port; - - servent *se = getservbyname(name, protocol); - if (!se) - throw Err(INVALID_SOCKET, "getservbyname", SOCKET_EINVAL); - return ntohs(se->s_port); -} - -void Socket::StartSockets() -{ -#ifdef USE_WINDOWS_STYLE_SOCKETS - WSADATA wsd; - int result = WSAStartup(0x0202, &wsd); - if (result != 0) - throw Err(INVALID_SOCKET, "WSAStartup", result); -#endif -} - -void Socket::ShutdownSockets() -{ -#ifdef USE_WINDOWS_STYLE_SOCKETS - int result = WSACleanup(); - if (result != 0) - throw Err(INVALID_SOCKET, "WSACleanup", result); -#endif -} - -int Socket::GetLastError() -{ -#ifdef USE_WINDOWS_STYLE_SOCKETS - return WSAGetLastError(); -#else - return errno; -#endif -} - -void Socket::SetLastError(int errorCode) -{ -#ifdef USE_WINDOWS_STYLE_SOCKETS - WSASetLastError(errorCode); -#else - errno = errorCode; -#endif -} - -void Socket::HandleError(const char *operation) const -{ - int err = GetLastError(); - throw Err(m_s, operation, err); -} - -#ifdef USE_WINDOWS_STYLE_SOCKETS - -SocketReceiver::SocketReceiver(Socket &s) - : m_s(s), m_resultPending(false), m_eofReceived(false) -{ - m_event.AttachHandle(CreateEvent(NULL, true, false, NULL), true); - m_s.CheckAndHandleError("CreateEvent", m_event.HandleValid()); - memset(&m_overlapped, 0, sizeof(m_overlapped)); - m_overlapped.hEvent = m_event; -} - -SocketReceiver::~SocketReceiver() -{ -#ifdef USE_WINDOWS_STYLE_SOCKETS - CancelIo((HANDLE) m_s.GetSocket()); -#endif -} - -bool SocketReceiver::Receive(byte* buf, size_t bufLen) -{ - assert(!m_resultPending && !m_eofReceived); - - DWORD flags = 0; - // don't queue too much at once, or we might use up non-paged memory - WSABUF wsabuf = {UnsignedMin((u_long)128*1024, bufLen), (char *)buf}; - if (WSARecv(m_s, &wsabuf, 1, &m_lastResult, &flags, &m_overlapped, NULL) == 0) - { - if (m_lastResult == 0) - m_eofReceived = true; - } - else - { - switch (WSAGetLastError()) - { - default: - m_s.CheckAndHandleError_int("WSARecv", SOCKET_ERROR); - case WSAEDISCON: - m_lastResult = 0; - m_eofReceived = true; - break; - case WSA_IO_PENDING: - m_resultPending = true; - } - } - return !m_resultPending; -} - -void SocketReceiver::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) -{ - if (m_resultPending) - container.AddHandle(m_event, CallStack("SocketReceiver::GetWaitObjects() - result pending", &callStack)); - else if (!m_eofReceived) - container.SetNoWait(CallStack("SocketReceiver::GetWaitObjects() - result ready", &callStack)); -} - -unsigned int SocketReceiver::GetReceiveResult() -{ - if (m_resultPending) - { - DWORD flags = 0; - if (WSAGetOverlappedResult(m_s, &m_overlapped, &m_lastResult, false, &flags)) - { - if (m_lastResult == 0) - m_eofReceived = true; - } - else - { - switch (WSAGetLastError()) - { - default: - m_s.CheckAndHandleError("WSAGetOverlappedResult", FALSE); - case WSAEDISCON: - m_lastResult = 0; - m_eofReceived = true; - } - } - m_resultPending = false; - } - return m_lastResult; -} - -// ************************************************************* - -SocketSender::SocketSender(Socket &s) - : m_s(s), m_resultPending(false), m_lastResult(0) -{ - m_event.AttachHandle(CreateEvent(NULL, true, false, NULL), true); - m_s.CheckAndHandleError("CreateEvent", m_event.HandleValid()); - memset(&m_overlapped, 0, sizeof(m_overlapped)); - m_overlapped.hEvent = m_event; -} - - -SocketSender::~SocketSender() -{ -#ifdef USE_WINDOWS_STYLE_SOCKETS - CancelIo((HANDLE) m_s.GetSocket()); -#endif -} - -void SocketSender::Send(const byte* buf, size_t bufLen) -{ - assert(!m_resultPending); - DWORD written = 0; - // don't queue too much at once, or we might use up non-paged memory - WSABUF wsabuf = {UnsignedMin((u_long)128*1024, bufLen), (char *)buf}; - if (WSASend(m_s, &wsabuf, 1, &written, 0, &m_overlapped, NULL) == 0) - { - m_resultPending = false; - m_lastResult = written; - } - else - { - if (WSAGetLastError() != WSA_IO_PENDING) - m_s.CheckAndHandleError_int("WSASend", SOCKET_ERROR); - - m_resultPending = true; - } -} - -void SocketSender::SendEof() -{ - assert(!m_resultPending); - m_s.ShutDown(SD_SEND); - m_s.CheckAndHandleError("ResetEvent", ResetEvent(m_event)); - m_s.CheckAndHandleError_int("WSAEventSelect", WSAEventSelect(m_s, m_event, FD_CLOSE)); - m_resultPending = true; -} - -bool SocketSender::EofSent() -{ - if (m_resultPending) - { - WSANETWORKEVENTS events; - m_s.CheckAndHandleError_int("WSAEnumNetworkEvents", WSAEnumNetworkEvents(m_s, m_event, &events)); - if ((events.lNetworkEvents & FD_CLOSE) != FD_CLOSE) - throw Socket::Err(m_s, "WSAEnumNetworkEvents (FD_CLOSE not present)", E_FAIL); - if (events.iErrorCode[FD_CLOSE_BIT] != 0) - throw Socket::Err(m_s, "FD_CLOSE (via WSAEnumNetworkEvents)", events.iErrorCode[FD_CLOSE_BIT]); - m_resultPending = false; - } - return m_lastResult != 0; -} - -void SocketSender::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) -{ - if (m_resultPending) - container.AddHandle(m_event, CallStack("SocketSender::GetWaitObjects() - result pending", &callStack)); - else - container.SetNoWait(CallStack("SocketSender::GetWaitObjects() - result ready", &callStack)); -} - -unsigned int SocketSender::GetSendResult() -{ - if (m_resultPending) - { - DWORD flags = 0; - BOOL result = WSAGetOverlappedResult(m_s, &m_overlapped, &m_lastResult, false, &flags); - m_s.CheckAndHandleError("WSAGetOverlappedResult", result); - m_resultPending = false; - } - return m_lastResult; -} - -#endif - -#ifdef USE_BERKELEY_STYLE_SOCKETS - -SocketReceiver::SocketReceiver(Socket &s) - : m_s(s), m_lastResult(0), m_eofReceived(false) -{ -} - -void SocketReceiver::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) -{ - if (!m_eofReceived) - container.AddReadFd(m_s, CallStack("SocketReceiver::GetWaitObjects()", &callStack)); -} - -bool SocketReceiver::Receive(byte* buf, size_t bufLen) -{ - m_lastResult = m_s.Receive(buf, bufLen); - if (bufLen > 0 && m_lastResult == 0) - m_eofReceived = true; - return true; -} - -unsigned int SocketReceiver::GetReceiveResult() -{ - return m_lastResult; -} - -SocketSender::SocketSender(Socket &s) - : m_s(s), m_lastResult(0) -{ -} - -void SocketSender::Send(const byte* buf, size_t bufLen) -{ - m_lastResult = m_s.Send(buf, bufLen); -} - -void SocketSender::SendEof() -{ - m_s.ShutDown(SD_SEND); -} - -unsigned int SocketSender::GetSendResult() -{ - return m_lastResult; -} - -void SocketSender::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) -{ - container.AddWriteFd(m_s, CallStack("SocketSender::GetWaitObjects()", &callStack)); -} - -#endif - -NAMESPACE_END - -#endif // #ifdef SOCKETS_AVAILABLE diff --git a/lib/cryptopp/socketft.h b/lib/cryptopp/socketft.h deleted file mode 100644 index e414aa68f..000000000 --- a/lib/cryptopp/socketft.h +++ /dev/null @@ -1,224 +0,0 @@ -#ifndef CRYPTOPP_SOCKETFT_H -#define CRYPTOPP_SOCKETFT_H - -#include "config.h" - -#ifdef SOCKETS_AVAILABLE - -#include "network.h" -#include "queue.h" - -#ifdef USE_WINDOWS_STYLE_SOCKETS -# if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_) -# error Winsock 1 is not supported by this library. Please include this file or winsock2.h before windows.h. -# endif -#include <winsock2.h> -#include "winpipes.h" -#else -#include <sys/time.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <unistd.h> -#endif - -NAMESPACE_BEGIN(CryptoPP) - -#ifdef USE_WINDOWS_STYLE_SOCKETS -typedef ::SOCKET socket_t; -#else -typedef int socket_t; -const socket_t INVALID_SOCKET = -1; -// cygwin 1.1.4 doesn't have SHUT_RD -const int SD_RECEIVE = 0; -const int SD_SEND = 1; -const int SD_BOTH = 2; -const int SOCKET_ERROR = -1; -#endif - -#ifndef socklen_t -typedef TYPE_OF_SOCKLEN_T socklen_t; // see config.h -#endif - -//! wrapper for Windows or Berkeley Sockets -class Socket -{ -public: - //! exception thrown by Socket class - class Err : public OS_Error - { - public: - Err(socket_t s, const std::string& operation, int error); - socket_t GetSocket() const {return m_s;} - - private: - socket_t m_s; - }; - - Socket(socket_t s = INVALID_SOCKET, bool own=false) : m_s(s), m_own(own) {} - Socket(const Socket &s) : m_s(s.m_s), m_own(false) {} - virtual ~Socket(); - - bool GetOwnership() const {return m_own;} - void SetOwnership(bool own) {m_own = own;} - - operator socket_t() {return m_s;} - socket_t GetSocket() const {return m_s;} - void AttachSocket(socket_t s, bool own=false); - socket_t DetachSocket(); - void CloseSocket(); - - void Create(int nType = SOCK_STREAM); - void Bind(unsigned int port, const char *addr=NULL); - void Bind(const sockaddr* psa, socklen_t saLen); - void Listen(int backlog=5); - // the next three functions return false if the socket is in nonblocking mode - // and the operation cannot be completed immediately - bool Connect(const char *addr, unsigned int port); - bool Connect(const sockaddr* psa, socklen_t saLen); - bool Accept(Socket& s, sockaddr *psa=NULL, socklen_t *psaLen=NULL); - void GetSockName(sockaddr *psa, socklen_t *psaLen); - void GetPeerName(sockaddr *psa, socklen_t *psaLen); - unsigned int Send(const byte* buf, size_t bufLen, int flags=0); - unsigned int Receive(byte* buf, size_t bufLen, int flags=0); - void ShutDown(int how = SD_SEND); - - void IOCtl(long cmd, unsigned long *argp); - bool SendReady(const timeval *timeout); - bool ReceiveReady(const timeval *timeout); - - virtual void HandleError(const char *operation) const; - void CheckAndHandleError_int(const char *operation, int result) const - {if (result == SOCKET_ERROR) HandleError(operation);} - void CheckAndHandleError(const char *operation, socket_t result) const - {if (result == SOCKET_ERROR) HandleError(operation);} -#ifdef USE_WINDOWS_STYLE_SOCKETS - void CheckAndHandleError(const char *operation, BOOL result) const - {assert(result==TRUE || result==FALSE); if (!result) HandleError(operation);} - void CheckAndHandleError(const char *operation, bool result) const - {if (!result) HandleError(operation);} -#endif - - //! look up the port number given its name, returns 0 if not found - static unsigned int PortNameToNumber(const char *name, const char *protocol="tcp"); - //! start Windows Sockets 2 - static void StartSockets(); - //! calls WSACleanup for Windows Sockets - static void ShutdownSockets(); - //! returns errno or WSAGetLastError - static int GetLastError(); - //! sets errno or calls WSASetLastError - static void SetLastError(int errorCode); - -protected: - virtual void SocketChanged() {} - - socket_t m_s; - bool m_own; -}; - -class SocketsInitializer -{ -public: - SocketsInitializer() {Socket::StartSockets();} - ~SocketsInitializer() {try {Socket::ShutdownSockets();} catch (...) {}} -}; - -class SocketReceiver : public NetworkReceiver -{ -public: - SocketReceiver(Socket &s); - -#ifdef USE_BERKELEY_STYLE_SOCKETS - bool MustWaitToReceive() {return true;} -#else - ~SocketReceiver(); - bool MustWaitForResult() {return true;} -#endif - bool Receive(byte* buf, size_t bufLen); - unsigned int GetReceiveResult(); - bool EofReceived() const {return m_eofReceived;} - - unsigned int GetMaxWaitObjectCount() const {return 1;} - void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); - -private: - Socket &m_s; - bool m_eofReceived; - -#ifdef USE_WINDOWS_STYLE_SOCKETS - WindowsHandle m_event; - OVERLAPPED m_overlapped; - bool m_resultPending; - DWORD m_lastResult; -#else - unsigned int m_lastResult; -#endif -}; - -class SocketSender : public NetworkSender -{ -public: - SocketSender(Socket &s); - -#ifdef USE_BERKELEY_STYLE_SOCKETS - bool MustWaitToSend() {return true;} -#else - ~SocketSender(); - bool MustWaitForResult() {return true;} - bool MustWaitForEof() { return true; } - bool EofSent(); -#endif - void Send(const byte* buf, size_t bufLen); - unsigned int GetSendResult(); - void SendEof(); - - unsigned int GetMaxWaitObjectCount() const {return 1;} - void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); - -private: - Socket &m_s; -#ifdef USE_WINDOWS_STYLE_SOCKETS - WindowsHandle m_event; - OVERLAPPED m_overlapped; - bool m_resultPending; - DWORD m_lastResult; -#else - unsigned int m_lastResult; -#endif -}; - -//! socket-based implementation of NetworkSource -class SocketSource : public NetworkSource, public Socket -{ -public: - SocketSource(socket_t s = INVALID_SOCKET, bool pumpAll = false, BufferedTransformation *attachment = NULL) - : NetworkSource(attachment), Socket(s), m_receiver(*this) - { - if (pumpAll) - PumpAll(); - } - -private: - NetworkReceiver & AccessReceiver() {return m_receiver;} - SocketReceiver m_receiver; -}; - -//! socket-based implementation of NetworkSink -class SocketSink : public NetworkSink, public Socket -{ -public: - SocketSink(socket_t s=INVALID_SOCKET, unsigned int maxBufferSize=0, unsigned int autoFlushBound=16*1024) - : NetworkSink(maxBufferSize, autoFlushBound), Socket(s), m_sender(*this) {} - - void SendEof() {ShutDown(SD_SEND);} - -private: - NetworkSender & AccessSender() {return m_sender;} - SocketSender m_sender; -}; - -NAMESPACE_END - -#endif // #ifdef SOCKETS_AVAILABLE - -#endif diff --git a/lib/cryptopp/square.cpp b/lib/cryptopp/square.cpp deleted file mode 100644 index 00e6bddbe..000000000 --- a/lib/cryptopp/square.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// square.cpp - written and placed in the public domain by Wei Dai -// Based on Paulo S.L.M. Barreto's public domain implementation - -#include "pch.h" -#include "square.h" -#include "misc.h" -#include "gf256.h" - -NAMESPACE_BEGIN(CryptoPP) - -// apply theta to a roundkey -static void SquareTransform (word32 in[4], word32 out[4]) -{ - static const byte G[4][4] = - { - 0x02U, 0x01U, 0x01U, 0x03U, - 0x03U, 0x02U, 0x01U, 0x01U, - 0x01U, 0x03U, 0x02U, 0x01U, - 0x01U, 0x01U, 0x03U, 0x02U - }; - - GF256 gf256(0xf5); - - for (int i = 0; i < 4; i++) - { - word32 temp = 0; - for (int j = 0; j < 4; j++) - for (int k = 0; k < 4; k++) - temp ^= (word32)gf256.Multiply(GETBYTE(in[i], 3-k), G[k][j]) << ((3-j)*8); - out[i] = temp; - } -} - -#define roundkeys(i, j) m_roundkeys[(i)*4+(j)] -#define roundkeys4(i) (m_roundkeys+(i)*4) - -void Square::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) -{ - AssertValidKeyLength(length); - - static const word32 offset[ROUNDS] = { - 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL, - 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL, - }; - - GetUserKey(BIG_ENDIAN_ORDER, m_roundkeys.data(), KEYLENGTH/4, userKey, KEYLENGTH); - - /* apply the key evolution function */ - for (int i = 1; i < ROUNDS+1; i++) - { - roundkeys(i, 0) = roundkeys(i-1, 0) ^ rotlFixed(roundkeys(i-1, 3), 8U) ^ offset[i-1]; - roundkeys(i, 1) = roundkeys(i-1, 1) ^ roundkeys(i, 0); - roundkeys(i, 2) = roundkeys(i-1, 2) ^ roundkeys(i, 1); - roundkeys(i, 3) = roundkeys(i-1, 3) ^ roundkeys(i, 2); - } - - /* produce the round keys */ - if (IsForwardTransformation()) - { - for (int i = 0; i < ROUNDS; i++) - SquareTransform (roundkeys4(i), roundkeys4(i)); - } - else - { - for (int i = 0; i < ROUNDS/2; i++) - for (int j = 0; j < 4; j++) - std::swap(roundkeys(i, j), roundkeys(ROUNDS-i, j)); - SquareTransform (roundkeys4(ROUNDS), roundkeys4(ROUNDS)); - } -} - -#define MSB(x) (((x) >> 24) & 0xffU) /* most significant byte */ -#define SSB(x) (((x) >> 16) & 0xffU) /* second in significance */ -#define TSB(x) (((x) >> 8) & 0xffU) /* third in significance */ -#define LSB(x) (((x) ) & 0xffU) /* least significant byte */ - -#define squareRound(text, temp, T0, T1, T2, T3, roundkey) \ -{ \ - temp[0] = T0[MSB (text[0])] \ - ^ T1[MSB (text[1])] \ - ^ T2[MSB (text[2])] \ - ^ T3[MSB (text[3])] \ - ^ roundkey[0]; \ - temp[1] = T0[SSB (text[0])] \ - ^ T1[SSB (text[1])] \ - ^ T2[SSB (text[2])] \ - ^ T3[SSB (text[3])] \ - ^ roundkey[1]; \ - temp[2] = T0[TSB (text[0])] \ - ^ T1[TSB (text[1])] \ - ^ T2[TSB (text[2])] \ - ^ T3[TSB (text[3])] \ - ^ roundkey[2]; \ - temp[3] = T0[LSB (text[0])] \ - ^ T1[LSB (text[1])] \ - ^ T2[LSB (text[2])] \ - ^ T3[LSB (text[3])] \ - ^ roundkey[3]; \ -} /* squareRound */ - -#define squareFinal(text, temp, S, roundkey) \ -{ \ - text[0] = ((word32) (S[MSB (temp[0])]) << 24) \ - ^ ((word32) (S[MSB (temp[1])]) << 16) \ - ^ ((word32) (S[MSB (temp[2])]) << 8) \ - ^ (word32) (S[MSB (temp[3])]) \ - ^ roundkey[0]; \ - text[1] = ((word32) (S[SSB (temp[0])]) << 24) \ - ^ ((word32) (S[SSB (temp[1])]) << 16) \ - ^ ((word32) (S[SSB (temp[2])]) << 8) \ - ^ (word32) (S[SSB (temp[3])]) \ - ^ roundkey[1]; \ - text[2] = ((word32) (S[TSB (temp[0])]) << 24) \ - ^ ((word32) (S[TSB (temp[1])]) << 16) \ - ^ ((word32) (S[TSB (temp[2])]) << 8) \ - ^ (word32) (S[TSB (temp[3])]) \ - ^ roundkey[2]; \ - text[3] = ((word32) (S[LSB (temp[0])]) << 24) \ - ^ ((word32) (S[LSB (temp[1])]) << 16) \ - ^ ((word32) (S[LSB (temp[2])]) << 8) \ - ^ (word32) (S[LSB (temp[3])]) \ - ^ roundkey[3]; \ -} /* squareFinal */ - -typedef BlockGetAndPut<word32, BigEndian> Block; - -void Square::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - word32 text[4], temp[4]; - Block::Get(inBlock)(text[0])(text[1])(text[2])(text[3]); - - /* initial key addition */ - text[0] ^= roundkeys(0, 0); - text[1] ^= roundkeys(0, 1); - text[2] ^= roundkeys(0, 2); - text[3] ^= roundkeys(0, 3); - - /* ROUNDS - 1 full rounds */ - for (int i=1; i+1<ROUNDS; i+=2) - { - squareRound (text, temp, Te[0], Te[1], Te[2], Te[3], roundkeys4(i)); - squareRound (temp, text, Te[0], Te[1], Te[2], Te[3], roundkeys4(i+1)); - } - squareRound (text, temp, Te[0], Te[1], Te[2], Te[3], roundkeys4(ROUNDS-1)); - - /* last round (diffusion becomes only transposition) */ - squareFinal (text, temp, Se, roundkeys4(ROUNDS)); - - Block::Put(xorBlock, outBlock)(text[0])(text[1])(text[2])(text[3]); -} - -void Square::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - word32 text[4], temp[4]; - Block::Get(inBlock)(text[0])(text[1])(text[2])(text[3]); - - /* initial key addition */ - text[0] ^= roundkeys(0, 0); - text[1] ^= roundkeys(0, 1); - text[2] ^= roundkeys(0, 2); - text[3] ^= roundkeys(0, 3); - - /* ROUNDS - 1 full rounds */ - for (int i=1; i+1<ROUNDS; i+=2) - { - squareRound (text, temp, Td[0], Td[1], Td[2], Td[3], roundkeys4(i)); - squareRound (temp, text, Td[0], Td[1], Td[2], Td[3], roundkeys4(i+1)); - } - squareRound (text, temp, Td[0], Td[1], Td[2], Td[3], roundkeys4(ROUNDS-1)); - - /* last round (diffusion becomes only transposition) */ - squareFinal (text, temp, Sd, roundkeys4(ROUNDS)); - - Block::Put(xorBlock, outBlock)(text[0])(text[1])(text[2])(text[3]); -} - -NAMESPACE_END diff --git a/lib/cryptopp/square.h b/lib/cryptopp/square.h deleted file mode 100644 index d7e23c284..000000000 --- a/lib/cryptopp/square.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef CRYPTOPP_SQUARE_H -#define CRYPTOPP_SQUARE_H - -/** \file -*/ - -#include "seckey.h" -#include "secblock.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -struct Square_Info : public FixedBlockSize<16>, public FixedKeyLength<16>, FixedRounds<8> -{ - static const char *StaticAlgorithmName() {return "Square";} -}; - -/// <a href="http://www.weidai.com/scan-mirror/cs.html#Square">Square</a> -class Square : public Square_Info, public BlockCipherDocumentation -{ - class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<Square_Info> - { - public: - void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); - - protected: - FixedSizeSecBlock<word32, 4*(ROUNDS+1)> m_roundkeys; - }; - - class CRYPTOPP_NO_VTABLE Enc : public Base - { - public: - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - private: - static const byte Se[256]; - static const word32 Te[4][256]; - }; - - class CRYPTOPP_NO_VTABLE Dec : public Base - { - public: - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - private: - static const byte Sd[256]; - static const word32 Td[4][256]; - }; - -public: - typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption; - typedef BlockCipherFinal<DECRYPTION, Dec> Decryption; -}; - -typedef Square::Encryption SquareEncryption; -typedef Square::Decryption SquareDecryption; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/squaretb.cpp b/lib/cryptopp/squaretb.cpp deleted file mode 100644 index bc3bee7df..000000000 --- a/lib/cryptopp/squaretb.cpp +++ /dev/null @@ -1,582 +0,0 @@ -#include "pch.h" -#include "square.h" - -NAMESPACE_BEGIN(CryptoPP) - -const byte Square::Enc::Se[256] = { -177, 206, 195, 149, 90, 173, 231, 2, 77, 68, 251, 145, 12, 135, 161, 80, -203, 103, 84, 221, 70, 143, 225, 78, 240, 253, 252, 235, 249, 196, 26, 110, - 94, 245, 204, 141, 28, 86, 67, 254, 7, 97, 248, 117, 89, 255, 3, 34, -138, 209, 19, 238, 136, 0, 14, 52, 21, 128, 148, 227, 237, 181, 83, 35, - 75, 71, 23, 167, 144, 53, 171, 216, 184, 223, 79, 87, 154, 146, 219, 27, - 60, 200, 153, 4, 142, 224, 215, 125, 133, 187, 64, 44, 58, 69, 241, 66, -101, 32, 65, 24, 114, 37, 147, 112, 54, 5, 242, 11, 163, 121, 236, 8, - 39, 49, 50, 182, 124, 176, 10, 115, 91, 123, 183, 129, 210, 13, 106, 38, -158, 88, 156, 131, 116, 179, 172, 48, 122, 105, 119, 15, 174, 33, 222, 208, - 46, 151, 16, 164, 152, 168, 212, 104, 45, 98, 41, 109, 22, 73, 118, 199, -232, 193, 150, 55, 229, 202, 244, 233, 99, 18, 194, 166, 20, 188, 211, 40, -175, 47, 230, 36, 82, 198, 160, 9, 189, 140, 207, 93, 17, 95, 1, 197, -159, 61, 162, 155, 201, 59, 190, 81, 25, 31, 63, 92, 178, 239, 74, 205, -191, 186, 111, 100, 217, 243, 62, 180, 170, 220, 213, 6, 192, 126, 246, 102, -108, 132, 113, 56, 185, 29, 127, 157, 72, 139, 42, 218, 165, 51, 130, 57, -214, 120, 134, 250, 228, 43, 169, 30, 137, 96, 107, 234, 85, 76, 247, 226, -}; - -const byte Square::Dec::Sd[256] = { - 53, 190, 7, 46, 83, 105, 219, 40, 111, 183, 118, 107, 12, 125, 54, 139, -146, 188, 169, 50, 172, 56, 156, 66, 99, 200, 30, 79, 36, 229, 247, 201, - 97, 141, 47, 63, 179, 101, 127, 112, 175, 154, 234, 245, 91, 152, 144, 177, -135, 113, 114, 237, 55, 69, 104, 163, 227, 239, 92, 197, 80, 193, 214, 202, - 90, 98, 95, 38, 9, 93, 20, 65, 232, 157, 206, 64, 253, 8, 23, 74, - 15, 199, 180, 62, 18, 252, 37, 75, 129, 44, 4, 120, 203, 187, 32, 189, -249, 41, 153, 168, 211, 96, 223, 17, 151, 137, 126, 250, 224, 155, 31, 210, -103, 226, 100, 119, 132, 43, 158, 138, 241, 109, 136, 121, 116, 87, 221, 230, - 57, 123, 238, 131, 225, 88, 242, 13, 52, 248, 48, 233, 185, 35, 84, 21, - 68, 11, 77, 102, 58, 3, 162, 145, 148, 82, 76, 195, 130, 231, 128, 192, -182, 14, 194, 108, 147, 236, 171, 67, 149, 246, 216, 70, 134, 5, 140, 176, -117, 0, 204, 133, 215, 61, 115, 122, 72, 228, 209, 89, 173, 184, 198, 208, -220, 161, 170, 2, 29, 191, 181, 159, 81, 196, 165, 16, 34, 207, 1, 186, -143, 49, 124, 174, 150, 218, 240, 86, 71, 212, 235, 78, 217, 19, 142, 73, - 85, 22, 255, 59, 244, 164, 178, 6, 160, 167, 251, 27, 110, 60, 51, 205, - 24, 94, 106, 213, 166, 33, 222, 254, 42, 28, 243, 10, 26, 25, 39, 45, -}; - -const word32 Square::Enc::Te[4][256] = { -{ -0x97b1b126UL, 0x69cecea7UL, 0x73c3c3b0UL, 0xdf95954aUL, -0xb45a5aeeUL, 0xafadad02UL, 0x3be7e7dcUL, 0x04020206UL, -0x9a4d4dd7UL, 0x884444ccUL, 0x03fbfbf8UL, 0xd7919146UL, -0x180c0c14UL, 0xfb87877cUL, 0xb7a1a116UL, 0xa05050f0UL, -0x63cbcba8UL, 0xce6767a9UL, 0xa85454fcUL, 0x4fdddd92UL, -0x8c4646caUL, 0xeb8f8f64UL, 0x37e1e1d6UL, 0x9c4e4ed2UL, -0x15f0f0e5UL, 0x0ffdfdf2UL, 0x0dfcfcf1UL, 0x23ebebc8UL, -0x07f9f9feUL, 0x7dc4c4b9UL, 0x341a1a2eUL, 0xdc6e6eb2UL, -0xbc5e5ee2UL, 0x1ff5f5eaUL, 0x6dcccca1UL, 0xef8d8d62UL, -0x381c1c24UL, 0xac5656faUL, 0x864343c5UL, 0x09fefef7UL, -0x0e070709UL, 0xc26161a3UL, 0x05f8f8fdUL, 0xea75759fUL, -0xb25959ebUL, 0x0bfffff4UL, 0x06030305UL, 0x44222266UL, -0xe18a8a6bUL, 0x57d1d186UL, 0x26131335UL, 0x29eeeec7UL, -0xe588886dUL, 0x00000000UL, 0x1c0e0e12UL, 0x6834345cUL, -0x2a15153fUL, 0xf5808075UL, 0xdd949449UL, 0x33e3e3d0UL, -0x2fededc2UL, 0x9fb5b52aUL, 0xa65353f5UL, 0x46232365UL, -0x964b4bddUL, 0x8e4747c9UL, 0x2e171739UL, 0xbba7a71cUL, -0xd5909045UL, 0x6a35355fUL, 0xa3abab08UL, 0x45d8d89dUL, -0x85b8b83dUL, 0x4bdfdf94UL, 0x9e4f4fd1UL, 0xae5757f9UL, -0xc19a9a5bUL, 0xd1929243UL, 0x43dbdb98UL, 0x361b1b2dUL, -0x783c3c44UL, 0x65c8c8adUL, 0xc799995eUL, 0x0804040cUL, -0xe98e8e67UL, 0x35e0e0d5UL, 0x5bd7d78cUL, 0xfa7d7d87UL, -0xff85857aUL, 0x83bbbb38UL, 0x804040c0UL, 0x582c2c74UL, -0x743a3a4eUL, 0x8a4545cfUL, 0x17f1f1e6UL, 0x844242c6UL, -0xca6565afUL, 0x40202060UL, 0x824141c3UL, 0x30181828UL, -0xe4727296UL, 0x4a25256fUL, 0xd3939340UL, 0xe0707090UL, -0x6c36365aUL, 0x0a05050fUL, 0x11f2f2e3UL, 0x160b0b1dUL, -0xb3a3a310UL, 0xf279798bUL, 0x2dececc1UL, 0x10080818UL, -0x4e272769UL, 0x62313153UL, 0x64323256UL, 0x99b6b62fUL, -0xf87c7c84UL, 0x95b0b025UL, 0x140a0a1eUL, 0xe6737395UL, -0xb65b5bedUL, 0xf67b7b8dUL, 0x9bb7b72cUL, 0xf7818176UL, -0x51d2d283UL, 0x1a0d0d17UL, 0xd46a6abeUL, 0x4c26266aUL, -0xc99e9e57UL, 0xb05858e8UL, 0xcd9c9c51UL, 0xf3838370UL, -0xe874749cUL, 0x93b3b320UL, 0xadacac01UL, 0x60303050UL, -0xf47a7a8eUL, 0xd26969bbUL, 0xee777799UL, 0x1e0f0f11UL, -0xa9aeae07UL, 0x42212163UL, 0x49dede97UL, 0x55d0d085UL, -0x5c2e2e72UL, 0xdb97974cUL, 0x20101030UL, 0xbda4a419UL, -0xc598985dUL, 0xa5a8a80dUL, 0x5dd4d489UL, 0xd06868b8UL, -0x5a2d2d77UL, 0xc46262a6UL, 0x5229297bUL, 0xda6d6db7UL, -0x2c16163aUL, 0x924949dbUL, 0xec76769aUL, 0x7bc7c7bcUL, -0x25e8e8cdUL, 0x77c1c1b6UL, 0xd996964fUL, 0x6e373759UL, -0x3fe5e5daUL, 0x61cacaabUL, 0x1df4f4e9UL, 0x27e9e9ceUL, -0xc66363a5UL, 0x24121236UL, 0x71c2c2b3UL, 0xb9a6a61fUL, -0x2814143cUL, 0x8dbcbc31UL, 0x53d3d380UL, 0x50282878UL, -0xabafaf04UL, 0x5e2f2f71UL, 0x39e6e6dfUL, 0x4824246cUL, -0xa45252f6UL, 0x79c6c6bfUL, 0xb5a0a015UL, 0x1209091bUL, -0x8fbdbd32UL, 0xed8c8c61UL, 0x6bcfcfa4UL, 0xba5d5de7UL, -0x22111133UL, 0xbe5f5fe1UL, 0x02010103UL, 0x7fc5c5baUL, -0xcb9f9f54UL, 0x7a3d3d47UL, 0xb1a2a213UL, 0xc39b9b58UL, -0x67c9c9aeUL, 0x763b3b4dUL, 0x89bebe37UL, 0xa25151f3UL, -0x3219192bUL, 0x3e1f1f21UL, 0x7e3f3f41UL, 0xb85c5ce4UL, -0x91b2b223UL, 0x2befefc4UL, 0x944a4adeUL, 0x6fcdcda2UL, -0x8bbfbf34UL, 0x81baba3bUL, 0xde6f6fb1UL, 0xc86464acUL, -0x47d9d99eUL, 0x13f3f3e0UL, 0x7c3e3e42UL, 0x9db4b429UL, -0xa1aaaa0bUL, 0x4ddcdc91UL, 0x5fd5d58aUL, 0x0c06060aUL, -0x75c0c0b5UL, 0xfc7e7e82UL, 0x19f6f6efUL, 0xcc6666aaUL, -0xd86c6cb4UL, 0xfd848479UL, 0xe2717193UL, 0x70383848UL, -0x87b9b93eUL, 0x3a1d1d27UL, 0xfe7f7f81UL, 0xcf9d9d52UL, -0x904848d8UL, 0xe38b8b68UL, 0x542a2a7eUL, 0x41dada9bUL, -0xbfa5a51aUL, 0x66333355UL, 0xf1828273UL, 0x7239394bUL, -0x59d6d68fUL, 0xf0787888UL, 0xf986867fUL, 0x01fafafbUL, -0x3de4e4d9UL, 0x562b2b7dUL, 0xa7a9a90eUL, 0x3c1e1e22UL, -0xe789896eUL, 0xc06060a0UL, 0xd66b6bbdUL, 0x21eaeacbUL, -0xaa5555ffUL, 0x984c4cd4UL, 0x1bf7f7ecUL, 0x31e2e2d3UL, -}, - -{ -0x2697b1b1UL, 0xa769ceceUL, 0xb073c3c3UL, 0x4adf9595UL, -0xeeb45a5aUL, 0x02afadadUL, 0xdc3be7e7UL, 0x06040202UL, -0xd79a4d4dUL, 0xcc884444UL, 0xf803fbfbUL, 0x46d79191UL, -0x14180c0cUL, 0x7cfb8787UL, 0x16b7a1a1UL, 0xf0a05050UL, -0xa863cbcbUL, 0xa9ce6767UL, 0xfca85454UL, 0x924fddddUL, -0xca8c4646UL, 0x64eb8f8fUL, 0xd637e1e1UL, 0xd29c4e4eUL, -0xe515f0f0UL, 0xf20ffdfdUL, 0xf10dfcfcUL, 0xc823ebebUL, -0xfe07f9f9UL, 0xb97dc4c4UL, 0x2e341a1aUL, 0xb2dc6e6eUL, -0xe2bc5e5eUL, 0xea1ff5f5UL, 0xa16dccccUL, 0x62ef8d8dUL, -0x24381c1cUL, 0xfaac5656UL, 0xc5864343UL, 0xf709fefeUL, -0x090e0707UL, 0xa3c26161UL, 0xfd05f8f8UL, 0x9fea7575UL, -0xebb25959UL, 0xf40bffffUL, 0x05060303UL, 0x66442222UL, -0x6be18a8aUL, 0x8657d1d1UL, 0x35261313UL, 0xc729eeeeUL, -0x6de58888UL, 0x00000000UL, 0x121c0e0eUL, 0x5c683434UL, -0x3f2a1515UL, 0x75f58080UL, 0x49dd9494UL, 0xd033e3e3UL, -0xc22fededUL, 0x2a9fb5b5UL, 0xf5a65353UL, 0x65462323UL, -0xdd964b4bUL, 0xc98e4747UL, 0x392e1717UL, 0x1cbba7a7UL, -0x45d59090UL, 0x5f6a3535UL, 0x08a3ababUL, 0x9d45d8d8UL, -0x3d85b8b8UL, 0x944bdfdfUL, 0xd19e4f4fUL, 0xf9ae5757UL, -0x5bc19a9aUL, 0x43d19292UL, 0x9843dbdbUL, 0x2d361b1bUL, -0x44783c3cUL, 0xad65c8c8UL, 0x5ec79999UL, 0x0c080404UL, -0x67e98e8eUL, 0xd535e0e0UL, 0x8c5bd7d7UL, 0x87fa7d7dUL, -0x7aff8585UL, 0x3883bbbbUL, 0xc0804040UL, 0x74582c2cUL, -0x4e743a3aUL, 0xcf8a4545UL, 0xe617f1f1UL, 0xc6844242UL, -0xafca6565UL, 0x60402020UL, 0xc3824141UL, 0x28301818UL, -0x96e47272UL, 0x6f4a2525UL, 0x40d39393UL, 0x90e07070UL, -0x5a6c3636UL, 0x0f0a0505UL, 0xe311f2f2UL, 0x1d160b0bUL, -0x10b3a3a3UL, 0x8bf27979UL, 0xc12dececUL, 0x18100808UL, -0x694e2727UL, 0x53623131UL, 0x56643232UL, 0x2f99b6b6UL, -0x84f87c7cUL, 0x2595b0b0UL, 0x1e140a0aUL, 0x95e67373UL, -0xedb65b5bUL, 0x8df67b7bUL, 0x2c9bb7b7UL, 0x76f78181UL, -0x8351d2d2UL, 0x171a0d0dUL, 0xbed46a6aUL, 0x6a4c2626UL, -0x57c99e9eUL, 0xe8b05858UL, 0x51cd9c9cUL, 0x70f38383UL, -0x9ce87474UL, 0x2093b3b3UL, 0x01adacacUL, 0x50603030UL, -0x8ef47a7aUL, 0xbbd26969UL, 0x99ee7777UL, 0x111e0f0fUL, -0x07a9aeaeUL, 0x63422121UL, 0x9749dedeUL, 0x8555d0d0UL, -0x725c2e2eUL, 0x4cdb9797UL, 0x30201010UL, 0x19bda4a4UL, -0x5dc59898UL, 0x0da5a8a8UL, 0x895dd4d4UL, 0xb8d06868UL, -0x775a2d2dUL, 0xa6c46262UL, 0x7b522929UL, 0xb7da6d6dUL, -0x3a2c1616UL, 0xdb924949UL, 0x9aec7676UL, 0xbc7bc7c7UL, -0xcd25e8e8UL, 0xb677c1c1UL, 0x4fd99696UL, 0x596e3737UL, -0xda3fe5e5UL, 0xab61cacaUL, 0xe91df4f4UL, 0xce27e9e9UL, -0xa5c66363UL, 0x36241212UL, 0xb371c2c2UL, 0x1fb9a6a6UL, -0x3c281414UL, 0x318dbcbcUL, 0x8053d3d3UL, 0x78502828UL, -0x04abafafUL, 0x715e2f2fUL, 0xdf39e6e6UL, 0x6c482424UL, -0xf6a45252UL, 0xbf79c6c6UL, 0x15b5a0a0UL, 0x1b120909UL, -0x328fbdbdUL, 0x61ed8c8cUL, 0xa46bcfcfUL, 0xe7ba5d5dUL, -0x33221111UL, 0xe1be5f5fUL, 0x03020101UL, 0xba7fc5c5UL, -0x54cb9f9fUL, 0x477a3d3dUL, 0x13b1a2a2UL, 0x58c39b9bUL, -0xae67c9c9UL, 0x4d763b3bUL, 0x3789bebeUL, 0xf3a25151UL, -0x2b321919UL, 0x213e1f1fUL, 0x417e3f3fUL, 0xe4b85c5cUL, -0x2391b2b2UL, 0xc42befefUL, 0xde944a4aUL, 0xa26fcdcdUL, -0x348bbfbfUL, 0x3b81babaUL, 0xb1de6f6fUL, 0xacc86464UL, -0x9e47d9d9UL, 0xe013f3f3UL, 0x427c3e3eUL, 0x299db4b4UL, -0x0ba1aaaaUL, 0x914ddcdcUL, 0x8a5fd5d5UL, 0x0a0c0606UL, -0xb575c0c0UL, 0x82fc7e7eUL, 0xef19f6f6UL, 0xaacc6666UL, -0xb4d86c6cUL, 0x79fd8484UL, 0x93e27171UL, 0x48703838UL, -0x3e87b9b9UL, 0x273a1d1dUL, 0x81fe7f7fUL, 0x52cf9d9dUL, -0xd8904848UL, 0x68e38b8bUL, 0x7e542a2aUL, 0x9b41dadaUL, -0x1abfa5a5UL, 0x55663333UL, 0x73f18282UL, 0x4b723939UL, -0x8f59d6d6UL, 0x88f07878UL, 0x7ff98686UL, 0xfb01fafaUL, -0xd93de4e4UL, 0x7d562b2bUL, 0x0ea7a9a9UL, 0x223c1e1eUL, -0x6ee78989UL, 0xa0c06060UL, 0xbdd66b6bUL, 0xcb21eaeaUL, -0xffaa5555UL, 0xd4984c4cUL, 0xec1bf7f7UL, 0xd331e2e2UL, -}, - -{ -0xb12697b1UL, 0xcea769ceUL, 0xc3b073c3UL, 0x954adf95UL, -0x5aeeb45aUL, 0xad02afadUL, 0xe7dc3be7UL, 0x02060402UL, -0x4dd79a4dUL, 0x44cc8844UL, 0xfbf803fbUL, 0x9146d791UL, -0x0c14180cUL, 0x877cfb87UL, 0xa116b7a1UL, 0x50f0a050UL, -0xcba863cbUL, 0x67a9ce67UL, 0x54fca854UL, 0xdd924fddUL, -0x46ca8c46UL, 0x8f64eb8fUL, 0xe1d637e1UL, 0x4ed29c4eUL, -0xf0e515f0UL, 0xfdf20ffdUL, 0xfcf10dfcUL, 0xebc823ebUL, -0xf9fe07f9UL, 0xc4b97dc4UL, 0x1a2e341aUL, 0x6eb2dc6eUL, -0x5ee2bc5eUL, 0xf5ea1ff5UL, 0xcca16dccUL, 0x8d62ef8dUL, -0x1c24381cUL, 0x56faac56UL, 0x43c58643UL, 0xfef709feUL, -0x07090e07UL, 0x61a3c261UL, 0xf8fd05f8UL, 0x759fea75UL, -0x59ebb259UL, 0xfff40bffUL, 0x03050603UL, 0x22664422UL, -0x8a6be18aUL, 0xd18657d1UL, 0x13352613UL, 0xeec729eeUL, -0x886de588UL, 0x00000000UL, 0x0e121c0eUL, 0x345c6834UL, -0x153f2a15UL, 0x8075f580UL, 0x9449dd94UL, 0xe3d033e3UL, -0xedc22fedUL, 0xb52a9fb5UL, 0x53f5a653UL, 0x23654623UL, -0x4bdd964bUL, 0x47c98e47UL, 0x17392e17UL, 0xa71cbba7UL, -0x9045d590UL, 0x355f6a35UL, 0xab08a3abUL, 0xd89d45d8UL, -0xb83d85b8UL, 0xdf944bdfUL, 0x4fd19e4fUL, 0x57f9ae57UL, -0x9a5bc19aUL, 0x9243d192UL, 0xdb9843dbUL, 0x1b2d361bUL, -0x3c44783cUL, 0xc8ad65c8UL, 0x995ec799UL, 0x040c0804UL, -0x8e67e98eUL, 0xe0d535e0UL, 0xd78c5bd7UL, 0x7d87fa7dUL, -0x857aff85UL, 0xbb3883bbUL, 0x40c08040UL, 0x2c74582cUL, -0x3a4e743aUL, 0x45cf8a45UL, 0xf1e617f1UL, 0x42c68442UL, -0x65afca65UL, 0x20604020UL, 0x41c38241UL, 0x18283018UL, -0x7296e472UL, 0x256f4a25UL, 0x9340d393UL, 0x7090e070UL, -0x365a6c36UL, 0x050f0a05UL, 0xf2e311f2UL, 0x0b1d160bUL, -0xa310b3a3UL, 0x798bf279UL, 0xecc12decUL, 0x08181008UL, -0x27694e27UL, 0x31536231UL, 0x32566432UL, 0xb62f99b6UL, -0x7c84f87cUL, 0xb02595b0UL, 0x0a1e140aUL, 0x7395e673UL, -0x5bedb65bUL, 0x7b8df67bUL, 0xb72c9bb7UL, 0x8176f781UL, -0xd28351d2UL, 0x0d171a0dUL, 0x6abed46aUL, 0x266a4c26UL, -0x9e57c99eUL, 0x58e8b058UL, 0x9c51cd9cUL, 0x8370f383UL, -0x749ce874UL, 0xb32093b3UL, 0xac01adacUL, 0x30506030UL, -0x7a8ef47aUL, 0x69bbd269UL, 0x7799ee77UL, 0x0f111e0fUL, -0xae07a9aeUL, 0x21634221UL, 0xde9749deUL, 0xd08555d0UL, -0x2e725c2eUL, 0x974cdb97UL, 0x10302010UL, 0xa419bda4UL, -0x985dc598UL, 0xa80da5a8UL, 0xd4895dd4UL, 0x68b8d068UL, -0x2d775a2dUL, 0x62a6c462UL, 0x297b5229UL, 0x6db7da6dUL, -0x163a2c16UL, 0x49db9249UL, 0x769aec76UL, 0xc7bc7bc7UL, -0xe8cd25e8UL, 0xc1b677c1UL, 0x964fd996UL, 0x37596e37UL, -0xe5da3fe5UL, 0xcaab61caUL, 0xf4e91df4UL, 0xe9ce27e9UL, -0x63a5c663UL, 0x12362412UL, 0xc2b371c2UL, 0xa61fb9a6UL, -0x143c2814UL, 0xbc318dbcUL, 0xd38053d3UL, 0x28785028UL, -0xaf04abafUL, 0x2f715e2fUL, 0xe6df39e6UL, 0x246c4824UL, -0x52f6a452UL, 0xc6bf79c6UL, 0xa015b5a0UL, 0x091b1209UL, -0xbd328fbdUL, 0x8c61ed8cUL, 0xcfa46bcfUL, 0x5de7ba5dUL, -0x11332211UL, 0x5fe1be5fUL, 0x01030201UL, 0xc5ba7fc5UL, -0x9f54cb9fUL, 0x3d477a3dUL, 0xa213b1a2UL, 0x9b58c39bUL, -0xc9ae67c9UL, 0x3b4d763bUL, 0xbe3789beUL, 0x51f3a251UL, -0x192b3219UL, 0x1f213e1fUL, 0x3f417e3fUL, 0x5ce4b85cUL, -0xb22391b2UL, 0xefc42befUL, 0x4ade944aUL, 0xcda26fcdUL, -0xbf348bbfUL, 0xba3b81baUL, 0x6fb1de6fUL, 0x64acc864UL, -0xd99e47d9UL, 0xf3e013f3UL, 0x3e427c3eUL, 0xb4299db4UL, -0xaa0ba1aaUL, 0xdc914ddcUL, 0xd58a5fd5UL, 0x060a0c06UL, -0xc0b575c0UL, 0x7e82fc7eUL, 0xf6ef19f6UL, 0x66aacc66UL, -0x6cb4d86cUL, 0x8479fd84UL, 0x7193e271UL, 0x38487038UL, -0xb93e87b9UL, 0x1d273a1dUL, 0x7f81fe7fUL, 0x9d52cf9dUL, -0x48d89048UL, 0x8b68e38bUL, 0x2a7e542aUL, 0xda9b41daUL, -0xa51abfa5UL, 0x33556633UL, 0x8273f182UL, 0x394b7239UL, -0xd68f59d6UL, 0x7888f078UL, 0x867ff986UL, 0xfafb01faUL, -0xe4d93de4UL, 0x2b7d562bUL, 0xa90ea7a9UL, 0x1e223c1eUL, -0x896ee789UL, 0x60a0c060UL, 0x6bbdd66bUL, 0xeacb21eaUL, -0x55ffaa55UL, 0x4cd4984cUL, 0xf7ec1bf7UL, 0xe2d331e2UL, -}, - -{ -0xb1b12697UL, 0xcecea769UL, 0xc3c3b073UL, 0x95954adfUL, -0x5a5aeeb4UL, 0xadad02afUL, 0xe7e7dc3bUL, 0x02020604UL, -0x4d4dd79aUL, 0x4444cc88UL, 0xfbfbf803UL, 0x919146d7UL, -0x0c0c1418UL, 0x87877cfbUL, 0xa1a116b7UL, 0x5050f0a0UL, -0xcbcba863UL, 0x6767a9ceUL, 0x5454fca8UL, 0xdddd924fUL, -0x4646ca8cUL, 0x8f8f64ebUL, 0xe1e1d637UL, 0x4e4ed29cUL, -0xf0f0e515UL, 0xfdfdf20fUL, 0xfcfcf10dUL, 0xebebc823UL, -0xf9f9fe07UL, 0xc4c4b97dUL, 0x1a1a2e34UL, 0x6e6eb2dcUL, -0x5e5ee2bcUL, 0xf5f5ea1fUL, 0xcccca16dUL, 0x8d8d62efUL, -0x1c1c2438UL, 0x5656faacUL, 0x4343c586UL, 0xfefef709UL, -0x0707090eUL, 0x6161a3c2UL, 0xf8f8fd05UL, 0x75759feaUL, -0x5959ebb2UL, 0xfffff40bUL, 0x03030506UL, 0x22226644UL, -0x8a8a6be1UL, 0xd1d18657UL, 0x13133526UL, 0xeeeec729UL, -0x88886de5UL, 0x00000000UL, 0x0e0e121cUL, 0x34345c68UL, -0x15153f2aUL, 0x808075f5UL, 0x949449ddUL, 0xe3e3d033UL, -0xededc22fUL, 0xb5b52a9fUL, 0x5353f5a6UL, 0x23236546UL, -0x4b4bdd96UL, 0x4747c98eUL, 0x1717392eUL, 0xa7a71cbbUL, -0x909045d5UL, 0x35355f6aUL, 0xabab08a3UL, 0xd8d89d45UL, -0xb8b83d85UL, 0xdfdf944bUL, 0x4f4fd19eUL, 0x5757f9aeUL, -0x9a9a5bc1UL, 0x929243d1UL, 0xdbdb9843UL, 0x1b1b2d36UL, -0x3c3c4478UL, 0xc8c8ad65UL, 0x99995ec7UL, 0x04040c08UL, -0x8e8e67e9UL, 0xe0e0d535UL, 0xd7d78c5bUL, 0x7d7d87faUL, -0x85857affUL, 0xbbbb3883UL, 0x4040c080UL, 0x2c2c7458UL, -0x3a3a4e74UL, 0x4545cf8aUL, 0xf1f1e617UL, 0x4242c684UL, -0x6565afcaUL, 0x20206040UL, 0x4141c382UL, 0x18182830UL, -0x727296e4UL, 0x25256f4aUL, 0x939340d3UL, 0x707090e0UL, -0x36365a6cUL, 0x05050f0aUL, 0xf2f2e311UL, 0x0b0b1d16UL, -0xa3a310b3UL, 0x79798bf2UL, 0xececc12dUL, 0x08081810UL, -0x2727694eUL, 0x31315362UL, 0x32325664UL, 0xb6b62f99UL, -0x7c7c84f8UL, 0xb0b02595UL, 0x0a0a1e14UL, 0x737395e6UL, -0x5b5bedb6UL, 0x7b7b8df6UL, 0xb7b72c9bUL, 0x818176f7UL, -0xd2d28351UL, 0x0d0d171aUL, 0x6a6abed4UL, 0x26266a4cUL, -0x9e9e57c9UL, 0x5858e8b0UL, 0x9c9c51cdUL, 0x838370f3UL, -0x74749ce8UL, 0xb3b32093UL, 0xacac01adUL, 0x30305060UL, -0x7a7a8ef4UL, 0x6969bbd2UL, 0x777799eeUL, 0x0f0f111eUL, -0xaeae07a9UL, 0x21216342UL, 0xdede9749UL, 0xd0d08555UL, -0x2e2e725cUL, 0x97974cdbUL, 0x10103020UL, 0xa4a419bdUL, -0x98985dc5UL, 0xa8a80da5UL, 0xd4d4895dUL, 0x6868b8d0UL, -0x2d2d775aUL, 0x6262a6c4UL, 0x29297b52UL, 0x6d6db7daUL, -0x16163a2cUL, 0x4949db92UL, 0x76769aecUL, 0xc7c7bc7bUL, -0xe8e8cd25UL, 0xc1c1b677UL, 0x96964fd9UL, 0x3737596eUL, -0xe5e5da3fUL, 0xcacaab61UL, 0xf4f4e91dUL, 0xe9e9ce27UL, -0x6363a5c6UL, 0x12123624UL, 0xc2c2b371UL, 0xa6a61fb9UL, -0x14143c28UL, 0xbcbc318dUL, 0xd3d38053UL, 0x28287850UL, -0xafaf04abUL, 0x2f2f715eUL, 0xe6e6df39UL, 0x24246c48UL, -0x5252f6a4UL, 0xc6c6bf79UL, 0xa0a015b5UL, 0x09091b12UL, -0xbdbd328fUL, 0x8c8c61edUL, 0xcfcfa46bUL, 0x5d5de7baUL, -0x11113322UL, 0x5f5fe1beUL, 0x01010302UL, 0xc5c5ba7fUL, -0x9f9f54cbUL, 0x3d3d477aUL, 0xa2a213b1UL, 0x9b9b58c3UL, -0xc9c9ae67UL, 0x3b3b4d76UL, 0xbebe3789UL, 0x5151f3a2UL, -0x19192b32UL, 0x1f1f213eUL, 0x3f3f417eUL, 0x5c5ce4b8UL, -0xb2b22391UL, 0xefefc42bUL, 0x4a4ade94UL, 0xcdcda26fUL, -0xbfbf348bUL, 0xbaba3b81UL, 0x6f6fb1deUL, 0x6464acc8UL, -0xd9d99e47UL, 0xf3f3e013UL, 0x3e3e427cUL, 0xb4b4299dUL, -0xaaaa0ba1UL, 0xdcdc914dUL, 0xd5d58a5fUL, 0x06060a0cUL, -0xc0c0b575UL, 0x7e7e82fcUL, 0xf6f6ef19UL, 0x6666aaccUL, -0x6c6cb4d8UL, 0x848479fdUL, 0x717193e2UL, 0x38384870UL, -0xb9b93e87UL, 0x1d1d273aUL, 0x7f7f81feUL, 0x9d9d52cfUL, -0x4848d890UL, 0x8b8b68e3UL, 0x2a2a7e54UL, 0xdada9b41UL, -0xa5a51abfUL, 0x33335566UL, 0x828273f1UL, 0x39394b72UL, -0xd6d68f59UL, 0x787888f0UL, 0x86867ff9UL, 0xfafafb01UL, -0xe4e4d93dUL, 0x2b2b7d56UL, 0xa9a90ea7UL, 0x1e1e223cUL, -0x89896ee7UL, 0x6060a0c0UL, 0x6b6bbdd6UL, 0xeaeacb21UL, -0x5555ffaaUL, 0x4c4cd498UL, 0xf7f7ec1bUL, 0xe2e2d331UL, -}}; - -const word32 Square::Dec::Td[4][256] = { -{ -0xe368bc02UL, 0x5585620cUL, 0x2a3f2331UL, 0x61ab13f7UL, -0x98d46d72UL, 0x21cb9a19UL, 0x3c22a461UL, 0x459d3dcdUL, -0x05fdb423UL, 0x2bc4075fUL, 0x9b2c01c0UL, 0x3dd9800fUL, -0x486c5c74UL, 0xf97f7e85UL, 0xf173ab1fUL, 0xb6edde0eUL, -0x283c6bedUL, 0x4997781aUL, 0x9f2a918dUL, 0xc9579f33UL, -0xa907a8aaUL, 0xa50ded7dUL, 0x7c422d8fUL, 0x764db0c9UL, -0x4d91e857UL, 0xcea963ccUL, 0xb4ee96d2UL, 0x3028e1b6UL, -0x0df161b9UL, 0xbd196726UL, 0x419bad80UL, 0xc0a06ec7UL, -0x5183f241UL, 0x92dbf034UL, 0x6fa21efcUL, 0x8f32ce4cUL, -0x13e03373UL, 0x69a7c66dUL, 0xe56d6493UL, 0xbf1a2ffaUL, -0xbb1cbfb7UL, 0x587403b5UL, 0xe76e2c4fUL, 0x5d89b796UL, -0xe89c052aUL, 0x446619a3UL, 0x342e71fbUL, 0x0ff22965UL, -0xfe81827aUL, 0xb11322f1UL, 0xa30835ecUL, 0xcd510f7eUL, -0xff7aa614UL, 0x5c7293f8UL, 0x2fc29712UL, 0xf370e3c3UL, -0x992f491cUL, 0xd1431568UL, 0xc2a3261bUL, 0x88cc32b3UL, -0x8acf7a6fUL, 0xb0e8069fUL, 0x7a47f51eUL, 0xd2bb79daUL, -0xe6950821UL, 0x4398e55cUL, 0xd0b83106UL, 0x11e37bafUL, -0x7e416553UL, 0xccaa2b10UL, 0xd8b4e49cUL, 0x6456a7d4UL, -0xfb7c3659UL, 0x724b2084UL, 0xea9f4df6UL, 0x6a5faadfUL, -0x2dc1dfceUL, 0x70486858UL, 0xcaaff381UL, 0x0605d891UL, -0x5a774b69UL, 0x94de28a5UL, 0x39df1042UL, 0x813bc347UL, -0xfc82caa6UL, 0x23c8d2c5UL, 0x03f86cb2UL, 0x080cd59aUL, -0xdab7ac40UL, 0x7db909e1UL, 0x3824342cUL, 0xcf5247a2UL, -0xdcb274d1UL, 0x63a85b2bUL, 0x35d55595UL, 0x479e7511UL, -0x15e5ebe2UL, 0x4b9430c6UL, 0x4a6f14a8UL, 0x91239c86UL, -0x4c6acc39UL, 0x5f8aff4aUL, 0x0406904dUL, 0xee99ddbbUL, -0x1e1152caUL, 0xaaffc418UL, 0xeb646998UL, 0x07fefcffUL, -0x8b345e01UL, 0x567d0ebeUL, 0xbae79bd9UL, 0x4263c132UL, -0x75b5dc7bUL, 0x97264417UL, 0x67aecb66UL, 0x95250ccbUL, -0xec9a9567UL, 0x57862ad0UL, 0x60503799UL, 0xb8e4d305UL, -0x65ad83baUL, 0x19efae35UL, 0xa4f6c913UL, 0xc15b4aa9UL, -0x873e1bd6UL, 0xa0f0595eUL, 0x18148a5bUL, 0xaf02703bUL, -0xab04e076UL, 0xdd4950bfUL, 0xdf4a1863UL, 0xc6a5b656UL, -0x853d530aUL, 0xfa871237UL, 0x77b694a7UL, 0x4665517fUL, -0xed61b109UL, 0x1bece6e9UL, 0xd5458525UL, 0xf5753b52UL, -0x7fba413dUL, 0x27ce4288UL, 0xb2eb4e43UL, 0xd6bde997UL, -0x527b9ef3UL, 0x62537f45UL, 0x2c3afba0UL, 0x7bbcd170UL, -0xb91ff76bUL, 0x121b171dUL, 0xfd79eec8UL, 0x3a277cf0UL, -0x0c0a45d7UL, 0x96dd6079UL, 0x2233f6abUL, 0xacfa1c89UL, -0xc8acbb5dUL, 0xa10b7d30UL, 0xd4bea14bUL, 0xbee10b94UL, -0x25cd0a54UL, 0x547e4662UL, 0xa2f31182UL, 0x17e6a33eUL, -0x263566e6UL, 0xc3580275UL, 0x83388b9bUL, 0x7844bdc2UL, -0x020348dcUL, 0x4f92a08bUL, 0x2e39b37cUL, 0x4e6984e5UL, -0xf0888f71UL, 0x362d3927UL, 0x9cd2fd3fUL, 0x01fb246eUL, -0x893716ddUL, 0x00000000UL, 0xf68d57e0UL, 0xe293986cUL, -0x744ef815UL, 0x9320d45aUL, 0xad0138e7UL, 0xd3405db4UL, -0x1a17c287UL, 0xb3106a2dUL, 0x5078d62fUL, 0xf48e1f3cUL, -0xa70ea5a1UL, 0x71b34c36UL, 0x9ad725aeUL, 0x5e71db24UL, -0x161d8750UL, 0xef62f9d5UL, 0x8d318690UL, 0x1c121a16UL, -0xa6f581cfUL, 0x5b8c6f07UL, 0x37d61d49UL, 0x6e593a92UL, -0x84c67764UL, 0x86c53fb8UL, 0xd746cdf9UL, 0xe090d0b0UL, -0x29c74f83UL, 0xe49640fdUL, 0x0e090d0bUL, 0x6da15620UL, -0x8ec9ea22UL, 0xdb4c882eUL, 0xf776738eUL, 0xb515b2bcUL, -0x10185fc1UL, 0x322ba96aUL, 0x6ba48eb1UL, 0xaef95455UL, -0x406089eeUL, 0x6655ef08UL, 0xe9672144UL, 0x3e21ecbdUL, -0x2030be77UL, 0xf28bc7adUL, 0x80c0e729UL, 0x141ecf8cUL, -0xbce24348UL, 0xc4a6fe8aUL, 0x31d3c5d8UL, 0xb716fa60UL, -0x5380ba9dUL, 0xd94fc0f2UL, 0x1de93e78UL, 0x24362e3aUL, -0xe16bf4deUL, 0xcb54d7efUL, 0x09f7f1f4UL, 0x82c3aff5UL, -0x0bf4b928UL, 0x9d29d951UL, 0xc75e9238UL, 0xf8845aebUL, -0x90d8b8e8UL, 0xdeb13c0dUL, 0x33d08d04UL, 0x685ce203UL, -0xc55ddae4UL, 0x3bdc589eUL, 0x0a0f9d46UL, 0x3fdac8d3UL, -0x598f27dbUL, 0xa8fc8cc4UL, 0x79bf99acUL, 0x6c5a724eUL, -0x8ccaa2feUL, 0x9ed1b5e3UL, 0x1fea76a4UL, 0x73b004eaUL, -}, - -{ -0x02e368bcUL, 0x0c558562UL, 0x312a3f23UL, 0xf761ab13UL, -0x7298d46dUL, 0x1921cb9aUL, 0x613c22a4UL, 0xcd459d3dUL, -0x2305fdb4UL, 0x5f2bc407UL, 0xc09b2c01UL, 0x0f3dd980UL, -0x74486c5cUL, 0x85f97f7eUL, 0x1ff173abUL, 0x0eb6eddeUL, -0xed283c6bUL, 0x1a499778UL, 0x8d9f2a91UL, 0x33c9579fUL, -0xaaa907a8UL, 0x7da50dedUL, 0x8f7c422dUL, 0xc9764db0UL, -0x574d91e8UL, 0xcccea963UL, 0xd2b4ee96UL, 0xb63028e1UL, -0xb90df161UL, 0x26bd1967UL, 0x80419badUL, 0xc7c0a06eUL, -0x415183f2UL, 0x3492dbf0UL, 0xfc6fa21eUL, 0x4c8f32ceUL, -0x7313e033UL, 0x6d69a7c6UL, 0x93e56d64UL, 0xfabf1a2fUL, -0xb7bb1cbfUL, 0xb5587403UL, 0x4fe76e2cUL, 0x965d89b7UL, -0x2ae89c05UL, 0xa3446619UL, 0xfb342e71UL, 0x650ff229UL, -0x7afe8182UL, 0xf1b11322UL, 0xeca30835UL, 0x7ecd510fUL, -0x14ff7aa6UL, 0xf85c7293UL, 0x122fc297UL, 0xc3f370e3UL, -0x1c992f49UL, 0x68d14315UL, 0x1bc2a326UL, 0xb388cc32UL, -0x6f8acf7aUL, 0x9fb0e806UL, 0x1e7a47f5UL, 0xdad2bb79UL, -0x21e69508UL, 0x5c4398e5UL, 0x06d0b831UL, 0xaf11e37bUL, -0x537e4165UL, 0x10ccaa2bUL, 0x9cd8b4e4UL, 0xd46456a7UL, -0x59fb7c36UL, 0x84724b20UL, 0xf6ea9f4dUL, 0xdf6a5faaUL, -0xce2dc1dfUL, 0x58704868UL, 0x81caaff3UL, 0x910605d8UL, -0x695a774bUL, 0xa594de28UL, 0x4239df10UL, 0x47813bc3UL, -0xa6fc82caUL, 0xc523c8d2UL, 0xb203f86cUL, 0x9a080cd5UL, -0x40dab7acUL, 0xe17db909UL, 0x2c382434UL, 0xa2cf5247UL, -0xd1dcb274UL, 0x2b63a85bUL, 0x9535d555UL, 0x11479e75UL, -0xe215e5ebUL, 0xc64b9430UL, 0xa84a6f14UL, 0x8691239cUL, -0x394c6accUL, 0x4a5f8affUL, 0x4d040690UL, 0xbbee99ddUL, -0xca1e1152UL, 0x18aaffc4UL, 0x98eb6469UL, 0xff07fefcUL, -0x018b345eUL, 0xbe567d0eUL, 0xd9bae79bUL, 0x324263c1UL, -0x7b75b5dcUL, 0x17972644UL, 0x6667aecbUL, 0xcb95250cUL, -0x67ec9a95UL, 0xd057862aUL, 0x99605037UL, 0x05b8e4d3UL, -0xba65ad83UL, 0x3519efaeUL, 0x13a4f6c9UL, 0xa9c15b4aUL, -0xd6873e1bUL, 0x5ea0f059UL, 0x5b18148aUL, 0x3baf0270UL, -0x76ab04e0UL, 0xbfdd4950UL, 0x63df4a18UL, 0x56c6a5b6UL, -0x0a853d53UL, 0x37fa8712UL, 0xa777b694UL, 0x7f466551UL, -0x09ed61b1UL, 0xe91bece6UL, 0x25d54585UL, 0x52f5753bUL, -0x3d7fba41UL, 0x8827ce42UL, 0x43b2eb4eUL, 0x97d6bde9UL, -0xf3527b9eUL, 0x4562537fUL, 0xa02c3afbUL, 0x707bbcd1UL, -0x6bb91ff7UL, 0x1d121b17UL, 0xc8fd79eeUL, 0xf03a277cUL, -0xd70c0a45UL, 0x7996dd60UL, 0xab2233f6UL, 0x89acfa1cUL, -0x5dc8acbbUL, 0x30a10b7dUL, 0x4bd4bea1UL, 0x94bee10bUL, -0x5425cd0aUL, 0x62547e46UL, 0x82a2f311UL, 0x3e17e6a3UL, -0xe6263566UL, 0x75c35802UL, 0x9b83388bUL, 0xc27844bdUL, -0xdc020348UL, 0x8b4f92a0UL, 0x7c2e39b3UL, 0xe54e6984UL, -0x71f0888fUL, 0x27362d39UL, 0x3f9cd2fdUL, 0x6e01fb24UL, -0xdd893716UL, 0x00000000UL, 0xe0f68d57UL, 0x6ce29398UL, -0x15744ef8UL, 0x5a9320d4UL, 0xe7ad0138UL, 0xb4d3405dUL, -0x871a17c2UL, 0x2db3106aUL, 0x2f5078d6UL, 0x3cf48e1fUL, -0xa1a70ea5UL, 0x3671b34cUL, 0xae9ad725UL, 0x245e71dbUL, -0x50161d87UL, 0xd5ef62f9UL, 0x908d3186UL, 0x161c121aUL, -0xcfa6f581UL, 0x075b8c6fUL, 0x4937d61dUL, 0x926e593aUL, -0x6484c677UL, 0xb886c53fUL, 0xf9d746cdUL, 0xb0e090d0UL, -0x8329c74fUL, 0xfde49640UL, 0x0b0e090dUL, 0x206da156UL, -0x228ec9eaUL, 0x2edb4c88UL, 0x8ef77673UL, 0xbcb515b2UL, -0xc110185fUL, 0x6a322ba9UL, 0xb16ba48eUL, 0x55aef954UL, -0xee406089UL, 0x086655efUL, 0x44e96721UL, 0xbd3e21ecUL, -0x772030beUL, 0xadf28bc7UL, 0x2980c0e7UL, 0x8c141ecfUL, -0x48bce243UL, 0x8ac4a6feUL, 0xd831d3c5UL, 0x60b716faUL, -0x9d5380baUL, 0xf2d94fc0UL, 0x781de93eUL, 0x3a24362eUL, -0xdee16bf4UL, 0xefcb54d7UL, 0xf409f7f1UL, 0xf582c3afUL, -0x280bf4b9UL, 0x519d29d9UL, 0x38c75e92UL, 0xebf8845aUL, -0xe890d8b8UL, 0x0ddeb13cUL, 0x0433d08dUL, 0x03685ce2UL, -0xe4c55ddaUL, 0x9e3bdc58UL, 0x460a0f9dUL, 0xd33fdac8UL, -0xdb598f27UL, 0xc4a8fc8cUL, 0xac79bf99UL, 0x4e6c5a72UL, -0xfe8ccaa2UL, 0xe39ed1b5UL, 0xa41fea76UL, 0xea73b004UL, -}, - -{ -0xbc02e368UL, 0x620c5585UL, 0x23312a3fUL, 0x13f761abUL, -0x6d7298d4UL, 0x9a1921cbUL, 0xa4613c22UL, 0x3dcd459dUL, -0xb42305fdUL, 0x075f2bc4UL, 0x01c09b2cUL, 0x800f3dd9UL, -0x5c74486cUL, 0x7e85f97fUL, 0xab1ff173UL, 0xde0eb6edUL, -0x6bed283cUL, 0x781a4997UL, 0x918d9f2aUL, 0x9f33c957UL, -0xa8aaa907UL, 0xed7da50dUL, 0x2d8f7c42UL, 0xb0c9764dUL, -0xe8574d91UL, 0x63cccea9UL, 0x96d2b4eeUL, 0xe1b63028UL, -0x61b90df1UL, 0x6726bd19UL, 0xad80419bUL, 0x6ec7c0a0UL, -0xf2415183UL, 0xf03492dbUL, 0x1efc6fa2UL, 0xce4c8f32UL, -0x337313e0UL, 0xc66d69a7UL, 0x6493e56dUL, 0x2ffabf1aUL, -0xbfb7bb1cUL, 0x03b55874UL, 0x2c4fe76eUL, 0xb7965d89UL, -0x052ae89cUL, 0x19a34466UL, 0x71fb342eUL, 0x29650ff2UL, -0x827afe81UL, 0x22f1b113UL, 0x35eca308UL, 0x0f7ecd51UL, -0xa614ff7aUL, 0x93f85c72UL, 0x97122fc2UL, 0xe3c3f370UL, -0x491c992fUL, 0x1568d143UL, 0x261bc2a3UL, 0x32b388ccUL, -0x7a6f8acfUL, 0x069fb0e8UL, 0xf51e7a47UL, 0x79dad2bbUL, -0x0821e695UL, 0xe55c4398UL, 0x3106d0b8UL, 0x7baf11e3UL, -0x65537e41UL, 0x2b10ccaaUL, 0xe49cd8b4UL, 0xa7d46456UL, -0x3659fb7cUL, 0x2084724bUL, 0x4df6ea9fUL, 0xaadf6a5fUL, -0xdfce2dc1UL, 0x68587048UL, 0xf381caafUL, 0xd8910605UL, -0x4b695a77UL, 0x28a594deUL, 0x104239dfUL, 0xc347813bUL, -0xcaa6fc82UL, 0xd2c523c8UL, 0x6cb203f8UL, 0xd59a080cUL, -0xac40dab7UL, 0x09e17db9UL, 0x342c3824UL, 0x47a2cf52UL, -0x74d1dcb2UL, 0x5b2b63a8UL, 0x559535d5UL, 0x7511479eUL, -0xebe215e5UL, 0x30c64b94UL, 0x14a84a6fUL, 0x9c869123UL, -0xcc394c6aUL, 0xff4a5f8aUL, 0x904d0406UL, 0xddbbee99UL, -0x52ca1e11UL, 0xc418aaffUL, 0x6998eb64UL, 0xfcff07feUL, -0x5e018b34UL, 0x0ebe567dUL, 0x9bd9bae7UL, 0xc1324263UL, -0xdc7b75b5UL, 0x44179726UL, 0xcb6667aeUL, 0x0ccb9525UL, -0x9567ec9aUL, 0x2ad05786UL, 0x37996050UL, 0xd305b8e4UL, -0x83ba65adUL, 0xae3519efUL, 0xc913a4f6UL, 0x4aa9c15bUL, -0x1bd6873eUL, 0x595ea0f0UL, 0x8a5b1814UL, 0x703baf02UL, -0xe076ab04UL, 0x50bfdd49UL, 0x1863df4aUL, 0xb656c6a5UL, -0x530a853dUL, 0x1237fa87UL, 0x94a777b6UL, 0x517f4665UL, -0xb109ed61UL, 0xe6e91becUL, 0x8525d545UL, 0x3b52f575UL, -0x413d7fbaUL, 0x428827ceUL, 0x4e43b2ebUL, 0xe997d6bdUL, -0x9ef3527bUL, 0x7f456253UL, 0xfba02c3aUL, 0xd1707bbcUL, -0xf76bb91fUL, 0x171d121bUL, 0xeec8fd79UL, 0x7cf03a27UL, -0x45d70c0aUL, 0x607996ddUL, 0xf6ab2233UL, 0x1c89acfaUL, -0xbb5dc8acUL, 0x7d30a10bUL, 0xa14bd4beUL, 0x0b94bee1UL, -0x0a5425cdUL, 0x4662547eUL, 0x1182a2f3UL, 0xa33e17e6UL, -0x66e62635UL, 0x0275c358UL, 0x8b9b8338UL, 0xbdc27844UL, -0x48dc0203UL, 0xa08b4f92UL, 0xb37c2e39UL, 0x84e54e69UL, -0x8f71f088UL, 0x3927362dUL, 0xfd3f9cd2UL, 0x246e01fbUL, -0x16dd8937UL, 0x00000000UL, 0x57e0f68dUL, 0x986ce293UL, -0xf815744eUL, 0xd45a9320UL, 0x38e7ad01UL, 0x5db4d340UL, -0xc2871a17UL, 0x6a2db310UL, 0xd62f5078UL, 0x1f3cf48eUL, -0xa5a1a70eUL, 0x4c3671b3UL, 0x25ae9ad7UL, 0xdb245e71UL, -0x8750161dUL, 0xf9d5ef62UL, 0x86908d31UL, 0x1a161c12UL, -0x81cfa6f5UL, 0x6f075b8cUL, 0x1d4937d6UL, 0x3a926e59UL, -0x776484c6UL, 0x3fb886c5UL, 0xcdf9d746UL, 0xd0b0e090UL, -0x4f8329c7UL, 0x40fde496UL, 0x0d0b0e09UL, 0x56206da1UL, -0xea228ec9UL, 0x882edb4cUL, 0x738ef776UL, 0xb2bcb515UL, -0x5fc11018UL, 0xa96a322bUL, 0x8eb16ba4UL, 0x5455aef9UL, -0x89ee4060UL, 0xef086655UL, 0x2144e967UL, 0xecbd3e21UL, -0xbe772030UL, 0xc7adf28bUL, 0xe72980c0UL, 0xcf8c141eUL, -0x4348bce2UL, 0xfe8ac4a6UL, 0xc5d831d3UL, 0xfa60b716UL, -0xba9d5380UL, 0xc0f2d94fUL, 0x3e781de9UL, 0x2e3a2436UL, -0xf4dee16bUL, 0xd7efcb54UL, 0xf1f409f7UL, 0xaff582c3UL, -0xb9280bf4UL, 0xd9519d29UL, 0x9238c75eUL, 0x5aebf884UL, -0xb8e890d8UL, 0x3c0ddeb1UL, 0x8d0433d0UL, 0xe203685cUL, -0xdae4c55dUL, 0x589e3bdcUL, 0x9d460a0fUL, 0xc8d33fdaUL, -0x27db598fUL, 0x8cc4a8fcUL, 0x99ac79bfUL, 0x724e6c5aUL, -0xa2fe8ccaUL, 0xb5e39ed1UL, 0x76a41feaUL, 0x04ea73b0UL, -}, - -{ -0x68bc02e3UL, 0x85620c55UL, 0x3f23312aUL, 0xab13f761UL, -0xd46d7298UL, 0xcb9a1921UL, 0x22a4613cUL, 0x9d3dcd45UL, -0xfdb42305UL, 0xc4075f2bUL, 0x2c01c09bUL, 0xd9800f3dUL, -0x6c5c7448UL, 0x7f7e85f9UL, 0x73ab1ff1UL, 0xedde0eb6UL, -0x3c6bed28UL, 0x97781a49UL, 0x2a918d9fUL, 0x579f33c9UL, -0x07a8aaa9UL, 0x0ded7da5UL, 0x422d8f7cUL, 0x4db0c976UL, -0x91e8574dUL, 0xa963ccceUL, 0xee96d2b4UL, 0x28e1b630UL, -0xf161b90dUL, 0x196726bdUL, 0x9bad8041UL, 0xa06ec7c0UL, -0x83f24151UL, 0xdbf03492UL, 0xa21efc6fUL, 0x32ce4c8fUL, -0xe0337313UL, 0xa7c66d69UL, 0x6d6493e5UL, 0x1a2ffabfUL, -0x1cbfb7bbUL, 0x7403b558UL, 0x6e2c4fe7UL, 0x89b7965dUL, -0x9c052ae8UL, 0x6619a344UL, 0x2e71fb34UL, 0xf229650fUL, -0x81827afeUL, 0x1322f1b1UL, 0x0835eca3UL, 0x510f7ecdUL, -0x7aa614ffUL, 0x7293f85cUL, 0xc297122fUL, 0x70e3c3f3UL, -0x2f491c99UL, 0x431568d1UL, 0xa3261bc2UL, 0xcc32b388UL, -0xcf7a6f8aUL, 0xe8069fb0UL, 0x47f51e7aUL, 0xbb79dad2UL, -0x950821e6UL, 0x98e55c43UL, 0xb83106d0UL, 0xe37baf11UL, -0x4165537eUL, 0xaa2b10ccUL, 0xb4e49cd8UL, 0x56a7d464UL, -0x7c3659fbUL, 0x4b208472UL, 0x9f4df6eaUL, 0x5faadf6aUL, -0xc1dfce2dUL, 0x48685870UL, 0xaff381caUL, 0x05d89106UL, -0x774b695aUL, 0xde28a594UL, 0xdf104239UL, 0x3bc34781UL, -0x82caa6fcUL, 0xc8d2c523UL, 0xf86cb203UL, 0x0cd59a08UL, -0xb7ac40daUL, 0xb909e17dUL, 0x24342c38UL, 0x5247a2cfUL, -0xb274d1dcUL, 0xa85b2b63UL, 0xd5559535UL, 0x9e751147UL, -0xe5ebe215UL, 0x9430c64bUL, 0x6f14a84aUL, 0x239c8691UL, -0x6acc394cUL, 0x8aff4a5fUL, 0x06904d04UL, 0x99ddbbeeUL, -0x1152ca1eUL, 0xffc418aaUL, 0x646998ebUL, 0xfefcff07UL, -0x345e018bUL, 0x7d0ebe56UL, 0xe79bd9baUL, 0x63c13242UL, -0xb5dc7b75UL, 0x26441797UL, 0xaecb6667UL, 0x250ccb95UL, -0x9a9567ecUL, 0x862ad057UL, 0x50379960UL, 0xe4d305b8UL, -0xad83ba65UL, 0xefae3519UL, 0xf6c913a4UL, 0x5b4aa9c1UL, -0x3e1bd687UL, 0xf0595ea0UL, 0x148a5b18UL, 0x02703bafUL, -0x04e076abUL, 0x4950bfddUL, 0x4a1863dfUL, 0xa5b656c6UL, -0x3d530a85UL, 0x871237faUL, 0xb694a777UL, 0x65517f46UL, -0x61b109edUL, 0xece6e91bUL, 0x458525d5UL, 0x753b52f5UL, -0xba413d7fUL, 0xce428827UL, 0xeb4e43b2UL, 0xbde997d6UL, -0x7b9ef352UL, 0x537f4562UL, 0x3afba02cUL, 0xbcd1707bUL, -0x1ff76bb9UL, 0x1b171d12UL, 0x79eec8fdUL, 0x277cf03aUL, -0x0a45d70cUL, 0xdd607996UL, 0x33f6ab22UL, 0xfa1c89acUL, -0xacbb5dc8UL, 0x0b7d30a1UL, 0xbea14bd4UL, 0xe10b94beUL, -0xcd0a5425UL, 0x7e466254UL, 0xf31182a2UL, 0xe6a33e17UL, -0x3566e626UL, 0x580275c3UL, 0x388b9b83UL, 0x44bdc278UL, -0x0348dc02UL, 0x92a08b4fUL, 0x39b37c2eUL, 0x6984e54eUL, -0x888f71f0UL, 0x2d392736UL, 0xd2fd3f9cUL, 0xfb246e01UL, -0x3716dd89UL, 0x00000000UL, 0x8d57e0f6UL, 0x93986ce2UL, -0x4ef81574UL, 0x20d45a93UL, 0x0138e7adUL, 0x405db4d3UL, -0x17c2871aUL, 0x106a2db3UL, 0x78d62f50UL, 0x8e1f3cf4UL, -0x0ea5a1a7UL, 0xb34c3671UL, 0xd725ae9aUL, 0x71db245eUL, -0x1d875016UL, 0x62f9d5efUL, 0x3186908dUL, 0x121a161cUL, -0xf581cfa6UL, 0x8c6f075bUL, 0xd61d4937UL, 0x593a926eUL, -0xc6776484UL, 0xc53fb886UL, 0x46cdf9d7UL, 0x90d0b0e0UL, -0xc74f8329UL, 0x9640fde4UL, 0x090d0b0eUL, 0xa156206dUL, -0xc9ea228eUL, 0x4c882edbUL, 0x76738ef7UL, 0x15b2bcb5UL, -0x185fc110UL, 0x2ba96a32UL, 0xa48eb16bUL, 0xf95455aeUL, -0x6089ee40UL, 0x55ef0866UL, 0x672144e9UL, 0x21ecbd3eUL, -0x30be7720UL, 0x8bc7adf2UL, 0xc0e72980UL, 0x1ecf8c14UL, -0xe24348bcUL, 0xa6fe8ac4UL, 0xd3c5d831UL, 0x16fa60b7UL, -0x80ba9d53UL, 0x4fc0f2d9UL, 0xe93e781dUL, 0x362e3a24UL, -0x6bf4dee1UL, 0x54d7efcbUL, 0xf7f1f409UL, 0xc3aff582UL, -0xf4b9280bUL, 0x29d9519dUL, 0x5e9238c7UL, 0x845aebf8UL, -0xd8b8e890UL, 0xb13c0ddeUL, 0xd08d0433UL, 0x5ce20368UL, -0x5ddae4c5UL, 0xdc589e3bUL, 0x0f9d460aUL, 0xdac8d33fUL, -0x8f27db59UL, 0xfc8cc4a8UL, 0xbf99ac79UL, 0x5a724e6cUL, -0xcaa2fe8cUL, 0xd1b5e39eUL, 0xea76a41fUL, 0xb004ea73UL, -}}; - -NAMESPACE_END diff --git a/lib/cryptopp/stdcpp.h b/lib/cryptopp/stdcpp.h deleted file mode 100644 index 6511c4fa2..000000000 --- a/lib/cryptopp/stdcpp.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef CRYPTOPP_STDCPP_H -#define CRYPTOPP_STDCPP_H - -#if _MSC_VER >= 1500 -#define _DO_NOT_DECLARE_INTERLOCKED_INTRINSICS_IN_MEMORY -#include <intrin.h> -#endif - -#include <stddef.h> -#include <assert.h> -#include <limits.h> -#include <stdlib.h> -#include <string.h> -#include <memory> -#include <string> -#include <exception> -#include <typeinfo> -#include <algorithm> -#include <map> -#include <vector> - -#ifdef CRYPTOPP_INCLUDE_VECTOR_CC -// workaround needed on Sun Studio 12u1 Sun C++ 5.10 SunOS_i386 128229-02 2009/09/21 -#include <vector.cc> -#endif - -// for alloca -#ifdef __sun -#include <alloca.h> -#elif defined(__MINGW32__) || defined(__BORLANDC__) -#include <malloc.h> -#endif - -#ifdef _MSC_VER -#pragma warning(disable: 4231) // re-disable this -#ifdef _CRTAPI1 -#define CRYPTOPP_MSVCRT6 -#endif -#endif - -#endif diff --git a/lib/cryptopp/strciphr.cpp b/lib/cryptopp/strciphr.cpp deleted file mode 100644 index 53e007376..000000000 --- a/lib/cryptopp/strciphr.cpp +++ /dev/null @@ -1,252 +0,0 @@ -// strciphr.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "strciphr.h" - -NAMESPACE_BEGIN(CryptoPP) - -template <class S> -void AdditiveCipherTemplate<S>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) -{ - PolicyInterface &policy = this->AccessPolicy(); - policy.CipherSetKey(params, key, length); - m_leftOver = 0; - unsigned int bufferByteSize = policy.CanOperateKeystream() ? GetBufferByteSize(policy) : RoundUpToMultipleOf(1024U, GetBufferByteSize(policy)); - m_buffer.New(bufferByteSize); - - if (this->IsResynchronizable()) - { - size_t ivLength; - const byte *iv = this->GetIVAndThrowIfInvalid(params, ivLength); - policy.CipherResynchronize(m_buffer, iv, ivLength); - } -} - -template <class S> -void AdditiveCipherTemplate<S>::GenerateBlock(byte *outString, size_t length) -{ - if (m_leftOver > 0) - { - size_t len = STDMIN(m_leftOver, length); - memcpy(outString, KeystreamBufferEnd()-m_leftOver, len); - length -= len; - m_leftOver -= len; - outString += len; - - if (!length) - return; - } - assert(m_leftOver == 0); - - PolicyInterface &policy = this->AccessPolicy(); - unsigned int bytesPerIteration = policy.GetBytesPerIteration(); - - if (length >= bytesPerIteration) - { - size_t iterations = length / bytesPerIteration; - policy.WriteKeystream(outString, iterations); - outString += iterations * bytesPerIteration; - length -= iterations * bytesPerIteration; - } - - if (length > 0) - { - size_t bufferByteSize = RoundUpToMultipleOf(length, bytesPerIteration); - size_t bufferIterations = bufferByteSize / bytesPerIteration; - - policy.WriteKeystream(KeystreamBufferEnd()-bufferByteSize, bufferIterations); - memcpy(outString, KeystreamBufferEnd()-bufferByteSize, length); - m_leftOver = bufferByteSize - length; - } -} - -template <class S> -void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inString, size_t length) -{ - if (m_leftOver > 0) - { - size_t len = STDMIN(m_leftOver, length); - xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len); - length -= len; - m_leftOver -= len; - inString += len; - outString += len; - - if (!length) - return; - } - assert(m_leftOver == 0); - - PolicyInterface &policy = this->AccessPolicy(); - unsigned int bytesPerIteration = policy.GetBytesPerIteration(); - - if (policy.CanOperateKeystream() && length >= bytesPerIteration) - { - size_t iterations = length / bytesPerIteration; - unsigned int alignment = policy.GetAlignment(); - KeystreamOperation operation = KeystreamOperation((IsAlignedOn(inString, alignment) * 2) | (int)IsAlignedOn(outString, alignment)); - - policy.OperateKeystream(operation, outString, inString, iterations); - - inString += iterations * bytesPerIteration; - outString += iterations * bytesPerIteration; - length -= iterations * bytesPerIteration; - - if (!length) - return; - } - - size_t bufferByteSize = m_buffer.size(); - size_t bufferIterations = bufferByteSize / bytesPerIteration; - - while (length >= bufferByteSize) - { - policy.WriteKeystream(m_buffer, bufferIterations); - xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize); - length -= bufferByteSize; - inString += bufferByteSize; - outString += bufferByteSize; - } - - if (length > 0) - { - bufferByteSize = RoundUpToMultipleOf(length, bytesPerIteration); - bufferIterations = bufferByteSize / bytesPerIteration; - - policy.WriteKeystream(KeystreamBufferEnd()-bufferByteSize, bufferIterations); - xorbuf(outString, inString, KeystreamBufferEnd()-bufferByteSize, length); - m_leftOver = bufferByteSize - length; - } -} - -template <class S> -void AdditiveCipherTemplate<S>::Resynchronize(const byte *iv, int length) -{ - PolicyInterface &policy = this->AccessPolicy(); - m_leftOver = 0; - m_buffer.New(GetBufferByteSize(policy)); - policy.CipherResynchronize(m_buffer, iv, this->ThrowIfInvalidIVLength(length)); -} - -template <class BASE> -void AdditiveCipherTemplate<BASE>::Seek(lword position) -{ - PolicyInterface &policy = this->AccessPolicy(); - unsigned int bytesPerIteration = policy.GetBytesPerIteration(); - - policy.SeekToIteration(position / bytesPerIteration); - position %= bytesPerIteration; - - if (position > 0) - { - policy.WriteKeystream(KeystreamBufferEnd()-bytesPerIteration, 1); - m_leftOver = bytesPerIteration - (unsigned int)position; - } - else - m_leftOver = 0; -} - -template <class BASE> -void CFB_CipherTemplate<BASE>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) -{ - PolicyInterface &policy = this->AccessPolicy(); - policy.CipherSetKey(params, key, length); - - if (this->IsResynchronizable()) - { - size_t ivLength; - const byte *iv = this->GetIVAndThrowIfInvalid(params, ivLength); - policy.CipherResynchronize(iv, ivLength); - } - - m_leftOver = policy.GetBytesPerIteration(); -} - -template <class BASE> -void CFB_CipherTemplate<BASE>::Resynchronize(const byte *iv, int length) -{ - PolicyInterface &policy = this->AccessPolicy(); - policy.CipherResynchronize(iv, this->ThrowIfInvalidIVLength(length)); - m_leftOver = policy.GetBytesPerIteration(); -} - -template <class BASE> -void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString, size_t length) -{ - assert(length % this->MandatoryBlockSize() == 0); - - PolicyInterface &policy = this->AccessPolicy(); - unsigned int bytesPerIteration = policy.GetBytesPerIteration(); - unsigned int alignment = policy.GetAlignment(); - byte *reg = policy.GetRegisterBegin(); - - if (m_leftOver) - { - size_t len = STDMIN(m_leftOver, length); - CombineMessageAndShiftRegister(outString, reg + bytesPerIteration - m_leftOver, inString, len); - m_leftOver -= len; - length -= len; - inString += len; - outString += len; - } - - if (!length) - return; - - assert(m_leftOver == 0); - - if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment)) - { - if (IsAlignedOn(inString, alignment)) - policy.Iterate(outString, inString, GetCipherDir(*this), length / bytesPerIteration); - else - { - memcpy(outString, inString, length); - policy.Iterate(outString, outString, GetCipherDir(*this), length / bytesPerIteration); - } - inString += length - length % bytesPerIteration; - outString += length - length % bytesPerIteration; - length %= bytesPerIteration; - } - - while (length >= bytesPerIteration) - { - policy.TransformRegister(); - CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration); - length -= bytesPerIteration; - inString += bytesPerIteration; - outString += bytesPerIteration; - } - - if (length > 0) - { - policy.TransformRegister(); - CombineMessageAndShiftRegister(outString, reg, inString, length); - m_leftOver = bytesPerIteration - length; - } -} - -template <class BASE> -void CFB_EncryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) -{ - xorbuf(reg, message, length); - memcpy(output, reg, length); -} - -template <class BASE> -void CFB_DecryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) -{ - for (unsigned int i=0; i<length; i++) - { - byte b = message[i]; - output[i] = reg[i] ^ b; - reg[i] = b; - } -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/strciphr.h b/lib/cryptopp/strciphr.h deleted file mode 100644 index d1d11a17b..000000000 --- a/lib/cryptopp/strciphr.h +++ /dev/null @@ -1,306 +0,0 @@ -/*! \file - This file contains helper classes for implementing stream ciphers. - - All this infrastructure may look very complex compared to what's in Crypto++ 4.x, - but stream ciphers implementations now support a lot of new functionality, - including better performance (minimizing copying), resetting of keys and IVs, and methods to - query which features are supported by a cipher. - - Here's an explanation of these classes. The word "policy" is used here to mean a class with a - set of methods that must be implemented by individual stream cipher implementations. - This is usually much simpler than the full stream cipher API, which is implemented by - either AdditiveCipherTemplate or CFB_CipherTemplate using the policy. So for example, an - implementation of SEAL only needs to implement the AdditiveCipherAbstractPolicy interface - (since it's an additive cipher, i.e., it xors a keystream into the plaintext). - See this line in seal.h: - - typedef SymmetricCipherFinal\<ConcretePolicyHolder\<SEAL_Policy\<B\>, AdditiveCipherTemplate\<\> \> \> Encryption; - - AdditiveCipherTemplate and CFB_CipherTemplate are designed so that they don't need - to take a policy class as a template parameter (although this is allowed), so that - their code is not duplicated for each new cipher. Instead they each - get a reference to an abstract policy interface by calling AccessPolicy() on itself, so - AccessPolicy() must be overriden to return the actual policy reference. This is done - by the ConceretePolicyHolder class. Finally, SymmetricCipherFinal implements the constructors and - other functions that must be implemented by the most derived class. -*/ - -#ifndef CRYPTOPP_STRCIPHR_H -#define CRYPTOPP_STRCIPHR_H - -#include "seckey.h" -#include "secblock.h" -#include "argnames.h" - -NAMESPACE_BEGIN(CryptoPP) - -template <class POLICY_INTERFACE, class BASE = Empty> -class CRYPTOPP_NO_VTABLE AbstractPolicyHolder : public BASE -{ -public: - typedef POLICY_INTERFACE PolicyInterface; - virtual ~AbstractPolicyHolder() {} - -protected: - virtual const POLICY_INTERFACE & GetPolicy() const =0; - virtual POLICY_INTERFACE & AccessPolicy() =0; -}; - -template <class POLICY, class BASE, class POLICY_INTERFACE = CPP_TYPENAME BASE::PolicyInterface> -class ConcretePolicyHolder : public BASE, protected POLICY -{ -protected: - const POLICY_INTERFACE & GetPolicy() const {return *this;} - POLICY_INTERFACE & AccessPolicy() {return *this;} -}; - -enum KeystreamOperationFlags {OUTPUT_ALIGNED=1, INPUT_ALIGNED=2, INPUT_NULL = 4}; -enum KeystreamOperation { - WRITE_KEYSTREAM = INPUT_NULL, - WRITE_KEYSTREAM_ALIGNED = INPUT_NULL | OUTPUT_ALIGNED, - XOR_KEYSTREAM = 0, - XOR_KEYSTREAM_INPUT_ALIGNED = INPUT_ALIGNED, - XOR_KEYSTREAM_OUTPUT_ALIGNED= OUTPUT_ALIGNED, - XOR_KEYSTREAM_BOTH_ALIGNED = OUTPUT_ALIGNED | INPUT_ALIGNED}; - -struct CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AdditiveCipherAbstractPolicy -{ - virtual ~AdditiveCipherAbstractPolicy() {} - virtual unsigned int GetAlignment() const {return 1;} - virtual unsigned int GetBytesPerIteration() const =0; - virtual unsigned int GetOptimalBlockSize() const {return GetBytesPerIteration();} - virtual unsigned int GetIterationsToBuffer() const =0; - virtual void WriteKeystream(byte *keystream, size_t iterationCount) - {OperateKeystream(KeystreamOperation(INPUT_NULL | (KeystreamOperationFlags)IsAlignedOn(keystream, GetAlignment())), keystream, NULL, iterationCount);} - virtual bool CanOperateKeystream() const {return false;} - virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) {assert(false);} - virtual void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) =0; - virtual void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length) {throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");} - virtual bool CipherIsRandomAccess() const =0; - virtual void SeekToIteration(lword iterationCount) {assert(!CipherIsRandomAccess()); throw NotImplemented("StreamTransformation: this object doesn't support random access");} -}; - -template <typename WT, unsigned int W, unsigned int X = 1, class BASE = AdditiveCipherAbstractPolicy> -struct CRYPTOPP_NO_VTABLE AdditiveCipherConcretePolicy : public BASE -{ - typedef WT WordType; - CRYPTOPP_CONSTANT(BYTES_PER_ITERATION = sizeof(WordType) * W) - -#if !(CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64) - unsigned int GetAlignment() const {return GetAlignmentOf<WordType>();} -#endif - unsigned int GetBytesPerIteration() const {return BYTES_PER_ITERATION;} - unsigned int GetIterationsToBuffer() const {return X;} - bool CanOperateKeystream() const {return true;} - virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) =0; -}; - -// use these to implement OperateKeystream -#define CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, b, i, a) \ - PutWord(bool(x & OUTPUT_ALIGNED), b, output+i*sizeof(WordType), (x & INPUT_NULL) ? a : a ^ GetWord<WordType>(bool(x & INPUT_ALIGNED), b, input+i*sizeof(WordType))); -#define CRYPTOPP_KEYSTREAM_OUTPUT_XMM(x, i, a) {\ - __m128i t = (x & INPUT_NULL) ? a : _mm_xor_si128(a, (x & INPUT_ALIGNED) ? _mm_load_si128((__m128i *)input+i) : _mm_loadu_si128((__m128i *)input+i));\ - if (x & OUTPUT_ALIGNED) _mm_store_si128((__m128i *)output+i, t);\ - else _mm_storeu_si128((__m128i *)output+i, t);} -#define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y) \ - switch (operation) \ - { \ - case WRITE_KEYSTREAM: \ - x(WRITE_KEYSTREAM) \ - break; \ - case XOR_KEYSTREAM: \ - x(XOR_KEYSTREAM) \ - input += y; \ - break; \ - case XOR_KEYSTREAM_INPUT_ALIGNED: \ - x(XOR_KEYSTREAM_INPUT_ALIGNED) \ - input += y; \ - break; \ - case XOR_KEYSTREAM_OUTPUT_ALIGNED: \ - x(XOR_KEYSTREAM_OUTPUT_ALIGNED) \ - input += y; \ - break; \ - case WRITE_KEYSTREAM_ALIGNED: \ - x(WRITE_KEYSTREAM_ALIGNED) \ - break; \ - case XOR_KEYSTREAM_BOTH_ALIGNED: \ - x(XOR_KEYSTREAM_BOTH_ALIGNED) \ - input += y; \ - break; \ - } \ - output += y; - -template <class BASE = AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher> > -class CRYPTOPP_NO_VTABLE AdditiveCipherTemplate : public BASE, public RandomNumberGenerator -{ -public: - void GenerateBlock(byte *output, size_t size); - void ProcessData(byte *outString, const byte *inString, size_t length); - void Resynchronize(const byte *iv, int length=-1); - unsigned int OptimalBlockSize() const {return this->GetPolicy().GetOptimalBlockSize();} - unsigned int GetOptimalNextBlockSize() const {return (unsigned int)this->m_leftOver;} - unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();} - bool IsSelfInverting() const {return true;} - bool IsForwardTransformation() const {return true;} - bool IsRandomAccess() const {return this->GetPolicy().CipherIsRandomAccess();} - void Seek(lword position); - - typedef typename BASE::PolicyInterface PolicyInterface; - -protected: - void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); - - unsigned int GetBufferByteSize(const PolicyInterface &policy) const {return policy.GetBytesPerIteration() * policy.GetIterationsToBuffer();} - - inline byte * KeystreamBufferBegin() {return this->m_buffer.data();} - inline byte * KeystreamBufferEnd() {return (this->m_buffer.data() + this->m_buffer.size());} - - SecByteBlock m_buffer; - size_t m_leftOver; -}; - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_CipherAbstractPolicy -{ -public: - virtual ~CFB_CipherAbstractPolicy() {} - virtual unsigned int GetAlignment() const =0; - virtual unsigned int GetBytesPerIteration() const =0; - virtual byte * GetRegisterBegin() =0; - virtual void TransformRegister() =0; - virtual bool CanIterate() const {return false;} - virtual void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount) {assert(false); throw 0;} - virtual void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) =0; - virtual void CipherResynchronize(const byte *iv, size_t length) {throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");} -}; - -template <typename WT, unsigned int W, class BASE = CFB_CipherAbstractPolicy> -struct CRYPTOPP_NO_VTABLE CFB_CipherConcretePolicy : public BASE -{ - typedef WT WordType; - - unsigned int GetAlignment() const {return sizeof(WordType);} - unsigned int GetBytesPerIteration() const {return sizeof(WordType) * W;} - bool CanIterate() const {return true;} - void TransformRegister() {this->Iterate(NULL, NULL, ENCRYPTION, 1);} - - template <class B> - struct RegisterOutput - { - RegisterOutput(byte *output, const byte *input, CipherDir dir) - : m_output(output), m_input(input), m_dir(dir) {} - - inline RegisterOutput& operator()(WordType ®isterWord) - { - assert(IsAligned<WordType>(m_output)); - assert(IsAligned<WordType>(m_input)); - - if (!NativeByteOrderIs(B::ToEnum())) - registerWord = ByteReverse(registerWord); - - if (m_dir == ENCRYPTION) - { - if (m_input == NULL) - assert(m_output == NULL); - else - { - WordType ct = *(const WordType *)m_input ^ registerWord; - registerWord = ct; - *(WordType*)m_output = ct; - m_input += sizeof(WordType); - m_output += sizeof(WordType); - } - } - else - { - WordType ct = *(const WordType *)m_input; - *(WordType*)m_output = registerWord ^ ct; - registerWord = ct; - m_input += sizeof(WordType); - m_output += sizeof(WordType); - } - - // registerWord is left unreversed so it can be xor-ed with further input - - return *this; - } - - byte *m_output; - const byte *m_input; - CipherDir m_dir; - }; -}; - -template <class BASE> -class CRYPTOPP_NO_VTABLE CFB_CipherTemplate : public BASE -{ -public: - void ProcessData(byte *outString, const byte *inString, size_t length); - void Resynchronize(const byte *iv, int length=-1); - unsigned int OptimalBlockSize() const {return this->GetPolicy().GetBytesPerIteration();} - unsigned int GetOptimalNextBlockSize() const {return (unsigned int)m_leftOver;} - unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();} - bool IsRandomAccess() const {return false;} - bool IsSelfInverting() const {return false;} - - typedef typename BASE::PolicyInterface PolicyInterface; - -protected: - virtual void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) =0; - - void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); - - size_t m_leftOver; -}; - -template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> > -class CRYPTOPP_NO_VTABLE CFB_EncryptionTemplate : public CFB_CipherTemplate<BASE> -{ - bool IsForwardTransformation() const {return true;} - void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length); -}; - -template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> > -class CRYPTOPP_NO_VTABLE CFB_DecryptionTemplate : public CFB_CipherTemplate<BASE> -{ - bool IsForwardTransformation() const {return false;} - void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length); -}; - -template <class BASE> -class CFB_RequireFullDataBlocks : public BASE -{ -public: - unsigned int MandatoryBlockSize() const {return this->OptimalBlockSize();} -}; - -//! _ -template <class BASE, class INFO = BASE> -class SymmetricCipherFinal : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO> -{ -public: - SymmetricCipherFinal() {} - SymmetricCipherFinal(const byte *key) - {this->SetKey(key, this->DEFAULT_KEYLENGTH);} - SymmetricCipherFinal(const byte *key, size_t length) - {this->SetKey(key, length);} - SymmetricCipherFinal(const byte *key, size_t length, const byte *iv) - {this->SetKeyWithIV(key, length, iv);} - - Clonable * Clone() const {return static_cast<SymmetricCipher *>(new SymmetricCipherFinal<BASE, INFO>(*this));} -}; - -NAMESPACE_END - -#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES -#include "strciphr.cpp" -#endif - -NAMESPACE_BEGIN(CryptoPP) -CRYPTOPP_DLL_TEMPLATE_CLASS AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher>; -CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, SymmetricCipher> >; -CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >; -CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >; -CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >; -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/tea.cpp b/lib/cryptopp/tea.cpp deleted file mode 100644 index b1fb6f140..000000000 --- a/lib/cryptopp/tea.cpp +++ /dev/null @@ -1,159 +0,0 @@ -// tea.cpp - modified by Wei Dai from code in the original paper - -#include "pch.h" -#include "tea.h" -#include "misc.h" - -NAMESPACE_BEGIN(CryptoPP) - -static const word32 DELTA = 0x9e3779b9; -typedef BlockGetAndPut<word32, BigEndian> Block; - -void TEA::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) -{ - AssertValidKeyLength(length); - - GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, userKey, KEYLENGTH); - m_limit = GetRoundsAndThrowIfInvalid(params, this) * DELTA; -} - -void TEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - word32 y, z; - Block::Get(inBlock)(y)(z); - - word32 sum = 0; - while (sum != m_limit) - { - sum += DELTA; - y += (z << 4) + m_k[0] ^ z + sum ^ (z >> 5) + m_k[1]; - z += (y << 4) + m_k[2] ^ y + sum ^ (y >> 5) + m_k[3]; - } - - Block::Put(xorBlock, outBlock)(y)(z); -} - -void TEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - word32 y, z; - Block::Get(inBlock)(y)(z); - - word32 sum = m_limit; - while (sum != 0) - { - z -= (y << 4) + m_k[2] ^ y + sum ^ (y >> 5) + m_k[3]; - y -= (z << 4) + m_k[0] ^ z + sum ^ (z >> 5) + m_k[1]; - sum -= DELTA; - } - - Block::Put(xorBlock, outBlock)(y)(z); -} - -void XTEA::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) -{ - AssertValidKeyLength(length); - - GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, userKey, KEYLENGTH); - m_limit = GetRoundsAndThrowIfInvalid(params, this) * DELTA; -} - -void XTEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - word32 y, z; - Block::Get(inBlock)(y)(z); - -#ifdef __SUNPRO_CC - // workaround needed on Sun Studio 12u1 Sun C++ 5.10 SunOS_i386 128229-02 2009/09/21 - size_t sum = 0; - while ((sum&0xffffffff) != m_limit) -#else - word32 sum = 0; - while (sum != m_limit) -#endif - { - y += (z<<4 ^ z>>5) + z ^ sum + m_k[sum&3]; - sum += DELTA; - z += (y<<4 ^ y>>5) + y ^ sum + m_k[sum>>11 & 3]; - } - - Block::Put(xorBlock, outBlock)(y)(z); -} - -void XTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - word32 y, z; - Block::Get(inBlock)(y)(z); - -#ifdef __SUNPRO_CC - // workaround needed on Sun Studio 12u1 Sun C++ 5.10 SunOS_i386 128229-02 2009/09/21 - size_t sum = m_limit; - while ((sum&0xffffffff) != 0) -#else - word32 sum = m_limit; - while (sum != 0) -#endif - { - z -= (y<<4 ^ y>>5) + y ^ sum + m_k[sum>>11 & 3]; - sum -= DELTA; - y -= (z<<4 ^ z>>5) + z ^ sum + m_k[sum&3]; - } - - Block::Put(xorBlock, outBlock)(y)(z); -} - -#define MX (z>>5^y<<2)+(y>>3^z<<4)^(sum^y)+(m_k[p&3^e]^z) - -void BTEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - unsigned int n = m_blockSize / 4; - word32 *v = (word32*)outBlock; - ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)inBlock, m_blockSize); - - word32 y = v[0], z = v[n-1], e; - word32 p, q = 6+52/n; - word32 sum = 0; - - while (q-- > 0) - { - sum += DELTA; - e = sum>>2 & 3; - for (p = 0; p < n-1; p++) - { - y = v[p+1]; - z = v[p] += MX; - } - y = v[0]; - z = v[n-1] += MX; - } - - ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize); -} - -void BTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - unsigned int n = m_blockSize / 4; - word32 *v = (word32*)outBlock; - ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)inBlock, m_blockSize); - - word32 y = v[0], z = v[n-1], e; - word32 p, q = 6+52/n; - word32 sum = q * DELTA; - - while (sum != 0) - { - e = sum>>2 & 3; - for (p = n-1; p > 0; p--) - { - z = v[p-1]; - y = v[p] -= MX; - } - - z = v[n-1]; - y = v[0] -= MX; - sum -= DELTA; - } - - ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize); -} - -NAMESPACE_END diff --git a/lib/cryptopp/tea.h b/lib/cryptopp/tea.h deleted file mode 100644 index d8ddded86..000000000 --- a/lib/cryptopp/tea.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef CRYPTOPP_TEA_H -#define CRYPTOPP_TEA_H - -/** \file -*/ - -#include "seckey.h" -#include "secblock.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -struct TEA_Info : public FixedBlockSize<8>, public FixedKeyLength<16>, public VariableRounds<32> -{ - static const char *StaticAlgorithmName() {return "TEA";} -}; - -/// <a href="http://www.weidai.com/scan-mirror/cs.html#TEA">TEA</a> -class TEA : public TEA_Info, public BlockCipherDocumentation -{ - class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<TEA_Info> - { - public: - void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); - - protected: - FixedSizeSecBlock<word32, 4> m_k; - word32 m_limit; - }; - - class CRYPTOPP_NO_VTABLE Enc : public Base - { - public: - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - }; - - class CRYPTOPP_NO_VTABLE Dec : public Base - { - public: - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - }; - -public: - typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption; - typedef BlockCipherFinal<DECRYPTION, Dec> Decryption; -}; - -typedef TEA::Encryption TEAEncryption; -typedef TEA::Decryption TEADecryption; - -//! _ -struct XTEA_Info : public FixedBlockSize<8>, public FixedKeyLength<16>, public VariableRounds<32> -{ - static const char *StaticAlgorithmName() {return "XTEA";} -}; - -/// <a href="http://www.weidai.com/scan-mirror/cs.html#TEA">XTEA</a> -class XTEA : public XTEA_Info, public BlockCipherDocumentation -{ - class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<XTEA_Info> - { - public: - void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); - - protected: - FixedSizeSecBlock<word32, 4> m_k; - word32 m_limit; - }; - - class CRYPTOPP_NO_VTABLE Enc : public Base - { - public: - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - }; - - class CRYPTOPP_NO_VTABLE Dec : public Base - { - public: - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - }; - -public: - typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption; - typedef BlockCipherFinal<DECRYPTION, Dec> Decryption; -}; - -//! _ -struct BTEA_Info : public FixedKeyLength<16> -{ - static const char *StaticAlgorithmName() {return "BTEA";} -}; - -//! <a href="http://www.weidai.com/scan-mirror/cs.html#TEA">corrected Block TEA</a> (as described in "xxtea"). -/*! This class hasn't been tested yet. */ -class BTEA : public BTEA_Info, public BlockCipherDocumentation -{ - class CRYPTOPP_NO_VTABLE Base : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BlockCipher, BTEA_Info>, BTEA_Info>, public BTEA_Info - { - public: - void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) - { - m_blockSize = params.GetIntValueWithDefault("BlockSize", 60*4); - GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, key, KEYLENGTH); - } - - unsigned int BlockSize() const {return m_blockSize;} - - protected: - FixedSizeSecBlock<word32, 4> m_k; - unsigned int m_blockSize; - }; - - class CRYPTOPP_NO_VTABLE Enc : public Base - { - public: - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - }; - - class CRYPTOPP_NO_VTABLE Dec : public Base - { - public: - void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - }; - -public: - typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption; - typedef BlockCipherFinal<DECRYPTION, Dec> Decryption; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/tiger.cpp b/lib/cryptopp/tiger.cpp deleted file mode 100644 index c6c05caed..000000000 --- a/lib/cryptopp/tiger.cpp +++ /dev/null @@ -1,265 +0,0 @@ -// tiger.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "tiger.h" -#include "misc.h" -#include "cpu.h" - -NAMESPACE_BEGIN(CryptoPP) - -void Tiger::InitState(HashWordType *state) -{ - state[0] = W64LIT(0x0123456789ABCDEF); - state[1] = W64LIT(0xFEDCBA9876543210); - state[2] = W64LIT(0xF096A5B4C3B2E187); -} - -void Tiger::TruncatedFinal(byte *hash, size_t size) -{ - ThrowIfInvalidTruncatedSize(size); - - PadLastBlock(56, 0x01); - CorrectEndianess(m_data, m_data, 56); - - m_data[7] = GetBitCountLo(); - - Transform(m_state, m_data); - CorrectEndianess(m_state, m_state, DigestSize()); - memcpy(hash, m_state, size); - - Restart(); // reinit for next use -} - -void Tiger::Transform (word64 *digest, const word64 *X) -{ -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 - if (HasSSE2()) - { -#ifdef __GNUC__ - __asm__ __volatile__ - ( - ".intel_syntax noprefix;" - AS1( push ebx) -#else - #if _MSC_VER < 1300 - const word64 *t = table; - AS2( mov edx, t) - #else - AS2( lea edx, [table]) - #endif - AS2( mov eax, digest) - AS2( mov esi, X) -#endif - AS2( movq mm0, [eax]) - AS2( movq mm1, [eax+1*8]) - AS2( movq mm5, mm1) - AS2( movq mm2, [eax+2*8]) - AS2( movq mm7, [edx+4*2048+0*8]) - AS2( movq mm6, [edx+4*2048+1*8]) - AS2( mov ecx, esp) - AS2( and esp, 0xfffffff0) - AS2( sub esp, 8*8) - AS1( push ecx) - -#define SSE2_round(a,b,c,x,mul) \ - AS2( pxor c, [x])\ - AS2( movd ecx, c)\ - AS2( movzx edi, cl)\ - AS2( movq mm3, [edx+0*2048+edi*8])\ - AS2( movzx edi, ch)\ - AS2( movq mm4, [edx+3*2048+edi*8])\ - AS2( shr ecx, 16)\ - AS2( movzx edi, cl)\ - AS2( pxor mm3, [edx+1*2048+edi*8])\ - AS2( movzx edi, ch)\ - AS2( pxor mm4, [edx+2*2048+edi*8])\ - AS3( pextrw ecx, c, 2)\ - AS2( movzx edi, cl)\ - AS2( pxor mm3, [edx+2*2048+edi*8])\ - AS2( movzx edi, ch)\ - AS2( pxor mm4, [edx+1*2048+edi*8])\ - AS3( pextrw ecx, c, 3)\ - AS2( movzx edi, cl)\ - AS2( pxor mm3, [edx+3*2048+edi*8])\ - AS2( psubq a, mm3)\ - AS2( movzx edi, ch)\ - AS2( pxor mm4, [edx+0*2048+edi*8])\ - AS2( paddq b, mm4)\ - SSE2_mul_##mul(b) - -#define SSE2_mul_5(b) \ - AS2( movq mm3, b)\ - AS2( psllq b, 2)\ - AS2( paddq b, mm3) - -#define SSE2_mul_7(b) \ - AS2( movq mm3, b)\ - AS2( psllq b, 3)\ - AS2( psubq b, mm3) - -#define SSE2_mul_9(b) \ - AS2( movq mm3, b)\ - AS2( psllq b, 3)\ - AS2( paddq b, mm3) - -#define label2_5 1 -#define label2_7 2 -#define label2_9 3 - -#define SSE2_pass(A,B,C,mul,X) \ - AS2( xor ebx, ebx)\ - ASL(mul)\ - SSE2_round(A,B,C,X+0*8+ebx,mul)\ - SSE2_round(B,C,A,X+1*8+ebx,mul)\ - AS2( cmp ebx, 6*8)\ - ASJ( je, label2_##mul, f)\ - SSE2_round(C,A,B,X+2*8+ebx,mul)\ - AS2( add ebx, 3*8)\ - ASJ( jmp, mul, b)\ - ASL(label2_##mul) - -#define SSE2_key_schedule(Y,X) \ - AS2( movq mm3, [X+7*8])\ - AS2( pxor mm3, mm6)\ - AS2( movq mm4, [X+0*8])\ - AS2( psubq mm4, mm3)\ - AS2( movq [Y+0*8], mm4)\ - AS2( pxor mm4, [X+1*8])\ - AS2( movq mm3, mm4)\ - AS2( movq [Y+1*8], mm4)\ - AS2( paddq mm4, [X+2*8])\ - AS2( pxor mm3, mm7)\ - AS2( psllq mm3, 19)\ - AS2( movq [Y+2*8], mm4)\ - AS2( pxor mm3, mm4)\ - AS2( movq mm4, [X+3*8])\ - AS2( psubq mm4, mm3)\ - AS2( movq [Y+3*8], mm4)\ - AS2( pxor mm4, [X+4*8])\ - AS2( movq mm3, mm4)\ - AS2( movq [Y+4*8], mm4)\ - AS2( paddq mm4, [X+5*8])\ - AS2( pxor mm3, mm7)\ - AS2( psrlq mm3, 23)\ - AS2( movq [Y+5*8], mm4)\ - AS2( pxor mm3, mm4)\ - AS2( movq mm4, [X+6*8])\ - AS2( psubq mm4, mm3)\ - AS2( movq [Y+6*8], mm4)\ - AS2( pxor mm4, [X+7*8])\ - AS2( movq mm3, mm4)\ - AS2( movq [Y+7*8], mm4)\ - AS2( paddq mm4, [Y+0*8])\ - AS2( pxor mm3, mm7)\ - AS2( psllq mm3, 19)\ - AS2( movq [Y+0*8], mm4)\ - AS2( pxor mm3, mm4)\ - AS2( movq mm4, [Y+1*8])\ - AS2( psubq mm4, mm3)\ - AS2( movq [Y+1*8], mm4)\ - AS2( pxor mm4, [Y+2*8])\ - AS2( movq mm3, mm4)\ - AS2( movq [Y+2*8], mm4)\ - AS2( paddq mm4, [Y+3*8])\ - AS2( pxor mm3, mm7)\ - AS2( psrlq mm3, 23)\ - AS2( movq [Y+3*8], mm4)\ - AS2( pxor mm3, mm4)\ - AS2( movq mm4, [Y+4*8])\ - AS2( psubq mm4, mm3)\ - AS2( movq [Y+4*8], mm4)\ - AS2( pxor mm4, [Y+5*8])\ - AS2( movq [Y+5*8], mm4)\ - AS2( paddq mm4, [Y+6*8])\ - AS2( movq [Y+6*8], mm4)\ - AS2( pxor mm4, [edx+4*2048+2*8])\ - AS2( movq mm3, [Y+7*8])\ - AS2( psubq mm3, mm4)\ - AS2( movq [Y+7*8], mm3) - - SSE2_pass(mm0, mm1, mm2, 5, esi) - SSE2_key_schedule(esp+4, esi) - SSE2_pass(mm2, mm0, mm1, 7, esp+4) - SSE2_key_schedule(esp+4, esp+4) - SSE2_pass(mm1, mm2, mm0, 9, esp+4) - - AS2( pxor mm0, [eax+0*8]) - AS2( movq [eax+0*8], mm0) - AS2( psubq mm1, mm5) - AS2( movq [eax+1*8], mm1) - AS2( paddq mm2, [eax+2*8]) - AS2( movq [eax+2*8], mm2) - - AS1( pop esp) - AS1( emms) -#ifdef __GNUC__ - AS1( pop ebx) - ".att_syntax prefix;" - : - : "a" (digest), "S" (X), "d" (table) - : "%ecx", "%edi", "memory", "cc" - ); -#endif - } - else -#endif - { - word64 a = digest[0]; - word64 b = digest[1]; - word64 c = digest[2]; - word64 Y[8]; - -#define t1 (table) -#define t2 (table+256) -#define t3 (table+256*2) -#define t4 (table+256*3) - -#define round(a,b,c,x,mul) \ - c ^= x; \ - a -= t1[GETBYTE(c,0)] ^ t2[GETBYTE(c,2)] ^ t3[GETBYTE(c,4)] ^ t4[GETBYTE(c,6)]; \ - b += t4[GETBYTE(c,1)] ^ t3[GETBYTE(c,3)] ^ t2[GETBYTE(c,5)] ^ t1[GETBYTE(c,7)]; \ - b *= mul - -#define pass(a,b,c,mul,X) {\ - int i=0;\ - while (true)\ - {\ - round(a,b,c,X[i+0],mul); \ - round(b,c,a,X[i+1],mul); \ - if (i==6)\ - break;\ - round(c,a,b,X[i+2],mul); \ - i+=3;\ - }} - -#define key_schedule(Y,X) \ - Y[0] = X[0] - (X[7]^W64LIT(0xA5A5A5A5A5A5A5A5)); \ - Y[1] = X[1] ^ Y[0]; \ - Y[2] = X[2] + Y[1]; \ - Y[3] = X[3] - (Y[2] ^ ((~Y[1])<<19)); \ - Y[4] = X[4] ^ Y[3]; \ - Y[5] = X[5] + Y[4]; \ - Y[6] = X[6] - (Y[5] ^ ((~Y[4])>>23)); \ - Y[7] = X[7] ^ Y[6]; \ - Y[0] += Y[7]; \ - Y[1] -= Y[0] ^ ((~Y[7])<<19); \ - Y[2] ^= Y[1]; \ - Y[3] += Y[2]; \ - Y[4] -= Y[3] ^ ((~Y[2])>>23); \ - Y[5] ^= Y[4]; \ - Y[6] += Y[5]; \ - Y[7] -= Y[6] ^ W64LIT(0x0123456789ABCDEF) - - pass(a,b,c,5,X); - key_schedule(Y,X); - pass(c,a,b,7,Y); - key_schedule(Y,Y); - pass(b,c,a,9,Y); - - digest[0] = a ^ digest[0]; - digest[1] = b - digest[1]; - digest[2] = c + digest[2]; - } -} - -NAMESPACE_END diff --git a/lib/cryptopp/tiger.h b/lib/cryptopp/tiger.h deleted file mode 100644 index 5f6e941ac..000000000 --- a/lib/cryptopp/tiger.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef CRYPTOPP_TIGER_H -#define CRYPTOPP_TIGER_H - -#include "config.h" -#include "iterhash.h" - -NAMESPACE_BEGIN(CryptoPP) - -/// <a href="http://www.cryptolounge.org/wiki/Tiger">Tiger</a> -class Tiger : public IteratedHashWithStaticTransform<word64, LittleEndian, 64, 24, Tiger> -{ -public: - static void InitState(HashWordType *state); - static void Transform(word64 *digest, const word64 *data); - void TruncatedFinal(byte *hash, size_t size); - static const char * StaticAlgorithmName() {return "Tiger";} - -protected: - static const word64 table[4*256+3]; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/tigertab.cpp b/lib/cryptopp/tigertab.cpp deleted file mode 100644 index 5c1595b5b..000000000 --- a/lib/cryptopp/tigertab.cpp +++ /dev/null @@ -1,525 +0,0 @@ -#include "pch.h" -#include "tiger.h" - -NAMESPACE_BEGIN(CryptoPP) - -const word64 Tiger::table[4*256+3] = -{ - W64LIT(0x02AAB17CF7E90C5E) /* 0 */, W64LIT(0xAC424B03E243A8EC) /* 1 */, - W64LIT(0x72CD5BE30DD5FCD3) /* 2 */, W64LIT(0x6D019B93F6F97F3A) /* 3 */, - W64LIT(0xCD9978FFD21F9193) /* 4 */, W64LIT(0x7573A1C9708029E2) /* 5 */, - W64LIT(0xB164326B922A83C3) /* 6 */, W64LIT(0x46883EEE04915870) /* 7 */, - W64LIT(0xEAACE3057103ECE6) /* 8 */, W64LIT(0xC54169B808A3535C) /* 9 */, - W64LIT(0x4CE754918DDEC47C) /* 10 */, W64LIT(0x0AA2F4DFDC0DF40C) /* 11 */, - W64LIT(0x10B76F18A74DBEFA) /* 12 */, W64LIT(0xC6CCB6235AD1AB6A) /* 13 */, - W64LIT(0x13726121572FE2FF) /* 14 */, W64LIT(0x1A488C6F199D921E) /* 15 */, - W64LIT(0x4BC9F9F4DA0007CA) /* 16 */, W64LIT(0x26F5E6F6E85241C7) /* 17 */, - W64LIT(0x859079DBEA5947B6) /* 18 */, W64LIT(0x4F1885C5C99E8C92) /* 19 */, - W64LIT(0xD78E761EA96F864B) /* 20 */, W64LIT(0x8E36428C52B5C17D) /* 21 */, - W64LIT(0x69CF6827373063C1) /* 22 */, W64LIT(0xB607C93D9BB4C56E) /* 23 */, - W64LIT(0x7D820E760E76B5EA) /* 24 */, W64LIT(0x645C9CC6F07FDC42) /* 25 */, - W64LIT(0xBF38A078243342E0) /* 26 */, W64LIT(0x5F6B343C9D2E7D04) /* 27 */, - W64LIT(0xF2C28AEB600B0EC6) /* 28 */, W64LIT(0x6C0ED85F7254BCAC) /* 29 */, - W64LIT(0x71592281A4DB4FE5) /* 30 */, W64LIT(0x1967FA69CE0FED9F) /* 31 */, - W64LIT(0xFD5293F8B96545DB) /* 32 */, W64LIT(0xC879E9D7F2A7600B) /* 33 */, - W64LIT(0x860248920193194E) /* 34 */, W64LIT(0xA4F9533B2D9CC0B3) /* 35 */, - W64LIT(0x9053836C15957613) /* 36 */, W64LIT(0xDB6DCF8AFC357BF1) /* 37 */, - W64LIT(0x18BEEA7A7A370F57) /* 38 */, W64LIT(0x037117CA50B99066) /* 39 */, - W64LIT(0x6AB30A9774424A35) /* 40 */, W64LIT(0xF4E92F02E325249B) /* 41 */, - W64LIT(0x7739DB07061CCAE1) /* 42 */, W64LIT(0xD8F3B49CECA42A05) /* 43 */, - W64LIT(0xBD56BE3F51382F73) /* 44 */, W64LIT(0x45FAED5843B0BB28) /* 45 */, - W64LIT(0x1C813D5C11BF1F83) /* 46 */, W64LIT(0x8AF0E4B6D75FA169) /* 47 */, - W64LIT(0x33EE18A487AD9999) /* 48 */, W64LIT(0x3C26E8EAB1C94410) /* 49 */, - W64LIT(0xB510102BC0A822F9) /* 50 */, W64LIT(0x141EEF310CE6123B) /* 51 */, - W64LIT(0xFC65B90059DDB154) /* 52 */, W64LIT(0xE0158640C5E0E607) /* 53 */, - W64LIT(0x884E079826C3A3CF) /* 54 */, W64LIT(0x930D0D9523C535FD) /* 55 */, - W64LIT(0x35638D754E9A2B00) /* 56 */, W64LIT(0x4085FCCF40469DD5) /* 57 */, - W64LIT(0xC4B17AD28BE23A4C) /* 58 */, W64LIT(0xCAB2F0FC6A3E6A2E) /* 59 */, - W64LIT(0x2860971A6B943FCD) /* 60 */, W64LIT(0x3DDE6EE212E30446) /* 61 */, - W64LIT(0x6222F32AE01765AE) /* 62 */, W64LIT(0x5D550BB5478308FE) /* 63 */, - W64LIT(0xA9EFA98DA0EDA22A) /* 64 */, W64LIT(0xC351A71686C40DA7) /* 65 */, - W64LIT(0x1105586D9C867C84) /* 66 */, W64LIT(0xDCFFEE85FDA22853) /* 67 */, - W64LIT(0xCCFBD0262C5EEF76) /* 68 */, W64LIT(0xBAF294CB8990D201) /* 69 */, - W64LIT(0xE69464F52AFAD975) /* 70 */, W64LIT(0x94B013AFDF133E14) /* 71 */, - W64LIT(0x06A7D1A32823C958) /* 72 */, W64LIT(0x6F95FE5130F61119) /* 73 */, - W64LIT(0xD92AB34E462C06C0) /* 74 */, W64LIT(0xED7BDE33887C71D2) /* 75 */, - W64LIT(0x79746D6E6518393E) /* 76 */, W64LIT(0x5BA419385D713329) /* 77 */, - W64LIT(0x7C1BA6B948A97564) /* 78 */, W64LIT(0x31987C197BFDAC67) /* 79 */, - W64LIT(0xDE6C23C44B053D02) /* 80 */, W64LIT(0x581C49FED002D64D) /* 81 */, - W64LIT(0xDD474D6338261571) /* 82 */, W64LIT(0xAA4546C3E473D062) /* 83 */, - W64LIT(0x928FCE349455F860) /* 84 */, W64LIT(0x48161BBACAAB94D9) /* 85 */, - W64LIT(0x63912430770E6F68) /* 86 */, W64LIT(0x6EC8A5E602C6641C) /* 87 */, - W64LIT(0x87282515337DDD2B) /* 88 */, W64LIT(0x2CDA6B42034B701B) /* 89 */, - W64LIT(0xB03D37C181CB096D) /* 90 */, W64LIT(0xE108438266C71C6F) /* 91 */, - W64LIT(0x2B3180C7EB51B255) /* 92 */, W64LIT(0xDF92B82F96C08BBC) /* 93 */, - W64LIT(0x5C68C8C0A632F3BA) /* 94 */, W64LIT(0x5504CC861C3D0556) /* 95 */, - W64LIT(0xABBFA4E55FB26B8F) /* 96 */, W64LIT(0x41848B0AB3BACEB4) /* 97 */, - W64LIT(0xB334A273AA445D32) /* 98 */, W64LIT(0xBCA696F0A85AD881) /* 99 */, - W64LIT(0x24F6EC65B528D56C) /* 100 */, W64LIT(0x0CE1512E90F4524A) /* 101 */, - W64LIT(0x4E9DD79D5506D35A) /* 102 */, W64LIT(0x258905FAC6CE9779) /* 103 */, - W64LIT(0x2019295B3E109B33) /* 104 */, W64LIT(0xF8A9478B73A054CC) /* 105 */, - W64LIT(0x2924F2F934417EB0) /* 106 */, W64LIT(0x3993357D536D1BC4) /* 107 */, - W64LIT(0x38A81AC21DB6FF8B) /* 108 */, W64LIT(0x47C4FBF17D6016BF) /* 109 */, - W64LIT(0x1E0FAADD7667E3F5) /* 110 */, W64LIT(0x7ABCFF62938BEB96) /* 111 */, - W64LIT(0xA78DAD948FC179C9) /* 112 */, W64LIT(0x8F1F98B72911E50D) /* 113 */, - W64LIT(0x61E48EAE27121A91) /* 114 */, W64LIT(0x4D62F7AD31859808) /* 115 */, - W64LIT(0xECEBA345EF5CEAEB) /* 116 */, W64LIT(0xF5CEB25EBC9684CE) /* 117 */, - W64LIT(0xF633E20CB7F76221) /* 118 */, W64LIT(0xA32CDF06AB8293E4) /* 119 */, - W64LIT(0x985A202CA5EE2CA4) /* 120 */, W64LIT(0xCF0B8447CC8A8FB1) /* 121 */, - W64LIT(0x9F765244979859A3) /* 122 */, W64LIT(0xA8D516B1A1240017) /* 123 */, - W64LIT(0x0BD7BA3EBB5DC726) /* 124 */, W64LIT(0xE54BCA55B86ADB39) /* 125 */, - W64LIT(0x1D7A3AFD6C478063) /* 126 */, W64LIT(0x519EC608E7669EDD) /* 127 */, - W64LIT(0x0E5715A2D149AA23) /* 128 */, W64LIT(0x177D4571848FF194) /* 129 */, - W64LIT(0xEEB55F3241014C22) /* 130 */, W64LIT(0x0F5E5CA13A6E2EC2) /* 131 */, - W64LIT(0x8029927B75F5C361) /* 132 */, W64LIT(0xAD139FABC3D6E436) /* 133 */, - W64LIT(0x0D5DF1A94CCF402F) /* 134 */, W64LIT(0x3E8BD948BEA5DFC8) /* 135 */, - W64LIT(0xA5A0D357BD3FF77E) /* 136 */, W64LIT(0xA2D12E251F74F645) /* 137 */, - W64LIT(0x66FD9E525E81A082) /* 138 */, W64LIT(0x2E0C90CE7F687A49) /* 139 */, - W64LIT(0xC2E8BCBEBA973BC5) /* 140 */, W64LIT(0x000001BCE509745F) /* 141 */, - W64LIT(0x423777BBE6DAB3D6) /* 142 */, W64LIT(0xD1661C7EAEF06EB5) /* 143 */, - W64LIT(0xA1781F354DAACFD8) /* 144 */, W64LIT(0x2D11284A2B16AFFC) /* 145 */, - W64LIT(0xF1FC4F67FA891D1F) /* 146 */, W64LIT(0x73ECC25DCB920ADA) /* 147 */, - W64LIT(0xAE610C22C2A12651) /* 148 */, W64LIT(0x96E0A810D356B78A) /* 149 */, - W64LIT(0x5A9A381F2FE7870F) /* 150 */, W64LIT(0xD5AD62EDE94E5530) /* 151 */, - W64LIT(0xD225E5E8368D1427) /* 152 */, W64LIT(0x65977B70C7AF4631) /* 153 */, - W64LIT(0x99F889B2DE39D74F) /* 154 */, W64LIT(0x233F30BF54E1D143) /* 155 */, - W64LIT(0x9A9675D3D9A63C97) /* 156 */, W64LIT(0x5470554FF334F9A8) /* 157 */, - W64LIT(0x166ACB744A4F5688) /* 158 */, W64LIT(0x70C74CAAB2E4AEAD) /* 159 */, - W64LIT(0xF0D091646F294D12) /* 160 */, W64LIT(0x57B82A89684031D1) /* 161 */, - W64LIT(0xEFD95A5A61BE0B6B) /* 162 */, W64LIT(0x2FBD12E969F2F29A) /* 163 */, - W64LIT(0x9BD37013FEFF9FE8) /* 164 */, W64LIT(0x3F9B0404D6085A06) /* 165 */, - W64LIT(0x4940C1F3166CFE15) /* 166 */, W64LIT(0x09542C4DCDF3DEFB) /* 167 */, - W64LIT(0xB4C5218385CD5CE3) /* 168 */, W64LIT(0xC935B7DC4462A641) /* 169 */, - W64LIT(0x3417F8A68ED3B63F) /* 170 */, W64LIT(0xB80959295B215B40) /* 171 */, - W64LIT(0xF99CDAEF3B8C8572) /* 172 */, W64LIT(0x018C0614F8FCB95D) /* 173 */, - W64LIT(0x1B14ACCD1A3ACDF3) /* 174 */, W64LIT(0x84D471F200BB732D) /* 175 */, - W64LIT(0xC1A3110E95E8DA16) /* 176 */, W64LIT(0x430A7220BF1A82B8) /* 177 */, - W64LIT(0xB77E090D39DF210E) /* 178 */, W64LIT(0x5EF4BD9F3CD05E9D) /* 179 */, - W64LIT(0x9D4FF6DA7E57A444) /* 180 */, W64LIT(0xDA1D60E183D4A5F8) /* 181 */, - W64LIT(0xB287C38417998E47) /* 182 */, W64LIT(0xFE3EDC121BB31886) /* 183 */, - W64LIT(0xC7FE3CCC980CCBEF) /* 184 */, W64LIT(0xE46FB590189BFD03) /* 185 */, - W64LIT(0x3732FD469A4C57DC) /* 186 */, W64LIT(0x7EF700A07CF1AD65) /* 187 */, - W64LIT(0x59C64468A31D8859) /* 188 */, W64LIT(0x762FB0B4D45B61F6) /* 189 */, - W64LIT(0x155BAED099047718) /* 190 */, W64LIT(0x68755E4C3D50BAA6) /* 191 */, - W64LIT(0xE9214E7F22D8B4DF) /* 192 */, W64LIT(0x2ADDBF532EAC95F4) /* 193 */, - W64LIT(0x32AE3909B4BD0109) /* 194 */, W64LIT(0x834DF537B08E3450) /* 195 */, - W64LIT(0xFA209DA84220728D) /* 196 */, W64LIT(0x9E691D9B9EFE23F7) /* 197 */, - W64LIT(0x0446D288C4AE8D7F) /* 198 */, W64LIT(0x7B4CC524E169785B) /* 199 */, - W64LIT(0x21D87F0135CA1385) /* 200 */, W64LIT(0xCEBB400F137B8AA5) /* 201 */, - W64LIT(0x272E2B66580796BE) /* 202 */, W64LIT(0x3612264125C2B0DE) /* 203 */, - W64LIT(0x057702BDAD1EFBB2) /* 204 */, W64LIT(0xD4BABB8EACF84BE9) /* 205 */, - W64LIT(0x91583139641BC67B) /* 206 */, W64LIT(0x8BDC2DE08036E024) /* 207 */, - W64LIT(0x603C8156F49F68ED) /* 208 */, W64LIT(0xF7D236F7DBEF5111) /* 209 */, - W64LIT(0x9727C4598AD21E80) /* 210 */, W64LIT(0xA08A0896670A5FD7) /* 211 */, - W64LIT(0xCB4A8F4309EBA9CB) /* 212 */, W64LIT(0x81AF564B0F7036A1) /* 213 */, - W64LIT(0xC0B99AA778199ABD) /* 214 */, W64LIT(0x959F1EC83FC8E952) /* 215 */, - W64LIT(0x8C505077794A81B9) /* 216 */, W64LIT(0x3ACAAF8F056338F0) /* 217 */, - W64LIT(0x07B43F50627A6778) /* 218 */, W64LIT(0x4A44AB49F5ECCC77) /* 219 */, - W64LIT(0x3BC3D6E4B679EE98) /* 220 */, W64LIT(0x9CC0D4D1CF14108C) /* 221 */, - W64LIT(0x4406C00B206BC8A0) /* 222 */, W64LIT(0x82A18854C8D72D89) /* 223 */, - W64LIT(0x67E366B35C3C432C) /* 224 */, W64LIT(0xB923DD61102B37F2) /* 225 */, - W64LIT(0x56AB2779D884271D) /* 226 */, W64LIT(0xBE83E1B0FF1525AF) /* 227 */, - W64LIT(0xFB7C65D4217E49A9) /* 228 */, W64LIT(0x6BDBE0E76D48E7D4) /* 229 */, - W64LIT(0x08DF828745D9179E) /* 230 */, W64LIT(0x22EA6A9ADD53BD34) /* 231 */, - W64LIT(0xE36E141C5622200A) /* 232 */, W64LIT(0x7F805D1B8CB750EE) /* 233 */, - W64LIT(0xAFE5C7A59F58E837) /* 234 */, W64LIT(0xE27F996A4FB1C23C) /* 235 */, - W64LIT(0xD3867DFB0775F0D0) /* 236 */, W64LIT(0xD0E673DE6E88891A) /* 237 */, - W64LIT(0x123AEB9EAFB86C25) /* 238 */, W64LIT(0x30F1D5D5C145B895) /* 239 */, - W64LIT(0xBB434A2DEE7269E7) /* 240 */, W64LIT(0x78CB67ECF931FA38) /* 241 */, - W64LIT(0xF33B0372323BBF9C) /* 242 */, W64LIT(0x52D66336FB279C74) /* 243 */, - W64LIT(0x505F33AC0AFB4EAA) /* 244 */, W64LIT(0xE8A5CD99A2CCE187) /* 245 */, - W64LIT(0x534974801E2D30BB) /* 246 */, W64LIT(0x8D2D5711D5876D90) /* 247 */, - W64LIT(0x1F1A412891BC038E) /* 248 */, W64LIT(0xD6E2E71D82E56648) /* 249 */, - W64LIT(0x74036C3A497732B7) /* 250 */, W64LIT(0x89B67ED96361F5AB) /* 251 */, - W64LIT(0xFFED95D8F1EA02A2) /* 252 */, W64LIT(0xE72B3BD61464D43D) /* 253 */, - W64LIT(0xA6300F170BDC4820) /* 254 */, W64LIT(0xEBC18760ED78A77A) /* 255 */, - W64LIT(0xE6A6BE5A05A12138) /* 256 */, W64LIT(0xB5A122A5B4F87C98) /* 257 */, - W64LIT(0x563C6089140B6990) /* 258 */, W64LIT(0x4C46CB2E391F5DD5) /* 259 */, - W64LIT(0xD932ADDBC9B79434) /* 260 */, W64LIT(0x08EA70E42015AFF5) /* 261 */, - W64LIT(0xD765A6673E478CF1) /* 262 */, W64LIT(0xC4FB757EAB278D99) /* 263 */, - W64LIT(0xDF11C6862D6E0692) /* 264 */, W64LIT(0xDDEB84F10D7F3B16) /* 265 */, - W64LIT(0x6F2EF604A665EA04) /* 266 */, W64LIT(0x4A8E0F0FF0E0DFB3) /* 267 */, - W64LIT(0xA5EDEEF83DBCBA51) /* 268 */, W64LIT(0xFC4F0A2A0EA4371E) /* 269 */, - W64LIT(0xE83E1DA85CB38429) /* 270 */, W64LIT(0xDC8FF882BA1B1CE2) /* 271 */, - W64LIT(0xCD45505E8353E80D) /* 272 */, W64LIT(0x18D19A00D4DB0717) /* 273 */, - W64LIT(0x34A0CFEDA5F38101) /* 274 */, W64LIT(0x0BE77E518887CAF2) /* 275 */, - W64LIT(0x1E341438B3C45136) /* 276 */, W64LIT(0xE05797F49089CCF9) /* 277 */, - W64LIT(0xFFD23F9DF2591D14) /* 278 */, W64LIT(0x543DDA228595C5CD) /* 279 */, - W64LIT(0x661F81FD99052A33) /* 280 */, W64LIT(0x8736E641DB0F7B76) /* 281 */, - W64LIT(0x15227725418E5307) /* 282 */, W64LIT(0xE25F7F46162EB2FA) /* 283 */, - W64LIT(0x48A8B2126C13D9FE) /* 284 */, W64LIT(0xAFDC541792E76EEA) /* 285 */, - W64LIT(0x03D912BFC6D1898F) /* 286 */, W64LIT(0x31B1AAFA1B83F51B) /* 287 */, - W64LIT(0xF1AC2796E42AB7D9) /* 288 */, W64LIT(0x40A3A7D7FCD2EBAC) /* 289 */, - W64LIT(0x1056136D0AFBBCC5) /* 290 */, W64LIT(0x7889E1DD9A6D0C85) /* 291 */, - W64LIT(0xD33525782A7974AA) /* 292 */, W64LIT(0xA7E25D09078AC09B) /* 293 */, - W64LIT(0xBD4138B3EAC6EDD0) /* 294 */, W64LIT(0x920ABFBE71EB9E70) /* 295 */, - W64LIT(0xA2A5D0F54FC2625C) /* 296 */, W64LIT(0xC054E36B0B1290A3) /* 297 */, - W64LIT(0xF6DD59FF62FE932B) /* 298 */, W64LIT(0x3537354511A8AC7D) /* 299 */, - W64LIT(0xCA845E9172FADCD4) /* 300 */, W64LIT(0x84F82B60329D20DC) /* 301 */, - W64LIT(0x79C62CE1CD672F18) /* 302 */, W64LIT(0x8B09A2ADD124642C) /* 303 */, - W64LIT(0xD0C1E96A19D9E726) /* 304 */, W64LIT(0x5A786A9B4BA9500C) /* 305 */, - W64LIT(0x0E020336634C43F3) /* 306 */, W64LIT(0xC17B474AEB66D822) /* 307 */, - W64LIT(0x6A731AE3EC9BAAC2) /* 308 */, W64LIT(0x8226667AE0840258) /* 309 */, - W64LIT(0x67D4567691CAECA5) /* 310 */, W64LIT(0x1D94155C4875ADB5) /* 311 */, - W64LIT(0x6D00FD985B813FDF) /* 312 */, W64LIT(0x51286EFCB774CD06) /* 313 */, - W64LIT(0x5E8834471FA744AF) /* 314 */, W64LIT(0xF72CA0AEE761AE2E) /* 315 */, - W64LIT(0xBE40E4CDAEE8E09A) /* 316 */, W64LIT(0xE9970BBB5118F665) /* 317 */, - W64LIT(0x726E4BEB33DF1964) /* 318 */, W64LIT(0x703B000729199762) /* 319 */, - W64LIT(0x4631D816F5EF30A7) /* 320 */, W64LIT(0xB880B5B51504A6BE) /* 321 */, - W64LIT(0x641793C37ED84B6C) /* 322 */, W64LIT(0x7B21ED77F6E97D96) /* 323 */, - W64LIT(0x776306312EF96B73) /* 324 */, W64LIT(0xAE528948E86FF3F4) /* 325 */, - W64LIT(0x53DBD7F286A3F8F8) /* 326 */, W64LIT(0x16CADCE74CFC1063) /* 327 */, - W64LIT(0x005C19BDFA52C6DD) /* 328 */, W64LIT(0x68868F5D64D46AD3) /* 329 */, - W64LIT(0x3A9D512CCF1E186A) /* 330 */, W64LIT(0x367E62C2385660AE) /* 331 */, - W64LIT(0xE359E7EA77DCB1D7) /* 332 */, W64LIT(0x526C0773749ABE6E) /* 333 */, - W64LIT(0x735AE5F9D09F734B) /* 334 */, W64LIT(0x493FC7CC8A558BA8) /* 335 */, - W64LIT(0xB0B9C1533041AB45) /* 336 */, W64LIT(0x321958BA470A59BD) /* 337 */, - W64LIT(0x852DB00B5F46C393) /* 338 */, W64LIT(0x91209B2BD336B0E5) /* 339 */, - W64LIT(0x6E604F7D659EF19F) /* 340 */, W64LIT(0xB99A8AE2782CCB24) /* 341 */, - W64LIT(0xCCF52AB6C814C4C7) /* 342 */, W64LIT(0x4727D9AFBE11727B) /* 343 */, - W64LIT(0x7E950D0C0121B34D) /* 344 */, W64LIT(0x756F435670AD471F) /* 345 */, - W64LIT(0xF5ADD442615A6849) /* 346 */, W64LIT(0x4E87E09980B9957A) /* 347 */, - W64LIT(0x2ACFA1DF50AEE355) /* 348 */, W64LIT(0xD898263AFD2FD556) /* 349 */, - W64LIT(0xC8F4924DD80C8FD6) /* 350 */, W64LIT(0xCF99CA3D754A173A) /* 351 */, - W64LIT(0xFE477BACAF91BF3C) /* 352 */, W64LIT(0xED5371F6D690C12D) /* 353 */, - W64LIT(0x831A5C285E687094) /* 354 */, W64LIT(0xC5D3C90A3708A0A4) /* 355 */, - W64LIT(0x0F7F903717D06580) /* 356 */, W64LIT(0x19F9BB13B8FDF27F) /* 357 */, - W64LIT(0xB1BD6F1B4D502843) /* 358 */, W64LIT(0x1C761BA38FFF4012) /* 359 */, - W64LIT(0x0D1530C4E2E21F3B) /* 360 */, W64LIT(0x8943CE69A7372C8A) /* 361 */, - W64LIT(0xE5184E11FEB5CE66) /* 362 */, W64LIT(0x618BDB80BD736621) /* 363 */, - W64LIT(0x7D29BAD68B574D0B) /* 364 */, W64LIT(0x81BB613E25E6FE5B) /* 365 */, - W64LIT(0x071C9C10BC07913F) /* 366 */, W64LIT(0xC7BEEB7909AC2D97) /* 367 */, - W64LIT(0xC3E58D353BC5D757) /* 368 */, W64LIT(0xEB017892F38F61E8) /* 369 */, - W64LIT(0xD4EFFB9C9B1CC21A) /* 370 */, W64LIT(0x99727D26F494F7AB) /* 371 */, - W64LIT(0xA3E063A2956B3E03) /* 372 */, W64LIT(0x9D4A8B9A4AA09C30) /* 373 */, - W64LIT(0x3F6AB7D500090FB4) /* 374 */, W64LIT(0x9CC0F2A057268AC0) /* 375 */, - W64LIT(0x3DEE9D2DEDBF42D1) /* 376 */, W64LIT(0x330F49C87960A972) /* 377 */, - W64LIT(0xC6B2720287421B41) /* 378 */, W64LIT(0x0AC59EC07C00369C) /* 379 */, - W64LIT(0xEF4EAC49CB353425) /* 380 */, W64LIT(0xF450244EEF0129D8) /* 381 */, - W64LIT(0x8ACC46E5CAF4DEB6) /* 382 */, W64LIT(0x2FFEAB63989263F7) /* 383 */, - W64LIT(0x8F7CB9FE5D7A4578) /* 384 */, W64LIT(0x5BD8F7644E634635) /* 385 */, - W64LIT(0x427A7315BF2DC900) /* 386 */, W64LIT(0x17D0C4AA2125261C) /* 387 */, - W64LIT(0x3992486C93518E50) /* 388 */, W64LIT(0xB4CBFEE0A2D7D4C3) /* 389 */, - W64LIT(0x7C75D6202C5DDD8D) /* 390 */, W64LIT(0xDBC295D8E35B6C61) /* 391 */, - W64LIT(0x60B369D302032B19) /* 392 */, W64LIT(0xCE42685FDCE44132) /* 393 */, - W64LIT(0x06F3DDB9DDF65610) /* 394 */, W64LIT(0x8EA4D21DB5E148F0) /* 395 */, - W64LIT(0x20B0FCE62FCD496F) /* 396 */, W64LIT(0x2C1B912358B0EE31) /* 397 */, - W64LIT(0xB28317B818F5A308) /* 398 */, W64LIT(0xA89C1E189CA6D2CF) /* 399 */, - W64LIT(0x0C6B18576AAADBC8) /* 400 */, W64LIT(0xB65DEAA91299FAE3) /* 401 */, - W64LIT(0xFB2B794B7F1027E7) /* 402 */, W64LIT(0x04E4317F443B5BEB) /* 403 */, - W64LIT(0x4B852D325939D0A6) /* 404 */, W64LIT(0xD5AE6BEEFB207FFC) /* 405 */, - W64LIT(0x309682B281C7D374) /* 406 */, W64LIT(0xBAE309A194C3B475) /* 407 */, - W64LIT(0x8CC3F97B13B49F05) /* 408 */, W64LIT(0x98A9422FF8293967) /* 409 */, - W64LIT(0x244B16B01076FF7C) /* 410 */, W64LIT(0xF8BF571C663D67EE) /* 411 */, - W64LIT(0x1F0D6758EEE30DA1) /* 412 */, W64LIT(0xC9B611D97ADEB9B7) /* 413 */, - W64LIT(0xB7AFD5887B6C57A2) /* 414 */, W64LIT(0x6290AE846B984FE1) /* 415 */, - W64LIT(0x94DF4CDEACC1A5FD) /* 416 */, W64LIT(0x058A5BD1C5483AFF) /* 417 */, - W64LIT(0x63166CC142BA3C37) /* 418 */, W64LIT(0x8DB8526EB2F76F40) /* 419 */, - W64LIT(0xE10880036F0D6D4E) /* 420 */, W64LIT(0x9E0523C9971D311D) /* 421 */, - W64LIT(0x45EC2824CC7CD691) /* 422 */, W64LIT(0x575B8359E62382C9) /* 423 */, - W64LIT(0xFA9E400DC4889995) /* 424 */, W64LIT(0xD1823ECB45721568) /* 425 */, - W64LIT(0xDAFD983B8206082F) /* 426 */, W64LIT(0xAA7D29082386A8CB) /* 427 */, - W64LIT(0x269FCD4403B87588) /* 428 */, W64LIT(0x1B91F5F728BDD1E0) /* 429 */, - W64LIT(0xE4669F39040201F6) /* 430 */, W64LIT(0x7A1D7C218CF04ADE) /* 431 */, - W64LIT(0x65623C29D79CE5CE) /* 432 */, W64LIT(0x2368449096C00BB1) /* 433 */, - W64LIT(0xAB9BF1879DA503BA) /* 434 */, W64LIT(0xBC23ECB1A458058E) /* 435 */, - W64LIT(0x9A58DF01BB401ECC) /* 436 */, W64LIT(0xA070E868A85F143D) /* 437 */, - W64LIT(0x4FF188307DF2239E) /* 438 */, W64LIT(0x14D565B41A641183) /* 439 */, - W64LIT(0xEE13337452701602) /* 440 */, W64LIT(0x950E3DCF3F285E09) /* 441 */, - W64LIT(0x59930254B9C80953) /* 442 */, W64LIT(0x3BF299408930DA6D) /* 443 */, - W64LIT(0xA955943F53691387) /* 444 */, W64LIT(0xA15EDECAA9CB8784) /* 445 */, - W64LIT(0x29142127352BE9A0) /* 446 */, W64LIT(0x76F0371FFF4E7AFB) /* 447 */, - W64LIT(0x0239F450274F2228) /* 448 */, W64LIT(0xBB073AF01D5E868B) /* 449 */, - W64LIT(0xBFC80571C10E96C1) /* 450 */, W64LIT(0xD267088568222E23) /* 451 */, - W64LIT(0x9671A3D48E80B5B0) /* 452 */, W64LIT(0x55B5D38AE193BB81) /* 453 */, - W64LIT(0x693AE2D0A18B04B8) /* 454 */, W64LIT(0x5C48B4ECADD5335F) /* 455 */, - W64LIT(0xFD743B194916A1CA) /* 456 */, W64LIT(0x2577018134BE98C4) /* 457 */, - W64LIT(0xE77987E83C54A4AD) /* 458 */, W64LIT(0x28E11014DA33E1B9) /* 459 */, - W64LIT(0x270CC59E226AA213) /* 460 */, W64LIT(0x71495F756D1A5F60) /* 461 */, - W64LIT(0x9BE853FB60AFEF77) /* 462 */, W64LIT(0xADC786A7F7443DBF) /* 463 */, - W64LIT(0x0904456173B29A82) /* 464 */, W64LIT(0x58BC7A66C232BD5E) /* 465 */, - W64LIT(0xF306558C673AC8B2) /* 466 */, W64LIT(0x41F639C6B6C9772A) /* 467 */, - W64LIT(0x216DEFE99FDA35DA) /* 468 */, W64LIT(0x11640CC71C7BE615) /* 469 */, - W64LIT(0x93C43694565C5527) /* 470 */, W64LIT(0xEA038E6246777839) /* 471 */, - W64LIT(0xF9ABF3CE5A3E2469) /* 472 */, W64LIT(0x741E768D0FD312D2) /* 473 */, - W64LIT(0x0144B883CED652C6) /* 474 */, W64LIT(0xC20B5A5BA33F8552) /* 475 */, - W64LIT(0x1AE69633C3435A9D) /* 476 */, W64LIT(0x97A28CA4088CFDEC) /* 477 */, - W64LIT(0x8824A43C1E96F420) /* 478 */, W64LIT(0x37612FA66EEEA746) /* 479 */, - W64LIT(0x6B4CB165F9CF0E5A) /* 480 */, W64LIT(0x43AA1C06A0ABFB4A) /* 481 */, - W64LIT(0x7F4DC26FF162796B) /* 482 */, W64LIT(0x6CBACC8E54ED9B0F) /* 483 */, - W64LIT(0xA6B7FFEFD2BB253E) /* 484 */, W64LIT(0x2E25BC95B0A29D4F) /* 485 */, - W64LIT(0x86D6A58BDEF1388C) /* 486 */, W64LIT(0xDED74AC576B6F054) /* 487 */, - W64LIT(0x8030BDBC2B45805D) /* 488 */, W64LIT(0x3C81AF70E94D9289) /* 489 */, - W64LIT(0x3EFF6DDA9E3100DB) /* 490 */, W64LIT(0xB38DC39FDFCC8847) /* 491 */, - W64LIT(0x123885528D17B87E) /* 492 */, W64LIT(0xF2DA0ED240B1B642) /* 493 */, - W64LIT(0x44CEFADCD54BF9A9) /* 494 */, W64LIT(0x1312200E433C7EE6) /* 495 */, - W64LIT(0x9FFCC84F3A78C748) /* 496 */, W64LIT(0xF0CD1F72248576BB) /* 497 */, - W64LIT(0xEC6974053638CFE4) /* 498 */, W64LIT(0x2BA7B67C0CEC4E4C) /* 499 */, - W64LIT(0xAC2F4DF3E5CE32ED) /* 500 */, W64LIT(0xCB33D14326EA4C11) /* 501 */, - W64LIT(0xA4E9044CC77E58BC) /* 502 */, W64LIT(0x5F513293D934FCEF) /* 503 */, - W64LIT(0x5DC9645506E55444) /* 504 */, W64LIT(0x50DE418F317DE40A) /* 505 */, - W64LIT(0x388CB31A69DDE259) /* 506 */, W64LIT(0x2DB4A83455820A86) /* 507 */, - W64LIT(0x9010A91E84711AE9) /* 508 */, W64LIT(0x4DF7F0B7B1498371) /* 509 */, - W64LIT(0xD62A2EABC0977179) /* 510 */, W64LIT(0x22FAC097AA8D5C0E) /* 511 */, - W64LIT(0xF49FCC2FF1DAF39B) /* 512 */, W64LIT(0x487FD5C66FF29281) /* 513 */, - W64LIT(0xE8A30667FCDCA83F) /* 514 */, W64LIT(0x2C9B4BE3D2FCCE63) /* 515 */, - W64LIT(0xDA3FF74B93FBBBC2) /* 516 */, W64LIT(0x2FA165D2FE70BA66) /* 517 */, - W64LIT(0xA103E279970E93D4) /* 518 */, W64LIT(0xBECDEC77B0E45E71) /* 519 */, - W64LIT(0xCFB41E723985E497) /* 520 */, W64LIT(0xB70AAA025EF75017) /* 521 */, - W64LIT(0xD42309F03840B8E0) /* 522 */, W64LIT(0x8EFC1AD035898579) /* 523 */, - W64LIT(0x96C6920BE2B2ABC5) /* 524 */, W64LIT(0x66AF4163375A9172) /* 525 */, - W64LIT(0x2174ABDCCA7127FB) /* 526 */, W64LIT(0xB33CCEA64A72FF41) /* 527 */, - W64LIT(0xF04A4933083066A5) /* 528 */, W64LIT(0x8D970ACDD7289AF5) /* 529 */, - W64LIT(0x8F96E8E031C8C25E) /* 530 */, W64LIT(0xF3FEC02276875D47) /* 531 */, - W64LIT(0xEC7BF310056190DD) /* 532 */, W64LIT(0xF5ADB0AEBB0F1491) /* 533 */, - W64LIT(0x9B50F8850FD58892) /* 534 */, W64LIT(0x4975488358B74DE8) /* 535 */, - W64LIT(0xA3354FF691531C61) /* 536 */, W64LIT(0x0702BBE481D2C6EE) /* 537 */, - W64LIT(0x89FB24057DEDED98) /* 538 */, W64LIT(0xAC3075138596E902) /* 539 */, - W64LIT(0x1D2D3580172772ED) /* 540 */, W64LIT(0xEB738FC28E6BC30D) /* 541 */, - W64LIT(0x5854EF8F63044326) /* 542 */, W64LIT(0x9E5C52325ADD3BBE) /* 543 */, - W64LIT(0x90AA53CF325C4623) /* 544 */, W64LIT(0xC1D24D51349DD067) /* 545 */, - W64LIT(0x2051CFEEA69EA624) /* 546 */, W64LIT(0x13220F0A862E7E4F) /* 547 */, - W64LIT(0xCE39399404E04864) /* 548 */, W64LIT(0xD9C42CA47086FCB7) /* 549 */, - W64LIT(0x685AD2238A03E7CC) /* 550 */, W64LIT(0x066484B2AB2FF1DB) /* 551 */, - W64LIT(0xFE9D5D70EFBF79EC) /* 552 */, W64LIT(0x5B13B9DD9C481854) /* 553 */, - W64LIT(0x15F0D475ED1509AD) /* 554 */, W64LIT(0x0BEBCD060EC79851) /* 555 */, - W64LIT(0xD58C6791183AB7F8) /* 556 */, W64LIT(0xD1187C5052F3EEE4) /* 557 */, - W64LIT(0xC95D1192E54E82FF) /* 558 */, W64LIT(0x86EEA14CB9AC6CA2) /* 559 */, - W64LIT(0x3485BEB153677D5D) /* 560 */, W64LIT(0xDD191D781F8C492A) /* 561 */, - W64LIT(0xF60866BAA784EBF9) /* 562 */, W64LIT(0x518F643BA2D08C74) /* 563 */, - W64LIT(0x8852E956E1087C22) /* 564 */, W64LIT(0xA768CB8DC410AE8D) /* 565 */, - W64LIT(0x38047726BFEC8E1A) /* 566 */, W64LIT(0xA67738B4CD3B45AA) /* 567 */, - W64LIT(0xAD16691CEC0DDE19) /* 568 */, W64LIT(0xC6D4319380462E07) /* 569 */, - W64LIT(0xC5A5876D0BA61938) /* 570 */, W64LIT(0x16B9FA1FA58FD840) /* 571 */, - W64LIT(0x188AB1173CA74F18) /* 572 */, W64LIT(0xABDA2F98C99C021F) /* 573 */, - W64LIT(0x3E0580AB134AE816) /* 574 */, W64LIT(0x5F3B05B773645ABB) /* 575 */, - W64LIT(0x2501A2BE5575F2F6) /* 576 */, W64LIT(0x1B2F74004E7E8BA9) /* 577 */, - W64LIT(0x1CD7580371E8D953) /* 578 */, W64LIT(0x7F6ED89562764E30) /* 579 */, - W64LIT(0xB15926FF596F003D) /* 580 */, W64LIT(0x9F65293DA8C5D6B9) /* 581 */, - W64LIT(0x6ECEF04DD690F84C) /* 582 */, W64LIT(0x4782275FFF33AF88) /* 583 */, - W64LIT(0xE41433083F820801) /* 584 */, W64LIT(0xFD0DFE409A1AF9B5) /* 585 */, - W64LIT(0x4325A3342CDB396B) /* 586 */, W64LIT(0x8AE77E62B301B252) /* 587 */, - W64LIT(0xC36F9E9F6655615A) /* 588 */, W64LIT(0x85455A2D92D32C09) /* 589 */, - W64LIT(0xF2C7DEA949477485) /* 590 */, W64LIT(0x63CFB4C133A39EBA) /* 591 */, - W64LIT(0x83B040CC6EBC5462) /* 592 */, W64LIT(0x3B9454C8FDB326B0) /* 593 */, - W64LIT(0x56F56A9E87FFD78C) /* 594 */, W64LIT(0x2DC2940D99F42BC6) /* 595 */, - W64LIT(0x98F7DF096B096E2D) /* 596 */, W64LIT(0x19A6E01E3AD852BF) /* 597 */, - W64LIT(0x42A99CCBDBD4B40B) /* 598 */, W64LIT(0xA59998AF45E9C559) /* 599 */, - W64LIT(0x366295E807D93186) /* 600 */, W64LIT(0x6B48181BFAA1F773) /* 601 */, - W64LIT(0x1FEC57E2157A0A1D) /* 602 */, W64LIT(0x4667446AF6201AD5) /* 603 */, - W64LIT(0xE615EBCACFB0F075) /* 604 */, W64LIT(0xB8F31F4F68290778) /* 605 */, - W64LIT(0x22713ED6CE22D11E) /* 606 */, W64LIT(0x3057C1A72EC3C93B) /* 607 */, - W64LIT(0xCB46ACC37C3F1F2F) /* 608 */, W64LIT(0xDBB893FD02AAF50E) /* 609 */, - W64LIT(0x331FD92E600B9FCF) /* 610 */, W64LIT(0xA498F96148EA3AD6) /* 611 */, - W64LIT(0xA8D8426E8B6A83EA) /* 612 */, W64LIT(0xA089B274B7735CDC) /* 613 */, - W64LIT(0x87F6B3731E524A11) /* 614 */, W64LIT(0x118808E5CBC96749) /* 615 */, - W64LIT(0x9906E4C7B19BD394) /* 616 */, W64LIT(0xAFED7F7E9B24A20C) /* 617 */, - W64LIT(0x6509EADEEB3644A7) /* 618 */, W64LIT(0x6C1EF1D3E8EF0EDE) /* 619 */, - W64LIT(0xB9C97D43E9798FB4) /* 620 */, W64LIT(0xA2F2D784740C28A3) /* 621 */, - W64LIT(0x7B8496476197566F) /* 622 */, W64LIT(0x7A5BE3E6B65F069D) /* 623 */, - W64LIT(0xF96330ED78BE6F10) /* 624 */, W64LIT(0xEEE60DE77A076A15) /* 625 */, - W64LIT(0x2B4BEE4AA08B9BD0) /* 626 */, W64LIT(0x6A56A63EC7B8894E) /* 627 */, - W64LIT(0x02121359BA34FEF4) /* 628 */, W64LIT(0x4CBF99F8283703FC) /* 629 */, - W64LIT(0x398071350CAF30C8) /* 630 */, W64LIT(0xD0A77A89F017687A) /* 631 */, - W64LIT(0xF1C1A9EB9E423569) /* 632 */, W64LIT(0x8C7976282DEE8199) /* 633 */, - W64LIT(0x5D1737A5DD1F7ABD) /* 634 */, W64LIT(0x4F53433C09A9FA80) /* 635 */, - W64LIT(0xFA8B0C53DF7CA1D9) /* 636 */, W64LIT(0x3FD9DCBC886CCB77) /* 637 */, - W64LIT(0xC040917CA91B4720) /* 638 */, W64LIT(0x7DD00142F9D1DCDF) /* 639 */, - W64LIT(0x8476FC1D4F387B58) /* 640 */, W64LIT(0x23F8E7C5F3316503) /* 641 */, - W64LIT(0x032A2244E7E37339) /* 642 */, W64LIT(0x5C87A5D750F5A74B) /* 643 */, - W64LIT(0x082B4CC43698992E) /* 644 */, W64LIT(0xDF917BECB858F63C) /* 645 */, - W64LIT(0x3270B8FC5BF86DDA) /* 646 */, W64LIT(0x10AE72BB29B5DD76) /* 647 */, - W64LIT(0x576AC94E7700362B) /* 648 */, W64LIT(0x1AD112DAC61EFB8F) /* 649 */, - W64LIT(0x691BC30EC5FAA427) /* 650 */, W64LIT(0xFF246311CC327143) /* 651 */, - W64LIT(0x3142368E30E53206) /* 652 */, W64LIT(0x71380E31E02CA396) /* 653 */, - W64LIT(0x958D5C960AAD76F1) /* 654 */, W64LIT(0xF8D6F430C16DA536) /* 655 */, - W64LIT(0xC8FFD13F1BE7E1D2) /* 656 */, W64LIT(0x7578AE66004DDBE1) /* 657 */, - W64LIT(0x05833F01067BE646) /* 658 */, W64LIT(0xBB34B5AD3BFE586D) /* 659 */, - W64LIT(0x095F34C9A12B97F0) /* 660 */, W64LIT(0x247AB64525D60CA8) /* 661 */, - W64LIT(0xDCDBC6F3017477D1) /* 662 */, W64LIT(0x4A2E14D4DECAD24D) /* 663 */, - W64LIT(0xBDB5E6D9BE0A1EEB) /* 664 */, W64LIT(0x2A7E70F7794301AB) /* 665 */, - W64LIT(0xDEF42D8A270540FD) /* 666 */, W64LIT(0x01078EC0A34C22C1) /* 667 */, - W64LIT(0xE5DE511AF4C16387) /* 668 */, W64LIT(0x7EBB3A52BD9A330A) /* 669 */, - W64LIT(0x77697857AA7D6435) /* 670 */, W64LIT(0x004E831603AE4C32) /* 671 */, - W64LIT(0xE7A21020AD78E312) /* 672 */, W64LIT(0x9D41A70C6AB420F2) /* 673 */, - W64LIT(0x28E06C18EA1141E6) /* 674 */, W64LIT(0xD2B28CBD984F6B28) /* 675 */, - W64LIT(0x26B75F6C446E9D83) /* 676 */, W64LIT(0xBA47568C4D418D7F) /* 677 */, - W64LIT(0xD80BADBFE6183D8E) /* 678 */, W64LIT(0x0E206D7F5F166044) /* 679 */, - W64LIT(0xE258A43911CBCA3E) /* 680 */, W64LIT(0x723A1746B21DC0BC) /* 681 */, - W64LIT(0xC7CAA854F5D7CDD3) /* 682 */, W64LIT(0x7CAC32883D261D9C) /* 683 */, - W64LIT(0x7690C26423BA942C) /* 684 */, W64LIT(0x17E55524478042B8) /* 685 */, - W64LIT(0xE0BE477656A2389F) /* 686 */, W64LIT(0x4D289B5E67AB2DA0) /* 687 */, - W64LIT(0x44862B9C8FBBFD31) /* 688 */, W64LIT(0xB47CC8049D141365) /* 689 */, - W64LIT(0x822C1B362B91C793) /* 690 */, W64LIT(0x4EB14655FB13DFD8) /* 691 */, - W64LIT(0x1ECBBA0714E2A97B) /* 692 */, W64LIT(0x6143459D5CDE5F14) /* 693 */, - W64LIT(0x53A8FBF1D5F0AC89) /* 694 */, W64LIT(0x97EA04D81C5E5B00) /* 695 */, - W64LIT(0x622181A8D4FDB3F3) /* 696 */, W64LIT(0xE9BCD341572A1208) /* 697 */, - W64LIT(0x1411258643CCE58A) /* 698 */, W64LIT(0x9144C5FEA4C6E0A4) /* 699 */, - W64LIT(0x0D33D06565CF620F) /* 700 */, W64LIT(0x54A48D489F219CA1) /* 701 */, - W64LIT(0xC43E5EAC6D63C821) /* 702 */, W64LIT(0xA9728B3A72770DAF) /* 703 */, - W64LIT(0xD7934E7B20DF87EF) /* 704 */, W64LIT(0xE35503B61A3E86E5) /* 705 */, - W64LIT(0xCAE321FBC819D504) /* 706 */, W64LIT(0x129A50B3AC60BFA6) /* 707 */, - W64LIT(0xCD5E68EA7E9FB6C3) /* 708 */, W64LIT(0xB01C90199483B1C7) /* 709 */, - W64LIT(0x3DE93CD5C295376C) /* 710 */, W64LIT(0xAED52EDF2AB9AD13) /* 711 */, - W64LIT(0x2E60F512C0A07884) /* 712 */, W64LIT(0xBC3D86A3E36210C9) /* 713 */, - W64LIT(0x35269D9B163951CE) /* 714 */, W64LIT(0x0C7D6E2AD0CDB5FA) /* 715 */, - W64LIT(0x59E86297D87F5733) /* 716 */, W64LIT(0x298EF221898DB0E7) /* 717 */, - W64LIT(0x55000029D1A5AA7E) /* 718 */, W64LIT(0x8BC08AE1B5061B45) /* 719 */, - W64LIT(0xC2C31C2B6C92703A) /* 720 */, W64LIT(0x94CC596BAF25EF42) /* 721 */, - W64LIT(0x0A1D73DB22540456) /* 722 */, W64LIT(0x04B6A0F9D9C4179A) /* 723 */, - W64LIT(0xEFFDAFA2AE3D3C60) /* 724 */, W64LIT(0xF7C8075BB49496C4) /* 725 */, - W64LIT(0x9CC5C7141D1CD4E3) /* 726 */, W64LIT(0x78BD1638218E5534) /* 727 */, - W64LIT(0xB2F11568F850246A) /* 728 */, W64LIT(0xEDFABCFA9502BC29) /* 729 */, - W64LIT(0x796CE5F2DA23051B) /* 730 */, W64LIT(0xAAE128B0DC93537C) /* 731 */, - W64LIT(0x3A493DA0EE4B29AE) /* 732 */, W64LIT(0xB5DF6B2C416895D7) /* 733 */, - W64LIT(0xFCABBD25122D7F37) /* 734 */, W64LIT(0x70810B58105DC4B1) /* 735 */, - W64LIT(0xE10FDD37F7882A90) /* 736 */, W64LIT(0x524DCAB5518A3F5C) /* 737 */, - W64LIT(0x3C9E85878451255B) /* 738 */, W64LIT(0x4029828119BD34E2) /* 739 */, - W64LIT(0x74A05B6F5D3CECCB) /* 740 */, W64LIT(0xB610021542E13ECA) /* 741 */, - W64LIT(0x0FF979D12F59E2AC) /* 742 */, W64LIT(0x6037DA27E4F9CC50) /* 743 */, - W64LIT(0x5E92975A0DF1847D) /* 744 */, W64LIT(0xD66DE190D3E623FE) /* 745 */, - W64LIT(0x5032D6B87B568048) /* 746 */, W64LIT(0x9A36B7CE8235216E) /* 747 */, - W64LIT(0x80272A7A24F64B4A) /* 748 */, W64LIT(0x93EFED8B8C6916F7) /* 749 */, - W64LIT(0x37DDBFF44CCE1555) /* 750 */, W64LIT(0x4B95DB5D4B99BD25) /* 751 */, - W64LIT(0x92D3FDA169812FC0) /* 752 */, W64LIT(0xFB1A4A9A90660BB6) /* 753 */, - W64LIT(0x730C196946A4B9B2) /* 754 */, W64LIT(0x81E289AA7F49DA68) /* 755 */, - W64LIT(0x64669A0F83B1A05F) /* 756 */, W64LIT(0x27B3FF7D9644F48B) /* 757 */, - W64LIT(0xCC6B615C8DB675B3) /* 758 */, W64LIT(0x674F20B9BCEBBE95) /* 759 */, - W64LIT(0x6F31238275655982) /* 760 */, W64LIT(0x5AE488713E45CF05) /* 761 */, - W64LIT(0xBF619F9954C21157) /* 762 */, W64LIT(0xEABAC46040A8EAE9) /* 763 */, - W64LIT(0x454C6FE9F2C0C1CD) /* 764 */, W64LIT(0x419CF6496412691C) /* 765 */, - W64LIT(0xD3DC3BEF265B0F70) /* 766 */, W64LIT(0x6D0E60F5C3578A9E) /* 767 */, - W64LIT(0x5B0E608526323C55) /* 768 */, W64LIT(0x1A46C1A9FA1B59F5) /* 769 */, - W64LIT(0xA9E245A17C4C8FFA) /* 770 */, W64LIT(0x65CA5159DB2955D7) /* 771 */, - W64LIT(0x05DB0A76CE35AFC2) /* 772 */, W64LIT(0x81EAC77EA9113D45) /* 773 */, - W64LIT(0x528EF88AB6AC0A0D) /* 774 */, W64LIT(0xA09EA253597BE3FF) /* 775 */, - W64LIT(0x430DDFB3AC48CD56) /* 776 */, W64LIT(0xC4B3A67AF45CE46F) /* 777 */, - W64LIT(0x4ECECFD8FBE2D05E) /* 778 */, W64LIT(0x3EF56F10B39935F0) /* 779 */, - W64LIT(0x0B22D6829CD619C6) /* 780 */, W64LIT(0x17FD460A74DF2069) /* 781 */, - W64LIT(0x6CF8CC8E8510ED40) /* 782 */, W64LIT(0xD6C824BF3A6ECAA7) /* 783 */, - W64LIT(0x61243D581A817049) /* 784 */, W64LIT(0x048BACB6BBC163A2) /* 785 */, - W64LIT(0xD9A38AC27D44CC32) /* 786 */, W64LIT(0x7FDDFF5BAAF410AB) /* 787 */, - W64LIT(0xAD6D495AA804824B) /* 788 */, W64LIT(0xE1A6A74F2D8C9F94) /* 789 */, - W64LIT(0xD4F7851235DEE8E3) /* 790 */, W64LIT(0xFD4B7F886540D893) /* 791 */, - W64LIT(0x247C20042AA4BFDA) /* 792 */, W64LIT(0x096EA1C517D1327C) /* 793 */, - W64LIT(0xD56966B4361A6685) /* 794 */, W64LIT(0x277DA5C31221057D) /* 795 */, - W64LIT(0x94D59893A43ACFF7) /* 796 */, W64LIT(0x64F0C51CCDC02281) /* 797 */, - W64LIT(0x3D33BCC4FF6189DB) /* 798 */, W64LIT(0xE005CB184CE66AF1) /* 799 */, - W64LIT(0xFF5CCD1D1DB99BEA) /* 800 */, W64LIT(0xB0B854A7FE42980F) /* 801 */, - W64LIT(0x7BD46A6A718D4B9F) /* 802 */, W64LIT(0xD10FA8CC22A5FD8C) /* 803 */, - W64LIT(0xD31484952BE4BD31) /* 804 */, W64LIT(0xC7FA975FCB243847) /* 805 */, - W64LIT(0x4886ED1E5846C407) /* 806 */, W64LIT(0x28CDDB791EB70B04) /* 807 */, - W64LIT(0xC2B00BE2F573417F) /* 808 */, W64LIT(0x5C9590452180F877) /* 809 */, - W64LIT(0x7A6BDDFFF370EB00) /* 810 */, W64LIT(0xCE509E38D6D9D6A4) /* 811 */, - W64LIT(0xEBEB0F00647FA702) /* 812 */, W64LIT(0x1DCC06CF76606F06) /* 813 */, - W64LIT(0xE4D9F28BA286FF0A) /* 814 */, W64LIT(0xD85A305DC918C262) /* 815 */, - W64LIT(0x475B1D8732225F54) /* 816 */, W64LIT(0x2D4FB51668CCB5FE) /* 817 */, - W64LIT(0xA679B9D9D72BBA20) /* 818 */, W64LIT(0x53841C0D912D43A5) /* 819 */, - W64LIT(0x3B7EAA48BF12A4E8) /* 820 */, W64LIT(0x781E0E47F22F1DDF) /* 821 */, - W64LIT(0xEFF20CE60AB50973) /* 822 */, W64LIT(0x20D261D19DFFB742) /* 823 */, - W64LIT(0x16A12B03062A2E39) /* 824 */, W64LIT(0x1960EB2239650495) /* 825 */, - W64LIT(0x251C16FED50EB8B8) /* 826 */, W64LIT(0x9AC0C330F826016E) /* 827 */, - W64LIT(0xED152665953E7671) /* 828 */, W64LIT(0x02D63194A6369570) /* 829 */, - W64LIT(0x5074F08394B1C987) /* 830 */, W64LIT(0x70BA598C90B25CE1) /* 831 */, - W64LIT(0x794A15810B9742F6) /* 832 */, W64LIT(0x0D5925E9FCAF8C6C) /* 833 */, - W64LIT(0x3067716CD868744E) /* 834 */, W64LIT(0x910AB077E8D7731B) /* 835 */, - W64LIT(0x6A61BBDB5AC42F61) /* 836 */, W64LIT(0x93513EFBF0851567) /* 837 */, - W64LIT(0xF494724B9E83E9D5) /* 838 */, W64LIT(0xE887E1985C09648D) /* 839 */, - W64LIT(0x34B1D3C675370CFD) /* 840 */, W64LIT(0xDC35E433BC0D255D) /* 841 */, - W64LIT(0xD0AAB84234131BE0) /* 842 */, W64LIT(0x08042A50B48B7EAF) /* 843 */, - W64LIT(0x9997C4EE44A3AB35) /* 844 */, W64LIT(0x829A7B49201799D0) /* 845 */, - W64LIT(0x263B8307B7C54441) /* 846 */, W64LIT(0x752F95F4FD6A6CA6) /* 847 */, - W64LIT(0x927217402C08C6E5) /* 848 */, W64LIT(0x2A8AB754A795D9EE) /* 849 */, - W64LIT(0xA442F7552F72943D) /* 850 */, W64LIT(0x2C31334E19781208) /* 851 */, - W64LIT(0x4FA98D7CEAEE6291) /* 852 */, W64LIT(0x55C3862F665DB309) /* 853 */, - W64LIT(0xBD0610175D53B1F3) /* 854 */, W64LIT(0x46FE6CB840413F27) /* 855 */, - W64LIT(0x3FE03792DF0CFA59) /* 856 */, W64LIT(0xCFE700372EB85E8F) /* 857 */, - W64LIT(0xA7BE29E7ADBCE118) /* 858 */, W64LIT(0xE544EE5CDE8431DD) /* 859 */, - W64LIT(0x8A781B1B41F1873E) /* 860 */, W64LIT(0xA5C94C78A0D2F0E7) /* 861 */, - W64LIT(0x39412E2877B60728) /* 862 */, W64LIT(0xA1265EF3AFC9A62C) /* 863 */, - W64LIT(0xBCC2770C6A2506C5) /* 864 */, W64LIT(0x3AB66DD5DCE1CE12) /* 865 */, - W64LIT(0xE65499D04A675B37) /* 866 */, W64LIT(0x7D8F523481BFD216) /* 867 */, - W64LIT(0x0F6F64FCEC15F389) /* 868 */, W64LIT(0x74EFBE618B5B13C8) /* 869 */, - W64LIT(0xACDC82B714273E1D) /* 870 */, W64LIT(0xDD40BFE003199D17) /* 871 */, - W64LIT(0x37E99257E7E061F8) /* 872 */, W64LIT(0xFA52626904775AAA) /* 873 */, - W64LIT(0x8BBBF63A463D56F9) /* 874 */, W64LIT(0xF0013F1543A26E64) /* 875 */, - W64LIT(0xA8307E9F879EC898) /* 876 */, W64LIT(0xCC4C27A4150177CC) /* 877 */, - W64LIT(0x1B432F2CCA1D3348) /* 878 */, W64LIT(0xDE1D1F8F9F6FA013) /* 879 */, - W64LIT(0x606602A047A7DDD6) /* 880 */, W64LIT(0xD237AB64CC1CB2C7) /* 881 */, - W64LIT(0x9B938E7225FCD1D3) /* 882 */, W64LIT(0xEC4E03708E0FF476) /* 883 */, - W64LIT(0xFEB2FBDA3D03C12D) /* 884 */, W64LIT(0xAE0BCED2EE43889A) /* 885 */, - W64LIT(0x22CB8923EBFB4F43) /* 886 */, W64LIT(0x69360D013CF7396D) /* 887 */, - W64LIT(0x855E3602D2D4E022) /* 888 */, W64LIT(0x073805BAD01F784C) /* 889 */, - W64LIT(0x33E17A133852F546) /* 890 */, W64LIT(0xDF4874058AC7B638) /* 891 */, - W64LIT(0xBA92B29C678AA14A) /* 892 */, W64LIT(0x0CE89FC76CFAADCD) /* 893 */, - W64LIT(0x5F9D4E0908339E34) /* 894 */, W64LIT(0xF1AFE9291F5923B9) /* 895 */, - W64LIT(0x6E3480F60F4A265F) /* 896 */, W64LIT(0xEEBF3A2AB29B841C) /* 897 */, - W64LIT(0xE21938A88F91B4AD) /* 898 */, W64LIT(0x57DFEFF845C6D3C3) /* 899 */, - W64LIT(0x2F006B0BF62CAAF2) /* 900 */, W64LIT(0x62F479EF6F75EE78) /* 901 */, - W64LIT(0x11A55AD41C8916A9) /* 902 */, W64LIT(0xF229D29084FED453) /* 903 */, - W64LIT(0x42F1C27B16B000E6) /* 904 */, W64LIT(0x2B1F76749823C074) /* 905 */, - W64LIT(0x4B76ECA3C2745360) /* 906 */, W64LIT(0x8C98F463B91691BD) /* 907 */, - W64LIT(0x14BCC93CF1ADE66A) /* 908 */, W64LIT(0x8885213E6D458397) /* 909 */, - W64LIT(0x8E177DF0274D4711) /* 910 */, W64LIT(0xB49B73B5503F2951) /* 911 */, - W64LIT(0x10168168C3F96B6B) /* 912 */, W64LIT(0x0E3D963B63CAB0AE) /* 913 */, - W64LIT(0x8DFC4B5655A1DB14) /* 914 */, W64LIT(0xF789F1356E14DE5C) /* 915 */, - W64LIT(0x683E68AF4E51DAC1) /* 916 */, W64LIT(0xC9A84F9D8D4B0FD9) /* 917 */, - W64LIT(0x3691E03F52A0F9D1) /* 918 */, W64LIT(0x5ED86E46E1878E80) /* 919 */, - W64LIT(0x3C711A0E99D07150) /* 920 */, W64LIT(0x5A0865B20C4E9310) /* 921 */, - W64LIT(0x56FBFC1FE4F0682E) /* 922 */, W64LIT(0xEA8D5DE3105EDF9B) /* 923 */, - W64LIT(0x71ABFDB12379187A) /* 924 */, W64LIT(0x2EB99DE1BEE77B9C) /* 925 */, - W64LIT(0x21ECC0EA33CF4523) /* 926 */, W64LIT(0x59A4D7521805C7A1) /* 927 */, - W64LIT(0x3896F5EB56AE7C72) /* 928 */, W64LIT(0xAA638F3DB18F75DC) /* 929 */, - W64LIT(0x9F39358DABE9808E) /* 930 */, W64LIT(0xB7DEFA91C00B72AC) /* 931 */, - W64LIT(0x6B5541FD62492D92) /* 932 */, W64LIT(0x6DC6DEE8F92E4D5B) /* 933 */, - W64LIT(0x353F57ABC4BEEA7E) /* 934 */, W64LIT(0x735769D6DA5690CE) /* 935 */, - W64LIT(0x0A234AA642391484) /* 936 */, W64LIT(0xF6F9508028F80D9D) /* 937 */, - W64LIT(0xB8E319A27AB3F215) /* 938 */, W64LIT(0x31AD9C1151341A4D) /* 939 */, - W64LIT(0x773C22A57BEF5805) /* 940 */, W64LIT(0x45C7561A07968633) /* 941 */, - W64LIT(0xF913DA9E249DBE36) /* 942 */, W64LIT(0xDA652D9B78A64C68) /* 943 */, - W64LIT(0x4C27A97F3BC334EF) /* 944 */, W64LIT(0x76621220E66B17F4) /* 945 */, - W64LIT(0x967743899ACD7D0B) /* 946 */, W64LIT(0xF3EE5BCAE0ED6782) /* 947 */, - W64LIT(0x409F753600C879FC) /* 948 */, W64LIT(0x06D09A39B5926DB6) /* 949 */, - W64LIT(0x6F83AEB0317AC588) /* 950 */, W64LIT(0x01E6CA4A86381F21) /* 951 */, - W64LIT(0x66FF3462D19F3025) /* 952 */, W64LIT(0x72207C24DDFD3BFB) /* 953 */, - W64LIT(0x4AF6B6D3E2ECE2EB) /* 954 */, W64LIT(0x9C994DBEC7EA08DE) /* 955 */, - W64LIT(0x49ACE597B09A8BC4) /* 956 */, W64LIT(0xB38C4766CF0797BA) /* 957 */, - W64LIT(0x131B9373C57C2A75) /* 958 */, W64LIT(0xB1822CCE61931E58) /* 959 */, - W64LIT(0x9D7555B909BA1C0C) /* 960 */, W64LIT(0x127FAFDD937D11D2) /* 961 */, - W64LIT(0x29DA3BADC66D92E4) /* 962 */, W64LIT(0xA2C1D57154C2ECBC) /* 963 */, - W64LIT(0x58C5134D82F6FE24) /* 964 */, W64LIT(0x1C3AE3515B62274F) /* 965 */, - W64LIT(0xE907C82E01CB8126) /* 966 */, W64LIT(0xF8ED091913E37FCB) /* 967 */, - W64LIT(0x3249D8F9C80046C9) /* 968 */, W64LIT(0x80CF9BEDE388FB63) /* 969 */, - W64LIT(0x1881539A116CF19E) /* 970 */, W64LIT(0x5103F3F76BD52457) /* 971 */, - W64LIT(0x15B7E6F5AE47F7A8) /* 972 */, W64LIT(0xDBD7C6DED47E9CCF) /* 973 */, - W64LIT(0x44E55C410228BB1A) /* 974 */, W64LIT(0xB647D4255EDB4E99) /* 975 */, - W64LIT(0x5D11882BB8AAFC30) /* 976 */, W64LIT(0xF5098BBB29D3212A) /* 977 */, - W64LIT(0x8FB5EA14E90296B3) /* 978 */, W64LIT(0x677B942157DD025A) /* 979 */, - W64LIT(0xFB58E7C0A390ACB5) /* 980 */, W64LIT(0x89D3674C83BD4A01) /* 981 */, - W64LIT(0x9E2DA4DF4BF3B93B) /* 982 */, W64LIT(0xFCC41E328CAB4829) /* 983 */, - W64LIT(0x03F38C96BA582C52) /* 984 */, W64LIT(0xCAD1BDBD7FD85DB2) /* 985 */, - W64LIT(0xBBB442C16082AE83) /* 986 */, W64LIT(0xB95FE86BA5DA9AB0) /* 987 */, - W64LIT(0xB22E04673771A93F) /* 988 */, W64LIT(0x845358C9493152D8) /* 989 */, - W64LIT(0xBE2A488697B4541E) /* 990 */, W64LIT(0x95A2DC2DD38E6966) /* 991 */, - W64LIT(0xC02C11AC923C852B) /* 992 */, W64LIT(0x2388B1990DF2A87B) /* 993 */, - W64LIT(0x7C8008FA1B4F37BE) /* 994 */, W64LIT(0x1F70D0C84D54E503) /* 995 */, - W64LIT(0x5490ADEC7ECE57D4) /* 996 */, W64LIT(0x002B3C27D9063A3A) /* 997 */, - W64LIT(0x7EAEA3848030A2BF) /* 998 */, W64LIT(0xC602326DED2003C0) /* 999 */, - W64LIT(0x83A7287D69A94086) /* 1000 */, W64LIT(0xC57A5FCB30F57A8A) /* 1001 */, - W64LIT(0xB56844E479EBE779) /* 1002 */, W64LIT(0xA373B40F05DCBCE9) /* 1003 */, - W64LIT(0xD71A786E88570EE2) /* 1004 */, W64LIT(0x879CBACDBDE8F6A0) /* 1005 */, - W64LIT(0x976AD1BCC164A32F) /* 1006 */, W64LIT(0xAB21E25E9666D78B) /* 1007 */, - W64LIT(0x901063AAE5E5C33C) /* 1008 */, W64LIT(0x9818B34448698D90) /* 1009 */, - W64LIT(0xE36487AE3E1E8ABB) /* 1010 */, W64LIT(0xAFBDF931893BDCB4) /* 1011 */, - W64LIT(0x6345A0DC5FBBD519) /* 1012 */, W64LIT(0x8628FE269B9465CA) /* 1013 */, - W64LIT(0x1E5D01603F9C51EC) /* 1014 */, W64LIT(0x4DE44006A15049B7) /* 1015 */, - W64LIT(0xBF6C70E5F776CBB1) /* 1016 */, W64LIT(0x411218F2EF552BED) /* 1017 */, - W64LIT(0xCB0C0708705A36A3) /* 1018 */, W64LIT(0xE74D14754F986044) /* 1019 */, - W64LIT(0xCD56D9430EA8280E) /* 1020 */, W64LIT(0xC12591D7535F5065) /* 1021 */, - W64LIT(0xC83223F1720AEF96) /* 1022 */, W64LIT(0xC3A0396F7363A51F) /* 1023 */, - W64LIT(0xffffffffffffffff), - W64LIT(0xA5A5A5A5A5A5A5A5), - W64LIT(0x0123456789ABCDEF), -}; - -NAMESPACE_END diff --git a/lib/cryptopp/trdlocal.cpp b/lib/cryptopp/trdlocal.cpp deleted file mode 100644 index 6d6b822c0..000000000 --- a/lib/cryptopp/trdlocal.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// trdlocal.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS -#ifdef THREADS_AVAILABLE - -#include "trdlocal.h" - -#ifdef HAS_WINTHREADS -#include <windows.h> -#endif - -NAMESPACE_BEGIN(CryptoPP) - -ThreadLocalStorage::Err::Err(const std::string& operation, int error) - : OS_Error(OTHER_ERROR, "ThreadLocalStorage: " + operation + " operation failed with error 0x" + IntToString(error, 16), operation, error) -{ -} - -ThreadLocalStorage::ThreadLocalStorage() -{ -#ifdef HAS_WINTHREADS - m_index = TlsAlloc(); - if (m_index == TLS_OUT_OF_INDEXES) - throw Err("TlsAlloc", GetLastError()); -#else - int error = pthread_key_create(&m_index, NULL); - if (error) - throw Err("pthread_key_create", error); -#endif -} - -ThreadLocalStorage::~ThreadLocalStorage() -{ -#ifdef HAS_WINTHREADS - if (!TlsFree(m_index)) - throw Err("TlsFree", GetLastError()); -#else - int error = pthread_key_delete(m_index); - if (error) - throw Err("pthread_key_delete", error); -#endif -} - -void ThreadLocalStorage::SetValue(void *value) -{ -#ifdef HAS_WINTHREADS - if (!TlsSetValue(m_index, value)) - throw Err("TlsSetValue", GetLastError()); -#else - int error = pthread_setspecific(m_index, value); - if (error) - throw Err("pthread_key_getspecific", error); -#endif -} - -void *ThreadLocalStorage::GetValue() const -{ -#ifdef HAS_WINTHREADS - void *result = TlsGetValue(m_index); - if (!result && GetLastError() != NO_ERROR) - throw Err("TlsGetValue", GetLastError()); -#else - void *result = pthread_getspecific(m_index); -#endif - return result; -} - -NAMESPACE_END - -#endif // #ifdef THREADS_AVAILABLE -#endif diff --git a/lib/cryptopp/trdlocal.h b/lib/cryptopp/trdlocal.h deleted file mode 100644 index 92d244a0a..000000000 --- a/lib/cryptopp/trdlocal.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef CRYPTOPP_TRDLOCAL_H -#define CRYPTOPP_TRDLOCAL_H - -#include "config.h" - -#ifdef THREADS_AVAILABLE - -#include "misc.h" - -#ifdef HAS_WINTHREADS -typedef unsigned long ThreadLocalIndexType; -#else -#include <pthread.h> -typedef pthread_key_t ThreadLocalIndexType; -#endif - -NAMESPACE_BEGIN(CryptoPP) - -//! thread local storage -class CRYPTOPP_DLL ThreadLocalStorage : public NotCopyable -{ -public: - //! exception thrown by ThreadLocalStorage class - class Err : public OS_Error - { - public: - Err(const std::string& operation, int error); - }; - - ThreadLocalStorage(); - ~ThreadLocalStorage(); - - void SetValue(void *value); - void *GetValue() const; - -private: - ThreadLocalIndexType m_index; -}; - -NAMESPACE_END - -#endif // #ifdef THREADS_AVAILABLE - -#endif diff --git a/lib/cryptopp/trunhash.h b/lib/cryptopp/trunhash.h deleted file mode 100644 index c1c4e9b64..000000000 --- a/lib/cryptopp/trunhash.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef CRYPTOPP_TRUNHASH_H -#define CRYPTOPP_TRUNHASH_H - -#include "cryptlib.h" - -NAMESPACE_BEGIN(CryptoPP) - -class NullHash : public HashTransformation -{ -public: - void Update(const byte *input, size_t length) {} - unsigned int DigestSize() const {return 0;} - void TruncatedFinal(byte *digest, size_t digestSize) {} - bool TruncatedVerify(const byte *digest, size_t digestLength) {return true;} -}; - -//! construct new HashModule with smaller DigestSize() from existing one -template <class T> -class TruncatedHashTemplate : public HashTransformation -{ -public: - TruncatedHashTemplate(T hm, unsigned int digestSize) - : m_hm(hm), m_digestSize(digestSize) {} - TruncatedHashTemplate(const byte *key, size_t keyLength, unsigned int digestSize) - : m_hm(key, keyLength), m_digestSize(digestSize) {} - TruncatedHashTemplate(size_t digestSize) - : m_digestSize(digestSize) {} - - void Restart() - {m_hm.Restart();} - void Update(const byte *input, size_t length) - {m_hm.Update(input, length);} - unsigned int DigestSize() const {return m_digestSize;} - void TruncatedFinal(byte *digest, size_t digestSize) - {m_hm.TruncatedFinal(digest, digestSize);} - bool TruncatedVerify(const byte *digest, size_t digestLength) - {return m_hm.TruncatedVerify(digest, digestLength);} - -private: - T m_hm; - unsigned int m_digestSize; -}; - -typedef TruncatedHashTemplate<HashTransformation &> TruncatedHashModule; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/ttmac.cpp b/lib/cryptopp/ttmac.cpp deleted file mode 100644 index d4ff38104..000000000 --- a/lib/cryptopp/ttmac.cpp +++ /dev/null @@ -1,338 +0,0 @@ -// ttmac.cpp - written and placed in the public domain by Kevin Springle - -#include "pch.h" -#include "ttmac.h" -#include "misc.h" - -NAMESPACE_BEGIN(CryptoPP) - -void TTMAC_Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs &) -{ - AssertValidKeyLength(keylength); - - memcpy(m_key, userKey, KEYLENGTH); - CorrectEndianess(m_key, m_key, KEYLENGTH); - - Init(); -} - -void TTMAC_Base::Init() -{ - m_digest[0] = m_digest[5] = m_key[0]; - m_digest[1] = m_digest[6] = m_key[1]; - m_digest[2] = m_digest[7] = m_key[2]; - m_digest[3] = m_digest[8] = m_key[3]; - m_digest[4] = m_digest[9] = m_key[4]; -} - -void TTMAC_Base::TruncatedFinal(byte *hash, size_t size) -{ - PadLastBlock(BlockSize() - 2*sizeof(HashWordType)); - CorrectEndianess(m_data, m_data, BlockSize() - 2*sizeof(HashWordType)); - - m_data[m_data.size()-2] = GetBitCountLo(); - m_data[m_data.size()-1] = GetBitCountHi(); - - Transform(m_digest, m_data, true); - - word32 t2 = m_digest[2]; - word32 t3 = m_digest[3]; - if (size != DIGESTSIZE) - { - switch (size) - { - case 16: - m_digest[3] += m_digest[1] + m_digest[4]; - - case 12: - m_digest[2] += m_digest[0] + t3; - - case 8: - m_digest[0] += m_digest[1] + t3; - m_digest[1] += m_digest[4] + t2; - break; - - case 4: - m_digest[0] += - m_digest[1] + - m_digest[2] + - m_digest[3] + - m_digest[4]; - break; - - case 0: - // Used by HashTransformation::Restart() - break; - - default: - throw InvalidArgument("TTMAC_Base: can't truncate a Two-Track-MAC 20 byte digest to " + IntToString(size) + " bytes"); - break; - } - } - - CorrectEndianess(m_digest, m_digest, size); - memcpy(hash, m_digest, size); - - Restart(); // reinit for next use -} - -// RIPEMD-160 definitions used by Two-Track-MAC - -#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 0x5a827999UL -#define k2 0x6ed9eba1UL -#define k3 0x8f1bbcdcUL -#define k4 0xa953fd4eUL -#define k5 0x50a28be6UL -#define k6 0x5c4dd124UL -#define k7 0x6d703ef3UL -#define k8 0x7a6d76e9UL -#define k9 0 - -void TTMAC_Base::Transform(word32 *digest, const word32 *X, bool last) -{ -#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) - - word32 a1, b1, c1, d1, e1, a2, b2, c2, d2, e2; - word32 *trackA, *trackB; - - if (!last) - { - trackA = digest; - trackB = digest+5; - } - else - { - trackB = digest; - trackA = digest+5; - } - a1 = trackA[0]; - b1 = trackA[1]; - c1 = trackA[2]; - d1 = trackA[3]; - e1 = trackA[4]; - a2 = trackB[0]; - b2 = trackB[1]; - c2 = trackB[2]; - d2 = trackB[3]; - e2 = trackB[4]; - - Subround(F, a1, b1, c1, d1, e1, X[ 0], 11, k0); - Subround(F, e1, a1, b1, c1, d1, X[ 1], 14, k0); - Subround(F, d1, e1, a1, b1, c1, X[ 2], 15, k0); - Subround(F, c1, d1, e1, a1, b1, X[ 3], 12, k0); - Subround(F, b1, c1, d1, e1, a1, X[ 4], 5, k0); - Subround(F, a1, b1, c1, d1, e1, X[ 5], 8, k0); - Subround(F, e1, a1, b1, c1, d1, X[ 6], 7, k0); - Subround(F, d1, e1, a1, b1, c1, X[ 7], 9, k0); - Subround(F, c1, d1, e1, a1, b1, X[ 8], 11, k0); - Subround(F, b1, c1, d1, e1, a1, X[ 9], 13, k0); - Subround(F, a1, b1, c1, d1, e1, X[10], 14, k0); - Subround(F, e1, a1, b1, c1, d1, X[11], 15, k0); - Subround(F, d1, e1, a1, b1, c1, X[12], 6, k0); - Subround(F, c1, d1, e1, a1, b1, X[13], 7, k0); - Subround(F, b1, c1, d1, e1, a1, X[14], 9, k0); - Subround(F, a1, b1, c1, d1, e1, X[15], 8, k0); - - Subround(G, e1, a1, b1, c1, d1, X[ 7], 7, k1); - Subround(G, d1, e1, a1, b1, c1, X[ 4], 6, k1); - Subround(G, c1, d1, e1, a1, b1, X[13], 8, k1); - Subround(G, b1, c1, d1, e1, a1, X[ 1], 13, k1); - Subround(G, a1, b1, c1, d1, e1, X[10], 11, k1); - Subround(G, e1, a1, b1, c1, d1, X[ 6], 9, k1); - Subround(G, d1, e1, a1, b1, c1, X[15], 7, k1); - Subround(G, c1, d1, e1, a1, b1, X[ 3], 15, k1); - Subround(G, b1, c1, d1, e1, a1, X[12], 7, k1); - Subround(G, a1, b1, c1, d1, e1, X[ 0], 12, k1); - Subround(G, e1, a1, b1, c1, d1, X[ 9], 15, k1); - Subround(G, d1, e1, a1, b1, c1, X[ 5], 9, k1); - Subround(G, c1, d1, e1, a1, b1, X[ 2], 11, k1); - Subround(G, b1, c1, d1, e1, a1, X[14], 7, k1); - Subround(G, a1, b1, c1, d1, e1, X[11], 13, k1); - Subround(G, e1, a1, b1, c1, d1, X[ 8], 12, k1); - - Subround(H, d1, e1, a1, b1, c1, X[ 3], 11, k2); - Subround(H, c1, d1, e1, a1, b1, X[10], 13, k2); - Subround(H, b1, c1, d1, e1, a1, X[14], 6, k2); - Subround(H, a1, b1, c1, d1, e1, X[ 4], 7, k2); - Subround(H, e1, a1, b1, c1, d1, X[ 9], 14, k2); - Subround(H, d1, e1, a1, b1, c1, X[15], 9, k2); - Subround(H, c1, d1, e1, a1, b1, X[ 8], 13, k2); - Subround(H, b1, c1, d1, e1, a1, X[ 1], 15, k2); - Subround(H, a1, b1, c1, d1, e1, X[ 2], 14, k2); - Subround(H, e1, a1, b1, c1, d1, X[ 7], 8, k2); - Subround(H, d1, e1, a1, b1, c1, X[ 0], 13, k2); - Subround(H, c1, d1, e1, a1, b1, X[ 6], 6, k2); - Subround(H, b1, c1, d1, e1, a1, X[13], 5, k2); - Subround(H, a1, b1, c1, d1, e1, X[11], 12, k2); - Subround(H, e1, a1, b1, c1, d1, X[ 5], 7, k2); - Subround(H, d1, e1, a1, b1, c1, X[12], 5, k2); - - Subround(I, c1, d1, e1, a1, b1, X[ 1], 11, k3); - Subround(I, b1, c1, d1, e1, a1, X[ 9], 12, k3); - Subround(I, a1, b1, c1, d1, e1, X[11], 14, k3); - Subround(I, e1, a1, b1, c1, d1, X[10], 15, k3); - Subround(I, d1, e1, a1, b1, c1, X[ 0], 14, k3); - Subround(I, c1, d1, e1, a1, b1, X[ 8], 15, k3); - Subround(I, b1, c1, d1, e1, a1, X[12], 9, k3); - Subround(I, a1, b1, c1, d1, e1, X[ 4], 8, k3); - Subround(I, e1, a1, b1, c1, d1, X[13], 9, k3); - Subround(I, d1, e1, a1, b1, c1, X[ 3], 14, k3); - Subround(I, c1, d1, e1, a1, b1, X[ 7], 5, k3); - Subround(I, b1, c1, d1, e1, a1, X[15], 6, k3); - Subround(I, a1, b1, c1, d1, e1, X[14], 8, k3); - Subround(I, e1, a1, b1, c1, d1, X[ 5], 6, k3); - Subround(I, d1, e1, a1, b1, c1, X[ 6], 5, k3); - Subround(I, c1, d1, e1, a1, b1, X[ 2], 12, k3); - - Subround(J, b1, c1, d1, e1, a1, X[ 4], 9, k4); - Subround(J, a1, b1, c1, d1, e1, X[ 0], 15, k4); - Subround(J, e1, a1, b1, c1, d1, X[ 5], 5, k4); - Subround(J, d1, e1, a1, b1, c1, X[ 9], 11, k4); - Subround(J, c1, d1, e1, a1, b1, X[ 7], 6, k4); - Subround(J, b1, c1, d1, e1, a1, X[12], 8, k4); - Subround(J, a1, b1, c1, d1, e1, X[ 2], 13, k4); - Subround(J, e1, a1, b1, c1, d1, X[10], 12, k4); - Subround(J, d1, e1, a1, b1, c1, X[14], 5, k4); - Subround(J, c1, d1, e1, a1, b1, X[ 1], 12, k4); - Subround(J, b1, c1, d1, e1, a1, X[ 3], 13, k4); - Subround(J, a1, b1, c1, d1, e1, X[ 8], 14, k4); - Subround(J, e1, a1, b1, c1, d1, X[11], 11, k4); - Subround(J, d1, e1, a1, b1, c1, X[ 6], 8, k4); - Subround(J, c1, d1, e1, a1, b1, X[15], 5, k4); - Subround(J, b1, c1, d1, e1, a1, X[13], 6, k4); - - Subround(J, a2, b2, c2, d2, e2, X[ 5], 8, k5); - Subround(J, e2, a2, b2, c2, d2, X[14], 9, k5); - Subround(J, d2, e2, a2, b2, c2, X[ 7], 9, k5); - Subround(J, c2, d2, e2, a2, b2, X[ 0], 11, k5); - Subround(J, b2, c2, d2, e2, a2, X[ 9], 13, k5); - Subround(J, a2, b2, c2, d2, e2, X[ 2], 15, k5); - Subround(J, e2, a2, b2, c2, d2, X[11], 15, k5); - Subround(J, d2, e2, a2, b2, c2, X[ 4], 5, k5); - Subround(J, c2, d2, e2, a2, b2, X[13], 7, k5); - Subround(J, b2, c2, d2, e2, a2, X[ 6], 7, k5); - Subround(J, a2, b2, c2, d2, e2, X[15], 8, k5); - Subround(J, e2, a2, b2, c2, d2, X[ 8], 11, k5); - Subround(J, d2, e2, a2, b2, c2, X[ 1], 14, k5); - Subround(J, c2, d2, e2, a2, b2, X[10], 14, k5); - Subround(J, b2, c2, d2, e2, a2, X[ 3], 12, k5); - Subround(J, a2, b2, c2, d2, e2, X[12], 6, k5); - - Subround(I, e2, a2, b2, c2, d2, X[ 6], 9, k6); - Subround(I, d2, e2, a2, b2, c2, X[11], 13, k6); - Subround(I, c2, d2, e2, a2, b2, X[ 3], 15, k6); - Subround(I, b2, c2, d2, e2, a2, X[ 7], 7, k6); - Subround(I, a2, b2, c2, d2, e2, X[ 0], 12, k6); - Subround(I, e2, a2, b2, c2, d2, X[13], 8, k6); - Subround(I, d2, e2, a2, b2, c2, X[ 5], 9, k6); - Subround(I, c2, d2, e2, a2, b2, X[10], 11, k6); - Subround(I, b2, c2, d2, e2, a2, X[14], 7, k6); - Subround(I, a2, b2, c2, d2, e2, X[15], 7, k6); - Subround(I, e2, a2, b2, c2, d2, X[ 8], 12, k6); - Subround(I, d2, e2, a2, b2, c2, X[12], 7, k6); - Subround(I, c2, d2, e2, a2, b2, X[ 4], 6, k6); - Subround(I, b2, c2, d2, e2, a2, X[ 9], 15, k6); - Subround(I, a2, b2, c2, d2, e2, X[ 1], 13, k6); - Subround(I, e2, a2, b2, c2, d2, X[ 2], 11, k6); - - Subround(H, d2, e2, a2, b2, c2, X[15], 9, k7); - Subround(H, c2, d2, e2, a2, b2, X[ 5], 7, k7); - Subround(H, b2, c2, d2, e2, a2, X[ 1], 15, k7); - Subround(H, a2, b2, c2, d2, e2, X[ 3], 11, k7); - Subround(H, e2, a2, b2, c2, d2, X[ 7], 8, k7); - Subround(H, d2, e2, a2, b2, c2, X[14], 6, k7); - Subround(H, c2, d2, e2, a2, b2, X[ 6], 6, k7); - Subround(H, b2, c2, d2, e2, a2, X[ 9], 14, k7); - Subround(H, a2, b2, c2, d2, e2, X[11], 12, k7); - Subround(H, e2, a2, b2, c2, d2, X[ 8], 13, k7); - Subround(H, d2, e2, a2, b2, c2, X[12], 5, k7); - Subround(H, c2, d2, e2, a2, b2, X[ 2], 14, k7); - Subround(H, b2, c2, d2, e2, a2, X[10], 13, k7); - Subround(H, a2, b2, c2, d2, e2, X[ 0], 13, k7); - Subround(H, e2, a2, b2, c2, d2, X[ 4], 7, k7); - Subround(H, d2, e2, a2, b2, c2, X[13], 5, k7); - - Subround(G, c2, d2, e2, a2, b2, X[ 8], 15, k8); - Subround(G, b2, c2, d2, e2, a2, X[ 6], 5, k8); - Subround(G, a2, b2, c2, d2, e2, X[ 4], 8, k8); - Subround(G, e2, a2, b2, c2, d2, X[ 1], 11, k8); - Subround(G, d2, e2, a2, b2, c2, X[ 3], 14, k8); - Subround(G, c2, d2, e2, a2, b2, X[11], 14, k8); - Subround(G, b2, c2, d2, e2, a2, X[15], 6, k8); - Subround(G, a2, b2, c2, d2, e2, X[ 0], 14, k8); - Subround(G, e2, a2, b2, c2, d2, X[ 5], 6, k8); - Subround(G, d2, e2, a2, b2, c2, X[12], 9, k8); - Subround(G, c2, d2, e2, a2, b2, X[ 2], 12, k8); - Subround(G, b2, c2, d2, e2, a2, X[13], 9, k8); - Subround(G, a2, b2, c2, d2, e2, X[ 9], 12, k8); - Subround(G, e2, a2, b2, c2, d2, X[ 7], 5, k8); - Subround(G, d2, e2, a2, b2, c2, X[10], 15, k8); - Subround(G, c2, d2, e2, a2, b2, X[14], 8, k8); - - Subround(F, b2, c2, d2, e2, a2, X[12], 8, k9); - Subround(F, a2, b2, c2, d2, e2, X[15], 5, k9); - Subround(F, e2, a2, b2, c2, d2, X[10], 12, k9); - Subround(F, d2, e2, a2, b2, c2, X[ 4], 9, k9); - Subround(F, c2, d2, e2, a2, b2, X[ 1], 12, k9); - Subround(F, b2, c2, d2, e2, a2, X[ 5], 5, k9); - Subround(F, a2, b2, c2, d2, e2, X[ 8], 14, k9); - Subround(F, e2, a2, b2, c2, d2, X[ 7], 6, k9); - Subround(F, d2, e2, a2, b2, c2, X[ 6], 8, k9); - Subround(F, c2, d2, e2, a2, b2, X[ 2], 13, k9); - Subround(F, b2, c2, d2, e2, a2, X[13], 6, k9); - Subround(F, a2, b2, c2, d2, e2, X[14], 5, k9); - Subround(F, e2, a2, b2, c2, d2, X[ 0], 15, k9); - Subround(F, d2, e2, a2, b2, c2, X[ 3], 13, k9); - Subround(F, c2, d2, e2, a2, b2, X[ 9], 11, k9); - Subround(F, b2, c2, d2, e2, a2, X[11], 11, k9); - - a1 -= trackA[0]; - b1 -= trackA[1]; - c1 -= trackA[2]; - d1 -= trackA[3]; - e1 -= trackA[4]; - a2 -= trackB[0]; - b2 -= trackB[1]; - c2 -= trackB[2]; - d2 -= trackB[3]; - e2 -= trackB[4]; - - if (!last) - { - trackA[0] = (b1 + e1) - d2; - trackA[1] = c1 - e2; - trackA[2] = d1 - a2; - trackA[3] = e1 - b2; - trackA[4] = a1 - c2; - trackB[0] = d1 - e2; - trackB[1] = (e1 + c1) - a2; - trackB[2] = a1 - b2; - trackB[3] = b1 - c2; - trackB[4] = c1 - d2; - } - else - { - trackB[0] = a2 - a1; - trackB[1] = b2 - b1; - trackB[2] = c2 - c1; - trackB[3] = d2 - d1; - trackB[4] = e2 - e1; - trackA[0] = 0; - trackA[1] = 0; - trackA[2] = 0; - trackA[3] = 0; - trackA[4] = 0; - } -} - -NAMESPACE_END diff --git a/lib/cryptopp/ttmac.h b/lib/cryptopp/ttmac.h deleted file mode 100644 index b4bf86e26..000000000 --- a/lib/cryptopp/ttmac.h +++ /dev/null @@ -1,38 +0,0 @@ -// ttmac.h - written and placed in the public domain by Kevin Springle - -#ifndef CRYPTOPP_TTMAC_H -#define CRYPTOPP_TTMAC_H - -#include "seckey.h" -#include "iterhash.h" - -NAMESPACE_BEGIN(CryptoPP) - -//! _ -class CRYPTOPP_NO_VTABLE TTMAC_Base : public FixedKeyLength<20>, public IteratedHash<word32, LittleEndian, 64, MessageAuthenticationCode> -{ -public: - static std::string StaticAlgorithmName() {return std::string("Two-Track-MAC");} - CRYPTOPP_CONSTANT(DIGESTSIZE=20) - - unsigned int DigestSize() const {return DIGESTSIZE;}; - void UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs ¶ms); - void TruncatedFinal(byte *mac, size_t size); - -protected: - static void Transform (word32 *digest, const word32 *X, bool last); - void HashEndianCorrectedBlock(const word32 *data) {Transform(m_digest, data, false);} - void Init(); - word32* StateBuf() {return m_digest;} - - FixedSizeSecBlock<word32, 10> m_digest; - FixedSizeSecBlock<word32, 5> m_key; -}; - -//! <a href="http://www.weidai.com/scan-mirror/mac.html#TTMAC">Two-Track-MAC</a> -/*! 160 Bit MAC with 160 Bit Key */ -DOCUMENTED_TYPEDEF(MessageAuthenticationCodeFinal<TTMAC_Base>, TTMAC) - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/validate.h b/lib/cryptopp/validate.h deleted file mode 100644 index 0ab23cba3..000000000 --- a/lib/cryptopp/validate.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef CRYPTOPP_VALIDATE_H -#define CRYPTOPP_VALIDATE_H - -#include "cryptlib.h" - -bool ValidateAll(bool thorough); -bool TestSettings(); -bool TestOS_RNG(); -bool ValidateBaseCode(); - -bool ValidateCRC32(); -bool ValidateAdler32(); -bool ValidateMD2(); -bool ValidateMD4(); -bool ValidateMD5(); -bool ValidateSHA(); -bool ValidateSHA2(); -bool ValidateTiger(); -bool ValidateRIPEMD(); -bool ValidatePanama(); -bool ValidateWhirlpool(); - -bool ValidateHMAC(); -bool ValidateTTMAC(); - -bool ValidateCipherModes(); -bool ValidatePBKDF(); - -bool ValidateDES(); -bool ValidateIDEA(); -bool ValidateSAFER(); -bool ValidateRC2(); -bool ValidateARC4(); - -bool ValidateRC5(); -bool ValidateBlowfish(); -bool ValidateThreeWay(); -bool ValidateGOST(); -bool ValidateSHARK(); -bool ValidateSEAL(); -bool ValidateCAST(); -bool ValidateSquare(); -bool ValidateSKIPJACK(); -bool ValidateRC6(); -bool ValidateMARS(); -bool ValidateRijndael(); -bool ValidateTwofish(); -bool ValidateSerpent(); -bool ValidateSHACAL2(); -bool ValidateCamellia(); -bool ValidateSalsa(); -bool ValidateSosemanuk(); -bool ValidateVMAC(); -bool ValidateCCM(); -bool ValidateGCM(); -bool ValidateCMAC(); - -bool ValidateBBS(); -bool ValidateDH(); -bool ValidateMQV(); -bool ValidateRSA(); -bool ValidateElGamal(); -bool ValidateDLIES(); -bool ValidateNR(); -bool ValidateDSA(bool thorough); -bool ValidateLUC(); -bool ValidateLUC_DL(); -bool ValidateLUC_DH(); -bool ValidateXTR_DH(); -bool ValidateRabin(); -bool ValidateRW(); -//bool ValidateBlumGoldwasser(); -bool ValidateECP(); -bool ValidateEC2N(); -bool ValidateECDSA(); -bool ValidateESIGN(); - -CryptoPP::RandomNumberGenerator & GlobalRNG(); -bool RunTestDataFile(const char *filename, const CryptoPP::NameValuePairs &overrideParameters=CryptoPP::g_nullNameValuePairs, bool thorough=true); - -#endif diff --git a/lib/cryptopp/vmac.cpp b/lib/cryptopp/vmac.cpp deleted file mode 100644 index 6b490f904..000000000 --- a/lib/cryptopp/vmac.cpp +++ /dev/null @@ -1,832 +0,0 @@ -// vmac.cpp - written and placed in the public domain by Wei Dai -// based on Ted Krovetz's public domain vmac.c and draft-krovetz-vmac-01.txt - -#include "pch.h" -#include "vmac.h" -#include "argnames.h" -#include "cpu.h" - -NAMESPACE_BEGIN(CryptoPP) - -#if defined(_MSC_VER) && !CRYPTOPP_BOOL_SLOW_WORD64 -#include <intrin.h> -#endif - -#define VMAC_BOOL_WORD128 (defined(CRYPTOPP_WORD128_AVAILABLE) && !defined(CRYPTOPP_X64_ASM_AVAILABLE)) -#ifdef __BORLANDC__ -#define const // Turbo C++ 2006 workaround -#endif -static const word64 p64 = W64LIT(0xfffffffffffffeff); /* 2^64 - 257 prime */ -static const word64 m62 = W64LIT(0x3fffffffffffffff); /* 62-bit mask */ -static const word64 m63 = W64LIT(0x7fffffffffffffff); /* 63-bit mask */ -static const word64 m64 = W64LIT(0xffffffffffffffff); /* 64-bit mask */ -static const word64 mpoly = W64LIT(0x1fffffff1fffffff); /* Poly key mask */ -#ifdef __BORLANDC__ -#undef const -#endif -#if VMAC_BOOL_WORD128 -#ifdef __powerpc__ -// workaround GCC Bug 31690: ICE with const __uint128_t and C++ front-end -#define m126 ((word128(m62)<<64)|m64) -#else -static const word128 m126 = (word128(m62)<<64)|m64; /* 126-bit mask */ -#endif -#endif - -void VMAC_Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs ¶ms) -{ - int digestLength = params.GetIntValueWithDefault(Name::DigestSize(), DefaultDigestSize()); - if (digestLength != 8 && digestLength != 16) - throw InvalidArgument("VMAC: DigestSize must be 8 or 16"); - m_is128 = digestLength == 16; - - m_L1KeyLength = params.GetIntValueWithDefault(Name::L1KeyLength(), 128); - if (m_L1KeyLength <= 0 || m_L1KeyLength % 128 != 0) - throw InvalidArgument("VMAC: L1KeyLength must be a positive multiple of 128"); - - AllocateBlocks(); - - BlockCipher &cipher = AccessCipher(); - cipher.SetKey(userKey, keylength, params); - unsigned int blockSize = cipher.BlockSize(); - unsigned int blockSizeInWords = blockSize / sizeof(word64); - SecBlock<word64> out(blockSizeInWords); - SecByteBlock in; - in.CleanNew(blockSize); - size_t i; - - /* Fill nh key */ - in[0] = 0x80; - cipher.AdvancedProcessBlocks(in, NULL, (byte *)m_nhKey(), m_nhKeySize()*sizeof(word64), cipher.BT_InBlockIsCounter); - ConditionalByteReverse<word64>(BIG_ENDIAN_ORDER, m_nhKey(), m_nhKey(), m_nhKeySize()*sizeof(word64)); - - /* Fill poly key */ - in[0] = 0xC0; - in[15] = 0; - for (i = 0; i <= (size_t)m_is128; i++) - { - cipher.ProcessBlock(in, out.BytePtr()); - m_polyState()[i*4+2] = GetWord<word64>(true, BIG_ENDIAN_ORDER, out.BytePtr()) & mpoly; - m_polyState()[i*4+3] = GetWord<word64>(true, BIG_ENDIAN_ORDER, out.BytePtr()+8) & mpoly; - in[15]++; - } - - /* Fill ip key */ - in[0] = 0xE0; - in[15] = 0; - word64 *l3Key = m_l3Key(); - for (i = 0; i <= (size_t)m_is128; i++) - do - { - cipher.ProcessBlock(in, out.BytePtr()); - l3Key[i*2+0] = GetWord<word64>(true, BIG_ENDIAN_ORDER, out.BytePtr()); - l3Key[i*2+1] = GetWord<word64>(true, BIG_ENDIAN_ORDER, out.BytePtr()+8); - in[15]++; - } while ((l3Key[i*2+0] >= p64) || (l3Key[i*2+1] >= p64)); - - m_padCached = false; - size_t nonceLength; - const byte *nonce = GetIVAndThrowIfInvalid(params, nonceLength); - Resynchronize(nonce, (int)nonceLength); -} - -void VMAC_Base::GetNextIV(RandomNumberGenerator &rng, byte *IV) -{ - SimpleKeyingInterface::GetNextIV(rng, IV); - IV[0] &= 0x7f; -} - -void VMAC_Base::Resynchronize(const byte *nonce, int len) -{ - size_t length = ThrowIfInvalidIVLength(len); - size_t s = IVSize(); - byte *storedNonce = m_nonce(); - - if (m_is128) - { - memset(storedNonce, 0, s-length); - memcpy(storedNonce+s-length, nonce, length); - AccessCipher().ProcessBlock(storedNonce, m_pad()); - } - else - { - if (m_padCached && (storedNonce[s-1] | 1) == (nonce[length-1] | 1)) - { - m_padCached = VerifyBufsEqual(storedNonce+s-length, nonce, length-1); - for (size_t i=0; m_padCached && i<s-length; i++) - m_padCached = (storedNonce[i] == 0); - } - if (!m_padCached) - { - memset(storedNonce, 0, s-length); - memcpy(storedNonce+s-length, nonce, length-1); - storedNonce[s-1] = nonce[length-1] & 0xfe; - AccessCipher().ProcessBlock(storedNonce, m_pad()); - m_padCached = true; - } - storedNonce[s-1] = nonce[length-1]; - } - m_isFirstBlock = true; - Restart(); -} - -void VMAC_Base::HashEndianCorrectedBlock(const word64 *data) -{ - assert(false); - throw 0; -} - -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 -#pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code -void -#ifdef __GNUC__ -__attribute__ ((noinline)) // Intel Compiler 9.1 workaround -#endif -VMAC_Base::VHASH_Update_SSE2(const word64 *data, size_t blocksRemainingInWord64, int tagPart) -{ - const word64 *nhK = m_nhKey(); - word64 *polyS = m_polyState(); - word32 L1KeyLength = m_L1KeyLength; - -#ifdef __GNUC__ - word32 temp; - __asm__ __volatile__ - ( - AS2( mov %%ebx, %0) - AS2( mov %1, %%ebx) - ".intel_syntax noprefix;" -#else - #if _MSC_VER < 1300 || defined(__INTEL_COMPILER) - char isFirstBlock = m_isFirstBlock; - AS2( mov ebx, [L1KeyLength]) - AS2( mov dl, [isFirstBlock]) - #else - AS2( mov ecx, this) - AS2( mov ebx, [ecx+m_L1KeyLength]) - AS2( mov dl, [ecx+m_isFirstBlock]) - #endif - AS2( mov eax, tagPart) - AS2( shl eax, 4) - AS2( mov edi, nhK) - AS2( add edi, eax) - AS2( add eax, eax) - AS2( add eax, polyS) - - AS2( mov esi, data) - AS2( mov ecx, blocksRemainingInWord64) -#endif - - AS2( shr ebx, 3) - AS1( push ebp) - AS2( sub esp, 12) - ASL(4) - AS2( mov ebp, ebx) - AS2( cmp ecx, ebx) - AS2( cmovl ebp, ecx) - AS2( sub ecx, ebp) - AS2( lea ebp, [edi+8*ebp]) // end of nhK - AS2( movq mm6, [esi]) - AS2( paddq mm6, [edi]) - AS2( movq mm5, [esi+8]) - AS2( paddq mm5, [edi+8]) - AS2( add esi, 16) - AS2( add edi, 16) - AS2( movq mm4, mm6) - ASS( pshufw mm2, mm6, 1, 0, 3, 2) - AS2( pmuludq mm6, mm5) - ASS( pshufw mm3, mm5, 1, 0, 3, 2) - AS2( pmuludq mm5, mm2) - AS2( pmuludq mm2, mm3) - AS2( pmuludq mm3, mm4) - AS2( pxor mm7, mm7) - AS2( movd [esp], mm6) - AS2( psrlq mm6, 32) - AS2( movd [esp+4], mm5) - AS2( psrlq mm5, 32) - AS2( cmp edi, ebp) - ASJ( je, 1, f) - ASL(0) - AS2( movq mm0, [esi]) - AS2( paddq mm0, [edi]) - AS2( movq mm1, [esi+8]) - AS2( paddq mm1, [edi+8]) - AS2( add esi, 16) - AS2( add edi, 16) - AS2( movq mm4, mm0) - AS2( paddq mm5, mm2) - ASS( pshufw mm2, mm0, 1, 0, 3, 2) - AS2( pmuludq mm0, mm1) - AS2( movd [esp+8], mm3) - AS2( psrlq mm3, 32) - AS2( paddq mm5, mm3) - ASS( pshufw mm3, mm1, 1, 0, 3, 2) - AS2( pmuludq mm1, mm2) - AS2( pmuludq mm2, mm3) - AS2( pmuludq mm3, mm4) - AS2( movd mm4, [esp]) - AS2( paddq mm7, mm4) - AS2( movd mm4, [esp+4]) - AS2( paddq mm6, mm4) - AS2( movd mm4, [esp+8]) - AS2( paddq mm6, mm4) - AS2( movd [esp], mm0) - AS2( psrlq mm0, 32) - AS2( paddq mm6, mm0) - AS2( movd [esp+4], mm1) - AS2( psrlq mm1, 32) - AS2( paddq mm5, mm1) - AS2( cmp edi, ebp) - ASJ( jne, 0, b) - ASL(1) - AS2( paddq mm5, mm2) - AS2( movd [esp+8], mm3) - AS2( psrlq mm3, 32) - AS2( paddq mm5, mm3) - AS2( movd mm4, [esp]) - AS2( paddq mm7, mm4) - AS2( movd mm4, [esp+4]) - AS2( paddq mm6, mm4) - AS2( movd mm4, [esp+8]) - AS2( paddq mm6, mm4) - AS2( lea ebp, [8*ebx]) - AS2( sub edi, ebp) // reset edi to start of nhK - - AS2( movd [esp], mm7) - AS2( psrlq mm7, 32) - AS2( paddq mm6, mm7) - AS2( movd [esp+4], mm6) - AS2( psrlq mm6, 32) - AS2( paddq mm5, mm6) - AS2( psllq mm5, 2) - AS2( psrlq mm5, 2) - -#define a0 [eax+2*4] -#define a1 [eax+3*4] -#define a2 [eax+0*4] -#define a3 [eax+1*4] -#define k0 [eax+2*8+2*4] -#define k1 [eax+2*8+3*4] -#define k2 [eax+2*8+0*4] -#define k3 [eax+2*8+1*4] - AS2( test dl, dl) - ASJ( jz, 2, f) - AS2( movd mm1, k0) - AS2( movd mm0, [esp]) - AS2( paddq mm0, mm1) - AS2( movd a0, mm0) - AS2( psrlq mm0, 32) - AS2( movd mm1, k1) - AS2( movd mm2, [esp+4]) - AS2( paddq mm1, mm2) - AS2( paddq mm0, mm1) - AS2( movd a1, mm0) - AS2( psrlq mm0, 32) - AS2( paddq mm5, k2) - AS2( paddq mm0, mm5) - AS2( movq a2, mm0) - AS2( xor edx, edx) - ASJ( jmp, 3, f) - ASL(2) - AS2( movd mm0, a3) - AS2( movq mm4, mm0) - AS2( pmuludq mm0, k3) // a3*k3 - AS2( movd mm1, a0) - AS2( pmuludq mm1, k2) // a0*k2 - AS2( movd mm2, a1) - AS2( movd mm6, k1) - AS2( pmuludq mm2, mm6) // a1*k1 - AS2( movd mm3, a2) - AS2( psllq mm0, 1) - AS2( paddq mm0, mm5) - AS2( movq mm5, mm3) - AS2( movd mm7, k0) - AS2( pmuludq mm3, mm7) // a2*k0 - AS2( pmuludq mm4, mm7) // a3*k0 - AS2( pmuludq mm5, mm6) // a2*k1 - AS2( paddq mm0, mm1) - AS2( movd mm1, a1) - AS2( paddq mm4, mm5) - AS2( movq mm5, mm1) - AS2( pmuludq mm1, k2) // a1*k2 - AS2( paddq mm0, mm2) - AS2( movd mm2, a0) - AS2( paddq mm0, mm3) - AS2( movq mm3, mm2) - AS2( pmuludq mm2, k3) // a0*k3 - AS2( pmuludq mm3, mm7) // a0*k0 - AS2( movd [esp+8], mm0) - AS2( psrlq mm0, 32) - AS2( pmuludq mm7, mm5) // a1*k0 - AS2( pmuludq mm5, k3) // a1*k3 - AS2( paddq mm0, mm1) - AS2( movd mm1, a2) - AS2( pmuludq mm1, k2) // a2*k2 - AS2( paddq mm0, mm2) - AS2( paddq mm0, mm4) - AS2( movq mm4, mm0) - AS2( movd mm2, a3) - AS2( pmuludq mm2, mm6) // a3*k1 - AS2( pmuludq mm6, a0) // a0*k1 - AS2( psrlq mm0, 31) - AS2( paddq mm0, mm3) - AS2( movd mm3, [esp]) - AS2( paddq mm0, mm3) - AS2( movd mm3, a2) - AS2( pmuludq mm3, k3) // a2*k3 - AS2( paddq mm5, mm1) - AS2( movd mm1, a3) - AS2( pmuludq mm1, k2) // a3*k2 - AS2( paddq mm5, mm2) - AS2( movd mm2, [esp+4]) - AS2( psllq mm5, 1) - AS2( paddq mm0, mm5) - AS2( psllq mm4, 33) - AS2( movd a0, mm0) - AS2( psrlq mm0, 32) - AS2( paddq mm6, mm7) - AS2( movd mm7, [esp+8]) - AS2( paddq mm0, mm6) - AS2( paddq mm0, mm2) - AS2( paddq mm3, mm1) - AS2( psllq mm3, 1) - AS2( paddq mm0, mm3) - AS2( psrlq mm4, 1) - AS2( movd a1, mm0) - AS2( psrlq mm0, 32) - AS2( por mm4, mm7) - AS2( paddq mm0, mm4) - AS2( movq a2, mm0) -#undef a0 -#undef a1 -#undef a2 -#undef a3 -#undef k0 -#undef k1 -#undef k2 -#undef k3 - - ASL(3) - AS2( test ecx, ecx) - ASJ( jnz, 4, b) - - AS2( add esp, 12) - AS1( pop ebp) - AS1( emms) -#ifdef __GNUC__ - ".att_syntax prefix;" - AS2( mov %0, %%ebx) - : "=m" (temp) - : "m" (L1KeyLength), "c" (blocksRemainingInWord64), "S" (data), "D" (nhK+tagPart*2), "d" (m_isFirstBlock), "a" (polyS+tagPart*4) - : "memory", "cc" - ); -#endif -} -#endif - -#if VMAC_BOOL_WORD128 - #define DeclareNH(a) word128 a=0 - #define MUL64(rh,rl,i1,i2) {word128 p = word128(i1)*(i2); rh = word64(p>>64); rl = word64(p);} - #define AccumulateNH(a, b, c) a += word128(b)*(c) - #define Multiply128(r, i1, i2) r = word128(word64(i1)) * word64(i2) -#else - #if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER) - #define MUL32(a, b) __emulu(word32(a), word32(b)) - #else - #define MUL32(a, b) ((word64)((word32)(a)) * (word32)(b)) - #endif - #if defined(CRYPTOPP_X64_ASM_AVAILABLE) - #define DeclareNH(a) word64 a##0=0, a##1=0 - #define MUL64(rh,rl,i1,i2) asm ("mulq %3" : "=a"(rl), "=d"(rh) : "a"(i1), "g"(i2) : "cc"); - #define AccumulateNH(a, b, c) asm ("mulq %3; addq %%rax, %0; adcq %%rdx, %1" : "+r"(a##0), "+r"(a##1) : "a"(b), "g"(c) : "%rdx", "cc"); - #define ADD128(rh,rl,ih,il) asm ("addq %3, %1; adcq %2, %0" : "+r"(rh),"+r"(rl) : "r"(ih),"r"(il) : "cc"); - #elif defined(_MSC_VER) && !CRYPTOPP_BOOL_SLOW_WORD64 - #define DeclareNH(a) word64 a##0=0, a##1=0 - #define MUL64(rh,rl,i1,i2) (rl) = _umul128(i1,i2,&(rh)); - #define AccumulateNH(a, b, c) {\ - word64 ph, pl;\ - pl = _umul128(b,c,&ph);\ - a##0 += pl;\ - a##1 += ph + (a##0 < pl);} - #else - #define VMAC_BOOL_32BIT 1 - #define DeclareNH(a) word64 a##0=0, a##1=0, a##2=0 - #define MUL64(rh,rl,i1,i2) \ - { word64 _i1 = (i1), _i2 = (i2); \ - word64 m1= MUL32(_i1,_i2>>32); \ - word64 m2= MUL32(_i1>>32,_i2); \ - rh = MUL32(_i1>>32,_i2>>32); \ - rl = MUL32(_i1,_i2); \ - ADD128(rh,rl,(m1 >> 32),(m1 << 32)); \ - ADD128(rh,rl,(m2 >> 32),(m2 << 32)); \ - } - #define AccumulateNH(a, b, c) {\ - word64 p = MUL32(b, c);\ - a##1 += word32((p)>>32);\ - a##0 += word32(p);\ - p = MUL32((b)>>32, c);\ - a##2 += word32((p)>>32);\ - a##1 += word32(p);\ - p = MUL32((b)>>32, (c)>>32);\ - a##2 += p;\ - p = MUL32(b, (c)>>32);\ - a##1 += word32(p);\ - a##2 += word32(p>>32);} - #endif -#endif -#ifndef VMAC_BOOL_32BIT - #define VMAC_BOOL_32BIT 0 -#endif -#ifndef ADD128 - #define ADD128(rh,rl,ih,il) \ - { word64 _il = (il); \ - (rl) += (_il); \ - (rh) += (ih) + ((rl) < (_il)); \ - } -#endif - -#if !(defined(_MSC_VER) && _MSC_VER < 1300) -template <bool T_128BitTag> -#endif -void VMAC_Base::VHASH_Update_Template(const word64 *data, size_t blocksRemainingInWord64) -{ - #define INNER_LOOP_ITERATION(j) {\ - word64 d0 = ConditionalByteReverse(LITTLE_ENDIAN_ORDER, data[i+2*j+0]);\ - word64 d1 = ConditionalByteReverse(LITTLE_ENDIAN_ORDER, data[i+2*j+1]);\ - AccumulateNH(nhA, d0+nhK[i+2*j+0], d1+nhK[i+2*j+1]);\ - if (T_128BitTag)\ - AccumulateNH(nhB, d0+nhK[i+2*j+2], d1+nhK[i+2*j+3]);\ - } - -#if (defined(_MSC_VER) && _MSC_VER < 1300) - bool T_128BitTag = m_is128; -#endif - size_t L1KeyLengthInWord64 = m_L1KeyLength / 8; - size_t innerLoopEnd = L1KeyLengthInWord64; - const word64 *nhK = m_nhKey(); - word64 *polyS = m_polyState(); - bool isFirstBlock = true; - size_t i; - - #if !VMAC_BOOL_32BIT - #if VMAC_BOOL_WORD128 - word128 a1, a2; - #else - word64 ah1, al1, ah2, al2; - #endif - word64 kh1, kl1, kh2, kl2; - kh1=(polyS+0*4+2)[0]; kl1=(polyS+0*4+2)[1]; - if (T_128BitTag) - { - kh2=(polyS+1*4+2)[0]; kl2=(polyS+1*4+2)[1]; - } - #endif - - do - { - DeclareNH(nhA); - DeclareNH(nhB); - - i = 0; - if (blocksRemainingInWord64 < L1KeyLengthInWord64) - { - if (blocksRemainingInWord64 % 8) - { - innerLoopEnd = blocksRemainingInWord64 % 8; - for (; i<innerLoopEnd; i+=2) - INNER_LOOP_ITERATION(0); - } - innerLoopEnd = blocksRemainingInWord64; - } - for (; i<innerLoopEnd; i+=8) - { - INNER_LOOP_ITERATION(0); - INNER_LOOP_ITERATION(1); - INNER_LOOP_ITERATION(2); - INNER_LOOP_ITERATION(3); - } - blocksRemainingInWord64 -= innerLoopEnd; - data += innerLoopEnd; - - #if VMAC_BOOL_32BIT - word32 nh0[2], nh1[2]; - word64 nh2[2]; - - nh0[0] = word32(nhA0); - nhA1 += (nhA0 >> 32); - nh1[0] = word32(nhA1); - nh2[0] = (nhA2 + (nhA1 >> 32)) & m62; - - if (T_128BitTag) - { - nh0[1] = word32(nhB0); - nhB1 += (nhB0 >> 32); - nh1[1] = word32(nhB1); - nh2[1] = (nhB2 + (nhB1 >> 32)) & m62; - } - - #define a0 (((word32 *)(polyS+i*4))[2+NativeByteOrder::ToEnum()]) - #define a1 (*(((word32 *)(polyS+i*4))+3-NativeByteOrder::ToEnum())) // workaround for GCC 3.2 - #define a2 (((word32 *)(polyS+i*4))[0+NativeByteOrder::ToEnum()]) - #define a3 (*(((word32 *)(polyS+i*4))+1-NativeByteOrder::ToEnum())) - #define aHi ((polyS+i*4)[0]) - #define k0 (((word32 *)(polyS+i*4+2))[2+NativeByteOrder::ToEnum()]) - #define k1 (*(((word32 *)(polyS+i*4+2))+3-NativeByteOrder::ToEnum())) - #define k2 (((word32 *)(polyS+i*4+2))[0+NativeByteOrder::ToEnum()]) - #define k3 (*(((word32 *)(polyS+i*4+2))+1-NativeByteOrder::ToEnum())) - #define kHi ((polyS+i*4+2)[0]) - - if (isFirstBlock) - { - isFirstBlock = false; - if (m_isFirstBlock) - { - m_isFirstBlock = false; - for (i=0; i<=(size_t)T_128BitTag; i++) - { - word64 t = (word64)nh0[i] + k0; - a0 = (word32)t; - t = (t >> 32) + nh1[i] + k1; - a1 = (word32)t; - aHi = (t >> 32) + nh2[i] + kHi; - } - continue; - } - } - for (i=0; i<=(size_t)T_128BitTag; i++) - { - word64 p, t; - word32 t2; - - p = MUL32(a3, 2*k3); - p += nh2[i]; - p += MUL32(a0, k2); - p += MUL32(a1, k1); - p += MUL32(a2, k0); - t2 = (word32)p; - p >>= 32; - p += MUL32(a0, k3); - p += MUL32(a1, k2); - p += MUL32(a2, k1); - p += MUL32(a3, k0); - t = (word64(word32(p) & 0x7fffffff) << 32) | t2; - p >>= 31; - p += nh0[i]; - p += MUL32(a0, k0); - p += MUL32(a1, 2*k3); - p += MUL32(a2, 2*k2); - p += MUL32(a3, 2*k1); - t2 = (word32)p; - p >>= 32; - p += nh1[i]; - p += MUL32(a0, k1); - p += MUL32(a1, k0); - p += MUL32(a2, 2*k3); - p += MUL32(a3, 2*k2); - a0 = t2; - a1 = (word32)p; - aHi = (p >> 32) + t; - } - - #undef a0 - #undef a1 - #undef a2 - #undef a3 - #undef aHi - #undef k0 - #undef k1 - #undef k2 - #undef k3 - #undef kHi - #else // #if VMAC_BOOL_32BIT - if (isFirstBlock) - { - isFirstBlock = false; - if (m_isFirstBlock) - { - m_isFirstBlock = false; - #if VMAC_BOOL_WORD128 - #define first_poly_step(a, kh, kl, m) a = (m & m126) + ((word128(kh) << 64) | kl) - - first_poly_step(a1, kh1, kl1, nhA); - if (T_128BitTag) - first_poly_step(a2, kh2, kl2, nhB); - #else - #define first_poly_step(ah, al, kh, kl, mh, ml) {\ - mh &= m62;\ - ADD128(mh, ml, kh, kl); \ - ah = mh; al = ml;} - - first_poly_step(ah1, al1, kh1, kl1, nhA1, nhA0); - if (T_128BitTag) - first_poly_step(ah2, al2, kh2, kl2, nhB1, nhB0); - #endif - continue; - } - else - { - #if VMAC_BOOL_WORD128 - a1 = (word128((polyS+0*4)[0]) << 64) | (polyS+0*4)[1]; - #else - ah1=(polyS+0*4)[0]; al1=(polyS+0*4)[1]; - #endif - if (T_128BitTag) - { - #if VMAC_BOOL_WORD128 - a2 = (word128((polyS+1*4)[0]) << 64) | (polyS+1*4)[1]; - #else - ah2=(polyS+1*4)[0]; al2=(polyS+1*4)[1]; - #endif - } - } - } - - #if VMAC_BOOL_WORD128 - #define poly_step(a, kh, kl, m) \ - { word128 t1, t2, t3, t4;\ - Multiply128(t2, a>>64, kl);\ - Multiply128(t3, a, kh);\ - Multiply128(t1, a, kl);\ - Multiply128(t4, a>>64, 2*kh);\ - t2 += t3;\ - t4 += t1;\ - t2 += t4>>64;\ - a = (word128(word64(t2)&m63) << 64) | word64(t4);\ - t2 *= 2;\ - a += m & m126;\ - a += t2>>64;} - - poly_step(a1, kh1, kl1, nhA); - if (T_128BitTag) - poly_step(a2, kh2, kl2, nhB); - #else - #define poly_step(ah, al, kh, kl, mh, ml) \ - { word64 t1h, t1l, t2h, t2l, t3h, t3l, z=0; \ - /* compute ab*cd, put bd into result registers */ \ - MUL64(t2h,t2l,ah,kl); \ - MUL64(t3h,t3l,al,kh); \ - MUL64(t1h,t1l,ah,2*kh); \ - MUL64(ah,al,al,kl); \ - /* add together ad + bc */ \ - ADD128(t2h,t2l,t3h,t3l); \ - /* add 2 * ac to result */ \ - ADD128(ah,al,t1h,t1l); \ - /* now (ah,al), (t2l,2*t2h) need summing */ \ - /* first add the high registers, carrying into t2h */ \ - ADD128(t2h,ah,z,t2l); \ - /* double t2h and add top bit of ah */ \ - t2h += t2h + (ah >> 63); \ - ah &= m63; \ - /* now add the low registers */ \ - mh &= m62; \ - ADD128(ah,al,mh,ml); \ - ADD128(ah,al,z,t2h); \ - } - - poly_step(ah1, al1, kh1, kl1, nhA1, nhA0); - if (T_128BitTag) - poly_step(ah2, al2, kh2, kl2, nhB1, nhB0); - #endif - #endif // #if VMAC_BOOL_32BIT - } while (blocksRemainingInWord64); - - #if VMAC_BOOL_WORD128 - (polyS+0*4)[0]=word64(a1>>64); (polyS+0*4)[1]=word64(a1); - if (T_128BitTag) - { - (polyS+1*4)[0]=word64(a2>>64); (polyS+1*4)[1]=word64(a2); - } - #elif !VMAC_BOOL_32BIT - (polyS+0*4)[0]=ah1; (polyS+0*4)[1]=al1; - if (T_128BitTag) - { - (polyS+1*4)[0]=ah2; (polyS+1*4)[1]=al2; - } - #endif -} - -inline void VMAC_Base::VHASH_Update(const word64 *data, size_t blocksRemainingInWord64) -{ -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 - if (HasSSE2()) - { - VHASH_Update_SSE2(data, blocksRemainingInWord64, 0); - if (m_is128) - VHASH_Update_SSE2(data, blocksRemainingInWord64, 1); - m_isFirstBlock = false; - } - else -#endif - { -#if defined(_MSC_VER) && _MSC_VER < 1300 - VHASH_Update_Template(data, blocksRemainingInWord64); -#else - if (m_is128) - VHASH_Update_Template<true>(data, blocksRemainingInWord64); - else - VHASH_Update_Template<false>(data, blocksRemainingInWord64); -#endif - } -} - -size_t VMAC_Base::HashMultipleBlocks(const word64 *data, size_t length) -{ - size_t remaining = ModPowerOf2(length, m_L1KeyLength); - VHASH_Update(data, (length-remaining)/8); - return remaining; -} - -static word64 L3Hash(const word64 *input, const word64 *l3Key, size_t len) -{ - word64 rh, rl, t, z=0; - word64 p1 = input[0], p2 = input[1]; - word64 k1 = l3Key[0], k2 = l3Key[1]; - - /* fully reduce (p1,p2)+(len,0) mod p127 */ - t = p1 >> 63; - p1 &= m63; - ADD128(p1, p2, len, t); - /* At this point, (p1,p2) is at most 2^127+(len<<64) */ - t = (p1 > m63) + ((p1 == m63) & (p2 == m64)); - ADD128(p1, p2, z, t); - p1 &= m63; - - /* compute (p1,p2)/(2^64-2^32) and (p1,p2)%(2^64-2^32) */ - t = p1 + (p2 >> 32); - t += (t >> 32); - t += (word32)t > 0xfffffffeU; - p1 += (t >> 32); - p2 += (p1 << 32); - - /* compute (p1+k1)%p64 and (p2+k2)%p64 */ - p1 += k1; - p1 += (0 - (p1 < k1)) & 257; - p2 += k2; - p2 += (0 - (p2 < k2)) & 257; - - /* compute (p1+k1)*(p2+k2)%p64 */ - MUL64(rh, rl, p1, p2); - t = rh >> 56; - ADD128(t, rl, z, rh); - rh <<= 8; - ADD128(t, rl, z, rh); - t += t << 8; - rl += t; - rl += (0 - (rl < t)) & 257; - rl += (0 - (rl > p64-1)) & 257; - return rl; -} - -void VMAC_Base::TruncatedFinal(byte *mac, size_t size) -{ - size_t len = ModPowerOf2(GetBitCountLo()/8, m_L1KeyLength); - - if (len) - { - memset(m_data()+len, 0, (0-len)%16); - VHASH_Update(DataBuf(), ((len+15)/16)*2); - len *= 8; // convert to bits - } - else if (m_isFirstBlock) - { - // special case for empty string - m_polyState()[0] = m_polyState()[2]; - m_polyState()[1] = m_polyState()[3]; - if (m_is128) - { - m_polyState()[4] = m_polyState()[6]; - m_polyState()[5] = m_polyState()[7]; - } - } - - if (m_is128) - { - word64 t[2]; - t[0] = L3Hash(m_polyState(), m_l3Key(), len) + GetWord<word64>(true, BIG_ENDIAN_ORDER, m_pad()); - t[1] = L3Hash(m_polyState()+4, m_l3Key()+2, len) + GetWord<word64>(true, BIG_ENDIAN_ORDER, m_pad()+8); - if (size == 16) - { - PutWord(false, BIG_ENDIAN_ORDER, mac, t[0]); - PutWord(false, BIG_ENDIAN_ORDER, mac+8, t[1]); - } - else - { - t[0] = ConditionalByteReverse(BIG_ENDIAN_ORDER, t[0]); - t[1] = ConditionalByteReverse(BIG_ENDIAN_ORDER, t[1]); - memcpy(mac, t, size); - } - } - else - { - word64 t = L3Hash(m_polyState(), m_l3Key(), len); - t += GetWord<word64>(true, BIG_ENDIAN_ORDER, m_pad() + (m_nonce()[IVSize()-1]&1) * 8); - if (size == 8) - PutWord(false, BIG_ENDIAN_ORDER, mac, t); - else - { - t = ConditionalByteReverse(BIG_ENDIAN_ORDER, t); - memcpy(mac, &t, size); - } - } -} - -NAMESPACE_END diff --git a/lib/cryptopp/vmac.h b/lib/cryptopp/vmac.h deleted file mode 100644 index 07240173c..000000000 --- a/lib/cryptopp/vmac.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef CRYPTOPP_VMAC_H -#define CRYPTOPP_VMAC_H - -#include "iterhash.h" -#include "seckey.h" - -NAMESPACE_BEGIN(CryptoPP) - -/// . -class VMAC_Base : public IteratedHashBase<word64, MessageAuthenticationCode> -{ -public: - std::string AlgorithmName() const {return std::string("VMAC(") + GetCipher().AlgorithmName() + ")-" + IntToString(DigestSize()*8);} - unsigned int IVSize() const {return GetCipher().BlockSize();} - unsigned int MinIVLength() const {return 1;} - void Resynchronize(const byte *nonce, int length=-1); - void GetNextIV(RandomNumberGenerator &rng, byte *IV); - unsigned int DigestSize() const {return m_is128 ? 16 : 8;}; - void UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs ¶ms); - void TruncatedFinal(byte *mac, size_t size); - unsigned int BlockSize() const {return m_L1KeyLength;} - ByteOrder GetByteOrder() const {return LITTLE_ENDIAN_ORDER;} - -protected: - virtual BlockCipher & AccessCipher() =0; - virtual int DefaultDigestSize() const =0; - const BlockCipher & GetCipher() const {return const_cast<VMAC_Base *>(this)->AccessCipher();} - void HashEndianCorrectedBlock(const word64 *data); - size_t HashMultipleBlocks(const word64 *input, size_t length); - void Init() {} - word64* StateBuf() {return NULL;} - word64* DataBuf() {return (word64 *)m_data();} - - void VHASH_Update_SSE2(const word64 *data, size_t blocksRemainingInWord64, int tagPart); -#if !(defined(_MSC_VER) && _MSC_VER < 1300) // can't use function template here with VC6 - template <bool T_128BitTag> -#endif - void VHASH_Update_Template(const word64 *data, size_t blockRemainingInWord128); - void VHASH_Update(const word64 *data, size_t blocksRemainingInWord128); - - CRYPTOPP_BLOCK_1(polyState, word64, 4*(m_is128+1)) - CRYPTOPP_BLOCK_2(nhKey, word64, m_L1KeyLength/sizeof(word64) + 2*m_is128) - CRYPTOPP_BLOCK_3(data, byte, m_L1KeyLength) - CRYPTOPP_BLOCK_4(l3Key, word64, 2*(m_is128+1)) - CRYPTOPP_BLOCK_5(nonce, byte, IVSize()) - CRYPTOPP_BLOCK_6(pad, byte, IVSize()) - CRYPTOPP_BLOCKS_END(6) - - bool m_is128, m_padCached, m_isFirstBlock; - int m_L1KeyLength; -}; - -/// <a href="http://www.cryptolounge.org/wiki/VMAC">VMAC</a> -template <class T_BlockCipher, int T_DigestBitSize = 128> -class VMAC : public SimpleKeyingInterfaceImpl<VMAC_Base, SameKeyLengthAs<T_BlockCipher, SimpleKeyingInterface::UNIQUE_IV, T_BlockCipher::BLOCKSIZE> > -{ -public: - static std::string StaticAlgorithmName() {return std::string("VMAC(") + T_BlockCipher::StaticAlgorithmName() + ")-" + IntToString(T_DigestBitSize);} - -private: - BlockCipher & AccessCipher() {return m_cipher;} - int DefaultDigestSize() const {return T_DigestBitSize/8;} - typename T_BlockCipher::Encryption m_cipher; -}; - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/wait.cpp b/lib/cryptopp/wait.cpp deleted file mode 100644 index 198785838..000000000 --- a/lib/cryptopp/wait.cpp +++ /dev/null @@ -1,397 +0,0 @@ -// wait.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "wait.h" -#include "misc.h" - -#ifdef SOCKETS_AVAILABLE - -#ifdef USE_BERKELEY_STYLE_SOCKETS -#include <errno.h> -#include <sys/types.h> -#include <sys/time.h> -#include <unistd.h> -#endif - -NAMESPACE_BEGIN(CryptoPP) - -unsigned int WaitObjectContainer::MaxWaitObjects() -{ -#ifdef USE_WINDOWS_STYLE_SOCKETS - return MAXIMUM_WAIT_OBJECTS * (MAXIMUM_WAIT_OBJECTS-1); -#else - return FD_SETSIZE; -#endif -} - -WaitObjectContainer::WaitObjectContainer(WaitObjectsTracer* tracer) - : m_tracer(tracer), m_eventTimer(Timer::MILLISECONDS) - , m_sameResultCount(0), m_noWaitTimer(Timer::MILLISECONDS) -{ - Clear(); - m_eventTimer.StartTimer(); -} - -void WaitObjectContainer::Clear() -{ -#ifdef USE_WINDOWS_STYLE_SOCKETS - m_handles.clear(); -#else - m_maxFd = 0; - FD_ZERO(&m_readfds); - FD_ZERO(&m_writefds); -#endif - m_noWait = false; - m_firstEventTime = 0; -} - -inline void WaitObjectContainer::SetLastResult(LastResultType result) -{ - if (result == m_lastResult) - m_sameResultCount++; - else - { - m_lastResult = result; - m_sameResultCount = 0; - } -} - -void WaitObjectContainer::DetectNoWait(LastResultType result, CallStack const& callStack) -{ - if (result == m_lastResult && m_noWaitTimer.ElapsedTime() > 1000) - { - if (m_sameResultCount > m_noWaitTimer.ElapsedTime()) - { - if (m_tracer) - { - std::string desc = "No wait loop detected - m_lastResult: "; - desc.append(IntToString(m_lastResult)).append(", call stack:"); - for (CallStack const* cs = &callStack; cs; cs = cs->Prev()) - desc.append("\n- ").append(cs->Format()); - m_tracer->TraceNoWaitLoop(desc); - } - try { throw 0; } catch (...) {} // help debugger break - } - - m_noWaitTimer.StartTimer(); - m_sameResultCount = 0; - } -} - -void WaitObjectContainer::SetNoWait(CallStack const& callStack) -{ - DetectNoWait(LASTRESULT_NOWAIT, CallStack("WaitObjectContainer::SetNoWait()", &callStack)); - m_noWait = true; -} - -void WaitObjectContainer::ScheduleEvent(double milliseconds, CallStack const& callStack) -{ - if (milliseconds <= 3) - DetectNoWait(LASTRESULT_SCHEDULED, CallStack("WaitObjectContainer::ScheduleEvent()", &callStack)); - double thisEventTime = m_eventTimer.ElapsedTimeAsDouble() + milliseconds; - if (!m_firstEventTime || thisEventTime < m_firstEventTime) - m_firstEventTime = thisEventTime; -} - -#ifdef USE_WINDOWS_STYLE_SOCKETS - -struct WaitingThreadData -{ - bool waitingToWait, terminate; - HANDLE startWaiting, stopWaiting; - const HANDLE *waitHandles; - unsigned int count; - HANDLE threadHandle; - DWORD threadId; - DWORD* error; -}; - -WaitObjectContainer::~WaitObjectContainer() -{ - try // don't let exceptions escape destructor - { - if (!m_threads.empty()) - { - HANDLE threadHandles[MAXIMUM_WAIT_OBJECTS]; - unsigned int i; - for (i=0; i<m_threads.size(); i++) - { - WaitingThreadData &thread = *m_threads[i]; - while (!thread.waitingToWait) // spin until thread is in the initial "waiting to wait" state - Sleep(0); - thread.terminate = true; - threadHandles[i] = thread.threadHandle; - } - PulseEvent(m_startWaiting); - ::WaitForMultipleObjects((DWORD)m_threads.size(), threadHandles, TRUE, INFINITE); - for (i=0; i<m_threads.size(); i++) - CloseHandle(threadHandles[i]); - CloseHandle(m_startWaiting); - CloseHandle(m_stopWaiting); - } - } - catch (...) - { - } -} - - -void WaitObjectContainer::AddHandle(HANDLE handle, CallStack const& callStack) -{ - DetectNoWait(m_handles.size(), CallStack("WaitObjectContainer::AddHandle()", &callStack)); - m_handles.push_back(handle); -} - -DWORD WINAPI WaitingThread(LPVOID lParam) -{ - std::auto_ptr<WaitingThreadData> pThread((WaitingThreadData *)lParam); - WaitingThreadData &thread = *pThread; - std::vector<HANDLE> handles; - - while (true) - { - thread.waitingToWait = true; - ::WaitForSingleObject(thread.startWaiting, INFINITE); - thread.waitingToWait = false; - - if (thread.terminate) - break; - if (!thread.count) - continue; - - handles.resize(thread.count + 1); - handles[0] = thread.stopWaiting; - std::copy(thread.waitHandles, thread.waitHandles+thread.count, handles.begin()+1); - - DWORD result = ::WaitForMultipleObjects((DWORD)handles.size(), &handles[0], FALSE, INFINITE); - - if (result == WAIT_OBJECT_0) - continue; // another thread finished waiting first, so do nothing - SetEvent(thread.stopWaiting); - if (!(result > WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + handles.size())) - { - assert(!"error in WaitingThread"); // break here so we can see which thread has an error - *thread.error = ::GetLastError(); - } - } - - return S_OK; // return a value here to avoid compiler warning -} - -void WaitObjectContainer::CreateThreads(unsigned int count) -{ - size_t currentCount = m_threads.size(); - if (currentCount == 0) - { - m_startWaiting = ::CreateEvent(NULL, TRUE, FALSE, NULL); - m_stopWaiting = ::CreateEvent(NULL, TRUE, FALSE, NULL); - } - - if (currentCount < count) - { - m_threads.resize(count); - for (size_t i=currentCount; i<count; i++) - { - m_threads[i] = new WaitingThreadData; - WaitingThreadData &thread = *m_threads[i]; - thread.terminate = false; - thread.startWaiting = m_startWaiting; - thread.stopWaiting = m_stopWaiting; - thread.waitingToWait = false; - thread.threadHandle = CreateThread(NULL, 0, &WaitingThread, &thread, 0, &thread.threadId); - } - } -} - -bool WaitObjectContainer::Wait(unsigned long milliseconds) -{ - if (m_noWait || (m_handles.empty() && !m_firstEventTime)) - { - SetLastResult(LASTRESULT_NOWAIT); - return true; - } - - bool timeoutIsScheduledEvent = false; - - if (m_firstEventTime) - { - double timeToFirstEvent = SaturatingSubtract(m_firstEventTime, m_eventTimer.ElapsedTimeAsDouble()); - - if (timeToFirstEvent <= milliseconds) - { - milliseconds = (unsigned long)timeToFirstEvent; - timeoutIsScheduledEvent = true; - } - - if (m_handles.empty() || !milliseconds) - { - if (milliseconds) - Sleep(milliseconds); - SetLastResult(timeoutIsScheduledEvent ? LASTRESULT_SCHEDULED : LASTRESULT_TIMEOUT); - return timeoutIsScheduledEvent; - } - } - - if (m_handles.size() > MAXIMUM_WAIT_OBJECTS) - { - // too many wait objects for a single WaitForMultipleObjects call, so use multiple threads - static const unsigned int WAIT_OBJECTS_PER_THREAD = MAXIMUM_WAIT_OBJECTS-1; - unsigned int nThreads = (unsigned int)((m_handles.size() + WAIT_OBJECTS_PER_THREAD - 1) / WAIT_OBJECTS_PER_THREAD); - if (nThreads > MAXIMUM_WAIT_OBJECTS) // still too many wait objects, maybe implement recursive threading later? - throw Err("WaitObjectContainer: number of wait objects exceeds limit"); - CreateThreads(nThreads); - DWORD error = S_OK; - - for (unsigned int i=0; i<m_threads.size(); i++) - { - WaitingThreadData &thread = *m_threads[i]; - while (!thread.waitingToWait) // spin until thread is in the initial "waiting to wait" state - Sleep(0); - if (i<nThreads) - { - thread.waitHandles = &m_handles[i*WAIT_OBJECTS_PER_THREAD]; - thread.count = UnsignedMin(WAIT_OBJECTS_PER_THREAD, m_handles.size() - i*WAIT_OBJECTS_PER_THREAD); - thread.error = &error; - } - else - thread.count = 0; - } - - ResetEvent(m_stopWaiting); - PulseEvent(m_startWaiting); - - DWORD result = ::WaitForSingleObject(m_stopWaiting, milliseconds); - if (result == WAIT_OBJECT_0) - { - if (error == S_OK) - return true; - else - throw Err("WaitObjectContainer: WaitForMultipleObjects in thread failed with error " + IntToString(error)); - } - SetEvent(m_stopWaiting); - if (result == WAIT_TIMEOUT) - { - SetLastResult(timeoutIsScheduledEvent ? LASTRESULT_SCHEDULED : LASTRESULT_TIMEOUT); - return timeoutIsScheduledEvent; - } - else - throw Err("WaitObjectContainer: WaitForSingleObject failed with error " + IntToString(::GetLastError())); - } - else - { -#if TRACE_WAIT - static Timer t(Timer::MICROSECONDS); - static unsigned long lastTime = 0; - unsigned long timeBeforeWait = t.ElapsedTime(); -#endif - DWORD result = ::WaitForMultipleObjects((DWORD)m_handles.size(), &m_handles[0], FALSE, milliseconds); -#if TRACE_WAIT - if (milliseconds > 0) - { - unsigned long timeAfterWait = t.ElapsedTime(); - OutputDebugString(("Handles " + IntToString(m_handles.size()) + ", Woke up by " + IntToString(result-WAIT_OBJECT_0) + ", Busied for " + IntToString(timeBeforeWait-lastTime) + " us, Waited for " + IntToString(timeAfterWait-timeBeforeWait) + " us, max " + IntToString(milliseconds) + "ms\n").c_str()); - lastTime = timeAfterWait; - } -#endif - if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + m_handles.size()) - { - if (result == m_lastResult) - m_sameResultCount++; - else - { - m_lastResult = result; - m_sameResultCount = 0; - } - return true; - } - else if (result == WAIT_TIMEOUT) - { - SetLastResult(timeoutIsScheduledEvent ? LASTRESULT_SCHEDULED : LASTRESULT_TIMEOUT); - return timeoutIsScheduledEvent; - } - else - throw Err("WaitObjectContainer: WaitForMultipleObjects failed with error " + IntToString(::GetLastError())); - } -} - -#else // #ifdef USE_WINDOWS_STYLE_SOCKETS - -void WaitObjectContainer::AddReadFd(int fd, CallStack const& callStack) // TODO: do something with callStack -{ - FD_SET(fd, &m_readfds); - m_maxFd = STDMAX(m_maxFd, fd); -} - -void WaitObjectContainer::AddWriteFd(int fd, CallStack const& callStack) // TODO: do something with callStack -{ - FD_SET(fd, &m_writefds); - m_maxFd = STDMAX(m_maxFd, fd); -} - -bool WaitObjectContainer::Wait(unsigned long milliseconds) -{ - if (m_noWait || (!m_maxFd && !m_firstEventTime)) - return true; - - bool timeoutIsScheduledEvent = false; - - if (m_firstEventTime) - { - double timeToFirstEvent = SaturatingSubtract(m_firstEventTime, m_eventTimer.ElapsedTimeAsDouble()); - if (timeToFirstEvent <= milliseconds) - { - milliseconds = (unsigned long)timeToFirstEvent; - timeoutIsScheduledEvent = true; - } - } - - timeval tv, *timeout; - - if (milliseconds == INFINITE_TIME) - timeout = NULL; - else - { - tv.tv_sec = milliseconds / 1000; - tv.tv_usec = (milliseconds % 1000) * 1000; - timeout = &tv; - } - - int result = select(m_maxFd+1, &m_readfds, &m_writefds, NULL, timeout); - - if (result > 0) - return true; - else if (result == 0) - return timeoutIsScheduledEvent; - else - throw Err("WaitObjectContainer: select failed with error " + errno); -} - -#endif - -// ******************************************************** - -std::string CallStack::Format() const -{ - return m_info; -} - -std::string CallStackWithNr::Format() const -{ - return std::string(m_info) + " / nr: " + IntToString(m_nr); -} - -std::string CallStackWithStr::Format() const -{ - return std::string(m_info) + " / " + std::string(m_z); -} - -bool Waitable::Wait(unsigned long milliseconds, CallStack const& callStack) -{ - WaitObjectContainer container; - GetWaitObjects(container, callStack); // reduce clutter by not adding this func to stack - return container.Wait(milliseconds); -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/wait.h b/lib/cryptopp/wait.h deleted file mode 100644 index 045afbc18..000000000 --- a/lib/cryptopp/wait.h +++ /dev/null @@ -1,208 +0,0 @@ -#ifndef CRYPTOPP_WAIT_H -#define CRYPTOPP_WAIT_H - -#include "config.h" - -#ifdef SOCKETS_AVAILABLE - -#include "misc.h" -#include "cryptlib.h" -#include <vector> - -#ifdef USE_WINDOWS_STYLE_SOCKETS -#include <winsock2.h> -#else -#include <sys/types.h> -#endif - -#include "hrtimer.h" - -NAMESPACE_BEGIN(CryptoPP) - -class Tracer -{ -public: - Tracer(unsigned int level) : m_level(level) {} - virtual ~Tracer() {} - -protected: - //! Override this in your most-derived tracer to do the actual tracing. - virtual void Trace(unsigned int n, std::string const& s) = 0; - - /*! By default, tracers will decide which trace messages to trace according to a trace level - mechanism. If your most-derived tracer uses a different mechanism, override this to - return false. If this method returns false, the default TraceXxxx(void) methods will all - return 0 and must be overridden explicitly by your tracer for trace messages you want. */ - virtual bool UsingDefaults() const { return true; } - -protected: - unsigned int m_level; - - void TraceIf(unsigned int n, std::string const&s) - { if (n) Trace(n, s); } - - /*! Returns nr if, according to the default log settings mechanism (using log levels), - the message should be traced. Returns 0 if the default trace level mechanism is not - in use, or if it is in use but the event should not be traced. Provided as a utility - method for easier and shorter coding of default TraceXxxx(void) implementations. */ - unsigned int Tracing(unsigned int nr, unsigned int minLevel) const - { return (UsingDefaults() && m_level >= minLevel) ? nr : 0; } -}; - -// Your Tracer-derived class should inherit as virtual public from Tracer or another -// Tracer-derived class, and should pass the log level in its constructor. You can use the -// following methods to begin and end your Tracer definition. - -// This constructor macro initializes Tracer directly even if not derived directly from it; -// this is intended, virtual base classes are always initialized by the most derived class. -#define CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED) \ - public: DERIVED(unsigned int level = 0) : Tracer(level) {} - -#define CRYPTOPP_BEGIN_TRACER_CLASS_1(DERIVED, BASE1) \ - class DERIVED : virtual public BASE1 { CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED) - -#define CRYPTOPP_BEGIN_TRACER_CLASS_2(DERIVED, BASE1, BASE2) \ - class DERIVED : virtual public BASE1, virtual public BASE2 { CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED) - -#define CRYPTOPP_END_TRACER_CLASS }; - -// In your Tracer-derived class, you should define a globally unique event number for each -// new event defined. This can be done using the following macros. - -#define CRYPTOPP_BEGIN_TRACER_EVENTS(UNIQUENR) enum { EVENTBASE = UNIQUENR, -#define CRYPTOPP_TRACER_EVENT(EVENTNAME) EventNr_##EVENTNAME, -#define CRYPTOPP_END_TRACER_EVENTS }; - -// In your own Tracer-derived class, you must define two methods per new trace event type: -// - unsigned int TraceXxxx() const -// Your default implementation of this method should return the event number if according -// to the default trace level system the event should be traced, or 0 if it should not. -// - void TraceXxxx(string const& s) -// This method should call TraceIf(TraceXxxx(), s); to do the tracing. -// For your convenience, a macro to define these two types of methods are defined below. -// If you use this macro, you should also use the TRACER_EVENTS macros above to associate -// event names with numbers. - -#define CRYPTOPP_TRACER_EVENT_METHODS(EVENTNAME, LOGLEVEL) \ - virtual unsigned int Trace##EVENTNAME() const { return Tracing(EventNr_##EVENTNAME, LOGLEVEL); } \ - virtual void Trace##EVENTNAME(std::string const& s) { TraceIf(Trace##EVENTNAME(), s); } - - -/*! A simple unidirectional linked list with m_prev == 0 to indicate the final entry. - The aim of this implementation is to provide a very lightweight and practical - tracing mechanism with a low performance impact. Functions and methods supporting - this call-stack mechanism would take a parameter of the form "CallStack const& callStack", - and would pass this parameter to subsequent functions they call using the construct: - - SubFunc(arg1, arg2, CallStack("my func at place such and such", &callStack)); - - The advantage of this approach is that it is easy to use and should be very efficient, - involving no allocation from the heap, just a linked list of stack objects containing - pointers to static ASCIIZ strings (or possibly additional but simple data if derived). */ -class CallStack -{ -public: - CallStack(char const* i, CallStack const* p) : m_info(i), m_prev(p) {} - CallStack const* Prev() const { return m_prev; } - virtual std::string Format() const; - -protected: - char const* m_info; - CallStack const* m_prev; -}; - -/*! An extended CallStack entry type with an additional numeric parameter. */ -class CallStackWithNr : public CallStack -{ -public: - CallStackWithNr(char const* i, word32 n, CallStack const* p) : CallStack(i, p), m_nr(n) {} - std::string Format() const; - -protected: - word32 m_nr; -}; - -/*! An extended CallStack entry type with an additional string parameter. */ -class CallStackWithStr : public CallStack -{ -public: - CallStackWithStr(char const* i, char const* z, CallStack const* p) : CallStack(i, p), m_z(z) {} - std::string Format() const; - -protected: - char const* m_z; -}; - -CRYPTOPP_BEGIN_TRACER_CLASS_1(WaitObjectsTracer, Tracer) - CRYPTOPP_BEGIN_TRACER_EVENTS(0x48752841) - CRYPTOPP_TRACER_EVENT(NoWaitLoop) - CRYPTOPP_END_TRACER_EVENTS - CRYPTOPP_TRACER_EVENT_METHODS(NoWaitLoop, 1) -CRYPTOPP_END_TRACER_CLASS - -struct WaitingThreadData; - -//! container of wait objects -class WaitObjectContainer : public NotCopyable -{ -public: - //! exception thrown by WaitObjectContainer - class Err : public Exception - { - public: - Err(const std::string& s) : Exception(IO_ERROR, s) {} - }; - - static unsigned int MaxWaitObjects(); - - WaitObjectContainer(WaitObjectsTracer* tracer = 0); - - void Clear(); - void SetNoWait(CallStack const& callStack); - void ScheduleEvent(double milliseconds, CallStack const& callStack); - // returns false if timed out - bool Wait(unsigned long milliseconds); - -#ifdef USE_WINDOWS_STYLE_SOCKETS - ~WaitObjectContainer(); - void AddHandle(HANDLE handle, CallStack const& callStack); -#else - void AddReadFd(int fd, CallStack const& callStack); - void AddWriteFd(int fd, CallStack const& callStack); -#endif - -private: - WaitObjectsTracer* m_tracer; - -#ifdef USE_WINDOWS_STYLE_SOCKETS - void CreateThreads(unsigned int count); - std::vector<HANDLE> m_handles; - std::vector<WaitingThreadData *> m_threads; - HANDLE m_startWaiting; - HANDLE m_stopWaiting; -#else - fd_set m_readfds, m_writefds; - int m_maxFd; -#endif - bool m_noWait; - double m_firstEventTime; - Timer m_eventTimer; - -#ifdef USE_WINDOWS_STYLE_SOCKETS - typedef size_t LastResultType; -#else - typedef int LastResultType; -#endif - enum { LASTRESULT_NOWAIT = -1, LASTRESULT_SCHEDULED = -2, LASTRESULT_TIMEOUT = -3 }; - LastResultType m_lastResult; - unsigned int m_sameResultCount; - Timer m_noWaitTimer; - void SetLastResult(LastResultType result); - void DetectNoWait(LastResultType result, CallStack const& callStack); -}; - -NAMESPACE_END - -#endif - -#endif diff --git a/lib/cryptopp/winpipes.cpp b/lib/cryptopp/winpipes.cpp deleted file mode 100644 index 1c2e047b0..000000000 --- a/lib/cryptopp/winpipes.cpp +++ /dev/null @@ -1,205 +0,0 @@ -// winpipes.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "winpipes.h" - -#ifdef WINDOWS_PIPES_AVAILABLE - -#include "wait.h" - -NAMESPACE_BEGIN(CryptoPP) - -WindowsHandle::WindowsHandle(HANDLE h, bool own) - : m_h(h), m_own(own) -{ -} - -WindowsHandle::~WindowsHandle() -{ - if (m_own) - { - try - { - CloseHandle(); - } - catch (...) - { - } - } -} - -bool WindowsHandle::HandleValid() const -{ - return m_h && m_h != INVALID_HANDLE_VALUE; -} - -void WindowsHandle::AttachHandle(HANDLE h, bool own) -{ - if (m_own) - CloseHandle(); - - m_h = h; - m_own = own; - HandleChanged(); -} - -HANDLE WindowsHandle::DetachHandle() -{ - HANDLE h = m_h; - m_h = INVALID_HANDLE_VALUE; - HandleChanged(); - return h; -} - -void WindowsHandle::CloseHandle() -{ - if (m_h != INVALID_HANDLE_VALUE) - { - ::CloseHandle(m_h); - m_h = INVALID_HANDLE_VALUE; - HandleChanged(); - } -} - -// ******************************************************** - -void WindowsPipe::HandleError(const char *operation) const -{ - DWORD err = GetLastError(); - throw Err(GetHandle(), operation, err); -} - -WindowsPipe::Err::Err(HANDLE s, const std::string& operation, int error) - : OS_Error(IO_ERROR, "WindowsPipe: " + operation + " operation failed with error 0x" + IntToString(error, 16), operation, error) - , m_h(s) -{ -} - -// ************************************************************* - -WindowsPipeReceiver::WindowsPipeReceiver() - : m_resultPending(false), m_eofReceived(false) -{ - m_event.AttachHandle(CreateEvent(NULL, true, false, NULL), true); - CheckAndHandleError("CreateEvent", m_event.HandleValid()); - memset(&m_overlapped, 0, sizeof(m_overlapped)); - m_overlapped.hEvent = m_event; -} - -bool WindowsPipeReceiver::Receive(byte* buf, size_t bufLen) -{ - assert(!m_resultPending && !m_eofReceived); - - HANDLE h = GetHandle(); - // don't queue too much at once, or we might use up non-paged memory - if (ReadFile(h, buf, UnsignedMin((DWORD)128*1024, bufLen), &m_lastResult, &m_overlapped)) - { - if (m_lastResult == 0) - m_eofReceived = true; - } - else - { - switch (GetLastError()) - { - default: - CheckAndHandleError("ReadFile", false); - case ERROR_BROKEN_PIPE: - case ERROR_HANDLE_EOF: - m_lastResult = 0; - m_eofReceived = true; - break; - case ERROR_IO_PENDING: - m_resultPending = true; - } - } - return !m_resultPending; -} - -void WindowsPipeReceiver::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) -{ - if (m_resultPending) - container.AddHandle(m_event, CallStack("WindowsPipeReceiver::GetWaitObjects() - result pending", &callStack)); - else if (!m_eofReceived) - container.SetNoWait(CallStack("WindowsPipeReceiver::GetWaitObjects() - result ready", &callStack)); -} - -unsigned int WindowsPipeReceiver::GetReceiveResult() -{ - if (m_resultPending) - { - HANDLE h = GetHandle(); - if (GetOverlappedResult(h, &m_overlapped, &m_lastResult, false)) - { - if (m_lastResult == 0) - m_eofReceived = true; - } - else - { - switch (GetLastError()) - { - default: - CheckAndHandleError("GetOverlappedResult", false); - case ERROR_BROKEN_PIPE: - case ERROR_HANDLE_EOF: - m_lastResult = 0; - m_eofReceived = true; - } - } - m_resultPending = false; - } - return m_lastResult; -} - -// ************************************************************* - -WindowsPipeSender::WindowsPipeSender() - : m_resultPending(false), m_lastResult(0) -{ - m_event.AttachHandle(CreateEvent(NULL, true, false, NULL), true); - CheckAndHandleError("CreateEvent", m_event.HandleValid()); - memset(&m_overlapped, 0, sizeof(m_overlapped)); - m_overlapped.hEvent = m_event; -} - -void WindowsPipeSender::Send(const byte* buf, size_t bufLen) -{ - DWORD written = 0; - HANDLE h = GetHandle(); - // don't queue too much at once, or we might use up non-paged memory - if (WriteFile(h, buf, UnsignedMin((DWORD)128*1024, bufLen), &written, &m_overlapped)) - { - m_resultPending = false; - m_lastResult = written; - } - else - { - if (GetLastError() != ERROR_IO_PENDING) - CheckAndHandleError("WriteFile", false); - - m_resultPending = true; - } -} - -void WindowsPipeSender::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) -{ - if (m_resultPending) - container.AddHandle(m_event, CallStack("WindowsPipeSender::GetWaitObjects() - result pending", &callStack)); - else - container.SetNoWait(CallStack("WindowsPipeSender::GetWaitObjects() - result ready", &callStack)); -} - -unsigned int WindowsPipeSender::GetSendResult() -{ - if (m_resultPending) - { - HANDLE h = GetHandle(); - BOOL result = GetOverlappedResult(h, &m_overlapped, &m_lastResult, false); - CheckAndHandleError("GetOverlappedResult", result); - m_resultPending = false; - } - return m_lastResult; -} - -NAMESPACE_END - -#endif diff --git a/lib/cryptopp/winpipes.h b/lib/cryptopp/winpipes.h deleted file mode 100644 index 07225f9f1..000000000 --- a/lib/cryptopp/winpipes.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef CRYPTOPP_WINPIPES_H -#define CRYPTOPP_WINPIPES_H - -#include "config.h" - -#ifdef WINDOWS_PIPES_AVAILABLE - -#include "network.h" -#include "queue.h" -#include <winsock2.h> - -NAMESPACE_BEGIN(CryptoPP) - -//! Windows Handle -class WindowsHandle -{ -public: - WindowsHandle(HANDLE h = INVALID_HANDLE_VALUE, bool own=false); - WindowsHandle(const WindowsHandle &h) : m_h(h.m_h), m_own(false) {} - virtual ~WindowsHandle(); - - bool GetOwnership() const {return m_own;} - void SetOwnership(bool own) {m_own = own;} - - operator HANDLE() {return m_h;} - HANDLE GetHandle() const {return m_h;} - bool HandleValid() const; - void AttachHandle(HANDLE h, bool own=false); - HANDLE DetachHandle(); - void CloseHandle(); - -protected: - virtual void HandleChanged() {} - - HANDLE m_h; - bool m_own; -}; - -//! Windows Pipe -class WindowsPipe -{ -public: - class Err : public OS_Error - { - public: - Err(HANDLE h, const std::string& operation, int error); - HANDLE GetHandle() const {return m_h;} - - private: - HANDLE m_h; - }; - -protected: - virtual HANDLE GetHandle() const =0; - virtual void HandleError(const char *operation) const; - void CheckAndHandleError(const char *operation, BOOL result) const - {assert(result==TRUE || result==FALSE); if (!result) HandleError(operation);} -}; - -//! pipe-based implementation of NetworkReceiver -class WindowsPipeReceiver : public WindowsPipe, public NetworkReceiver -{ -public: - WindowsPipeReceiver(); - - bool MustWaitForResult() {return true;} - bool Receive(byte* buf, size_t bufLen); - unsigned int GetReceiveResult(); - bool EofReceived() const {return m_eofReceived;} - - unsigned int GetMaxWaitObjectCount() const {return 1;} - void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); - -private: - WindowsHandle m_event; - OVERLAPPED m_overlapped; - bool m_resultPending; - DWORD m_lastResult; - bool m_eofReceived; -}; - -//! pipe-based implementation of NetworkSender -class WindowsPipeSender : public WindowsPipe, public NetworkSender -{ -public: - WindowsPipeSender(); - - bool MustWaitForResult() {return true;} - void Send(const byte* buf, size_t bufLen); - unsigned int GetSendResult(); - bool MustWaitForEof() { return false; } - void SendEof() {} - - unsigned int GetMaxWaitObjectCount() const {return 1;} - void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); - -private: - WindowsHandle m_event; - OVERLAPPED m_overlapped; - bool m_resultPending; - DWORD m_lastResult; -}; - -//! Windows Pipe Source -class WindowsPipeSource : public WindowsHandle, public NetworkSource, public WindowsPipeReceiver -{ -public: - WindowsPipeSource(HANDLE h=INVALID_HANDLE_VALUE, bool pumpAll=false, BufferedTransformation *attachment=NULL) - : WindowsHandle(h), NetworkSource(attachment) - { - if (pumpAll) - PumpAll(); - } - - NetworkSource::GetMaxWaitObjectCount; - NetworkSource::GetWaitObjects; - -private: - HANDLE GetHandle() const {return WindowsHandle::GetHandle();} - NetworkReceiver & AccessReceiver() {return *this;} -}; - -//! Windows Pipe Sink -class WindowsPipeSink : public WindowsHandle, public NetworkSink, public WindowsPipeSender -{ -public: - WindowsPipeSink(HANDLE h=INVALID_HANDLE_VALUE, unsigned int maxBufferSize=0, unsigned int autoFlushBound=16*1024) - : WindowsHandle(h), NetworkSink(maxBufferSize, autoFlushBound) {} - - NetworkSink::GetMaxWaitObjectCount; - NetworkSink::GetWaitObjects; - -private: - HANDLE GetHandle() const {return WindowsHandle::GetHandle();} - NetworkSender & AccessSender() {return *this;} -}; - -NAMESPACE_END - -#endif - -#endif diff --git a/lib/cryptopp/words.h b/lib/cryptopp/words.h deleted file mode 100644 index d5fda71da..000000000 --- a/lib/cryptopp/words.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef CRYPTOPP_WORDS_H -#define CRYPTOPP_WORDS_H - -#include "misc.h" - -NAMESPACE_BEGIN(CryptoPP) - -inline size_t CountWords(const word *X, size_t N) -{ - while (N && X[N-1]==0) - N--; - return N; -} - -inline void SetWords(word *r, word a, size_t n) -{ - for (size_t i=0; i<n; i++) - r[i] = a; -} - -inline void CopyWords(word *r, const word *a, size_t n) -{ - if (r != a) - memcpy(r, a, n*WORD_SIZE); -} - -inline void XorWords(word *r, const word *a, const word *b, size_t n) -{ - for (size_t i=0; i<n; i++) - r[i] = a[i] ^ b[i]; -} - -inline void XorWords(word *r, const word *a, size_t n) -{ - for (size_t i=0; i<n; i++) - r[i] ^= a[i]; -} - -inline void AndWords(word *r, const word *a, const word *b, size_t n) -{ - for (size_t i=0; i<n; i++) - r[i] = a[i] & b[i]; -} - -inline void AndWords(word *r, const word *a, size_t n) -{ - for (size_t i=0; i<n; i++) - r[i] &= a[i]; -} - -inline word ShiftWordsLeftByBits(word *r, size_t n, unsigned int shiftBits) -{ - assert (shiftBits<WORD_BITS); - word u, carry=0; - if (shiftBits) - for (size_t i=0; i<n; i++) - { - u = r[i]; - r[i] = (u << shiftBits) | carry; - carry = u >> (WORD_BITS-shiftBits); - } - return carry; -} - -inline word ShiftWordsRightByBits(word *r, size_t n, unsigned int shiftBits) -{ - assert (shiftBits<WORD_BITS); - word u, carry=0; - if (shiftBits) - for (size_t i=n; i>0; i--) - { - u = r[i-1]; - r[i-1] = (u >> shiftBits) | carry; - carry = u << (WORD_BITS-shiftBits); - } - return carry; -} - -inline void ShiftWordsLeftByWords(word *r, size_t n, size_t shiftWords) -{ - shiftWords = STDMIN(shiftWords, n); - if (shiftWords) - { - for (size_t i=n-1; i>=shiftWords; i--) - r[i] = r[i-shiftWords]; - SetWords(r, 0, shiftWords); - } -} - -inline void ShiftWordsRightByWords(word *r, size_t n, size_t shiftWords) -{ - shiftWords = STDMIN(shiftWords, n); - if (shiftWords) - { - for (size_t i=0; i+shiftWords<n; i++) - r[i] = r[i+shiftWords]; - SetWords(r+n-shiftWords, 0, shiftWords); - } -} - -NAMESPACE_END - -#endif diff --git a/lib/inifile/iniFile.cpp b/lib/inifile/iniFile.cpp index afa1c110d..cf8b63987 100644 --- a/lib/inifile/iniFile.cpp +++ b/lib/inifile/iniFile.cpp @@ -83,6 +83,8 @@ bool cIniFile::ReadFile(const AString & a_FileName, bool a_AllowExampleRedirect) } } + bool IsFirstLine = true; + while (getline(f, line)) { // To be compatible with Win32, check for existence of '\r'. @@ -90,6 +92,14 @@ bool cIniFile::ReadFile(const AString & a_FileName, bool a_AllowExampleRedirect) // Note that the '\r' will be written to INI files from // Unix so that the created INI file can be read under Win32 // without change. + + // Removes UTF-8 Byte Order Markers (BOM) if, present. + if (IsFirstLine) + { + RemoveBom(line); + IsFirstLine = false; + } + size_t lineLength = line.length(); if (lineLength == 0) { @@ -162,11 +172,12 @@ bool cIniFile::ReadFile(const AString & a_FileName, bool a_AllowExampleRedirect) { return false; } - + if (IsFromExampleRedirect) { WriteFile(FILE_IO_PREFIX + a_FileName); } + return true; } @@ -824,3 +835,28 @@ AString cIniFile::CheckCase(const AString & s) const + +void cIniFile::RemoveBom(AString & a_line) const +{ + // The BOM sequence for UTF-8 is 0xEF,0xBB,0xBF + static unsigned const char BOM[] = { 0xEF, 0xBB, 0xBF }; + + // The BOM sequence, if present, is always th e first three characters of the input. + const AString ref = a_line.substr(0, 3); + + // If any of the first three chars do not match, return and do nothing. + for (int i = 0; i < 3; ++i) + { + if (static_cast<unsigned char>(ref[i]) != BOM[i]) + { + return; + } + } + + // First three characters match; erase them. + a_line.erase(0, 3); +} + + + + diff --git a/lib/inifile/iniFile.h b/lib/inifile/iniFile.h index 40af618dc..0bf1d917e 100644 --- a/lib/inifile/iniFile.h +++ b/lib/inifile/iniFile.h @@ -51,6 +51,8 @@ private: /// If the object is case-insensitive, returns s as lowercase; otherwise returns s as-is AString CheckCase(const AString & s) const; + /// Removes the UTF-8 BOMs (Byte order makers), if present. + void RemoveBom(AString & a_line) const; public: enum errors { diff --git a/lib/lua/CMakeLists.txt b/lib/lua/CMakeLists.txt index 4babae9b2..db112d557 100644 --- a/lib/lua/CMakeLists.txt +++ b/lib/lua/CMakeLists.txt @@ -47,8 +47,12 @@ if (WIN32) ) endif() + set_target_properties(lua PROPERTIES OUTPUT_NAME "lua51") + # NOTE: The DLL for each configuration is stored at the same place, thus overwriting each other. - # This is known, however such behavior is needed for LuaRocks - they always load "lua.dll" + # This is known, however such behavior is needed for LuaRocks - they always load "lua5.1.dll" or "lua51.dll" + # We make it work by compiling to "lua51.dll" and providing a proxy-DLL "lua5.1.dll" + # See http://lua-users.org/wiki/LuaProxyDllFour for details else() add_library(lua ${SOURCE}) endif() diff --git a/lib/md5/md5.h b/lib/md5/md5.h index ad5ad5384..3aa88ac22 100644 --- a/lib/md5/md5.h +++ b/lib/md5/md5.h @@ -90,4 +90,4 @@ private: std::string md5(const std::string & str); -#endif
\ No newline at end of file +#endif diff --git a/lib/polarssl b/lib/polarssl new file mode 160000 +Subproject 2cb1a0c4009ecf368ecc74eb428394e10f9e6d0 diff --git a/lib/polarssl.cmake b/lib/polarssl.cmake new file mode 100644 index 000000000..d57cc9220 --- /dev/null +++ b/lib/polarssl.cmake @@ -0,0 +1,5 @@ + +if(NOT TARGET polarssl) + message("including polarssl") + add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/polarssl/ ${CMAKE_CURRENT_BINARY_DIR}/lib/polarssl EXCLUDE_FROM_ALL ) +endif() diff --git a/lib/tolua++/CMakeLists.txt b/lib/tolua++/CMakeLists.txt index 239232c38..e68a0e15b 100644 --- a/lib/tolua++/CMakeLists.txt +++ b/lib/tolua++/CMakeLists.txt @@ -5,6 +5,36 @@ project (tolua++) include_directories ("${PROJECT_SOURCE_DIR}/../../src/") include_directories ("${PROJECT_SOURCE_DIR}/include/") include_directories ("${PROJECT_SOURCE_DIR}/../") +include_directories ("${PROJECT_SOURCE_DIR}") + +find_program(XXD_EXECUTABLE xxd) + +if(NOT XXD_EXECUTABLE STREQUAL "XXD_EXECUTABLE-NOTFOUND") + add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/basic_lua.h + COMMAND ${XXD_EXECUTABLE} -i lua/basic.lua | sed 's/unsigned char/static const unsigned char/g' >basic_lua.h + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ + DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/basic.lua) + add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/enumerate_lua.h + COMMAND ${XXD_EXECUTABLE} -i lua/enumerate.lua | sed 's/unsigned char/static const unsigned char/g' >enumerate_lua.h + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ + DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/enumerate.lua) + add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/function_lua.h + COMMAND ${XXD_EXECUTABLE} -i lua/function.lua | sed 's/unsigned char/static const unsigned char/g' >function_lua.h + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ + DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/function.lua) + add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/declaration_lua.h + COMMAND ${XXD_EXECUTABLE} -i lua/declaration.lua | sed 's/unsigned char/static const unsigned char/g' >declaration_lua.h + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ + DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/declaration.lua) + add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/container_lua.h + COMMAND ${XXD_EXECUTABLE} -i lua/container.lua | sed 's/unsigned char/static const unsigned char/g' >container_lua.h + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ + DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/container.lua) + set_property(SOURCE src/bin/toluabind.c APPEND PROPERTY OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/enumerate_lua.h ${PROJECT_SOURCE_DIR}/src/bin/basic_lua.h ${PROJECT_SOURCE_DIR}/src/bin/function_lua.h ${PROJECT_SOURCE_DIR}/src/bin/declaration_lua.h ${PROJECT_SOURCE_DIR}/src/bin/container_lua.h) +else() + message("xxd not found, changes to tolua scripts will be ignored") +endif() + file(GLOB LIB_SOURCE "src/lib/*.c" @@ -14,12 +44,14 @@ file(GLOB BIN_SOURCE "src/bin/*.c" ) + + add_executable(tolua ${BIN_SOURCE}) add_library(tolualib ${LIB_SOURCE}) #m is the standard math librarys if(UNIX) -target_link_libraries(tolua m) +target_link_libraries(tolua m ${DYNAMIC_LOADER}) endif() target_link_libraries(tolua lua tolualib) diff --git a/lib/tolua++/src/bin/basic_lua.h b/lib/tolua++/src/bin/basic_lua.h new file mode 100644 index 000000000..effd79ee9 --- /dev/null +++ b/lib/tolua++/src/bin/basic_lua.h @@ -0,0 +1,760 @@ +static const unsigned char lua_basic_lua[] = { + 0x2d, 0x2d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x3a, 0x20, 0x62, 0x61, + 0x73, 0x69, 0x63, 0x20, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, + 0x20, 0x57, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x62, 0x79, 0x20, + 0x57, 0x61, 0x6c, 0x64, 0x65, 0x6d, 0x61, 0x72, 0x20, 0x43, 0x65, 0x6c, + 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x65, 0x43, 0x47, 0x72, 0x61, + 0x66, 0x2f, 0x50, 0x55, 0x43, 0x2d, 0x52, 0x69, 0x6f, 0x0a, 0x2d, 0x2d, + 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x31, 0x39, 0x39, 0x38, 0x0a, 0x2d, 0x2d, + 0x20, 0x4c, 0x61, 0x73, 0x74, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x3a, 0x20, 0x41, 0x70, 0x72, 0x20, 0x32, 0x30, 0x30, 0x33, 0x0a, 0x2d, + 0x2d, 0x20, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x24, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x69, + 0x73, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, + 0x61, 0x72, 0x65, 0x3b, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x63, 0x61, 0x6e, + 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x2f, 0x6f, 0x72, 0x20, + 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x20, 0x69, 0x74, 0x2e, 0x0a, 0x2d, + 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, + 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x69, 0x73, + 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x61, 0x73, 0x20, 0x69, + 0x73, 0x22, 0x20, 0x62, 0x61, 0x73, 0x69, 0x73, 0x2c, 0x20, 0x61, 0x6e, + 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x6f, + 0x62, 0x6c, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, + 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x69, + 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x2c, 0x20, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2c, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x73, 0x2c, 0x0a, 0x2d, 0x2d, 0x20, 0x65, 0x6e, 0x68, 0x61, 0x6e, + 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x6f, 0x72, 0x20, + 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x42, 0x61, 0x73, 0x69, + 0x63, 0x20, 0x43, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x63, 0x6f, 0x72, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x4c, 0x75, + 0x61, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x41, + 0x6c, 0x6c, 0x20, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x22, 0x63, 0x68, 0x61, 0x72, 0x2a, + 0x22, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x72, 0x65, + 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x22, 0x5f, + 0x63, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x2c, 0x0a, 0x2d, 0x2d, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x63, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, + 0x22, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x22, 0x20, 0x77, 0x69, 0x6c, 0x6c, + 0x20, 0x62, 0x65, 0x20, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, + 0x20, 0x62, 0x79, 0x20, 0x22, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, + 0x74, 0x61, 0x22, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x3d, + 0x20, 0x7b, 0x0a, 0x20, 0x5b, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x5d, + 0x20, 0x3d, 0x20, 0x27, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x63, 0x68, + 0x61, 0x72, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x69, 0x6e, 0x74, 0x27, + 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, + 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x27, 0x5d, + 0x20, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x2c, + 0x0a, 0x20, 0x5b, 0x27, 0x6c, 0x6f, 0x6e, 0x67, 0x27, 0x5d, 0x20, 0x3d, + 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x2c, 0x0a, 0x20, + 0x5b, 0x27, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x27, 0x5d, + 0x20, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x2c, + 0x0a, 0x20, 0x5b, 0x27, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x27, 0x5d, 0x20, + 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x2c, 0x0a, + 0x20, 0x5b, 0x27, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x27, 0x5d, 0x20, + 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x2c, 0x0a, + 0x20, 0x5b, 0x27, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x74, 0x27, 0x5d, 0x20, + 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x2c, 0x0a, + 0x20, 0x5b, 0x27, 0x5f, 0x63, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x27, + 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x27, + 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, + 0x74, 0x61, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x75, 0x73, 0x65, 0x72, + 0x64, 0x61, 0x74, 0x61, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x63, 0x68, + 0x61, 0x72, 0x2a, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x76, 0x6f, 0x69, + 0x64, 0x2a, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x75, 0x73, 0x65, 0x72, + 0x64, 0x61, 0x74, 0x61, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x62, 0x6f, + 0x6f, 0x6c, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x62, 0x6f, 0x6f, 0x6c, + 0x65, 0x61, 0x6e, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x6c, 0x75, 0x61, + 0x5f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x27, 0x5d, 0x20, 0x3d, 0x20, + 0x27, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, + 0x4c, 0x55, 0x41, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x27, 0x5d, 0x20, + 0x3d, 0x20, 0x27, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x27, 0x2c, 0x20, 0x20, + 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x6d, + 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x20, 0x34, 0x2e, + 0x30, 0x0a, 0x20, 0x5b, 0x27, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x2a, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x5f, 0x6c, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x6c, 0x75, 0x61, 0x5f, + 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x27, 0x5d, 0x20, 0x3d, + 0x20, 0x27, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x27, 0x2c, 0x0a, 0x7d, 0x0a, + 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x63, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x20, 0x3d, 0x20, 0x22, 0x6c, 0x75, 0x61, 0x5f, 0x4e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x20, 0x3d, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, + 0x68, 0x61, 0x72, 0x2a, 0x22, 0x2c, 0x0a, 0x20, 0x75, 0x73, 0x65, 0x72, + 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x22, 0x76, 0x6f, 0x69, 0x64, + 0x2a, 0x22, 0x2c, 0x0a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, + 0x20, 0x3d, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x22, 0x2c, 0x0a, 0x20, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x22, 0x69, 0x6e, 0x74, + 0x22, 0x2c, 0x0a, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x20, + 0x22, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x22, + 0x2c, 0x0a, 0x7d, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, + 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x6f, + 0x20, 0x61, 0x20, 0x27, 0x72, 0x61, 0x77, 0x20, 0x70, 0x75, 0x73, 0x68, + 0x27, 0x20, 0x6f, 0x66, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, + 0x72, 0x61, 0x77, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x20, 0x3d, 0x20, 0x7b, + 0x7d, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x6f, + 0x66, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, + 0x65, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x20, + 0x45, 0x61, 0x63, 0x68, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x63, 0x6f, + 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x73, 0x20, 0x74, 0x6f, + 0x20, 0x61, 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x73, 0x20, 0x69, 0x74, 0x73, 0x20, 0x74, 0x61, 0x67, + 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x0a, 0x5f, 0x75, 0x73, 0x65, + 0x72, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, + 0x76, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x63, 0x6f, 0x6c, + 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x0a, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, + 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x0a, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, 0x7d, + 0x0a, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x20, 0x3d, 0x20, 0x7b, 0x7d, + 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x0a, 0x5f, 0x67, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, + 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x4c, 0x69, + 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x0a, 0x5f, 0x67, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x20, 0x3d, + 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x4c, 0x69, 0x73, 0x74, + 0x20, 0x6f, 0x66, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x6e, + 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x0a, 0x5f, 0x72, 0x65, 0x6e, 0x61, 0x6d, + 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x5f, 0x65, + 0x6e, 0x75, 0x6d, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, + 0x64, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x73, + 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, + 0x2c, 0x6f, 0x6c, 0x64, 0x2c, 0x6e, 0x65, 0x77, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x25, 0x73, + 0x2a, 0x28, 0x2e, 0x2d, 0x29, 0x25, 0x73, 0x2a, 0x40, 0x25, 0x73, 0x2a, + 0x28, 0x2e, 0x2d, 0x29, 0x25, 0x73, 0x2a, 0x24, 0x22, 0x29, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x23, + 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x72, 0x65, 0x6e, 0x61, + 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x3b, + 0x20, 0x69, 0x74, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, + 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, + 0x6d, 0x3a, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x40, 0x70, + 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x09, 0x74, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x28, 0x5f, + 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x2c, 0x7b, 0x6f, 0x6c, + 0x64, 0x3d, 0x6f, 0x6c, 0x64, 0x2c, 0x20, 0x6e, 0x65, 0x77, 0x3d, 0x6e, + 0x65, 0x77, 0x7d, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, + 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x73, 0x29, + 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x31, 0x2c, 0x67, 0x65, + 0x74, 0x6e, 0x28, 0x5f, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, + 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x6d, 0x2c, 0x6e, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x2c, 0x5f, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x5b, + 0x69, 0x5d, 0x2e, 0x6f, 0x6c, 0x64, 0x2c, 0x5f, 0x72, 0x65, 0x6e, 0x61, + 0x6d, 0x69, 0x6e, 0x67, 0x5b, 0x69, 0x5d, 0x2e, 0x6e, 0x65, 0x77, 0x29, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x20, 0x7e, 0x3d, 0x20, 0x30, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, + 0x65, 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, + 0x28, 0x73, 0x2c, 0x66, 0x29, 0x0a, 0x69, 0x66, 0x20, 0x5f, 0x63, 0x75, + 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x22, 0x2a, 0x2a, 0x2a, + 0x63, 0x75, 0x72, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x69, 0x73, 0x20, 0x22, + 0x2e, 0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x5f, + 0x63, 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x29, 0x0a, + 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x64, 0x65, 0x62, 0x75, 0x67, + 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x29, + 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x5f, 0x4f, 0x55, 0x54, 0x50, + 0x55, 0x54, 0x0a, 0x20, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x20, + 0x3d, 0x20, 0x5f, 0x53, 0x54, 0x44, 0x45, 0x52, 0x52, 0x0a, 0x20, 0x69, + 0x66, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x31, + 0x2c, 0x31, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x23, 0x27, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, + 0x22, 0x5c, 0x6e, 0x2a, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x3a, + 0x20, 0x22, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x2c, 0x32, 0x29, 0x2e, 0x2e, 0x22, 0x2e, 0x5c, 0x6e, 0x5c, 0x6e, 0x22, + 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x5f, 0x63, 0x75, 0x72, 0x72, + 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, + 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, + 0x5f, 0x63, 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x22, + 0x5e, 0x25, 0x73, 0x2a, 0x28, 0x2e, 0x2d, 0x5c, 0x6e, 0x29, 0x22, 0x29, + 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x20, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x20, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x3d, 0x3d, 0x6e, 0x69, 0x6c, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x63, 0x75, + 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x2c, 0x22, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, + 0x22, 0x2c, 0x22, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x22, 0x29, 0x20, 0x2d, + 0x2d, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x27, 0x0a, 0x20, 0x20, + 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, + 0x22, 0x5f, 0x63, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x2c, 0x22, + 0x63, 0x68, 0x61, 0x72, 0x2a, 0x22, 0x29, 0x20, 0x20, 0x2d, 0x2d, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, + 0x27, 0x63, 0x68, 0x61, 0x72, 0x2a, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x73, + 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, 0x5f, + 0x6c, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x2c, 0x22, 0x6c, 0x75, 0x61, + 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x22, 0x29, 0x20, 0x20, 0x2d, + 0x2d, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x27, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x2a, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, + 0x22, 0x43, 0x6f, 0x64, 0x65, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x3a, 0x5c, 0x6e, + 0x22, 0x2e, 0x2e, 0x73, 0x2e, 0x2e, 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, + 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x22, 0x28, 0x66, 0x20, 0x69, + 0x73, 0x20, 0x6e, 0x69, 0x6c, 0x29, 0x22, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x22, 0x5c, 0x6e, 0x2a, + 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x20, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x20, + 0x22, 0x2e, 0x2e, 0x66, 0x2e, 0x2e, 0x73, 0x2e, 0x2e, 0x22, 0x2e, 0x5c, + 0x6e, 0x5c, 0x6e, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x5f, 0x4f, 0x55, + 0x54, 0x50, 0x55, 0x54, 0x20, 0x3d, 0x20, 0x6f, 0x75, 0x74, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x6d, 0x73, + 0x67, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, + 0x2e, 0x71, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x5f, 0x4f, 0x55, 0x54, + 0x50, 0x55, 0x54, 0x0a, 0x20, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, + 0x20, 0x3d, 0x20, 0x5f, 0x53, 0x54, 0x44, 0x45, 0x52, 0x52, 0x0a, 0x20, + 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x22, 0x5c, 0x6e, 0x2a, 0x2a, 0x20, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x20, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x6d, 0x73, 0x67, 0x2e, 0x2e, 0x22, + 0x2e, 0x5c, 0x6e, 0x5c, 0x6e, 0x22, 0x29, 0x0a, 0x20, 0x5f, 0x4f, 0x55, + 0x54, 0x50, 0x55, 0x54, 0x20, 0x3d, 0x20, 0x6f, 0x75, 0x74, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x66, 0x75, + 0x6c, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x67, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x2d, 0x2d, 0x69, 0x66, 0x20, 0x69, + 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x74, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x0a, 0x09, 0x2d, 0x2d, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x74, 0x20, 0x3d, 0x20, 0x66, + 0x69, 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x29, 0x0a, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x5f, 0x75, 0x73, 0x65, + 0x72, 0x74, 0x79, 0x70, 0x65, 0x5b, 0x66, 0x74, 0x5d, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, + 0x70, 0x65, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x74, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x66, 0x75, 0x6c, 0x6c, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x76, 0x61, 0x72, 0x28, 0x74, + 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x65, 0x6c, + 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, + 0x74, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, + 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, + 0x66, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x74, 0x0a, 0x09, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, + 0x70, 0x65, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, 0x3d, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x69, 0x73, 0x20, 0x65, 0x6e, + 0x75, 0x6d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x69, 0x73, 0x65, 0x6e, 0x75, 0x6d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x28, + 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x74, + 0x79, 0x70, 0x65, 0x5d, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x69, 0x66, 0x20, 0x62, 0x61, + 0x73, 0x69, 0x63, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, + 0x63, 0x20, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, + 0x28, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x20, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x6d, 0x2c, 0x74, 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, + 0x79, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x28, 0x27, 0x27, 0x2c, + 0x20, 0x74, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, + 0x20, 0x3d, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5b, 0x74, 0x5d, + 0x0a, 0x20, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x62, 0x2c, 0x5f, + 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x63, 0x74, 0x79, 0x70, 0x65, 0x5b, + 0x62, 0x5d, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, + 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x20, 0x28, 0x73, + 0x2c, 0x74, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, + 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, 0x7d, 0x0a, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x73, 0x29, 0x0a, 0x20, 0x20, 0x6c, + 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x6c, 0x2e, 0x6e, 0x20, 0x2b, 0x20, 0x31, + 0x0a, 0x20, 0x20, 0x6c, 0x5b, 0x6c, 0x2e, 0x6e, 0x5d, 0x20, 0x3d, 0x20, + 0x73, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, + 0x22, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x70, 0x20, 0x3d, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x28, 0x2e, + 0x2d, 0x29, 0x25, 0x73, 0x2a, 0x22, 0x2e, 0x2e, 0x74, 0x2e, 0x2e, 0x22, + 0x25, 0x73, 0x2a, 0x22, 0x0a, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, + 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, 0x5e, 0x25, 0x73, 0x2b, 0x22, 0x2c, + 0x22, 0x22, 0x29, 0x0a, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x2c, 0x22, 0x25, 0x73, 0x2b, 0x24, 0x22, 0x2c, 0x22, + 0x22, 0x29, 0x0a, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, + 0x28, 0x73, 0x2c, 0x70, 0x2c, 0x66, 0x29, 0x0a, 0x20, 0x6c, 0x2e, 0x6e, + 0x20, 0x3d, 0x20, 0x6c, 0x2e, 0x6e, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x20, + 0x6c, 0x5b, 0x6c, 0x2e, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x2c, 0x22, 0x28, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x29, + 0x24, 0x22, 0x2c, 0x22, 0x22, 0x29, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, + 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x2c, 0x20, 0x63, 0x6f, + 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x73, 0x70, 0x61, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x63, 0x61, + 0x73, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x43, 0x20, 0x63, 0x6f, 0x64, + 0x65, 0x20, 0x28, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, + 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x65, + 0x74, 0x63, 0x29, 0x0a, 0x2d, 0x2d, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, + 0x72, 0x6e, 0x20, 0x63, 0x61, 0x6e, 0x27, 0x74, 0x20, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x27, 0x5e, 0x27, + 0x20, 0x28, 0x61, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x29, 0x0a, + 0x2d, 0x2d, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x70, 0x73, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, + 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x73, 0x28, 0x73, 0x2c, 0x20, 0x70, 0x61, 0x74, 0x29, 0x0a, 0x0a, 0x09, + 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, + 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x5e, 0x25, 0x73, 0x2a, + 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x73, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, + 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x20, 0x3d, + 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x5f, 0x65, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x31, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x73, 0x20, 0x3d, + 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x65, + 0x74, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, 0x7d, 0x0a, 0x0a, 0x09, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x64, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x28, 0x6f, 0x66, 0x73, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x2c, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x62, 0x65, 0x67, + 0x69, 0x6e, 0x2c, 0x20, 0x6f, 0x66, 0x73, 0x29, 0x0a, 0x09, 0x09, 0x74, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, + 0x75, 0x62, 0x28, 0x74, 0x2c, 0x20, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x22, + 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x74, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x74, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, + 0x22, 0x29, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x2e, 0x6e, 0x20, 0x3d, + 0x20, 0x72, 0x65, 0x74, 0x2e, 0x6e, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x5b, 0x72, 0x65, 0x74, 0x2e, 0x6e, 0x5d, 0x20, + 0x3d, 0x20, 0x74, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x77, + 0x68, 0x69, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x73, 0x20, 0x3c, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x6c, 0x65, 0x6e, 0x28, 0x73, + 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x73, 0x75, 0x62, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x6f, 0x66, + 0x73, 0x2c, 0x20, 0x2d, 0x31, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x75, 0x62, + 0x2c, 0x20, 0x22, 0x5e, 0x22, 0x2e, 0x2e, 0x70, 0x61, 0x74, 0x29, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x61, 0x64, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x28, 0x6f, 0x66, 0x73, 0x2d, 0x31, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x6f, + 0x66, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, 0x2b, 0x65, 0x0a, 0x09, + 0x09, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x62, 0x65, 0x67, 0x69, + 0x6e, 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, 0x0a, 0x09, 0x09, 0x65, 0x6c, + 0x73, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x6f, 0x66, 0x73, + 0x2c, 0x20, 0x6f, 0x66, 0x73, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, + 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x28, 0x22, + 0x20, 0x6f, 0x72, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, 0x3d, 0x20, + 0x22, 0x3c, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x68, 0x61, + 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x28, 0x22, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x22, 0x5e, + 0x25, 0x62, 0x28, 0x29, 0x22, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, 0x3d, + 0x20, 0x22, 0x3c, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x22, 0x5e, 0x25, 0x62, 0x3c, 0x3e, + 0x22, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x62, + 0x2c, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x75, 0x62, 0x2c, 0x20, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, + 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x75, 0x6e, 0x74, 0x65, 0x72, + 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x3f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x6f, 0x66, 0x73, 0x20, + 0x3d, 0x20, 0x6f, 0x66, 0x73, 0x2b, 0x31, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x6f, 0x66, + 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, 0x20, 0x2b, 0x20, 0x65, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x09, 0x09, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x6f, 0x66, 0x73, + 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, 0x2b, 0x31, 0x0a, 0x09, 0x09, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x28, 0x6f, 0x66, 0x73, 0x29, 0x0a, 0x09, 0x2d, 0x2d, 0x69, + 0x66, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x6e, 0x20, 0x3d, 0x3d, 0x20, 0x30, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x72, + 0x65, 0x74, 0x2e, 0x6e, 0x3d, 0x31, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x72, + 0x65, 0x74, 0x5b, 0x31, 0x5d, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, + 0x2d, 0x2d, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x6e, + 0x61, 0x74, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x20, + 0x6f, 0x66, 0x20, 0x61, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x63, + 0x61, 0x74, 0x20, 0x28, 0x74, 0x2c, 0x66, 0x2c, 0x6c, 0x2c, 0x6a, 0x73, + 0x74, 0x72, 0x29, 0x0a, 0x09, 0x6a, 0x73, 0x74, 0x72, 0x20, 0x3d, 0x20, + 0x6a, 0x73, 0x74, 0x72, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x20, 0x22, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x27, + 0x27, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x66, + 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x69, 0x3c, 0x3d, 0x6c, + 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x2e, + 0x2e, 0x74, 0x5b, 0x69, 0x5d, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, + 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x69, 0x20, 0x3c, + 0x3d, 0x20, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x73, 0x20, 0x3d, + 0x20, 0x73, 0x2e, 0x2e, 0x6a, 0x73, 0x74, 0x72, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x73, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, + 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x6e, 0x61, 0x74, 0x65, 0x20, + 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x73, 0x2c, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, + 0x67, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x72, 0x75, 0x6c, + 0x65, 0x73, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x20, + 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, + 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x69, 0x3c, 0x3d, 0x61, 0x72, 0x67, + 0x2e, 0x6e, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x5f, + 0x63, 0x6f, 0x6e, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x5f, 0x63, 0x6f, + 0x6e, 0x74, 0x2c, 0x27, 0x5b, 0x25, 0x28, 0x2c, 0x22, 0x5d, 0x27, 0x29, + 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, + 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, + 0x2c, 0x22, 0x5e, 0x5b, 0x25, 0x61, 0x5f, 0x7e, 0x5d, 0x22, 0x29, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x69, + 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x2e, + 0x20, 0x27, 0x20, 0x27, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x69, 0x6e, 0x65, + 0x20, 0x2e, 0x2e, 0x20, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x0a, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x20, 0x7e, + 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x73, 0x75, 0x62, 0x28, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x2c, 0x2d, + 0x31, 0x2c, 0x2d, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, + 0x6e, 0x64, 0x28, 0x61, 0x72, 0x67, 0x5b, 0x61, 0x72, 0x67, 0x2e, 0x6e, + 0x5d, 0x2c, 0x22, 0x5b, 0x25, 0x2f, 0x25, 0x29, 0x25, 0x3b, 0x25, 0x7b, + 0x25, 0x7d, 0x5d, 0x24, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x3d, 0x6e, 0x69, 0x6c, 0x20, + 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, + 0x2e, 0x2e, 0x20, 0x27, 0x5c, 0x6e, 0x27, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x69, 0x6e, + 0x65, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x20, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, + 0x65, 0x20, 0x69, 0x3c, 0x3d, 0x61, 0x72, 0x67, 0x2e, 0x6e, 0x20, 0x64, + 0x6f, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x72, + 0x66, 0x69, 0x6e, 0x64, 0x28, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x2c, 0x27, + 0x5b, 0x25, 0x28, 0x2c, 0x22, 0x5d, 0x27, 0x29, 0x20, 0x61, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x2c, 0x22, 0x5e, 0x5b, + 0x25, 0x61, 0x5f, 0x7e, 0x5d, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x20, 0x20, 0x20, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, + 0x27, 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x61, 0x72, 0x67, 0x5b, 0x69, + 0x5d, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x61, 0x72, 0x67, 0x5b, + 0x69, 0x5d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x20, 0x3d, + 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x61, 0x72, 0x67, 0x5b, + 0x69, 0x5d, 0x2c, 0x2d, 0x31, 0x2c, 0x2d, 0x31, 0x29, 0x0a, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, + 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, + 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x61, 0x72, 0x67, 0x5b, 0x61, + 0x72, 0x67, 0x2e, 0x6e, 0x5d, 0x2c, 0x22, 0x5b, 0x25, 0x2f, 0x25, 0x29, + 0x25, 0x3b, 0x25, 0x7b, 0x25, 0x7d, 0x5d, 0x24, 0x22, 0x29, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x3d, + 0x6e, 0x69, 0x6c, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x27, 0x5c, + 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, + 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x28, 0x70, 0x74, 0x79, 0x70, + 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x0a, 0x09, 0x69, + 0x66, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x5f, 0x68, + 0x6f, 0x6f, 0x6b, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x67, 0x65, 0x74, 0x5f, + 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x73, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x74, + 0x79, 0x70, 0x65, 0x2c, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x5f, 0x68, 0x6f, 0x6f, + 0x6b, 0x28, 0x70, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, + 0x20, 0x70, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x2d, 0x2d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x20, 0x73, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, 0x67, 0x65, 0x74, + 0x5f, 0x22, 0x2e, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x73, + 0x65, 0x74, 0x5f, 0x22, 0x2e, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x70, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x71, 0x74, 0x22, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x20, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, + 0x22, 0x73, 0x65, 0x74, 0x22, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x75, 0x70, 0x70, 0x65, 0x72, 0x28, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x20, 0x31, 0x2c, 0x20, 0x31, 0x29, 0x29, 0x2e, 0x2e, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x20, 0x32, 0x2c, 0x20, 0x2d, 0x31, 0x29, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x70, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, + 0x64, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x09, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, + 0x6f, 0x6f, 0x6b, 0x73, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x61, 0x66, + 0x74, 0x65, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x24, 0x5b, 0x69, 0x63, 0x68, + 0x6c, 0x5d, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x73, 0x2c, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x70, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, + 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, + 0x2d, 0x2d, 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x29, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x70, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x20, + 0x68, 0x61, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x66, + 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6b, 0x67, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x76, 0x65, 0x72, + 0x79, 0x20, 0x24, 0x69, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x61, + 0x6b, 0x65, 0x73, 0x20, 0x61, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x27, 0x63, 0x6f, + 0x64, 0x65, 0x27, 0x20, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x65, 0x78, + 0x74, 0x72, 0x61, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x20, 0x24, 0x69, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x20, 0x6e, + 0x6f, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, + 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x74, 0x2c, 0x20, 0x66, 0x69, 0x6c, + 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x79, + 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x61, 0x74, 0x27, 0x73, + 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x28, 0x6c, + 0x69, 0x6b, 0x65, 0x20, 0x27, 0x24, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, + 0x6e, 0x67, 0x27, 0x2c, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2c, 0x20, 0x65, 0x74, 0x63, 0x29, 0x0a, 0x2d, 0x2d, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x62, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x20, 0x70, 0x61, 0x72, 0x73, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x63, + 0x6f, 0x64, 0x65, 0x2e, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x61, 0x6b, 0x65, + 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, + 0x65, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, + 0x64, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x27, 0x63, + 0x6f, 0x64, 0x65, 0x27, 0x20, 0x6b, 0x65, 0x79, 0x2e, 0x20, 0x6e, 0x6f, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, + 0x72, 0x65, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, + 0x28, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x29, 0x0a, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, + 0x64, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, + 0x65, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x68, 0x6f, 0x6f, + 0x6b, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x29, 0x0a, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x77, 0x72, 0x69, + 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x0a, 0x2d, 0x2d, 0x20, + 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x50, 0x61, + 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x6f, + 0x73, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x68, 0x6f, + 0x6f, 0x6b, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x29, 0x0a, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x27, 0x67, + 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x27, 0x20, 0x74, 0x6f, 0x20, + 0x67, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x74, 0x72, 0x69, + 0x65, 0x76, 0x65, 0x20, 0x61, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x74, 0x73, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x5f, 0x68, 0x6f, + 0x6f, 0x6b, 0x28, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x43, 0x6c, 0x61, + 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x3a, + 0x64, 0x6f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, + 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x64, + 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x69, 0x6c, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x73, 0x75, 0x62, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x68, + 0x6f, 0x6f, 0x6b, 0x28, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, + 0x72, 0x6f, 0x6d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x73, 0x75, 0x70, 0x63, 0x6f, 0x64, + 0x65, 0x2c, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, + 0x73, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x5f, 0x63, 0x61, + 0x6c, 0x6c, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x66, 0x29, 0x0a, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x73, 0x75, + 0x70, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x6f, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x6f, 0x73, + 0x74, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, + 0x66, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, + 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x61, 0x63, + 0x6b, 0x61, 0x67, 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x61, 0x6e, 0x20, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x68, + 0x6f, 0x6f, 0x6b, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x75, 0x73, 0x74, + 0x6f, 0x6d, 0x20, 0x70, 0x75, 0x73, 0x68, 0x65, 0x72, 0x73, 0x0a, 0x0a, + 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x69, 0x73, + 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, + 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x20, 0x3d, + 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, + 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, + 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x73, 0x5f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, + 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, + 0x7d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b, + 0x74, 0x5d, 0x0a, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x69, 0x66, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x73, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x5d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x62, 0x74, 0x79, 0x70, 0x65, 0x5d, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, + 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x73, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, + 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x75, 0x73, 0x68, + 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, + 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, + 0x73, 0x68, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72, + 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, + 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x6f, + 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, + 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, + 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x67, 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x5f, + 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, 0x20, 0x2e, 0x2e, + 0x20, 0x74, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72, 0x20, + 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, + 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x73, 0x5f, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x6f, + 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x75, + 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64, + 0x0a +}; +unsigned int lua_basic_lua_len = 9073; diff --git a/lib/tolua++/src/bin/container_lua.h b/lib/tolua++/src/bin/container_lua.h new file mode 100644 index 000000000..4c7cf6a67 --- /dev/null +++ b/lib/tolua++/src/bin/container_lua.h @@ -0,0 +1,1476 @@ +static const unsigned char lua_container_lua[] = { + 0x2d, 0x2d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x3a, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x61, 0x62, 0x73, 0x74, + 0x72, 0x61, 0x63, 0x74, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x0a, 0x2d, + 0x2d, 0x20, 0x57, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x62, 0x79, + 0x20, 0x57, 0x61, 0x6c, 0x64, 0x65, 0x6d, 0x61, 0x72, 0x20, 0x43, 0x65, + 0x6c, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x65, 0x43, 0x47, 0x72, + 0x61, 0x66, 0x2f, 0x50, 0x55, 0x43, 0x2d, 0x52, 0x69, 0x6f, 0x0a, 0x2d, + 0x2d, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x31, 0x39, 0x39, 0x38, 0x0a, 0x2d, + 0x2d, 0x20, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x24, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x69, + 0x73, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, + 0x61, 0x72, 0x65, 0x3b, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x63, 0x61, 0x6e, + 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x2f, 0x6f, 0x72, 0x20, + 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x20, 0x69, 0x74, 0x2e, 0x0a, 0x2d, + 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, + 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x69, 0x73, + 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x61, 0x73, 0x20, 0x69, + 0x73, 0x22, 0x20, 0x62, 0x61, 0x73, 0x69, 0x73, 0x2c, 0x20, 0x61, 0x6e, + 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x6f, + 0x62, 0x6c, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, + 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x69, + 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x2c, 0x20, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2c, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x73, 0x2c, 0x0a, 0x2d, 0x2d, 0x20, 0x65, 0x6e, 0x68, 0x61, 0x6e, + 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x6f, 0x72, 0x20, + 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x20, 0x74, 0x6f, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x64, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x64, 0x65, 0x66, 0x73, 0x2f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x20, + 0x69, 0x6e, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x73, 0x63, + 0x6f, 0x70, 0x65, 0x0a, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, + 0x0a, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x75, 0x6d, + 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x52, 0x65, 0x70, 0x72, 0x65, 0x73, + 0x65, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x65, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x62, + 0x6f, 0x75, 0x6e, 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x6f, 0x20, 0x6c, + 0x75, 0x61, 0x2e, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x3d, 0x0a, 0x7b, 0x0a, 0x20, + 0x63, 0x75, 0x72, 0x72, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x2c, 0x0a, + 0x7d, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x0a, 0x73, 0x65, 0x74, 0x6d, 0x65, 0x74, + 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2c, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x29, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x74, + 0x61, 0x67, 0x73, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x3a, 0x64, 0x65, 0x63, 0x6c, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x28, 0x29, 0x0a, 0x20, 0x70, 0x75, 0x73, 0x68, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, + 0x3d, 0x31, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x5b, 0x69, 0x5d, 0x3a, 0x64, 0x65, 0x63, 0x6c, 0x74, + 0x79, 0x70, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, + 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x70, 0x6f, + 0x70, 0x28, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x3a, 0x73, 0x75, 0x70, 0x63, + 0x6f, 0x64, 0x65, 0x20, 0x28, 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, + 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x20, 0x70, 0x75, 0x73, 0x68, 0x28, 0x73, 0x65, 0x6c, + 0x66, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, + 0x31, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x5b, 0x69, 0x5d, 0x3a, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x5b, 0x69, 0x5d, 0x3a, 0x73, + 0x75, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x70, 0x6f, 0x70, 0x28, 0x29, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x3a, 0x68, 0x61, 0x73, 0x76, 0x61, 0x72, + 0x20, 0x28, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, + 0x3d, 0x31, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x5b, 0x69, 0x5d, 0x3a, 0x69, 0x73, + 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x29, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, + 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x29, 0x0a, 0x20, 0x73, 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2c, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x29, 0x0a, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x20, 0x3d, + 0x20, 0x30, 0x0a, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x64, 0x65, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x6e, 0x3d, 0x30, 0x7d, 0x0a, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, + 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x65, + 0x6e, 0x75, 0x6d, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x6e, 0x3d, 0x30, 0x7d, 0x0a, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, + 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x70, 0x75, + 0x73, 0x68, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x75, + 0x73, 0x68, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x74, 0x2e, 0x70, 0x72, + 0x6f, 0x78, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, 0x72, 0x72, + 0x0a, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x20, 0x3d, 0x20, + 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x70, 0x6f, + 0x70, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x6f, 0x70, + 0x20, 0x28, 0x29, 0x0a, 0x2d, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, + 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, + 0x72, 0x72, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x2d, 0x2d, 0x66, + 0x6f, 0x72, 0x65, 0x61, 0x63, 0x68, 0x28, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, + 0x72, 0x72, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2c, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x29, 0x0a, 0x2d, 0x2d, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x28, 0x22, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, + 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x22, 0x29, 0x0a, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, + 0x63, 0x75, 0x72, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x67, 0x65, 0x74, 0x20, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x67, 0x65, 0x74, 0x63, 0x75, 0x72, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x28, 0x29, 0x0a, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, 0x72, + 0x72, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x61, + 0x70, 0x70, 0x65, 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x75, 0x72, + 0x72, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, + 0x72, 0x72, 0x3a, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x74, 0x29, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x70, 0x70, + 0x65, 0x6e, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x20, + 0x74, 0x6f, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, + 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x20, 0x28, 0x74, 0x29, 0x0a, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, + 0x75, 0x72, 0x72, 0x3a, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x74, 0x79, + 0x70, 0x65, 0x64, 0x65, 0x66, 0x28, 0x74, 0x29, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x20, + 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x20, 0x74, 0x6f, 0x20, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x75, 0x73, 0x65, + 0x72, 0x74, 0x79, 0x70, 0x65, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, 0x72, + 0x72, 0x3a, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x75, 0x73, 0x65, 0x72, + 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x20, 0x65, + 0x6e, 0x75, 0x6d, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x28, 0x74, 0x29, + 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, + 0x63, 0x75, 0x72, 0x72, 0x3a, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, + 0x6e, 0x75, 0x6d, 0x28, 0x74, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, + 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, + 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x20, 0x28, 0x6d, 0x6f, 0x64, + 0x2c, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x3a, 0x61, + 0x70, 0x70, 0x6c, 0x79, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x28, + 0x6d, 0x6f, 0x64, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, + 0x69, 0x66, 0x20, 0x69, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x69, 0x6e, 0x64, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x3a, 0x66, 0x69, 0x6e, 0x64, 0x74, + 0x79, 0x70, 0x65, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x69, 0x66, + 0x20, 0x69, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x74, + 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x20, 0x28, 0x74, 0x79, 0x70, 0x65, + 0x29, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x2e, 0x63, 0x75, 0x72, 0x72, 0x3a, 0x69, 0x73, 0x74, 0x79, 0x70, 0x65, + 0x64, 0x65, 0x66, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x67, 0x65, 0x74, 0x20, 0x66, 0x75, + 0x6c, 0x6c, 0x74, 0x79, 0x70, 0x65, 0x20, 0x28, 0x77, 0x69, 0x74, 0x68, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x29, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x75, 0x6c, + 0x6c, 0x74, 0x79, 0x70, 0x65, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x75, 0x72, 0x72, 0x20, 0x3d, 0x20, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x0a, 0x09, 0x77, 0x68, + 0x69, 0x6c, 0x65, 0x20, 0x63, 0x75, 0x72, 0x72, 0x20, 0x64, 0x6f, 0x0a, + 0x09, 0x20, 0x69, 0x66, 0x20, 0x63, 0x75, 0x72, 0x72, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x20, 0x69, 0x66, 0x20, 0x63, 0x75, 0x72, + 0x72, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x73, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x63, 0x75, 0x72, 0x72, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x64, 0x65, 0x66, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x09, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x63, 0x75, 0x72, 0x72, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, + 0x73, 0x5b, 0x74, 0x5d, 0x0a, 0x09, 0x09, 0x20, 0x65, 0x6c, 0x73, 0x65, + 0x69, 0x66, 0x20, 0x63, 0x75, 0x72, 0x72, 0x2e, 0x75, 0x73, 0x65, 0x72, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x75, + 0x72, 0x72, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x5b, 0x74, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x20, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x75, 0x72, 0x72, + 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x73, 0x5b, 0x74, + 0x5d, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x09, 0x20, 0x63, 0x75, 0x72, 0x72, 0x20, 0x3d, 0x20, + 0x63, 0x75, 0x72, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x0a, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x73, 0x20, 0x69, 0x66, 0x20, 0x69, 0x74, 0x20, 0x72, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x74, 0x29, 0x0a, 0x20, 0x70, 0x75, 0x73, 0x68, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, + 0x3d, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x20, + 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x77, 0x68, 0x69, + 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x5b, 0x69, 0x5d, 0x20, 0x64, + 0x6f, 0x0a, 0x20, 0x20, 0x72, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x5b, 0x69, 0x5d, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x63, + 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, + 0x20, 0x6f, 0x72, 0x20, 0x72, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, + 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x70, 0x6f, + 0x70, 0x28, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x72, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x67, + 0x65, 0x74, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x61, 0x70, 0x63, 0x65, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, + 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x28, + 0x63, 0x75, 0x72, 0x72, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x3d, + 0x20, 0x27, 0x27, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x63, + 0x75, 0x72, 0x72, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x20, 0x69, 0x66, 0x20, + 0x63, 0x75, 0x72, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x20, + 0x20, 0x20, 0x28, 0x20, 0x63, 0x75, 0x72, 0x72, 0x2e, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x75, 0x72, + 0x72, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, + 0x3d, 0x20, 0x28, 0x63, 0x75, 0x72, 0x72, 0x2e, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x72, + 0x20, 0x63, 0x75, 0x72, 0x72, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x20, + 0x2e, 0x2e, 0x20, 0x27, 0x3a, 0x3a, 0x27, 0x20, 0x2e, 0x2e, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x0a, 0x09, 0x09, 0x20, + 0x2d, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, + 0x3d, 0x20, 0x63, 0x75, 0x72, 0x72, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x2e, 0x2e, 0x20, 0x27, 0x3a, 0x3a, 0x27, 0x20, 0x2e, 0x2e, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x0a, 0x09, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x09, 0x20, 0x63, 0x75, 0x72, 0x72, 0x20, 0x3d, 0x20, + 0x63, 0x75, 0x72, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x0a, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x67, 0x65, 0x74, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x28, 0x6f, 0x6e, 0x6c, 0x79, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x29, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, + 0x6f, 0x6e, 0x6c, 0x79, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x20, 0x28, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x63, 0x75, 0x72, 0x72, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, + 0x72, 0x72, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x27, + 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x63, 0x75, 0x72, 0x72, + 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x75, 0x72, + 0x72, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x3d, 0x20, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x0a, + 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x63, 0x75, 0x72, + 0x72, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x3d, 0x20, 0x63, + 0x75, 0x72, 0x72, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x2e, 0x2e, 0x20, + 0x27, 0x3a, 0x3a, 0x27, 0x20, 0x2e, 0x2e, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x20, 0x63, 0x75, 0x72, 0x72, 0x20, 0x3d, 0x20, 0x63, 0x75, 0x72, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x69, 0x66, 0x20, 0x69, + 0x73, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x28, + 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x3a, 0x69, 0x73, + 0x65, 0x6e, 0x75, 0x6d, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, + 0x64, 0x20, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x3a, 0x61, + 0x70, 0x70, 0x65, 0x6e, 0x64, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6e, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x74, + 0x0a, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x3d, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x64, 0x65, 0x66, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x3a, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x74, + 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, + 0x72, 0x72, 0x29, 0x0a, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x64, 0x65, 0x66, 0x73, 0x2e, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x6e, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x64, 0x65, 0x66, 0x73, 0x2e, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x6e, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x73, 0x5b, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x73, 0x2e, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x74, + 0x0a, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x64, + 0x65, 0x66, 0x73, 0x5b, 0x74, 0x2e, 0x75, 0x74, 0x79, 0x70, 0x65, 0x5d, + 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x20, 0x2e, 0x2e, 0x20, 0x74, 0x2e, 0x75, 0x74, 0x79, 0x70, 0x65, 0x0a, + 0x09, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x64, 0x65, 0x66, 0x73, 0x5b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x2e, 0x2e, 0x74, 0x2e, 0x75, 0x74, 0x79, 0x70, 0x65, 0x5d, + 0x20, 0x3d, 0x20, 0x74, 0x0a, 0x09, 0x74, 0x2e, 0x66, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, + 0x28, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x6f, 0x72, 0x20, + 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x2d, 0x2d, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x28, 0x22, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x20, 0x22, + 0x2e, 0x2e, 0x74, 0x2e, 0x75, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x22, + 0x20, 0x61, 0x73, 0x20, 0x22, 0x2e, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x2e, 0x2e, 0x74, 0x2e, 0x75, 0x74, 0x79, 0x70, + 0x65, 0x2e, 0x2e, 0x22, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x66, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x22, 0x2e, 0x2e, 0x74, 0x2e, 0x66, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x5f, + 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x2e, 0x74, + 0x2e, 0x75, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, + 0x74, 0x2e, 0x66, 0x74, 0x79, 0x70, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x69, 0x73, 0x65, 0x6e, 0x75, 0x6d, 0x28, 0x74, 0x2e, 0x66, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x09, + 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, + 0x5b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x2e, + 0x74, 0x2e, 0x75, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, 0x3d, 0x20, 0x74, + 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x20, + 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x3a, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x75, 0x73, 0x65, + 0x72, 0x74, 0x79, 0x70, 0x65, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x74, 0x20, 0x3d, 0x3d, 0x20, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, + 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x72, + 0x6f, 0x78, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x66, 0x74, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x29, 0x20, 0x2e, 0x2e, 0x20, + 0x74, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x73, 0x5b, 0x74, + 0x5d, 0x20, 0x3d, 0x20, 0x66, 0x74, 0x0a, 0x09, 0x5f, 0x75, 0x73, 0x65, + 0x72, 0x74, 0x79, 0x70, 0x65, 0x5b, 0x66, 0x74, 0x5d, 0x20, 0x3d, 0x20, + 0x66, 0x74, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x64, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x3a, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x28, 0x74, 0x29, + 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, + 0x63, 0x75, 0x72, 0x72, 0x29, 0x0a, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x6e, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x65, 0x6e, 0x75, + 0x6d, 0x73, 0x2e, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x20, 0x2b, + 0x20, 0x31, 0x0a, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x65, 0x6e, 0x75, + 0x6d, 0x73, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x65, 0x6e, 0x75, 0x6d, + 0x73, 0x2e, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x5d, 0x20, 0x3d, + 0x20, 0x74, 0x0a, 0x09, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x65, + 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x2e, 0x2e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x20, + 0x3d, 0x20, 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, + 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x20, 0x6c, 0x75, + 0x61, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x3a, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x28, 0x6c, + 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x5b, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x5b, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x20, 0x3d, + 0x20, 0x30, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5b, 0x6c, + 0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5b, 0x6c, 0x6e, 0x61, 0x6d, + 0x65, 0x5d, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x28, 0x22, 0x25, 0x30, 0x32, 0x64, 0x22, 0x2c, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5b, 0x6c, 0x6e, + 0x61, 0x6d, 0x65, 0x5d, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x73, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x64, 0x65, 0x66, 0x3a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x27, 0x74, 0x68, 0x65, 0x20, + 0x66, 0x61, 0x63, 0x74, 0x6f, 0x27, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, + 0x69, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x3a, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, + 0x66, 0x20, 0x28, 0x6d, 0x6f, 0x64, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x29, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x73, 0x5b, 0x74, 0x79, 0x70, + 0x65, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x2d, 0x2d, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x22, 0x66, 0x6f, 0x75, 0x6e, 0x64, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x20, 0x22, 0x2e, 0x2e, + 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x64, + 0x65, 0x66, 0x73, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x6d, 0x6f, 0x64, 0x31, 0x2c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x31, 0x20, + 0x3d, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x64, 0x65, 0x66, 0x73, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x2e, + 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x73, 0x5b, 0x74, 0x79, 0x70, + 0x65, 0x5d, 0x2e, 0x66, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x6f, 0x64, 0x32, 0x2c, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x32, 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, + 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x28, 0x6d, 0x6f, 0x64, 0x2e, + 0x2e, 0x22, 0x20, 0x22, 0x2e, 0x2e, 0x6d, 0x6f, 0x64, 0x31, 0x2c, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x31, 0x29, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x6f, 0x64, 0x32, 0x20, 0x2e, + 0x2e, 0x20, 0x27, 0x20, 0x27, 0x20, 0x2e, 0x2e, 0x20, 0x6d, 0x6f, 0x64, + 0x31, 0x2c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x32, 0x0a, 0x09, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x6f, 0x64, 0x32, 0x2c, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x32, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x64, 0x6f, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x6f, + 0x64, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x20, 0x69, 0x66, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x0a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x3a, 0x69, 0x73, 0x74, 0x79, + 0x70, 0x65, 0x64, 0x65, 0x66, 0x20, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, + 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x6e, 0x76, 0x20, + 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, + 0x65, 0x20, 0x65, 0x6e, 0x76, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x65, 0x6e, 0x76, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, + 0x66, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x20, + 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x65, 0x6e, 0x76, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x64, 0x65, 0x66, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x65, 0x6e, 0x76, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x73, 0x5b, 0x69, 0x5d, 0x2e, + 0x75, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, + 0x6e, 0x76, 0x20, 0x3d, 0x20, 0x65, 0x6e, 0x76, 0x2e, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, + 0x69, 0x6e, 0x64, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x76, 0x61, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x74, + 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x76, 0x61, 0x72, 0x29, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x76, 0x61, 0x72, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, + 0x63, 0x75, 0x72, 0x72, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, + 0x63, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, 0x63, 0x29, 0x0a, 0x09, 0x09, + 0x66, 0x6f, 0x72, 0x20, 0x6b, 0x2c, 0x76, 0x20, 0x69, 0x6e, 0x20, 0x70, + 0x61, 0x69, 0x72, 0x73, 0x28, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x09, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x28, 0x76, 0x61, 0x72, 0x2c, 0x20, 0x76, 0x2c, 0x20, + 0x6e, 0x73, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x0a, 0x09, 0x09, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x63, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x20, 0x7e, 0x3d, + 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, + 0x63, 0x20, 0x3d, 0x20, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b, 0x63, 0x3a, 0x66, 0x69, + 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x28, 0x63, 0x2e, 0x62, 0x61, 0x73, + 0x65, 0x29, 0x5d, 0x0a, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, + 0x09, 0x09, 0x63, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x09, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x72, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, + 0x69, 0x66, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6c, 0x6c, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x69, 0x6c, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x3a, 0x66, 0x69, 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x20, 0x28, 0x74, + 0x29, 0x0a, 0x0a, 0x09, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2c, 0x20, 0x22, + 0x3d, 0x2e, 0x2a, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x69, + 0x66, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5b, 0x74, 0x5d, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, 0x65, 0x6d, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x74, 0x2c, 0x20, 0x22, 0x28, 0x5b, 0x26, 0x25, 0x2a, 0x5d, + 0x29, 0x25, 0x73, 0x2a, 0x24, 0x22, 0x29, 0x0a, 0x09, 0x74, 0x20, 0x3d, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, + 0x28, 0x74, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x26, 0x25, + 0x2a, 0x5d, 0x29, 0x25, 0x73, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, + 0x29, 0x0a, 0x09, 0x70, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x0a, + 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x70, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x28, 0x70, 0x29, 0x3d, 0x3d, 0x27, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x27, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x67, 0x65, + 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, 0x70, + 0x29, 0x0a, 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x5f, + 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2e, 0x6e, 0x2c, 0x31, 0x2c, 0x2d, 0x31, 0x20, 0x64, 0x6f, 0x20, 0x2d, + 0x2d, 0x20, 0x69, 0x6e, 0x20, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, + 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x69, + 0x66, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2c, 0x20, 0x73, 0x74, + 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x2e, + 0x28, 0x65, 0x6d, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x70, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x70, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x20, 0x7e, + 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x2e, 0x62, + 0x61, 0x73, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x74, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x2d, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x28, 0x22, 0x74, 0x79, 0x70, 0x65, 0x20, 0x69, 0x73, 0x20, 0x22, 0x2e, + 0x2e, 0x74, 0x2e, 0x2e, 0x22, 0x2c, 0x20, 0x70, 0x20, 0x69, 0x73, 0x20, + 0x22, 0x2e, 0x2e, 0x70, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x2e, 0x22, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x69, + 0x73, 0x20, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x2e, 0x2e, 0x22, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x20, 0x69, 0x73, 0x20, 0x22, 0x2e, 0x2e, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x09, + 0x70, 0x20, 0x3d, 0x20, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b, 0x70, 0x3a, 0x66, 0x69, + 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x28, 0x70, 0x2e, 0x62, 0x61, 0x73, + 0x65, 0x29, 0x5d, 0x0a, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, + 0x09, 0x09, 0x70, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x09, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x29, 0x0a, 0x09, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x6e, 0x20, 0x3d, 0x20, + 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x6e, 0x20, 0x2b, 0x31, 0x0a, 0x09, 0x5f, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x5b, 0x5f, 0x67, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x0a, 0x09, 0x5f, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x5b, 0x74, 0x5d, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x69, + 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x5f, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, + 0x70, 0x70, 0x65, 0x6e, 0x64, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b, 0x74, 0x5d, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x2e, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x67, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, + 0x73, 0x5b, 0x74, 0x5d, 0x2e, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x0a, 0x09, + 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b, 0x74, 0x5d, 0x2e, 0x6c, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x5f, + 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x65, 0x73, 0x5b, 0x74, 0x5d, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x28, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b, 0x74, 0x5d, 0x2e, 0x62, + 0x61, 0x73, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x29, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x2e, 0x62, 0x61, 0x73, 0x65, 0x20, 0x3d, 0x20, 0x5f, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b, + 0x74, 0x5d, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x0a, 0x09, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x5f, 0x67, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, + 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x66, 0x6c, 0x61, 0x67, + 0x73, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x66, 0x6c, + 0x61, 0x67, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x7b, 0x7d, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x63, + 0x68, 0x69, 0x6c, 0x64, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x72, 0x65, + 0x67, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x73, 0x74, 0x29, 0x0a, 0x2d, + 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x22, 0x66, 0x69, 0x6e, 0x64, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x22, 0x2e, 0x2e, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x22, 0x2c, 0x20, 0x22, 0x2e, + 0x2e, 0x72, 0x65, 0x67, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x22, 0x2c, + 0x20, 0x22, 0x2e, 0x2e, 0x73, 0x74, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x72, 0x65, 0x67, + 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x74, + 0x79, 0x70, 0x65, 0x2c, 0x20, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x6c, 0x65, 0x6e, 0x28, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x2c, 0x20, 0x74, 0x72, 0x75, 0x65, 0x29, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, + 0x09, 0x69, 0x66, 0x20, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x6c, 0x65, 0x6e, 0x28, 0x72, 0x65, 0x67, 0x74, + 0x79, 0x70, 0x65, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x28, 0x62, 0x20, 0x3d, 0x3d, 0x20, 0x31, 0x20, 0x6f, 0x72, 0x20, + 0x28, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, + 0x72, 0x65, 0x67, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x62, 0x2d, 0x31, + 0x2c, 0x20, 0x62, 0x2d, 0x31, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x3a, + 0x27, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x72, 0x65, 0x67, + 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x62, 0x2d, 0x31, + 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x73, 0x75, 0x62, 0x28, 0x73, 0x74, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x62, + 0x2d, 0x31, 0x29, 0x29, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, + 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, + 0x6c, 0x73, 0x65, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x6f, 0x6e, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x73, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2c, 0x20, 0x74, 0x29, 0x0a, 0x0a, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x66, + 0x6f, 0x72, 0x20, 0x6b, 0x2c, 0x76, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x70, + 0x61, 0x69, 0x72, 0x73, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x29, 0x20, 0x64, + 0x6f, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x76, 0x2e, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x76, 0x2e, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, + 0x20, 0x27, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x27, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, + 0x20, 0x76, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x73, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x76, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, + 0x66, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x73, 0x5b, 0x74, 0x5d, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, + 0x76, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x76, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x76, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x73, 0x5b, + 0x74, 0x5d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x74, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x20, 0x3d, 0x20, + 0x66, 0x69, 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6f, 0x6e, 0x5f, + 0x63, 0x68, 0x69, 0x6c, 0x64, 0x73, 0x28, 0x76, 0x2c, 0x20, 0x74, 0x29, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x74, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x74, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x3a, 0x69, 0x73, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x28, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x67, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x74, 0x79, 0x70, + 0x65, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x0a, 0x20, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x61, 0x73, 0x65, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, + 0x79, 0x70, 0x65, 0x2c, 0x22, 0x5e, 0x2e, 0x2a, 0x3a, 0x3a, 0x22, 0x2c, + 0x22, 0x22, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, + 0x6e, 0x76, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x0a, 0x20, 0x77, + 0x68, 0x69, 0x6c, 0x65, 0x20, 0x65, 0x6e, 0x76, 0x20, 0x64, 0x6f, 0x0a, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x65, 0x6e, 0x76, 0x2e, 0x65, 0x6e, 0x75, + 0x6d, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x20, + 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x65, 0x6e, 0x76, 0x2e, 0x65, 0x6e, + 0x75, 0x6d, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x65, 0x6e, 0x76, 0x2e, 0x65, 0x6e, 0x75, + 0x6d, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, + 0x3d, 0x20, 0x62, 0x61, 0x73, 0x65, 0x74, 0x79, 0x70, 0x65, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, + 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x76, 0x20, + 0x3d, 0x20, 0x65, 0x6e, 0x76, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x69, 0x73, 0x76, 0x69, 0x72, + 0x74, 0x75, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, + 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x20, 0x63, + 0x68, 0x75, 0x6e, 0x6b, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x3a, 0x64, 0x6f, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x20, 0x28, 0x73, 0x29, 0x0a, 0x2d, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x20, 0x28, 0x22, 0x70, 0x61, 0x72, 0x73, 0x65, 0x20, 0x22, 0x2e, 0x2e, + 0x73, 0x29, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x20, 0x68, + 0x6f, 0x6f, 0x6b, 0x0a, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x73, 0x75, 0x62, 0x20, 0x3d, 0x20, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x73, 0x29, + 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, 0x73, 0x75, 0x62, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x73, 0x75, 0x62, 0x0a, 0x20, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x74, 0x72, 0x79, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x20, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x0a, 0x20, 0x64, 0x6f, 0x0a, + 0x20, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x2c, + 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x5e, + 0x25, 0x73, 0x2a, 0x3b, 0x22, 0x29, 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, + 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x2c, 0x65, 0x2b, 0x31, 0x29, 0x0a, 0x20, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x74, + 0x72, 0x79, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x20, 0x76, 0x65, 0x72, + 0x62, 0x61, 0x74, 0x69, 0x6d, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x20, + 0x64, 0x6f, 0x0a, 0x20, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, + 0x2c, 0x65, 0x2c, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, + 0x20, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x24, 0x5c, 0x6e, 0x22, 0x29, 0x0a, + 0x20, 0x09, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, + 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x65, 0x2b, 0x31, 0x29, 0x0a, + 0x20, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x20, 0x2d, 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, 0x4c, 0x75, 0x61, 0x20, + 0x63, 0x6f, 0x64, 0x65, 0x0a, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x63, 0x6f, 0x64, + 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, + 0x73, 0x2c, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x28, 0x25, 0x62, 0x5c, 0x31, + 0x5c, 0x32, 0x29, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x43, 0x6f, 0x64, + 0x65, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x63, 0x6f, 0x64, + 0x65, 0x2c, 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x2c, 0x65, 0x2b, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, + 0x20, 0x74, 0x72, 0x79, 0x20, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x0a, + 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x62, 0x2c, 0x65, 0x2c, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x5e, 0x25, + 0x73, 0x2a, 0x28, 0x25, 0x62, 0x5c, 0x33, 0x5c, 0x34, 0x29, 0x22, 0x29, + 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x7b, 0x27, + 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x63, 0x6f, 0x64, + 0x65, 0x2c, 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x2e, 0x2e, 0x27, 0x5c, 0x6e, + 0x7d, 0x5c, 0x6e, 0x27, 0x0a, 0x09, 0x56, 0x65, 0x72, 0x62, 0x61, 0x74, + 0x69, 0x6d, 0x28, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x27, 0x72, 0x27, 0x29, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x76, + 0x65, 0x72, 0x62, 0x61, 0x74, 0x69, 0x6d, 0x20, 0x63, 0x6f, 0x64, 0x65, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x27, 0x72, 0x27, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x20, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, + 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x65, 0x2b, 0x31, 0x29, 0x0a, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, + 0x2d, 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, 0x43, 0x20, 0x63, 0x6f, 0x64, + 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x70, 0x72, 0x65, 0x61, 0x6d, 0x62, + 0x6c, 0x65, 0x20, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, + 0x64, 0x6f, 0x0a, 0x20, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, + 0x2c, 0x65, 0x2c, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, + 0x20, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x28, 0x25, 0x62, 0x5c, 0x35, 0x5c, + 0x36, 0x29, 0x22, 0x29, 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, 0x62, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x09, 0x63, 0x6f, 0x64, 0x65, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, + 0x62, 0x28, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x32, 0x2c, 0x20, 0x2d, + 0x32, 0x29, 0x2e, 0x2e, 0x22, 0x5c, 0x6e, 0x22, 0x0a, 0x09, 0x09, 0x56, + 0x65, 0x72, 0x62, 0x61, 0x74, 0x69, 0x6d, 0x28, 0x63, 0x6f, 0x64, 0x65, + 0x2c, 0x20, 0x27, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x2c, 0x20, 0x65, 0x2b, 0x31, 0x29, 0x0a, 0x20, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, + 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x0a, 0x20, 0x64, 0x6f, + 0x0a, 0x20, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, + 0x2c, 0x70, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x5e, 0x25, 0x73, + 0x2a, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x50, 0x52, 0x4f, 0x50, 0x45, + 0x52, 0x54, 0x59, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x25, 0x73, 0x2a, 0x25, + 0x28, 0x2b, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5e, 0x25, 0x29, 0x25, 0x73, + 0x5d, 0x2a, 0x29, 0x25, 0x73, 0x2a, 0x25, 0x29, 0x2b, 0x25, 0x73, 0x2a, + 0x3b, 0x3f, 0x22, 0x29, 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, 0x62, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x70, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6f, 0x72, 0x20, + 0x70, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x22, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x09, 0x09, 0x70, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x3d, 0x20, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x22, 0x0a, 0x20, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x09, + 0x09, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x73, 0x65, 0x74, 0x5f, 0x70, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, + 0x70, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x20, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x2c, 0x20, 0x65, 0x2b, 0x31, 0x29, 0x0a, 0x20, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, + 0x74, 0x72, 0x79, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, + 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x0a, 0x20, + 0x64, 0x6f, 0x0a, 0x20, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, + 0x2c, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x5e, 0x25, 0x73, + 0x2a, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x45, + 0x43, 0x54, 0x45, 0x44, 0x5f, 0x44, 0x45, 0x53, 0x54, 0x52, 0x55, 0x43, + 0x54, 0x4f, 0x52, 0x25, 0x73, 0x2a, 0x3b, 0x3f, 0x22, 0x29, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, + 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x73, 0x65, 0x74, 0x5f, + 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x65, + 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x20, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x73, + 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x5f, 0x64, 0x65, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x28, + 0x74, 0x72, 0x75, 0x65, 0x29, 0x0a, 0x09, 0x20, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, + 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x65, 0x2b, 0x31, + 0x29, 0x0a, 0x20, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, 0x27, 0x65, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x27, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, + 0x72, 0x64, 0x0a, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x20, + 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x25, + 0x73, 0x2b, 0x22, 0x29, 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, 0x62, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x64, 0x6f, + 0x20, 0x6e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x09, 0x09, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x2c, 0x20, 0x65, 0x2b, 0x31, 0x29, 0x0a, 0x20, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, + 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, 0x27, 0x76, 0x69, 0x72, 0x74, 0x75, + 0x61, 0x6c, 0x27, 0x20, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x6b, 0x64, + 0x0a, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x62, 0x2c, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x5e, + 0x25, 0x73, 0x2a, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x25, 0x73, + 0x2b, 0x22, 0x29, 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x09, 0x6d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x69, 0x73, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x3d, + 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x20, 0x09, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x2c, 0x20, 0x65, 0x2b, 0x31, 0x29, 0x0a, 0x20, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x74, + 0x72, 0x79, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x20, 0x28, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2c, 0x20, 0x70, 0x72, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x2c, 0x20, 0x65, 0x74, 0x63, 0x29, 0x0a, 0x20, 0x64, 0x6f, + 0x0a, 0x20, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, + 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x25, + 0x77, 0x2a, 0x25, 0x73, 0x2a, 0x3a, 0x5b, 0x5e, 0x3a, 0x5d, 0x22, 0x29, + 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x20, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, + 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x65, 0x29, 0x20, + 0x2d, 0x2d, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x5b, 0x5e, 0x3a, 0x5d, 0x0a, 0x20, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, + 0x20, 0x74, 0x72, 0x79, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x0a, + 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x62, 0x2c, 0x65, 0x2c, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x62, 0x6f, 0x64, + 0x79, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, + 0x73, 0x2c, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5f, 0x25, 0x77, 0x5d, + 0x5b, 0x5f, 0x25, 0x77, 0x5d, 0x2a, 0x29, 0x25, 0x73, 0x2a, 0x28, 0x25, + 0x62, 0x7b, 0x7d, 0x29, 0x25, 0x73, 0x2a, 0x22, 0x29, 0x0a, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x62, + 0x2c, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x4d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x62, 0x6f, 0x64, 0x79, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, + 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x65, 0x2b, 0x31, 0x29, + 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x61, 0x70, 0x63, 0x65, 0x0a, 0x20, 0x64, 0x6f, 0x0a, 0x20, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x6e, + 0x61, 0x6d, 0x65, 0x2c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x5e, 0x25, + 0x73, 0x2a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x25, + 0x73, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5f, 0x25, 0x77, 0x5d, 0x5b, 0x5f, + 0x25, 0x77, 0x5d, 0x2a, 0x29, 0x25, 0x73, 0x2a, 0x28, 0x25, 0x62, 0x7b, + 0x7d, 0x29, 0x25, 0x73, 0x2a, 0x3b, 0x3f, 0x22, 0x29, 0x0a, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x62, + 0x2c, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x62, 0x6f, + 0x64, 0x79, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x65, + 0x2b, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x0a, 0x20, 0x64, 0x6f, 0x0a, 0x20, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x6e, + 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x73, 0x2c, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x23, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x65, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5e, + 0x25, 0x73, 0x5d, 0x2a, 0x29, 0x5b, 0x5e, 0x5c, 0x6e, 0x5d, 0x2a, 0x5c, + 0x6e, 0x25, 0x73, 0x2a, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x5f, 0x63, + 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x62, 0x2c, 0x65, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x28, 0x6e, + 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, + 0x65, 0x2b, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x74, 0x72, 0x79, + 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x73, 0x0a, + 0x0a, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x62, 0x6f, + 0x64, 0x79, 0x2c, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, + 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, + 0x5e, 0x25, 0x73, 0x2a, 0x65, 0x6e, 0x75, 0x6d, 0x25, 0x73, 0x2b, 0x28, + 0x25, 0x53, 0x2a, 0x29, 0x25, 0x73, 0x2a, 0x28, 0x25, 0x62, 0x7b, 0x7d, + 0x29, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5e, 0x25, 0x73, 0x3b, 0x5d, 0x2a, + 0x29, 0x25, 0x73, 0x2a, 0x3b, 0x3f, 0x25, 0x73, 0x2a, 0x22, 0x29, 0x0a, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, + 0x23, 0x53, 0x6f, 0x72, 0x72, 0x79, 0x2c, 0x20, 0x64, 0x65, 0x63, 0x6c, + 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x65, + 0x6e, 0x75, 0x6d, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x76, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x2e, 0x5c, 0x6e, + 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x20, 0x79, 0x6f, 0x75, 0x72, + 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x65, + 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x79, 0x20, 0x28, 0x65, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3a, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x20, 0x22, 0x2e, 0x2e, 0x76, 0x61, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x3b, 0x27, 0x29, 0x22, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x5f, 0x63, + 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, + 0x28, 0x73, 0x2c, 0x62, 0x2c, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x45, + 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x28, 0x6e, 0x61, 0x6d, + 0x65, 0x2c, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x76, 0x61, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x65, + 0x2b, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x64, 0x6f, 0x0a, 0x2d, 0x2d, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x2c, + 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x5e, + 0x25, 0x73, 0x2a, 0x65, 0x6e, 0x75, 0x6d, 0x25, 0x73, 0x2b, 0x28, 0x25, + 0x53, 0x2a, 0x29, 0x25, 0x73, 0x2a, 0x28, 0x25, 0x62, 0x7b, 0x7d, 0x29, + 0x25, 0x73, 0x2a, 0x3b, 0x3f, 0x25, 0x73, 0x2a, 0x22, 0x29, 0x0a, 0x2d, + 0x2d, 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x2d, 0x2d, 0x20, 0x20, 0x20, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x5f, + 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x2c, 0x62, 0x2c, 0x65, 0x29, 0x0a, 0x2d, 0x2d, 0x20, + 0x20, 0x20, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x28, + 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x62, 0x6f, 0x64, 0x79, 0x29, 0x0a, 0x2d, + 0x2d, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, + 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x65, 0x2b, 0x31, 0x29, 0x0a, + 0x2d, 0x2d, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x65, + 0x6e, 0x64, 0x20, 0x0a, 0x0a, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x62, 0x6f, 0x64, + 0x79, 0x2c, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x5e, 0x25, 0x73, 0x2a, + 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x25, 0x73, 0x2b, 0x65, 0x6e, + 0x75, 0x6d, 0x5b, 0x5e, 0x7b, 0x5d, 0x2a, 0x28, 0x25, 0x62, 0x7b, 0x7d, + 0x29, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x25, 0x77, 0x5f, 0x5d, 0x5b, 0x5e, + 0x25, 0x73, 0x5d, 0x2a, 0x29, 0x25, 0x73, 0x2a, 0x3b, 0x25, 0x73, 0x2a, + 0x22, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x5f, + 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x2c, 0x62, 0x2c, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x28, 0x6e, 0x61, + 0x6d, 0x65, 0x2c, 0x62, 0x6f, 0x64, 0x79, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x2c, 0x65, 0x2b, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, + 0x20, 0x74, 0x72, 0x79, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x0a, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x64, 0x65, 0x63, 0x6c, 0x2c, 0x6b, + 0x69, 0x6e, 0x64, 0x2c, 0x61, 0x72, 0x67, 0x2c, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, + 0x73, 0x2c, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5f, 0x25, 0x77, + 0x5d, 0x5b, 0x5f, 0x25, 0x77, 0x25, 0x73, 0x25, 0x2a, 0x26, 0x3a, 0x3c, + 0x3e, 0x2c, 0x5d, 0x2d, 0x25, 0x73, 0x2b, 0x6f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x6f, 0x72, 0x29, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5e, 0x25, 0x73, + 0x5d, 0x5b, 0x5e, 0x25, 0x73, 0x5d, 0x2a, 0x29, 0x25, 0x73, 0x2a, 0x28, + 0x25, 0x62, 0x28, 0x29, 0x29, 0x25, 0x73, 0x2a, 0x28, 0x63, 0x3f, 0x6f, + 0x3f, 0x6e, 0x3f, 0x73, 0x3f, 0x74, 0x3f, 0x29, 0x25, 0x73, 0x2a, 0x3b, + 0x25, 0x73, 0x2a, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, + 0x20, 0x2d, 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, 0x69, 0x6e, 0x6c, 0x69, + 0x6e, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x64, 0x65, + 0x63, 0x6c, 0x2c, 0x6b, 0x69, 0x6e, 0x64, 0x2c, 0x61, 0x72, 0x67, 0x2c, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, + 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x28, + 0x5b, 0x5f, 0x25, 0x77, 0x5d, 0x5b, 0x5f, 0x25, 0x77, 0x25, 0x73, 0x25, + 0x2a, 0x26, 0x3a, 0x3c, 0x3e, 0x2c, 0x5d, 0x2d, 0x25, 0x73, 0x2b, 0x6f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x29, 0x25, 0x73, 0x2a, 0x28, + 0x5b, 0x5e, 0x25, 0x73, 0x5d, 0x5b, 0x5e, 0x25, 0x73, 0x5d, 0x2a, 0x29, + 0x25, 0x73, 0x2a, 0x28, 0x25, 0x62, 0x28, 0x29, 0x29, 0x25, 0x73, 0x2a, + 0x28, 0x63, 0x3f, 0x6f, 0x3f, 0x6e, 0x3f, 0x73, 0x3f, 0x74, 0x3f, 0x29, + 0x5b, 0x25, 0x73, 0x5c, 0x6e, 0x5d, 0x2a, 0x25, 0x62, 0x7b, 0x7d, 0x25, + 0x73, 0x2a, 0x3b, 0x3f, 0x25, 0x73, 0x2a, 0x22, 0x29, 0x0a, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x09, 0x2d, + 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, 0x63, 0x61, 0x73, 0x74, 0x20, 0x6f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x09, 0x62, + 0x2c, 0x65, 0x2c, 0x64, 0x65, 0x63, 0x6c, 0x2c, 0x6b, 0x69, 0x6e, 0x64, + 0x2c, 0x61, 0x72, 0x67, 0x2c, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, + 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x20, + 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x28, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x29, 0x25, 0x73, 0x2b, 0x28, 0x5b, 0x25, 0x77, 0x5f, 0x3a, + 0x25, 0x64, 0x3c, 0x3e, 0x25, 0x2a, 0x25, 0x26, 0x25, 0x73, 0x5d, 0x2b, + 0x29, 0x25, 0x73, 0x2a, 0x28, 0x25, 0x62, 0x28, 0x29, 0x29, 0x25, 0x73, + 0x2a, 0x28, 0x63, 0x3f, 0x6f, 0x3f, 0x6e, 0x3f, 0x73, 0x3f, 0x74, 0x3f, + 0x29, 0x22, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x09, 0x69, 0x66, 0x20, 0x62, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x09, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x69, 0x65, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, + 0x2c, 0x20, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x25, 0x62, 0x7b, 0x7d, 0x22, + 0x2c, 0x20, 0x65, 0x2b, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x09, 0x09, 0x69, + 0x66, 0x20, 0x69, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x09, 0x09, 0x09, 0x65, 0x20, 0x3d, 0x20, 0x69, 0x65, 0x0a, 0x20, 0x20, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x5f, 0x63, + 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x62, 0x2c, 0x65, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x28, 0x64, 0x65, 0x63, 0x6c, 0x2c, 0x6b, 0x69, 0x6e, 0x64, 0x2c, 0x61, + 0x72, 0x67, 0x2c, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x73, + 0x75, 0x62, 0x28, 0x73, 0x2c, 0x65, 0x2b, 0x31, 0x29, 0x0a, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, + 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x0a, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x64, 0x65, 0x63, + 0x6c, 0x2c, 0x61, 0x72, 0x67, 0x2c, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, + 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x7e, 0x5f, 0x25, 0x77, 0x5d, + 0x5b, 0x5f, 0x40, 0x25, 0x77, 0x25, 0x73, 0x25, 0x2a, 0x26, 0x3a, 0x3c, + 0x3e, 0x5d, 0x2a, 0x5b, 0x5f, 0x25, 0x77, 0x5d, 0x29, 0x25, 0x73, 0x2a, + 0x28, 0x25, 0x62, 0x28, 0x29, 0x29, 0x25, 0x73, 0x2a, 0x28, 0x63, 0x3f, + 0x6f, 0x3f, 0x6e, 0x3f, 0x73, 0x3f, 0x74, 0x3f, 0x29, 0x25, 0x73, 0x2a, + 0x3d, 0x3f, 0x25, 0x73, 0x2a, 0x30, 0x3f, 0x25, 0x73, 0x2a, 0x3b, 0x25, + 0x73, 0x2a, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x64, 0x65, 0x63, 0x6c, 0x2c, 0x61, 0x72, + 0x67, 0x2c, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2c, 0x76, 0x69, 0x72, 0x74, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, + 0x2c, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5e, 0x25, 0x28, 0x5c, + 0x6e, 0x5d, 0x2b, 0x29, 0x25, 0x73, 0x2a, 0x28, 0x25, 0x62, 0x28, 0x29, + 0x29, 0x25, 0x73, 0x2a, 0x28, 0x63, 0x3f, 0x6f, 0x3f, 0x6e, 0x3f, 0x73, + 0x3f, 0x74, 0x3f, 0x29, 0x76, 0x3f, 0x65, 0x3f, 0x72, 0x3f, 0x72, 0x3f, + 0x69, 0x3f, 0x64, 0x3f, 0x65, 0x3f, 0x25, 0x73, 0x2a, 0x6f, 0x3f, 0x76, + 0x3f, 0x65, 0x3f, 0x72, 0x3f, 0x72, 0x3f, 0x69, 0x3f, 0x64, 0x3f, 0x65, + 0x3f, 0x25, 0x73, 0x2a, 0x28, 0x3d, 0x3f, 0x25, 0x73, 0x2a, 0x30, 0x3f, + 0x29, 0x25, 0x73, 0x2a, 0x3b, 0x25, 0x73, 0x2a, 0x22, 0x29, 0x0a, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x09, 0x2d, 0x2d, 0x20, 0x74, 0x72, 0x79, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, + 0x74, 0x68, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x0a, + 0x20, 0x20, 0x09, 0x62, 0x2c, 0x65, 0x2c, 0x64, 0x65, 0x63, 0x6c, 0x2c, + 0x61, 0x72, 0x67, 0x2c, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x5e, + 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x7e, 0x5f, 0x25, 0x77, 0x5d, 0x5b, 0x5f, + 0x40, 0x25, 0x77, 0x25, 0x73, 0x25, 0x2a, 0x26, 0x3a, 0x3c, 0x3e, 0x5d, + 0x2a, 0x5b, 0x5f, 0x25, 0x77, 0x5d, 0x25, 0x62, 0x3c, 0x3e, 0x29, 0x25, + 0x73, 0x2a, 0x28, 0x25, 0x62, 0x28, 0x29, 0x29, 0x25, 0x73, 0x2a, 0x28, + 0x63, 0x3f, 0x6f, 0x3f, 0x6e, 0x3f, 0x73, 0x3f, 0x74, 0x3f, 0x29, 0x76, + 0x3f, 0x65, 0x3f, 0x72, 0x3f, 0x72, 0x3f, 0x69, 0x3f, 0x64, 0x3f, 0x65, + 0x3f, 0x25, 0x73, 0x2a, 0x6f, 0x3f, 0x76, 0x3f, 0x65, 0x3f, 0x72, 0x3f, + 0x72, 0x3f, 0x69, 0x3f, 0x64, 0x3f, 0x65, 0x3f, 0x25, 0x73, 0x2a, 0x3d, + 0x3f, 0x25, 0x73, 0x2a, 0x30, 0x3f, 0x25, 0x73, 0x2a, 0x3b, 0x25, 0x73, + 0x2a, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, + 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x6c, 0x65, 0x74, + 0x74, 0x65, 0x72, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x62, 0x2c, 0x65, + 0x2c, 0x64, 0x65, 0x63, 0x6c, 0x2c, 0x61, 0x72, 0x67, 0x2c, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x73, 0x2c, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5f, + 0x25, 0x77, 0x5d, 0x29, 0x25, 0x73, 0x2a, 0x28, 0x25, 0x62, 0x28, 0x29, + 0x29, 0x25, 0x73, 0x2a, 0x28, 0x63, 0x3f, 0x6f, 0x3f, 0x6e, 0x3f, 0x73, + 0x3f, 0x74, 0x3f, 0x29, 0x76, 0x3f, 0x65, 0x3f, 0x72, 0x3f, 0x72, 0x3f, + 0x69, 0x3f, 0x64, 0x3f, 0x65, 0x3f, 0x25, 0x73, 0x2a, 0x6f, 0x3f, 0x76, + 0x3f, 0x65, 0x3f, 0x72, 0x3f, 0x72, 0x3f, 0x69, 0x3f, 0x64, 0x3f, 0x65, + 0x3f, 0x25, 0x73, 0x2a, 0x3b, 0x25, 0x73, 0x2a, 0x22, 0x29, 0x0a, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, + 0x2d, 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x0a, + 0x20, 0x20, 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x64, 0x65, 0x63, 0x6c, 0x2c, + 0x61, 0x72, 0x67, 0x2c, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x5e, + 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5e, 0x25, 0x28, 0x3b, 0x5c, 0x6e, 0x5d, + 0x2b, 0x25, 0x62, 0x28, 0x29, 0x29, 0x25, 0x73, 0x2a, 0x28, 0x25, 0x62, + 0x28, 0x29, 0x29, 0x25, 0x73, 0x2a, 0x3b, 0x25, 0x73, 0x2a, 0x22, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x20, 0x3d, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, + 0x28, 0x64, 0x65, 0x63, 0x6c, 0x2c, 0x20, 0x22, 0x25, 0x28, 0x25, 0x73, + 0x2a, 0x25, 0x2a, 0x28, 0x5b, 0x5e, 0x25, 0x29, 0x5d, 0x2a, 0x29, 0x25, + 0x73, 0x2a, 0x25, 0x29, 0x22, 0x2c, 0x20, 0x22, 0x20, 0x25, 0x31, 0x20, + 0x22, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x09, 0x69, 0x66, 0x20, 0x76, 0x69, + 0x72, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x76, 0x69, 0x72, 0x74, 0x2c, + 0x20, 0x22, 0x5b, 0x3d, 0x30, 0x5d, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x20, 0x20, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x66, + 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x70, 0x75, 0x72, 0x65, 0x5f, 0x76, 0x69, + 0x72, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, + 0x0a, 0x20, 0x20, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x5f, 0x63, 0x75, 0x72, 0x72, + 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, + 0x75, 0x62, 0x28, 0x73, 0x2c, 0x62, 0x2c, 0x65, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x3d, + 0x20, 0x27, 0x6f, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x27, + 0x27, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, + 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x64, 0x65, 0x63, + 0x6c, 0x2c, 0x61, 0x72, 0x67, 0x2c, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, + 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x65, 0x2b, 0x31, 0x29, + 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, 0x69, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x0a, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x64, 0x65, 0x63, 0x6c, 0x2c, 0x61, 0x72, + 0x67, 0x2c, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x5e, 0x25, 0x73, + 0x2a, 0x28, 0x5b, 0x5e, 0x25, 0x28, 0x5c, 0x6e, 0x5d, 0x2b, 0x29, 0x25, + 0x73, 0x2a, 0x28, 0x25, 0x62, 0x28, 0x29, 0x29, 0x25, 0x73, 0x2a, 0x28, + 0x63, 0x3f, 0x6f, 0x3f, 0x6e, 0x3f, 0x73, 0x3f, 0x74, 0x3f, 0x29, 0x76, + 0x3f, 0x65, 0x3f, 0x72, 0x3f, 0x72, 0x3f, 0x69, 0x3f, 0x64, 0x3f, 0x65, + 0x3f, 0x25, 0x73, 0x2a, 0x6f, 0x3f, 0x76, 0x3f, 0x65, 0x3f, 0x72, 0x3f, + 0x72, 0x3f, 0x69, 0x3f, 0x64, 0x3f, 0x65, 0x3f, 0x5b, 0x5e, 0x3b, 0x7b, + 0x5d, 0x2a, 0x25, 0x62, 0x7b, 0x7d, 0x25, 0x73, 0x2a, 0x3b, 0x3f, 0x25, + 0x73, 0x2a, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x64, 0x65, 0x63, 0x6c, 0x2c, + 0x61, 0x72, 0x67, 0x2c, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x5e, + 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x7e, 0x5f, 0x25, 0x77, 0x5d, 0x5b, 0x5f, + 0x40, 0x25, 0x77, 0x25, 0x73, 0x25, 0x2a, 0x26, 0x3a, 0x3c, 0x3e, 0x5d, + 0x2a, 0x5b, 0x5f, 0x25, 0x77, 0x3e, 0x5d, 0x29, 0x25, 0x73, 0x2a, 0x28, + 0x25, 0x62, 0x28, 0x29, 0x29, 0x25, 0x73, 0x2a, 0x28, 0x63, 0x3f, 0x6f, + 0x3f, 0x6e, 0x3f, 0x73, 0x3f, 0x74, 0x3f, 0x29, 0x5b, 0x5e, 0x3b, 0x5d, + 0x2a, 0x25, 0x62, 0x7b, 0x7d, 0x25, 0x73, 0x2a, 0x3b, 0x3f, 0x25, 0x73, + 0x2a, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x2d, + 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, + 0x6c, 0x65, 0x20, 0x6c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, + 0x20, 0x20, 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x64, 0x65, 0x63, 0x6c, 0x2c, + 0x61, 0x72, 0x67, 0x2c, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x5e, + 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5f, 0x25, 0x77, 0x5d, 0x29, 0x25, 0x73, + 0x2a, 0x28, 0x25, 0x62, 0x28, 0x29, 0x29, 0x25, 0x73, 0x2a, 0x28, 0x63, + 0x3f, 0x6f, 0x3f, 0x6e, 0x3f, 0x73, 0x3f, 0x74, 0x3f, 0x29, 0x76, 0x3f, + 0x65, 0x3f, 0x72, 0x3f, 0x72, 0x3f, 0x69, 0x3f, 0x64, 0x3f, 0x65, 0x3f, + 0x25, 0x73, 0x2a, 0x6f, 0x3f, 0x76, 0x3f, 0x65, 0x3f, 0x72, 0x3f, 0x72, + 0x3f, 0x69, 0x3f, 0x64, 0x3f, 0x65, 0x3f, 0x2e, 0x2d, 0x25, 0x62, 0x7b, + 0x7d, 0x25, 0x73, 0x2a, 0x3b, 0x3f, 0x25, 0x73, 0x2a, 0x22, 0x29, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x5f, 0x63, 0x75, + 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x62, 0x2c, 0x65, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, + 0x3d, 0x3d, 0x20, 0x27, 0x6f, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, + 0x20, 0x27, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x20, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x64, + 0x65, 0x63, 0x6c, 0x2c, 0x61, 0x72, 0x67, 0x2c, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x65, 0x2b, + 0x31, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x0a, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x6e, 0x61, 0x6d, + 0x65, 0x2c, 0x62, 0x61, 0x73, 0x65, 0x2c, 0x62, 0x6f, 0x64, 0x79, 0x0a, + 0x09, 0x09, 0x62, 0x61, 0x73, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x27, 0x20, + 0x62, 0x6f, 0x64, 0x79, 0x20, 0x3d, 0x20, 0x27, 0x27, 0x0a, 0x09, 0x09, + 0x62, 0x2c, 0x65, 0x2c, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x5e, 0x25, + 0x73, 0x2a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x25, 0x73, 0x2a, 0x28, 0x5b, + 0x5f, 0x25, 0x77, 0x5d, 0x5b, 0x5f, 0x25, 0x77, 0x40, 0x5d, 0x2a, 0x29, + 0x25, 0x73, 0x2a, 0x3b, 0x22, 0x29, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x64, + 0x75, 0x6d, 0x6d, 0x79, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x0a, 0x09, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, + 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x69, + 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x09, 0x09, 0x62, 0x2c, 0x65, 0x2c, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, + 0x2c, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5f, 0x25, 0x77, 0x5d, 0x5b, 0x5f, 0x25, + 0x77, 0x40, 0x5d, 0x2a, 0x29, 0x25, 0x73, 0x2a, 0x3b, 0x22, 0x29, 0x20, + 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x20, + 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, + 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x62, 0x2c, 0x65, 0x2c, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x62, 0x61, 0x73, 0x65, 0x2c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x3d, + 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, + 0x5e, 0x25, 0x73, 0x2a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x25, 0x73, 0x2a, + 0x28, 0x5b, 0x5f, 0x25, 0x77, 0x5d, 0x5b, 0x5f, 0x25, 0x77, 0x40, 0x5d, + 0x2a, 0x29, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5e, 0x7b, 0x5d, 0x2d, 0x29, + 0x25, 0x73, 0x2a, 0x28, 0x25, 0x62, 0x7b, 0x7d, 0x29, 0x25, 0x73, 0x2a, + 0x22, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x62, 0x2c, 0x65, 0x2c, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x62, + 0x61, 0x73, 0x65, 0x2c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x5e, 0x25, + 0x73, 0x2a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x25, 0x73, 0x2b, 0x28, + 0x5b, 0x5f, 0x25, 0x77, 0x5d, 0x5b, 0x5f, 0x25, 0x77, 0x40, 0x5d, 0x2a, + 0x29, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5e, 0x7b, 0x5d, 0x2d, 0x29, 0x25, + 0x73, 0x2a, 0x28, 0x25, 0x62, 0x7b, 0x7d, 0x29, 0x25, 0x73, 0x2a, 0x22, + 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x62, 0x2c, 0x65, 0x2c, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x62, 0x61, 0x73, 0x65, 0x2c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x5e, + 0x25, 0x73, 0x2a, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x25, 0x73, 0x2a, 0x28, + 0x5b, 0x5f, 0x25, 0x77, 0x5d, 0x5b, 0x5f, 0x25, 0x77, 0x40, 0x5d, 0x2a, + 0x29, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5e, 0x7b, 0x5d, 0x2d, 0x29, 0x25, + 0x73, 0x2a, 0x28, 0x25, 0x62, 0x7b, 0x7d, 0x29, 0x25, 0x73, 0x2a, 0x22, + 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x61, 0x73, 0x65, 0x20, 0x3d, 0x20, + 0x27, 0x27, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x62, 0x2c, + 0x65, 0x2c, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, + 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, + 0x25, 0x73, 0x25, 0x73, 0x2a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x25, + 0x73, 0x25, 0x73, 0x2a, 0x5b, 0x5f, 0x25, 0x77, 0x5d, 0x2a, 0x25, 0x73, + 0x2a, 0x28, 0x25, 0x62, 0x7b, 0x7d, 0x29, 0x25, 0x73, 0x2a, 0x28, 0x5b, + 0x5f, 0x25, 0x77, 0x5d, 0x5b, 0x5f, 0x25, 0x77, 0x40, 0x5d, 0x2a, 0x29, + 0x25, 0x73, 0x2a, 0x3b, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, + 0x09, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x20, + 0x3d, 0x20, 0x31, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6c, + 0x73, 0x65, 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x20, 0x3d, 0x20, 0x31, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x62, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x62, + 0x61, 0x73, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x62, 0x61, 0x73, 0x65, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x62, 0x61, 0x73, 0x65, 0x2c, 0x20, 0x22, 0x5e, 0x25, 0x73, + 0x2a, 0x3a, 0x25, 0x73, 0x2a, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x62, 0x61, 0x73, 0x65, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x62, + 0x61, 0x73, 0x65, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x25, 0x73, 0x2a, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x62, 0x61, 0x73, 0x65, 0x20, 0x3d, 0x20, + 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x62, 0x61, 0x73, 0x65, 0x2c, 0x20, + 0x22, 0x2c, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x2d, 0x2d, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x2d, 0x2d, 0x62, 0x2c, 0x65, 0x2c, 0x62, 0x61, 0x73, 0x65, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x62, 0x61, + 0x73, 0x65, 0x2c, 0x22, 0x2e, 0x2d, 0x28, 0x5b, 0x5f, 0x25, 0x77, 0x5d, + 0x5b, 0x5f, 0x25, 0x77, 0x3c, 0x3e, 0x2c, 0x3a, 0x5d, 0x2a, 0x29, 0x24, + 0x22, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x62, 0x61, 0x73, 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x7d, + 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x5f, + 0x63, 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x62, 0x2c, 0x65, + 0x29, 0x0a, 0x09, 0x09, 0x09, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x28, 0x6e, + 0x61, 0x6d, 0x65, 0x2c, 0x62, 0x61, 0x73, 0x65, 0x2c, 0x62, 0x6f, 0x64, + 0x79, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x76, 0x61, 0x72, 0x62, 0x2c, 0x76, 0x61, 0x72, + 0x65, 0x2c, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, + 0x73, 0x2c, 0x20, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5f, 0x25, + 0x77, 0x5d, 0x2b, 0x29, 0x25, 0x73, 0x2a, 0x3b, 0x22, 0x2c, 0x20, 0x65, + 0x2b, 0x31, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x76, + 0x61, 0x72, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x6e, + 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x20, 0x22, 0x2e, 0x2e, 0x76, 0x61, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x65, 0x20, 0x3d, 0x20, 0x76, 0x61, 0x72, 0x65, 0x0a, 0x09, 0x09, 0x09, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, + 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x65, 0x2b, 0x31, 0x29, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x20, 0x2d, 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x64, 0x65, 0x66, 0x0a, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, + 0x73, 0x2c, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x74, 0x79, 0x70, 0x65, 0x64, + 0x65, 0x66, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x28, 0x2e, 0x2d, 0x29, 0x25, + 0x73, 0x2a, 0x3b, 0x25, 0x73, 0x2a, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, + 0x5f, 0x63, 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, + 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x62, 0x2c, + 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x54, 0x79, 0x70, 0x65, 0x64, 0x65, + 0x66, 0x28, 0x74, 0x79, 0x70, 0x65, 0x73, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x2c, 0x65, 0x2b, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, + 0x20, 0x74, 0x72, 0x79, 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, + 0x65, 0x0a, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x64, 0x65, 0x63, 0x6c, 0x20, 0x3d, + 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, + 0x5e, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5f, 0x25, 0x77, 0x5d, 0x5b, 0x5f, + 0x40, 0x25, 0x73, 0x25, 0x77, 0x25, 0x64, 0x25, 0x2a, 0x26, 0x3a, 0x3c, + 0x3e, 0x2c, 0x5d, 0x2a, 0x5b, 0x5f, 0x25, 0x77, 0x25, 0x64, 0x5d, 0x29, + 0x25, 0x73, 0x2a, 0x3b, 0x25, 0x73, 0x2a, 0x22, 0x29, 0x0a, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x62, + 0x2c, 0x65, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x6c, 0x69, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, + 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x64, 0x65, + 0x63, 0x6c, 0x2c, 0x20, 0x22, 0x2c, 0x22, 0x29, 0x0a, 0x09, 0x56, 0x61, + 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x6c, 0x69, 0x73, 0x74, 0x5b, + 0x31, 0x5d, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x69, 0x73, 0x74, + 0x2e, 0x6e, 0x20, 0x3e, 0x20, 0x31, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, + 0x6e, 0x64, 0x28, 0x6c, 0x69, 0x73, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x20, + 0x22, 0x28, 0x2e, 0x2d, 0x29, 0x25, 0x73, 0x2b, 0x28, 0x5b, 0x5e, 0x25, + 0x73, 0x5d, 0x2a, 0x29, 0x24, 0x22, 0x29, 0x3b, 0x0a, 0x0a, 0x09, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x20, 0x3d, 0x32, 0x3b, 0x0a, + 0x09, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x6c, 0x69, 0x73, 0x74, + 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x09, 0x56, 0x61, + 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x74, 0x79, 0x70, 0x65, 0x2e, + 0x2e, 0x22, 0x20, 0x22, 0x2e, 0x2e, 0x6c, 0x69, 0x73, 0x74, 0x5b, 0x69, + 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x3d, 0x69, 0x2b, 0x31, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x20, 0x2d, 0x2d, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, + 0x28, 0x64, 0x65, 0x63, 0x6c, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x2c, 0x65, 0x2b, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x74, + 0x72, 0x79, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x64, + 0x6f, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, + 0x65, 0x2c, 0x64, 0x65, 0x63, 0x6c, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x5e, 0x25, 0x73, 0x2a, + 0x28, 0x5b, 0x5f, 0x25, 0x77, 0x5d, 0x3f, 0x5b, 0x5f, 0x25, 0x73, 0x25, + 0x77, 0x25, 0x64, 0x5d, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x25, 0x73, 0x2b, + 0x5b, 0x5f, 0x40, 0x25, 0x77, 0x25, 0x64, 0x5d, 0x2a, 0x25, 0x73, 0x2a, + 0x25, 0x5b, 0x25, 0x73, 0x2a, 0x25, 0x53, 0x2b, 0x25, 0x73, 0x2a, 0x25, + 0x5d, 0x29, 0x25, 0x73, 0x2a, 0x3b, 0x25, 0x73, 0x2a, 0x22, 0x29, 0x0a, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x20, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, + 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x2c, 0x62, 0x2c, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x56, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x64, 0x65, 0x63, 0x6c, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, + 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x65, 0x2b, 0x31, 0x29, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x20, 0x2d, 0x2d, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61, 0x72, 0x72, 0x61, + 0x79, 0x0a, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x64, 0x65, 0x63, 0x6c, 0x20, 0x3d, + 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, + 0x5e, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x5f, 0x25, 0x77, 0x5d, 0x5b, 0x5d, + 0x5b, 0x5f, 0x40, 0x25, 0x73, 0x25, 0x77, 0x25, 0x64, 0x25, 0x2a, 0x26, + 0x3a, 0x3c, 0x3e, 0x5d, 0x2a, 0x5b, 0x5d, 0x5f, 0x25, 0x77, 0x25, 0x64, + 0x5d, 0x29, 0x25, 0x73, 0x2a, 0x3b, 0x25, 0x73, 0x2a, 0x22, 0x29, 0x0a, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x20, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, + 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x2c, 0x62, 0x2c, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x41, 0x72, 0x72, + 0x61, 0x79, 0x28, 0x64, 0x65, 0x63, 0x6c, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x2c, 0x65, 0x2b, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, + 0x20, 0x6e, 0x6f, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, + 0x0a, 0x20, 0x69, 0x66, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, + 0x22, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x22, 0x2c, 0x22, 0x22, 0x29, 0x20, + 0x7e, 0x3d, 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, + 0x3d, 0x20, 0x73, 0x0a, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, + 0x22, 0x23, 0x70, 0x61, 0x72, 0x73, 0x65, 0x20, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x22, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x3a, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x20, 0x28, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x5f, 0x6d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3d, + 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, + 0x20, 0x73, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x64, 0x6f, 0x0a, + 0x20, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x64, + 0x6f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x28, 0x73, 0x29, 0x0a, 0x20, 0x20, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x69, 0x73, 0x76, 0x69, 0x72, 0x74, + 0x75, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x29, 0x0a, 0x0a, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, + 0x75, 0x72, 0x72, 0x3a, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x29, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x3a, 0x73, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x70, + 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x70, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, + 0x75, 0x62, 0x28, 0x70, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x22, 0x5e, + 0x25, 0x73, 0x2a, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x70, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x70, 0x74, 0x79, 0x70, 0x65, + 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, + 0x29, 0x0a, 0x0a, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, + 0x20, 0x70, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x3a, + 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6f, + 0x72, 0x20, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3a, 0x67, 0x65, 0x74, 0x5f, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x28, 0x29, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a +}; +unsigned int lua_container_lua_len = 17673; diff --git a/lib/tolua++/src/bin/declaration_lua.h b/lib/tolua++/src/bin/declaration_lua.h new file mode 100644 index 000000000..28deb4f60 --- /dev/null +++ b/lib/tolua++/src/bin/declaration_lua.h @@ -0,0 +1,1265 @@ +static const unsigned char lua_declaration_lua[] = { + 0x2d, 0x2d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x3a, 0x20, 0x64, 0x65, + 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x57, 0x72, 0x69, 0x74, 0x74, + 0x65, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x57, 0x61, 0x6c, 0x64, 0x65, 0x6d, + 0x61, 0x72, 0x20, 0x43, 0x65, 0x6c, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x20, + 0x54, 0x65, 0x43, 0x47, 0x72, 0x61, 0x66, 0x2f, 0x50, 0x55, 0x43, 0x2d, + 0x52, 0x69, 0x6f, 0x0a, 0x2d, 0x2d, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x31, + 0x39, 0x39, 0x38, 0x0a, 0x2d, 0x2d, 0x20, 0x24, 0x49, 0x64, 0x3a, 0x20, + 0x24, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, + 0x6f, 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, + 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x3b, 0x20, 0x79, 0x6f, + 0x75, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6e, + 0x64, 0x2f, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x20, + 0x69, 0x74, 0x2e, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, + 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x64, 0x20, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6e, 0x64, + 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x20, + 0x22, 0x61, 0x73, 0x20, 0x69, 0x73, 0x22, 0x20, 0x62, 0x61, 0x73, 0x69, + 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x73, + 0x20, 0x6e, 0x6f, 0x20, 0x6f, 0x62, 0x6c, 0x69, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, + 0x65, 0x2c, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2c, 0x20, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x2c, 0x0a, 0x2d, 0x2d, 0x20, + 0x65, 0x6e, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x52, 0x65, + 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x76, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x2d, 0x2d, 0x20, 0x53, 0x74, 0x6f, + 0x72, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, + 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x3a, 0x0a, 0x2d, 0x2d, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x20, 0x3d, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, + 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x20, + 0x70, 0x74, 0x72, 0x20, 0x20, 0x3d, 0x20, 0x22, 0x2a, 0x22, 0x20, 0x6f, + 0x72, 0x20, 0x22, 0x26, 0x22, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x72, 0x65, + 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, + 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x6f, 0x72, 0x20, + 0x61, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x0a, + 0x2d, 0x2d, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x20, 0x64, 0x69, 0x6d, 0x20, + 0x20, 0x3d, 0x20, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x2c, 0x20, 0x69, 0x66, 0x20, 0x61, 0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x0a, 0x2d, 0x2d, 0x20, 0x20, 0x64, 0x65, 0x66, 0x20, 0x20, 0x3d, + 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x28, + 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x0a, 0x2d, 0x2d, 0x20, 0x20, + 0x72, 0x65, 0x74, 0x20, 0x20, 0x3d, 0x20, 0x22, 0x2a, 0x22, 0x20, 0x6f, + 0x72, 0x20, 0x22, 0x26, 0x22, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x28, 0x6f, + 0x6e, 0x6c, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x3d, 0x20, 0x7b, 0x0a, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x27, + 0x27, 0x2c, 0x0a, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, + 0x27, 0x2c, 0x0a, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, 0x27, + 0x2c, 0x0a, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x27, + 0x2c, 0x0a, 0x20, 0x64, 0x69, 0x6d, 0x20, 0x3d, 0x20, 0x27, 0x27, 0x2c, + 0x0a, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x27, 0x27, 0x2c, 0x0a, + 0x20, 0x64, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x27, 0x27, 0x0a, 0x7d, 0x0a, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, + 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x73, 0x65, 0x74, 0x6d, + 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x29, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, + 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x28, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x5f, 0x76, 0x61, 0x72, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x5f, 0x76, 0x61, 0x72, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x30, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x5f, 0x76, 0x61, 0x72, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x20, 0x3d, 0x20, 0x5f, 0x76, 0x61, 0x72, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x76, 0x61, 0x72, + 0x5f, 0x22, 0x2e, 0x2e, 0x5f, 0x76, 0x61, 0x72, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x2d, 0x2d, + 0x20, 0x49, 0x74, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x28, + 0x29, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x31, 0x2c, 0x31, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x5b, 0x27, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x69, 0x6e, 0x64, + 0x74, 0x79, 0x70, 0x65, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, + 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x27, + 0x25, 0x73, 0x25, 0x73, 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x6d, 0x5b, + 0x6d, 0x2e, 0x6e, 0x5d, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, + 0x28, 0x6d, 0x2c, 0x31, 0x2c, 0x6d, 0x2e, 0x6e, 0x2d, 0x31, 0x29, 0x0a, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x3d, 0x27, + 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x3d, 0x3d, 0x32, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x31, 0x5d, + 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, + 0x3d, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x5f, + 0x76, 0x61, 0x72, 0x28, 0x74, 0x5b, 0x74, 0x2e, 0x6e, 0x5d, 0x29, 0x0a, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x64, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x2c, 0x22, 0x25, 0x5b, 0x28, 0x2e, 0x2d, 0x29, 0x25, 0x5d, + 0x22, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x31, 0x2c, 0x62, + 0x2d, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, + 0x69, 0x6d, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x65, 0x6e, + 0x75, 0x6d, 0x5f, 0x76, 0x61, 0x72, 0x28, 0x64, 0x29, 0x0a, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x20, 0x3d, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x76, + 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6b, 0x69, + 0x6e, 0x64, 0x3d, 0x3d, 0x27, 0x76, 0x61, 0x72, 0x27, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x3d, 0x27, 0x27, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x7e, + 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, + 0x66, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x3d, 0x27, 0x27, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x27, 0x20, 0x27, + 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x5f, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x29, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x63, 0x68, 0x61, 0x72, + 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, + 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x27, 0x63, 0x68, 0x61, 0x72, 0x2a, 0x27, 0x0a, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, + 0x20, 0x27, 0x76, 0x61, 0x72, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x20, 0x22, 0x3a, 0x2e, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, + 0x20, 0x2d, 0x2d, 0x20, 0x3f, 0x3f, 0x3f, 0x0a, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x53, + 0x75, 0x62, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x73, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x27, 0x73, 0x2e, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x74, 0x79, 0x70, 0x65, 0x20, 0x28, 0x29, + 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, + 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, + 0x61, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x74, 0x6f, + 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, + 0x20, 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x69, + 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6b, 0x69, 0x6e, 0x64, 0x20, + 0x3d, 0x3d, 0x20, 0x27, 0x66, 0x75, 0x6e, 0x63, 0x27, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x3d, 0x3d, 0x27, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2c, 0x20, 0x22, 0x25, 0x2a, 0x22, + 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x5f, 0x75, + 0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x27, 0x0a, 0x20, 0x09, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x22, 0x22, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x62, 0x61, + 0x73, 0x69, 0x63, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x70, 0x74, 0x72, 0x7e, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x65, 0x74, + 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x0a, + 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, + 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x69, 0x73, + 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x5f, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, + 0x74, 0x72, 0x75, 0x65, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, + 0x69, 0x73, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x74, 0x6f, 0x20, + 0x62, 0x65, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x0a, + 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, + 0x7e, 0x3d, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x72, 0x65, 0x74, 0x7e, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, + 0x27, 0x23, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x3a, 0x20, 0x63, 0x61, 0x6e, + 0x6e, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, + 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x27, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x27, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2a, 0x27, 0x0a, 0x20, + 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, + 0x74, 0x61, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x76, 0x6f, + 0x69, 0x64, 0x2a, 0x27, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, + 0x3d, 0x20, 0x27, 0x5f, 0x63, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x27, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x63, 0x68, 0x61, 0x72, 0x2a, + 0x27, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, + 0x5f, 0x6c, 0x73, 0x74, 0x61, 0x74, 0x65, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x20, 0x27, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x2a, 0x27, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, + 0x20, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x20, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x0a, + 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x73, + 0x6f, 0x6c, 0x76, 0x65, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x0a, 0x2d, 0x2d, 0x20, 0x2d, 0x2d, 0x20, 0x69, 0x66, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, + 0x74, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x73, 0x65, 0x74, 0x20, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x72, 0x65, 0x74, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, + 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x2d, + 0x2d, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, + 0x3d, 0x20, 0x27, 0x30, 0x27, 0x0a, 0x2d, 0x2d, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x2d, 0x2d, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x6c, + 0x76, 0x65, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, + 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x62, 0x2c, 0x5f, 0x2c, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x79, + 0x70, 0x65, 0x2c, 0x20, 0x22, 0x28, 0x25, 0x62, 0x3c, 0x3e, 0x29, 0x22, + 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x0a, 0x09, 0x09, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, + 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x6d, 0x2c, + 0x20, 0x32, 0x2c, 0x20, 0x2d, 0x32, 0x29, 0x2c, 0x20, 0x22, 0x2c, 0x22, + 0x29, 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x31, 0x2c, + 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x6e, 0x28, + 0x6d, 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x09, 0x6d, 0x5b, 0x69, + 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, + 0x73, 0x75, 0x62, 0x28, 0x6d, 0x5b, 0x69, 0x5d, 0x2c, 0x22, 0x25, 0x73, + 0x2a, 0x28, 0x5b, 0x25, 0x2a, 0x26, 0x5d, 0x29, 0x22, 0x2c, 0x20, 0x22, + 0x25, 0x31, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x6d, + 0x5b, 0x69, 0x5d, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x73, 0x65, + 0x6e, 0x75, 0x6d, 0x28, 0x6d, 0x5b, 0x69, 0x5d, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x20, 0x5f, 0x2c, 0x20, 0x6d, 0x5b, 0x69, 0x5d, 0x20, 0x3d, + 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, + 0x66, 0x28, 0x22, 0x22, 0x2c, 0x20, 0x6d, 0x5b, 0x69, 0x5d, 0x29, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x6d, 0x5b, 0x69, 0x5d, + 0x20, 0x3d, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x28, + 0x6d, 0x5b, 0x69, 0x5d, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x5b, 0x69, + 0x5d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x6d, 0x5b, 0x69, 0x5d, 0x20, 0x3d, + 0x20, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x5f, 0x74, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x28, + 0x6d, 0x5b, 0x69, 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x69, 0x0a, 0x09, 0x09, 0x74, 0x79, + 0x70, 0x65, 0x2c, 0x62, 0x2c, 0x69, 0x20, 0x3d, 0x20, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, + 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x2d, 0x2d, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x28, 0x22, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x22, 0x2c, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x6d, 0x2c, + 0x20, 0x31, 0x2c, 0x20, 0x6d, 0x2e, 0x6e, 0x29, 0x29, 0x0a, 0x09, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x20, 0x3d, 0x20, 0x22, 0x3c, + 0x22, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x6d, 0x2c, + 0x20, 0x31, 0x2c, 0x20, 0x6d, 0x2e, 0x6e, 0x2c, 0x20, 0x22, 0x2c, 0x22, + 0x29, 0x2e, 0x2e, 0x22, 0x3e, 0x22, 0x0a, 0x09, 0x09, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x74, 0x79, 0x70, + 0x65, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x29, 0x0a, 0x09, 0x09, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, + 0x22, 0x3e, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x3e, 0x20, 0x3e, 0x22, 0x29, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, + 0x73, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, + 0x65, 0x2c, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, + 0x20, 0x22, 0x28, 0x25, 0x62, 0x3c, 0x3e, 0x29, 0x22, 0x29, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, + 0x25, 0x62, 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x2c, 0x20, 0x62, + 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x0a, 0x09, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, + 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x73, 0x2c, 0x20, + 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x0a, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x62, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x73, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, + 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x62, 0x2d, 0x31, + 0x29, 0x2e, 0x2e, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x2e, 0x2e, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, + 0x62, 0x2c, 0x20, 0x2d, 0x31, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, + 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2c, 0x63, 0x6c, 0x6f, 0x73, 0x65, + 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, + 0x6d, 0x6f, 0x64, 0x20, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2e, 0x2e, 0x22, 0x27, 0x2c, + 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, + 0x2e, 0x22, 0x20, 0x70, 0x74, 0x72, 0x20, 0x20, 0x3d, 0x20, 0x27, 0x22, + 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2e, 0x2e, + 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, + 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x64, 0x69, 0x6d, 0x20, 0x20, 0x3d, + 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, + 0x6d, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, + 0x20, 0x64, 0x65, 0x66, 0x20, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x2e, 0x2e, 0x22, 0x27, + 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x72, 0x65, 0x74, 0x20, + 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, + 0x2e, 0x22, 0x7d, 0x22, 0x2e, 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x29, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x20, 0x69, 0x66, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, + 0x6f, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x61, 0x72, + 0x65, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x20, 0x4c, 0x75, 0x61, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, + 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x09, 0x20, + 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, + 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x73, 0x62, 0x61, + 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, + 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x3a, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x28, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x22, 0x25, 0x73, + 0x2a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2b, 0x22, 0x2c, 0x22, + 0x22, 0x29, 0x0a, 0x09, 0x09, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, + 0x20, 0x3d, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x63, 0x6f, + 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x5f, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x63, + 0x6c, 0x65, 0x61, 0x6e, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x20, 0x74, 0x61, 0x67, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x64, 0x65, 0x63, 0x6c, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x28, 0x29, 0x0a, 0x0a, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x76, 0x61, 0x72, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x27, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x27, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, + 0x20, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x27, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x67, 0x73, + 0x75, 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, + 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2a, 0x27, 0x2c, 0x27, + 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, + 0x67, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x3a, 0x6f, 0x75, 0x74, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x66, 0x0a, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x73, + 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x64, 0x65, 0x66, 0x7e, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x64, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x31, + 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x64, 0x65, 0x66, + 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, + 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, + 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x2d, + 0x2d, 0x69, 0x66, 0x20, 0x74, 0x3d, 0x3d, 0x27, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x2d, 0x2d, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x69, 0x73, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, + 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, + 0x27, 0x2e, 0x2e, 0x64, 0x65, 0x66, 0x2e, 0x2e, 0x27, 0x2c, 0x26, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x27, 0x0a, 0x09, + 0x2d, 0x2d, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x27, 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, + 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, + 0x27, 0x2c, 0x30, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, + 0x72, 0x72, 0x29, 0x27, 0x0a, 0x20, 0x09, 0x2d, 0x2d, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x69, 0x73, 0x65, + 0x6e, 0x75, 0x6d, 0x74, 0x79, 0x70, 0x65, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x7e, 0x3d, 0x20, 0x6e, 0x69, + 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x27, 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x69, 0x73, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, + 0x2c, 0x27, 0x2e, 0x2e, 0x64, 0x65, 0x66, 0x2e, 0x2e, 0x27, 0x2c, 0x26, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x27, 0x0a, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x74, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, + 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x27, 0x2e, 0x2e, + 0x74, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, + 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, + 0x27, 0x2e, 0x2e, 0x64, 0x65, 0x66, 0x2e, 0x2e, 0x27, 0x2c, 0x26, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x27, 0x0a, 0x20, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, + 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x26, 0x27, 0x20, 0x6f, + 0x72, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, + 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x28, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x6e, + 0x69, 0x6c, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, + 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, 0x26, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x20, 0x7c, 0x7c, + 0x20, 0x21, 0x27, 0x2e, 0x2e, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, + 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, + 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, 0x22, + 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x2e, 0x2e, 0x27, 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x64, 0x65, 0x66, 0x2e, + 0x2e, 0x27, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, + 0x72, 0x29, 0x29, 0x27, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x21, 0x27, 0x2e, + 0x2e, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2e, 0x2e, 0x27, 0x28, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, + 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, 0x22, 0x27, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x27, 0x22, + 0x2c, 0x27, 0x2e, 0x2e, 0x64, 0x65, 0x66, 0x2e, 0x2e, 0x27, 0x2c, 0x26, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x27, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x64, + 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x20, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, + 0x6c, 0x75, 0x73, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x29, 0x3d, 0x3d, 0x6e, + 0x69, 0x6c, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x69, + 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, 0x27, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x6f, 0x64, 0x0a, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x25, 0x73, 0x2b, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x0a, 0x20, 0x69, 0x66, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, + 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2b, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x20, + 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, + 0x65, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6d, 0x6f, 0x64, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x72, + 0x72, 0x61, 0x79, 0x73, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, + 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x7e, 0x3d, + 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, + 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, + 0x27, 0x2a, 0x27, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x69, 0x6e, + 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x22, 0x20, 0x22, + 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x74, 0x79, + 0x70, 0x65, 0x2c, 0x70, 0x74, 0x72, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, + 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, + 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, + 0x2c, 0x27, 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, + 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, + 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, + 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x29, 0x7e, 0x3d, + 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, + 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, + 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, + 0x27, 0x5b, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, + 0x2c, 0x27, 0x5d, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, + 0x6c, 0x75, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, + 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, + 0x20, 0x3d, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x65, + 0x77, 0x5f, 0x64, 0x69, 0x6d, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, + 0x2c, 0x70, 0x74, 0x72, 0x2c, 0x27, 0x2c, 0x20, 0x27, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x2e, 0x2e, 0x27, 0x29, 0x3b, + 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6c, + 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, + 0x20, 0x3d, 0x20, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x70, + 0x74, 0x72, 0x2c, 0x27, 0x2a, 0x29, 0x27, 0x2c, 0x0a, 0x09, 0x09, 0x27, + 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x28, 0x28, 0x27, 0x2c, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x2c, 0x27, 0x29, 0x2a, 0x73, 0x69, + 0x7a, 0x65, 0x6f, 0x66, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x2c, + 0x70, 0x74, 0x72, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, + 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x74, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, + 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, + 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x20, 0x3d, 0x20, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x20, 0x3d, 0x3d, + 0x20, 0x27, 0x73, 0x74, 0x61, 0x74, 0x65, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, + 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, + 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x20, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x53, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, + 0x0a, 0x20, 0x20, 0x09, 0x2d, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, + 0x22, 0x74, 0x20, 0x69, 0x73, 0x20, 0x22, 0x2e, 0x2e, 0x74, 0x6f, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x74, 0x29, 0x2e, 0x2e, 0x22, 0x2c, + 0x20, 0x70, 0x74, 0x72, 0x20, 0x69, 0x73, 0x20, 0x22, 0x2e, 0x2e, 0x74, + 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x70, 0x74, 0x72, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x09, 0x69, 0x66, + 0x20, 0x74, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x70, 0x74, 0x72, 0x2c, 0x20, 0x22, 0x25, 0x2a, 0x22, 0x29, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x09, 0x09, 0x74, 0x20, 0x3d, 0x20, + 0x27, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x27, 0x0a, 0x20, + 0x20, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x74, 0x72, 0x3d, + 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x69, 0x6e, + 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x2a, 0x27, + 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x20, + 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x28, 0x28, 0x27, 0x2c, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x74, 0x79, 0x70, + 0x65, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x65, + 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x2a, 0x27, 0x29, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x20, + 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x29, 0x20, 0x27, 0x29, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x69, 0x73, 0x65, 0x6e, 0x75, 0x6d, 0x28, + 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, + 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, + 0x6e, 0x65, 0x2c, 0x27, 0x28, 0x69, 0x6e, 0x74, 0x29, 0x20, 0x27, 0x29, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x64, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x69, 0x66, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, 0x7e, 0x3d, + 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x64, + 0x65, 0x66, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, + 0x66, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x70, 0x74, 0x72, 0x20, + 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x26, 0x27, + 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x64, 0x65, 0x66, 0x20, + 0x3d, 0x20, 0x22, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x26, 0x28, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x2e, 0x2e, 0x22, 0x29, 0x22, 0x2e, 0x2e, 0x64, 0x65, 0x66, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, + 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, + 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, + 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x27, 0x2e, 0x2e, + 0x74, 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, + 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, 0x2c, 0x27, 0x2c, 0x64, + 0x65, 0x66, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, + 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, + 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x69, + 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x74, 0x6f, + 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, + 0x27, 0x2c, 0x27, 0x2c, 0x64, 0x65, 0x66, 0x2c, 0x27, 0x29, 0x29, 0x3b, + 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x20, + 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, + 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x64, + 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x20, 0x28, 0x6e, 0x61, 0x72, 0x67, + 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, + 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x29, 0x3d, 0x3d, 0x6e, 0x69, 0x6c, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, 0x5f, + 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, 0x73, 0x5c, 0x6e, + 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x64, 0x65, + 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x61, + 0x72, 0x67, 0x2c, 0x74, 0x72, 0x75, 0x65, 0x29, 0x29, 0x0a, 0x09, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6c, 0x73, + 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x62, 0x75, 0x69, 0x6c, + 0x64, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, + 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x62, 0x75, 0x69, 0x6c, 0x64, + 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, 0x29, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x47, 0x65, 0x74, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x67, 0x65, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x28, 0x6e, 0x61, + 0x72, 0x67, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7b, + 0x27, 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, + 0x55, 0x41, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, 0x6e, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x64, + 0x65, 0x66, 0x3b, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x64, 0x65, 0x66, 0x7e, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x64, 0x65, 0x66, 0x3d, 0x31, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, + 0x64, 0x65, 0x66, 0x3d, 0x30, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x73, + 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x74, 0x29, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x27, 0x2e, 0x2e, 0x74, 0x2e, + 0x2e, 0x27, 0x61, 0x72, 0x72, 0x61, 0x79, 0x28, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, + 0x2c, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x2c, + 0x27, 0x2c, 0x27, 0x2c, 0x64, 0x65, 0x66, 0x2c, 0x27, 0x2c, 0x26, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x29, 0x27, 0x29, + 0x0a, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x20, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x28, 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, + 0x73, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x61, 0x72, 0x72, + 0x61, 0x79, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, + 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, 0x2c, 0x22, 0x27, 0x2c, 0x74, + 0x79, 0x70, 0x65, 0x2c, 0x27, 0x22, 0x2c, 0x27, 0x2c, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x2c, 0x27, 0x2c, 0x27, 0x2c, 0x64, 0x65, + 0x66, 0x2c, 0x27, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, + 0x72, 0x72, 0x29, 0x29, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x20, 0x20, 0x67, 0x6f, 0x74, 0x6f, 0x20, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x6c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3b, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, + 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x7b, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x69, 0x3b, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, + 0x20, 0x66, 0x6f, 0x72, 0x28, 0x69, 0x3d, 0x30, 0x3b, 0x20, 0x69, 0x3c, + 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x2e, + 0x2e, 0x27, 0x3b, 0x69, 0x2b, 0x2b, 0x29, 0x27, 0x29, 0x0a, 0x20, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x73, + 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x74, 0x72, 0x20, + 0x3d, 0x20, 0x27, 0x27, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x7e, 0x3d, 0x27, 0x27, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, 0x2a, + 0x27, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x5b, 0x69, 0x5d, + 0x20, 0x3d, 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x74, 0x72, + 0x3d, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x2a, 0x27, 0x29, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x28, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x29, 0x20, 0x27, + 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x65, + 0x66, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, 0x7e, 0x3d, 0x20, 0x27, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x64, 0x65, 0x66, 0x20, 0x3d, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x27, 0x2e, 0x2e, 0x74, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, + 0x2c, 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x27, 0x2c, 0x64, 0x65, 0x66, + 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x28, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, + 0x72, 0x67, 0x2c, 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x27, 0x2c, 0x64, + 0x65, 0x66, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x20, 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7d, 0x27, 0x29, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x47, 0x65, 0x74, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x73, 0x65, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x28, 0x6e, 0x61, + 0x72, 0x67, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x25, 0x73, 0x2b, 0x27, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, + 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x7b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x69, 0x3b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x28, 0x69, 0x3d, 0x30, 0x3b, + 0x20, 0x69, 0x3c, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, + 0x69, 0x6d, 0x2e, 0x2e, 0x27, 0x3b, 0x69, 0x2b, 0x2b, 0x29, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, 0x63, + 0x74, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, + 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x27, 0x2e, 0x2e, 0x74, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, + 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x28, 0x27, 0x2c, 0x63, 0x74, 0x2c, 0x27, + 0x29, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x27, 0x5b, 0x69, 0x5d, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x7b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, 0x5f, + 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, 0x73, 0x5c, 0x6e, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, + 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x20, + 0x3d, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x65, 0x77, + 0x28, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x29, 0x28, + 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x27, 0x5b, 0x69, 0x5d, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, + 0x68, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x6b, 0x65, 0x6f, + 0x77, 0x6e, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x28, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, + 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x6f, 0x62, 0x6a, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x2c, + 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6c, 0x73, + 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x6f, 0x69, 0x64, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, + 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x63, + 0x6f, 0x70, 0x79, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, + 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x26, 0x27, 0x2c, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x5b, 0x69, 0x5d, + 0x2c, 0x73, 0x69, 0x7a, 0x65, 0x6f, 0x66, 0x28, 0x27, 0x2c, 0x74, 0x79, + 0x70, 0x65, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, + 0x68, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, + 0x70, 0x65, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, + 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x2c, 0x22, 0x27, + 0x2c, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x20, 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x75, + 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, + 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, + 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x27, 0x5b, 0x69, 0x5d, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, + 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7d, 0x27, 0x29, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x46, 0x72, 0x65, 0x65, 0x20, 0x64, 0x79, 0x6e, 0x61, 0x6d, + 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x66, 0x72, 0x65, 0x65, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x28, + 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, + 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x29, 0x3d, 0x3d, 0x6e, 0x69, 0x6c, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, 0x5f, + 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, 0x73, 0x5c, 0x6e, + 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x20, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x64, 0x69, 0x6d, 0x28, 0x27, 0x2c, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x29, 0x3b, + 0x27, 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x66, + 0x72, 0x65, 0x65, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, + 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x50, 0x61, 0x73, 0x73, + 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x61, 0x72, 0x20, 0x28, 0x29, 0x0a, + 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, + 0x3d, 0x3d, 0x27, 0x26, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x2a, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x65, 0x74, 0x3d, 0x3d, 0x27, 0x2a, 0x27, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x26, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, + 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x52, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, + 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, + 0x65, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x28, 0x29, 0x0a, 0x20, + 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x65, 0x74, 0x20, + 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, 0x63, 0x74, 0x20, + 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x7e, 0x3d, 0x27, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x27, 0x2e, 0x2e, 0x74, 0x2e, + 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, + 0x27, 0x2c, 0x63, 0x74, 0x2c, 0x27, 0x29, 0x27, 0x2e, 0x2e, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x29, 0x3b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x75, 0x73, 0x68, 0x5f, + 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, + 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x20, 0x27, 0x2c, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, + 0x63, 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, + 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x27, 0x2e, 0x2e, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x2c, 0x22, + 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, + 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x0a, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x30, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x0a, 0x20, + 0x73, 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x28, 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, + 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x0a, 0x20, 0x74, 0x3a, + 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x28, 0x29, + 0x0a, 0x20, 0x74, 0x3a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6e, 0x61, 0x6d, + 0x65, 0x28, 0x29, 0x0a, 0x20, 0x74, 0x3a, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x74, 0x79, 0x70, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x66, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x74, + 0x79, 0x70, 0x65, 0x28, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, + 0x6f, 0x72, 0x20, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x20, 0x69, + 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x73, 0x65, 0x6e, 0x75, 0x6d, + 0x28, 0x66, 0x74, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x74, + 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x74, 0x79, 0x70, 0x65, + 0x64, 0x65, 0x66, 0x28, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x66, + 0x74, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x69, 0x66, + 0x20, 0x74, 0x2e, 0x6b, 0x69, 0x6e, 0x64, 0x3d, 0x3d, 0x22, 0x76, 0x61, + 0x72, 0x22, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x2e, 0x6d, 0x6f, + 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x25, 0x73, 0x22, 0x29, 0x20, 0x6f, + 0x72, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x24, 0x22, 0x29, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, + 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2e, 0x6d, 0x6f, + 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x22, 0x2c, 0x20, 0x22, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x5f, 0x5f, 0x22, 0x2e, 0x2e, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x29, + 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, + 0x72, 0x0a, 0x2d, 0x2d, 0x20, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, + 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6b, 0x69, 0x6e, 0x64, + 0x20, 0x6f, 0x66, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x22, + 0x76, 0x61, 0x72, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x66, 0x75, 0x6e, + 0x63, 0x22, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x73, 0x2c, 0x6b, 0x69, 0x6e, 0x64, 0x2c, 0x69, 0x73, 0x5f, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x29, 0x0a, 0x0a, + 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, + 0x65, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x20, 0x69, 0x66, 0x20, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x64, 0x0a, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x2c, 0x22, 0x25, 0x73, 0x2a, 0x3d, 0x25, 0x73, 0x2a, 0x22, 0x2c, + 0x22, 0x3d, 0x22, 0x29, 0x0a, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, + 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x3c, 0x22, + 0x2c, 0x20, 0x22, 0x3c, 0x22, 0x29, 0x0a, 0x0a, 0x20, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x64, 0x65, 0x66, 0x62, 0x2c, 0x74, 0x6d, 0x70, 0x64, + 0x65, 0x66, 0x0a, 0x20, 0x64, 0x65, 0x66, 0x62, 0x2c, 0x5f, 0x2c, 0x74, + 0x6d, 0x70, 0x64, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x20, 0x22, + 0x28, 0x3d, 0x2e, 0x2a, 0x29, 0x24, 0x22, 0x29, 0x0a, 0x20, 0x69, 0x66, + 0x20, 0x64, 0x65, 0x66, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x3d, 0x2e, 0x2a, + 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x20, 0x09, 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, 0x20, 0x3d, + 0x20, 0x27, 0x27, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, + 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x76, 0x61, + 0x72, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x2d, 0x2d, + 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, + 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x0a, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x6f, + 0x72, 0x20, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, + 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x2c, 0x20, 0x6b, 0x69, 0x6e, + 0x64, 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x2c, 0x20, 0x69, 0x73, + 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x3d, + 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x7d, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x6d, + 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x26, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, + 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, 0x27, 0x25, 0x2a, 0x25, 0x73, + 0x2a, 0x26, 0x27, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, + 0x20, 0x3d, 0x3d, 0x20, 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, 0x20, + 0x27, 0x66, 0x75, 0x6e, 0x63, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x23, 0x69, + 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x73, 0x29, 0x0a, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, + 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, 0x2a, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, + 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, + 0x25, 0x73, 0x2b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x32, 0x5d, 0x2e, 0x2e, 0x74, 0x6d, 0x70, + 0x64, 0x65, 0x66, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x70, 0x74, 0x72, 0x20, + 0x3d, 0x20, 0x27, 0x2a, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x72, 0x65, + 0x74, 0x20, 0x3d, 0x20, 0x27, 0x26, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x2d, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x62, + 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x28, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x20, 0x74, 0x62, + 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x6d, 0x5b, 0x6d, 0x2e, + 0x6e, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x3d, + 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x6d, 0x2c, 0x31, 0x2c, + 0x6d, 0x2e, 0x6e, 0x2d, 0x31, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x69, + 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, + 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, + 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x3a, + 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x2a, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, + 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, + 0x28, 0x73, 0x2c, 0x27, 0x25, 0x2a, 0x25, 0x73, 0x2a, 0x25, 0x2a, 0x27, + 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x20, 0x3d, 0x3d, + 0x20, 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x66, 0x75, + 0x6e, 0x63, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x23, 0x69, 0x6e, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x73, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, 0x5b, + 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, 0x20, + 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x73, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x2b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, + 0x74, 0x5b, 0x32, 0x5d, 0x2e, 0x2e, 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, + 0x2a, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, + 0x20, 0x27, 0x2a, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, + 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x6d, + 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x20, 0x74, 0x62, 0x2c, 0x20, 0x74, + 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x3d, 0x20, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x63, 0x6f, + 0x6e, 0x63, 0x61, 0x74, 0x28, 0x6d, 0x2c, 0x31, 0x2c, 0x6d, 0x2e, 0x6e, + 0x2d, 0x31, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x73, 0x5f, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x69, + 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x6b, + 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x6d, 0x6f, + 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x26, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x0a, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, + 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, 0x27, + 0x26, 0x27, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x20, + 0x3d, 0x3d, 0x20, 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, 0x20, + 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, + 0x25, 0x73, 0x25, 0x73, 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, + 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x74, + 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x2b, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, + 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x32, 0x5d, + 0x2e, 0x2e, 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, 0x26, 0x27, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, + 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x28, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, + 0x20, 0x74, 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x6d, + 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x6f, + 0x64, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x6d, + 0x2c, 0x31, 0x2c, 0x6d, 0x2e, 0x6e, 0x2d, 0x31, 0x29, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, + 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, + 0x7d, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x6d, 0x3a, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x2a, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x73, 0x31, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x2c, 0x22, 0x28, 0x25, 0x62, 0x5c, 0x5b, 0x5c, 0x5d, 0x29, 0x22, + 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6e, + 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x6e, 0x2c, 0x27, 0x25, 0x2a, 0x27, 0x2c, 0x27, 0x5c, 0x31, + 0x27, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x29, 0x0a, 0x20, 0x74, 0x20, 0x3d, + 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x73, 0x28, 0x73, 0x31, 0x2c, 0x27, 0x25, 0x2a, 0x27, 0x29, + 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x20, 0x3d, 0x3d, 0x20, + 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x74, 0x5b, 0x32, + 0x5d, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x5b, 0x32, + 0x5d, 0x2c, 0x27, 0x5c, 0x31, 0x27, 0x2c, 0x27, 0x25, 0x2a, 0x27, 0x29, + 0x20, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, + 0x2a, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, 0x5b, + 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, 0x20, + 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x73, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x2b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, + 0x74, 0x5b, 0x32, 0x5d, 0x2e, 0x2e, 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, + 0x2a, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x20, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x2d, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, + 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x28, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x20, 0x74, + 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, + 0x61, 0x74, 0x28, 0x6d, 0x2c, 0x31, 0x2c, 0x6d, 0x2e, 0x6e, 0x2d, 0x31, + 0x29, 0x20, 0x20, 0x20, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x73, 0x5f, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x3d, 0x20, + 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x20, + 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, + 0x3d, 0x3d, 0x20, 0x27, 0x76, 0x61, 0x72, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x6d, + 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, + 0x69, 0x74, 0x28, 0x73, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x27, + 0x29, 0x0a, 0x20, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, + 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, + 0x2c, 0x27, 0x25, 0x73, 0x2b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x76, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x66, + 0x69, 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x5b, 0x74, 0x2e, + 0x6e, 0x5d, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x76, 0x20, 0x3d, + 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x28, 0x29, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x76, + 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x74, 0x2e, 0x6e, 0x5d, 0x3b, 0x20, 0x74, + 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x74, 0x2e, 0x6e, 0x2d, 0x31, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, + 0x76, 0x2e, 0x2e, 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x72, + 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x28, 0x74, 0x5b, 0x74, 0x2e, 0x6e, 0x5d, 0x2c, 0x20, + 0x74, 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x5b, + 0x74, 0x2e, 0x6e, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, + 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x74, 0x2c, + 0x31, 0x2c, 0x74, 0x2e, 0x6e, 0x2d, 0x31, 0x29, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, 0x6e, + 0x64, 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, + 0x0a, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x2d, 0x2d, 0x20, 0x6b, + 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x66, 0x75, 0x6e, 0x63, + 0x22, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, + 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, + 0x6c, 0x69, 0x74, 0x28, 0x73, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, 0x2a, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, + 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, + 0x73, 0x2c, 0x27, 0x25, 0x73, 0x2b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x74, + 0x2e, 0x6e, 0x5d, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x6c, 0x61, 0x73, 0x74, + 0x20, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, + 0x70, 0x2c, 0x6d, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, + 0x6e, 0x3e, 0x31, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, + 0x74, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x74, 0x2e, 0x6e, 0x2d, 0x31, + 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x64, 0x20, 0x3d, 0x20, 0x63, 0x6f, + 0x6e, 0x63, 0x61, 0x74, 0x28, 0x74, 0x2c, 0x31, 0x2c, 0x74, 0x2e, 0x6e, + 0x2d, 0x32, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, + 0x2d, 0x2d, 0x69, 0x66, 0x20, 0x74, 0x70, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x74, 0x70, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, + 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x74, + 0x70, 0x2c, 0x20, 0x74, 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, + 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x3d, 0x20, 0x76, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x74, 0x70, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6d, + 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x6d, 0x64, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x20, 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, 0x6e, 0x64, + 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, 0x0a, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a +}; +unsigned int lua_declaration_lua_len = 15143; diff --git a/lib/tolua++/src/bin/enumerate_lua.h b/lib/tolua++/src/bin/enumerate_lua.h new file mode 100644 index 000000000..d23c9624a --- /dev/null +++ b/lib/tolua++/src/bin/enumerate_lua.h @@ -0,0 +1,295 @@ +static const unsigned char lua_enumerate_lua[] = { + 0x2d, 0x2d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x3a, 0x20, 0x65, 0x6e, + 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x57, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, + 0x20, 0x62, 0x79, 0x20, 0x57, 0x61, 0x6c, 0x64, 0x65, 0x6d, 0x61, 0x72, + 0x20, 0x43, 0x65, 0x6c, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x65, + 0x43, 0x47, 0x72, 0x61, 0x66, 0x2f, 0x50, 0x55, 0x43, 0x2d, 0x52, 0x69, + 0x6f, 0x0a, 0x2d, 0x2d, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x31, 0x39, 0x39, + 0x38, 0x0a, 0x2d, 0x2d, 0x20, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x65, 0x6e, + 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2e, 0x6c, 0x75, 0x61, 0x2c, + 0x76, 0x20, 0x31, 0x2e, 0x33, 0x20, 0x32, 0x30, 0x30, 0x30, 0x2f, 0x30, + 0x31, 0x2f, 0x32, 0x34, 0x20, 0x32, 0x30, 0x3a, 0x34, 0x31, 0x3a, 0x31, + 0x35, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x20, 0x45, 0x78, 0x70, 0x20, + 0x24, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, + 0x6f, 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, + 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x3b, 0x20, 0x79, 0x6f, + 0x75, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6e, + 0x64, 0x2f, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x20, + 0x69, 0x74, 0x2e, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, + 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x64, 0x20, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6e, 0x64, + 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x20, + 0x22, 0x61, 0x73, 0x20, 0x69, 0x73, 0x22, 0x20, 0x62, 0x61, 0x73, 0x69, + 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x73, + 0x20, 0x6e, 0x6f, 0x20, 0x6f, 0x62, 0x6c, 0x69, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, + 0x65, 0x2c, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2c, 0x20, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x2c, 0x0a, 0x2d, 0x2d, 0x20, + 0x65, 0x6e, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x52, 0x65, 0x70, 0x72, + 0x65, 0x73, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, + 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x64, 0x3a, 0x0a, 0x2d, 0x2d, 0x20, 0x20, 0x20, + 0x20, 0x7b, 0x69, 0x7d, 0x20, 0x3d, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, + 0x6f, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x45, + 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x7b, + 0x0a, 0x7d, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x45, 0x6e, 0x75, 0x6d, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x2e, 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x45, 0x6e, 0x75, + 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x0a, 0x73, 0x65, 0x74, 0x6d, 0x65, + 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2c, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x29, + 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x3a, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x20, 0x28, + 0x70, 0x72, 0x65, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x70, 0x72, 0x65, 0x20, 0x3d, 0x20, 0x70, 0x72, 0x65, 0x20, 0x6f, 0x72, + 0x20, 0x27, 0x27, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, + 0x63, 0x75, 0x72, 0x72, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, + 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5b, 0x69, + 0x5d, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x70, 0x72, 0x65, 0x2e, 0x2e, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x28, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2e, + 0x2e, 0x27, 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x5b, 0x69, 0x5d, 0x2e, 0x2e, + 0x27, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x50, 0x72, + 0x69, 0x6e, 0x74, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x3a, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x20, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2c, + 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x45, 0x6e, + 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x7b, 0x22, 0x29, 0x0a, 0x20, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, + 0x2e, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x22, 0x2e, + 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, + 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x5b, 0x69, + 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x27, 0x22, + 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x5b, 0x69, 0x5d, 0x2e, 0x2e, 0x22, + 0x27, 0x28, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x2e, 0x22, 0x29, 0x2c, + 0x22, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x7d, 0x22, 0x2e, + 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x6d, + 0x69, 0x74, 0x65, 0x6e, 0x75, 0x6d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, + 0x79, 0x70, 0x65, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x69, 0x6e, 0x74, 0x20, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, 0x20, 0x2e, 0x2e, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x74, 0x79, 0x70, 0x65, 0x2c, 0x22, 0x3a, 0x3a, 0x22, 0x2c, 0x22, 0x5f, + 0x22, 0x29, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x20, 0x28, 0x6c, 0x75, 0x61, + 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x20, 0x4c, 0x2c, 0x20, 0x69, + 0x6e, 0x74, 0x20, 0x6c, 0x6f, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x64, + 0x65, 0x66, 0x2c, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x2a, 0x20, 0x65, 0x72, 0x72, 0x29, 0x3b, 0x22, 0x29, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x6e, 0x75, + 0x6d, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, + 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x45, 0x6e, 0x75, + 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x3a, 0x73, 0x75, 0x70, 0x63, 0x6f, + 0x64, 0x65, 0x20, 0x28, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x5f, 0x67, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x20, 0x3d, 0x3d, 0x20, 0x6e, 0x69, 0x6c, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x5f, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, + 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x5d, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x09, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x69, 0x6e, 0x74, 0x20, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x22, 0x3a, 0x3a, + 0x22, 0x2c, 0x22, 0x5f, 0x22, 0x29, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x20, + 0x28, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x20, + 0x4c, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6c, 0x6f, 0x2c, 0x20, 0x69, + 0x6e, 0x74, 0x20, 0x64, 0x65, 0x66, 0x2c, 0x20, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2a, 0x20, 0x65, 0x72, 0x72, + 0x29, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x22, 0x7b, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x22, 0x69, 0x66, 0x20, 0x28, 0x21, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x69, 0x73, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, + 0x4c, 0x2c, 0x6c, 0x6f, 0x2c, 0x64, 0x65, 0x66, 0x2c, 0x65, 0x72, 0x72, + 0x29, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, 0x3b, + 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x22, 0x6c, 0x75, 0x61, 0x5f, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, + 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x4c, 0x2c, 0x6c, + 0x6f, 0x2c, 0x64, 0x65, 0x66, 0x29, 0x3b, 0x22, 0x29, 0x0a, 0x09, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3e, 0x3d, 0x20, 0x22, 0x20, + 0x2e, 0x2e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x69, 0x6e, 0x20, + 0x2e, 0x2e, 0x20, 0x22, 0x2e, 0x30, 0x20, 0x26, 0x26, 0x20, 0x76, 0x61, + 0x6c, 0x20, 0x3c, 0x3d, 0x20, 0x22, 0x20, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6d, 0x61, 0x78, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x2e, 0x30, + 0x3b, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x22, 0x7d, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x6f, 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x5f, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, + 0x28, 0x74, 0x2c, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, + 0x20, 0x73, 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x28, 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x45, 0x6e, 0x75, + 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x29, 0x0a, 0x20, 0x61, 0x70, 0x70, + 0x65, 0x6e, 0x64, 0x28, 0x74, 0x29, 0x0a, 0x20, 0x61, 0x70, 0x70, 0x65, + 0x6e, 0x64, 0x65, 0x6e, 0x75, 0x6d, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x20, + 0x69, 0x66, 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7e, + 0x3d, 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, + 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7e, 0x3d, + 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, + 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x74, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x20, 0x22, 0x2e, 0x2e, 0x76, 0x61, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, + 0x73, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x63, 0x75, 0x72, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, 0x29, 0x0a, 0x09, + 0x09, 0x09, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x28, 0x22, 0x56, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x22, 0x2e, 0x2e, 0x6e, + 0x73, 0x2e, 0x2e, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, + 0x22, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3c, 0x61, + 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x20, 0x65, 0x6e, 0x75, + 0x6d, 0x3e, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, + 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, + 0x6e, 0x6c, 0x79, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x56, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x69, 0x6e, + 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, 0x72, + 0x72, 0x0a, 0x09, 0x20, 0x69, 0x66, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x74, 0x2e, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x5f, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x0a, 0x09, 0x09, + 0x74, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x74, 0x3a, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x28, 0x29, 0x0a, 0x09, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x2d, 0x2d, 0x20, 0x45, 0x78, 0x70, + 0x65, 0x63, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x45, 0x6e, 0x75, 0x6d, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x20, 0x28, 0x6e, 0x2c, 0x62, 0x2c, 0x76, 0x61, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x62, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x62, 0x2c, 0x20, 0x22, 0x2c, 0x5b, 0x25, 0x73, 0x5c, 0x6e, 0x5d, 0x2a, + 0x7d, 0x22, 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x7d, 0x22, 0x29, 0x20, 0x2d, + 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, + 0x6c, 0x61, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x0a, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, + 0x74, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x62, 0x2c, 0x32, + 0x2c, 0x2d, 0x32, 0x29, 0x2c, 0x27, 0x2c, 0x27, 0x29, 0x20, 0x2d, 0x2d, + 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x62, + 0x72, 0x61, 0x63, 0x65, 0x73, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x69, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, 0x7d, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x6d, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, + 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x5b, 0x69, 0x5d, 0x20, 0x64, + 0x6f, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x74, + 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, 0x5b, 0x69, + 0x5d, 0x2c, 0x27, 0x3d, 0x27, 0x29, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x64, + 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x20, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x09, 0x09, 0x65, + 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x65, 0x2e, 0x6e, 0x20, 0x2b, 0x20, 0x31, + 0x0a, 0x09, 0x09, 0x65, 0x5b, 0x65, 0x2e, 0x6e, 0x5d, 0x20, 0x3d, 0x20, + 0x74, 0x74, 0x5b, 0x31, 0x5d, 0x0a, 0x09, 0x09, 0x74, 0x74, 0x5b, 0x32, + 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x28, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x66, + 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x3d, 0x20, 0x6e, 0x69, + 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x74, + 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x20, 0x0a, 0x20, 0x20, 0x09, 0x09, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, + 0x20, 0x2b, 0x20, 0x31, 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x64, 0x76, 0x61, + 0x6e, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x09, + 0x09, 0x69, 0x66, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3e, 0x20, + 0x6d, 0x61, 0x78, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, + 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x74, + 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3c, 0x20, 0x6d, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x20, 0x3d, + 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x09, 0x09, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x73, 0x65, 0x74, 0x20, + 0x6c, 0x75, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x0a, 0x09, 0x69, + 0x20, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x65, 0x2e, 0x6c, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, + 0x63, 0x75, 0x72, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x28, 0x29, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x65, + 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, + 0x28, 0x65, 0x5b, 0x69, 0x5d, 0x2c, 0x27, 0x40, 0x27, 0x29, 0x0a, 0x09, + 0x09, 0x65, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x31, 0x5d, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, 0x5b, + 0x32, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x74, + 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x72, + 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x28, 0x74, 0x5b, 0x31, 0x5d, + 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x2e, + 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, + 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x5b, 0x31, 0x5d, + 0x0a, 0x09, 0x09, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x65, + 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x20, 0x6e, 0x73, 0x2e, 0x2e, 0x65, 0x5b, + 0x69, 0x5d, 0x20, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x6e, 0x73, 0x2e, 0x2e, + 0x65, 0x5b, 0x69, 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x20, 0x3d, 0x20, + 0x69, 0x2b, 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x6e, 0x0a, 0x09, 0x65, 0x2e, + 0x6d, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x6d, 0x69, 0x6e, 0x0a, 0x09, 0x65, + 0x2e, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x78, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x6e, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x22, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, + 0x5b, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, + 0x09, 0x54, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x28, 0x22, 0x69, 0x6e, + 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x6e, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x45, 0x6e, + 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x28, 0x65, 0x2c, 0x20, 0x76, + 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a +}; +unsigned int lua_enumerate_lua_len = 3493; diff --git a/lib/tolua++/src/bin/function_lua.h b/lib/tolua++/src/bin/function_lua.h new file mode 100644 index 000000000..b34f106d2 --- /dev/null +++ b/lib/tolua++/src/bin/function_lua.h @@ -0,0 +1,1211 @@ +static const unsigned char lua_function_lua[] = { + 0x2d, 0x2d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x0a, 0x2d, 0x2d, 0x20, 0x57, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, + 0x62, 0x79, 0x20, 0x57, 0x61, 0x6c, 0x64, 0x65, 0x6d, 0x61, 0x72, 0x20, + 0x43, 0x65, 0x6c, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x65, 0x43, + 0x47, 0x72, 0x61, 0x66, 0x2f, 0x50, 0x55, 0x43, 0x2d, 0x52, 0x69, 0x6f, + 0x0a, 0x2d, 0x2d, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x31, 0x39, 0x39, 0x38, + 0x0a, 0x2d, 0x2d, 0x20, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x24, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x64, 0x65, + 0x20, 0x69, 0x73, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, 0x73, 0x6f, 0x66, + 0x74, 0x77, 0x61, 0x72, 0x65, 0x3b, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x63, + 0x61, 0x6e, 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x2f, 0x6f, + 0x72, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x20, 0x69, 0x74, 0x2e, + 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x66, 0x74, + 0x77, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x64, 0x20, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20, + 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x61, 0x73, + 0x20, 0x69, 0x73, 0x22, 0x20, 0x62, 0x61, 0x73, 0x69, 0x73, 0x2c, 0x20, + 0x61, 0x6e, 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x73, 0x20, 0x6e, 0x6f, + 0x20, 0x6f, 0x62, 0x6c, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x6d, + 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x2c, 0x20, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2c, 0x20, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x73, 0x2c, 0x0a, 0x2d, 0x2d, 0x20, 0x65, 0x6e, 0x68, + 0x61, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x6f, + 0x72, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x46, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x52, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, + 0x6e, 0x74, 0x73, 0x20, 0x61, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x2e, 0x0a, 0x2d, 0x2d, + 0x20, 0x54, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, + 0x6e, 0x67, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x20, 0x61, 0x72, + 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x3a, 0x0a, 0x2d, 0x2d, + 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x20, 0x3d, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x0a, + 0x2d, 0x2d, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x20, 0x70, 0x74, 0x72, 0x20, + 0x20, 0x3d, 0x20, 0x22, 0x2a, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x26, + 0x22, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, + 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, + 0x2d, 0x2d, 0x20, 0x20, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, + 0x6c, 0x75, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x2d, 0x2d, 0x20, + 0x20, 0x61, 0x72, 0x67, 0x73, 0x20, 0x20, 0x3d, 0x20, 0x6c, 0x69, 0x73, + 0x74, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x20, 0x3d, 0x20, 0x69, 0x66, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, + 0x61, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x20, 0x72, 0x65, 0x63, + 0x65, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x20, 0x22, 0x74, 0x68, 0x69, 0x73, 0x22, 0x2e, 0x0a, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, + 0x27, 0x27, 0x2c, 0x0a, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, + 0x27, 0x27, 0x2c, 0x0a, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, + 0x27, 0x2c, 0x0a, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, + 0x27, 0x2c, 0x0a, 0x20, 0x61, 0x72, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x7b, + 0x6e, 0x3d, 0x30, 0x7d, 0x2c, 0x0a, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x20, 0x3d, 0x20, 0x27, 0x27, 0x2c, 0x0a, 0x7d, 0x0a, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x5f, + 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x73, + 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x29, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x63, 0x6c, + 0x61, 0x72, 0x65, 0x20, 0x74, 0x61, 0x67, 0x73, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x64, 0x65, 0x63, 0x6c, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x28, 0x29, 0x0a, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x76, 0x61, 0x72, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x66, + 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, + 0x2c, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x27, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, + 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x20, + 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6d, 0x6f, 0x64, 0x2c, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x27, 0x2c, + 0x27, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x77, 0x68, 0x69, + 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, + 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x64, 0x65, + 0x63, 0x6c, 0x74, 0x79, 0x70, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x69, + 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x57, 0x72, 0x69, + 0x74, 0x65, 0x20, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x2d, 0x2d, 0x20, 0x4f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x20, 0x43, 0x2f, 0x43, 0x2b, 0x2b, + 0x20, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x73, 0x75, 0x70, 0x63, 0x6f, 0x64, + 0x65, 0x20, 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x29, 0x0a, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, + 0x64, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x2d, 0x32, + 0x2c, 0x2d, 0x31, 0x29, 0x20, 0x2d, 0x20, 0x31, 0x20, 0x20, 0x2d, 0x2d, + 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x6f, 0x76, + 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x72, 0x65, + 0x74, 0x20, 0x3d, 0x20, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, + 0x2d, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x3a, + 0x69, 0x6e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x28, 0x29, 0x0a, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x63, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x27, + 0x5e, 0x25, 0x73, 0x2a, 0x28, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x29, + 0x27, 0x29, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x6e, + 0x75, 0x6d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, + 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, + 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, + 0x31, 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, + 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x69, 0x73, 0x65, 0x6e, + 0x75, 0x6d, 0x74, 0x79, 0x70, 0x65, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6d, 0x69, 0x74, 0x65, 0x6e, 0x75, 0x6d, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, + 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x69, + 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x20, 0x09, + 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x2e, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x70, 0x75, 0x72, 0x65, + 0x5f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x6e, 0x6f, 0x20, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x20, 0x70, 0x75, 0x72, 0x65, 0x20, 0x76, 0x69, 0x72, + 0x74, 0x75, 0x61, 0x6c, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, + 0x0a, 0x20, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x2f, 0x2a, 0x20, 0x6d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3a, 0x20, 0x6e, 0x65, 0x77, 0x5f, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x20, 0x22, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2c, 0x22, 0x20, + 0x2a, 0x2f, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, + 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x2f, 0x2a, 0x20, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3a, 0x22, 0x2c, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x22, 0x20, 0x6f, 0x66, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x22, 0x2c, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x2c, 0x22, 0x20, 0x2a, 0x2f, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x2f, 0x2a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x22, 0x20, 0x2a, 0x2f, 0x22, 0x29, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x23, 0x69, 0x66, 0x6e, + 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, + 0x53, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x5f, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x22, 0x5c, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x20, 0x69, 0x6e, 0x74, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x5f, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x22, 0x2c, 0x22, 0x28, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, + 0x29, 0x22, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x23, 0x69, 0x66, 0x6e, + 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, + 0x53, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x5c, 0x6e, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x63, 0x20, 0x69, 0x6e, 0x74, 0x22, 0x2c, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x22, 0x28, 0x6c, 0x75, + 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x20, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x53, 0x29, 0x22, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x7b, 0x22, + 0x29, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, + 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x3c, 0x20, 0x30, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, + 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, + 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x65, 0x72, 0x72, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x69, 0x66, 0x20, 0x28, 0x5c, + 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6e, 0x61, + 0x72, 0x67, 0x3d, 0x32, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x6e, 0x61, + 0x72, 0x67, 0x3d, 0x31, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, + 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x69, + 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, + 0x3d, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x7e, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, + 0x20, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x75, 0x73, + 0x65, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x27, 0x0a, 0x09, 0x09, 0x09, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, + 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x27, 0x2e, 0x2e, 0x66, + 0x75, 0x6e, 0x63, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x53, 0x2c, 0x31, 0x2c, 0x22, 0x27, 0x2e, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x2e, 0x2e, 0x27, 0x22, 0x2c, 0x30, 0x2c, 0x26, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x20, 0x7c, 0x7c, 0x5c, 0x6e, + 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x2d, 0x2d, 0x20, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x61, 0x72, 0x67, 0x73, 0x0a, 0x20, + 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, + 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, + 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, + 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, + 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, + 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x62, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x62, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, + 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x6f, 0x75, 0x74, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x74, 0x79, 0x70, 0x65, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, + 0x2e, 0x2e, 0x27, 0x20, 0x7c, 0x7c, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x62, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, + 0x20, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, + 0x67, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x2d, 0x2d, + 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x6f, + 0x66, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x6e, 0x6f, 0x6f, 0x62, 0x6a, 0x28, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, + 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x5c, 0x6e, 0x20, 0x29, 0x27, 0x29, + 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x67, 0x6f, 0x74, 0x6f, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6c, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3b, 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x65, 0x6c, 0x73, 0x65, + 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x76, 0x65, + 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x3c, 0x20, 0x30, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x7b, 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, + 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2c, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, 0x73, + 0x65, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x61, 0x72, + 0x67, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, 0x20, + 0x65, 0x6c, 0x73, 0x65, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x7e, 0x3d, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x3d, 0x3d, 0x6e, + 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2c, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x2c, 0x27, 0x2a, 0x27, 0x2c, 0x27, 0x73, 0x65, 0x6c, 0x66, 0x20, 0x3d, + 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x2a, 0x29, + 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, + 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, + 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x31, + 0x2c, 0x30, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, + 0x69, 0x66, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, + 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, + 0x2c, 0x27, 0x5e, 0x25, 0x73, 0x2a, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x25, 0x73, 0x25, 0x73, 0x2a, 0x28, 0x2e, 0x2a, 0x29, 0x27, 0x29, 0x0a, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x63, + 0x6c, 0x61, 0x72, 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, + 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x64, 0x65, 0x63, + 0x6c, 0x61, 0x72, 0x65, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, + 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x7e, 0x3d, 0x20, 0x22, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, + 0x61, 0x72, 0x67, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x7e, 0x3d, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x3d, 0x3d, 0x6e, 0x69, + 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, + 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, + 0x53, 0x45, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, + 0x73, 0x65, 0x6c, 0x66, 0x29, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x53, 0x2c, 0x22, 0x27, 0x2e, 0x2e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, + 0x22, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x5c, 0x27, 0x73, + 0x65, 0x6c, 0x66, 0x5c, 0x27, 0x20, 0x69, 0x6e, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5c, 0x27, 0x25, 0x73, 0x5c, 0x27, + 0x22, 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x29, 0x2e, 0x2e, 0x27, 0x22, 0x2c, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x29, + 0x3b, 0x27, 0x29, 0x3b, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, + 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, + 0x67, 0x65, 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x65, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, + 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, 0x20, 0x65, + 0x6c, 0x73, 0x65, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, + 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x67, 0x65, 0x74, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, + 0x67, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, + 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x20, 0x70, 0x72, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x29, 0x0a, + 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x75, 0x74, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, + 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x75, 0x74, 0x73, 0x69, + 0x64, 0x65, 0x22, 0x29, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, + 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, + 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, + 0x27, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x20, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x64, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x29, 0x3b, 0x27, 0x29, + 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x26, 0x5b, 0x5d, 0x27, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, + 0x73, 0x5b, 0x27, 0x31, 0x27, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, + 0x2d, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x74, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x35, 0x20, 0x3f, 0x0a, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2d, 0x3e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x5b, 0x5d, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, + 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, + 0x2d, 0x31, 0x29, 0x20, 0x3d, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x32, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x2c, 0x27, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x3e, 0x6f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5b, 0x5d, 0x28, 0x27, 0x2c, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x29, 0x20, 0x3d, 0x20, 0x27, 0x2c, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x32, 0x5d, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x3b, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2c, + 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x20, 0x3d, + 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, + 0x6f, 0x64, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2c, 0x27, 0x29, + 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, + 0x6e, 0x65, 0x77, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x4d, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x65, 0x77, 0x28, 0x28, 0x27, 0x2c, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x29, 0x28, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x69, + 0x66, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x2e, 0x27, 0x3a, 0x3a, + 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, + 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x09, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x09, + 0x2d, 0x2d, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x5f, 0x63, 0x61, 0x73, 0x74, 0x3c, 0x27, 0x2c, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x70, 0x74, 0x72, 0x2c, 0x27, 0x20, 0x3e, 0x28, 0x2a, 0x73, 0x65, 0x6c, + 0x66, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x3e, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6d, 0x6f, 0x64, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x3e, 0x27, 0x2e, 0x2e, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, + 0x0a, 0x09, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6f, 0x75, 0x74, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x63, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, 0x65, 0x6c, 0x66, + 0x27, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x77, + 0x72, 0x69, 0x74, 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, + 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x70, 0x61, 0x73, 0x73, + 0x70, 0x61, 0x72, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, + 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x3d, 0x3d, 0x20, 0x27, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x5b, 0x5d, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x6c, 0x61, 0x67, + 0x73, 0x5b, 0x27, 0x31, 0x27, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x2d, 0x31, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, + 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x29, 0x29, 0x3b, + 0x27, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x20, + 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x65, 0x77, 0x28, 0x0a, + 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x2d, + 0x2d, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x72, 0x65, + 0x74, 0x20, 0x3d, 0x20, 0x6e, 0x72, 0x65, 0x74, 0x20, 0x2b, 0x20, 0x31, + 0x0a, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, + 0x63, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7e, 0x3d, + 0x20, 0x22, 0x6e, 0x65, 0x77, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x20, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x63, 0x61, 0x73, 0x74, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, + 0x5f, 0x72, 0x61, 0x77, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5b, 0x74, 0x5d, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x5f, 0x62, 0x61, + 0x73, 0x69, 0x63, 0x5f, 0x72, 0x61, 0x77, 0x5f, 0x70, 0x75, 0x73, 0x68, + 0x5b, 0x74, 0x5d, 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x53, 0x2c, 0x28, 0x27, 0x2c, 0x63, 0x74, 0x2c, 0x27, 0x29, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x29, 0x3b, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x20, 0x20, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x27, + 0x2e, 0x2e, 0x74, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x53, 0x2c, 0x28, 0x27, 0x2c, 0x63, 0x74, 0x2c, 0x27, 0x29, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x29, 0x3b, 0x27, 0x29, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x09, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x6e, 0x65, 0x77, 0x5f, 0x74, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x74, 0x2c, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x25, + 0x73, 0x2b, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x20, 0x3d, 0x20, + 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x22, 0x29, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x20, + 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x75, + 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, + 0x74, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, + 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x20, 0x7b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, + 0x66, 0x20, 0x5f, 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, + 0x73, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x6f, 0x69, 0x64, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, + 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x6e, 0x65, 0x77, 0x28, 0x28, 0x27, 0x2c, 0x6e, 0x65, 0x77, 0x5f, 0x74, + 0x2c, 0x27, 0x29, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, + 0x74, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, + 0x27, 0x2c, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, + 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x2c, 0x22, 0x27, 0x2c, 0x74, + 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, + 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x5f, 0x67, 0x63, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x53, 0x2c, 0x6c, 0x75, 0x61, 0x5f, 0x67, 0x65, 0x74, 0x74, 0x6f, + 0x70, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x29, 0x3b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x2a, + 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x20, 0x3d, + 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x28, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x76, 0x6f, 0x69, + 0x64, 0x2a, 0x29, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, + 0x74, 0x2c, 0x73, 0x69, 0x7a, 0x65, 0x6f, 0x66, 0x28, 0x27, 0x2c, 0x74, + 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, + 0x20, 0x27, 0x2c, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, + 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x2c, 0x22, 0x27, 0x2c, + 0x74, 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x20, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x5f, 0x67, 0x63, 0x28, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x53, 0x2c, 0x6c, 0x75, 0x61, 0x5f, 0x67, 0x65, 0x74, 0x74, + 0x6f, 0x70, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, + 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x7d, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, + 0x26, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, + 0x27, 0x2c, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, + 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x76, + 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x72, 0x65, 0x74, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x22, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, + 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x20, 0x27, 0x2c, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, + 0x63, 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, + 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x72, 0x65, 0x74, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x22, + 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x69, 0x66, 0x20, 0x6f, 0x77, + 0x6e, 0x65, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x5f, 0x67, 0x63, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x53, 0x2c, 0x6c, 0x75, 0x61, 0x5f, 0x67, 0x65, 0x74, 0x74, 0x6f, 0x70, + 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x29, 0x3b, 0x27, + 0x29, 0x0a, 0x09, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, + 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x72, 0x65, 0x74, + 0x20, 0x3d, 0x20, 0x6e, 0x72, 0x65, 0x74, 0x20, 0x2b, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x72, + 0x65, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x20, 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x2d, + 0x20, 0x73, 0x65, 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x65, + 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x77, + 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, + 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, + 0x5d, 0x3a, 0x73, 0x65, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x28, 0x6e, + 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x72, + 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x2b, 0x31, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, 0x64, + 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x61, + 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 0x72, 0x72, + 0x61, 0x79, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, + 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, + 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, + 0x66, 0x72, 0x65, 0x65, 0x61, 0x72, 0x72, 0x61, 0x79, 0x28, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, + 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x70, 0x6f, 0x73, 0x74, + 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x29, 0x0a, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x27, 0x2e, 0x2e, 0x6e, 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x27, 0x3b, + 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, + 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x72, 0x20, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, + 0x6f, 0x61, 0x64, 0x20, 0x3c, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, 0x55, + 0x41, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, 0x6e, 0x27, + 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6c, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x3a, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, + 0x2c, 0x22, 0x27, 0x2e, 0x2e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x22, + 0x23, 0x66, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5c, 0x27, 0x25, 0x73, + 0x5c, 0x27, 0x2e, 0x22, 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, + 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x2e, 0x2e, 0x27, 0x22, 0x2c, 0x26, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x3b, 0x27, 0x29, + 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, 0x3b, 0x27, 0x29, 0x0a, + 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, + 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, + 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, + 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x3d, 0x20, 0x22, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6c, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x27, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x31, 0x2c, 0x2d, 0x33, 0x29, 0x2e, 0x2e, 0x66, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x28, 0x22, 0x25, 0x30, 0x32, 0x64, 0x22, 0x2c, 0x6f, 0x76, + 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x29, 0x2e, 0x2e, 0x5f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x53, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x7d, 0x27, 0x29, + 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, + 0x6e, 0x64, 0x69, 0x66, 0x20, 0x2f, 0x2f, 0x23, 0x69, 0x66, 0x6e, 0x64, + 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, 0x53, + 0x41, 0x42, 0x4c, 0x45, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x0a, + 0x09, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, + 0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x72, + 0x69, 0x74, 0x65, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x09, 0x69, + 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, + 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x73, 0x75, 0x70, 0x63, + 0x6f, 0x64, 0x65, 0x28, 0x31, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x20, + 0x28, 0x70, 0x72, 0x65, 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, + 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, + 0x70, 0x75, 0x72, 0x65, 0x5f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x09, 0x2d, 0x2d, 0x20, + 0x6e, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x6f, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x65, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x70, 0x75, 0x72, 0x65, + 0x20, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x73, 0x0a, 0x20, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x0a, 0x20, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x70, 0x72, 0x65, 0x2e, 0x2e, 0x27, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, + 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, + 0x65, 0x2e, 0x2e, 0x27, 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x29, 0x3b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x65, + 0x77, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x70, 0x72, 0x65, 0x2e, 0x2e, 0x27, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, + 0x6e, 0x65, 0x77, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x2c, 0x27, + 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, + 0x2e, 0x2e, 0x27, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, 0x3b, 0x27, + 0x29, 0x0a, 0x09, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x70, 0x72, 0x65, 0x2e, 0x2e, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x22, + 0x2c, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, + 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x20, 0x2d, 0x2d, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x73, 0x65, 0x74, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, + 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, + 0x2e, 0x2e, 0x27, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2c, 0x20, 0x22, + 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x27, 0x22, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, + 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2c, 0x63, 0x6c, 0x6f, 0x73, 0x65, + 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x7b, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6d, 0x6f, 0x64, + 0x20, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6d, 0x6f, 0x64, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, + 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x2e, 0x2e, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, + 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, + 0x70, 0x74, 0x72, 0x20, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2e, 0x2e, 0x22, 0x27, 0x2c, + 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, + 0x2e, 0x22, 0x20, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, + 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, + 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, + 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, + 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2e, + 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x63, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, + 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6c, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, + 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x61, 0x72, 0x67, 0x73, 0x20, + 0x3d, 0x20, 0x7b, 0x22, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, + 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, + 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x20, 0x22, + 0x2c, 0x22, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, + 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, + 0x20, 0x7d, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x7d, 0x22, 0x2e, 0x2e, + 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x69, 0x66, 0x20, + 0x69, 0x74, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, + 0x6e, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x62, 0x79, 0x20, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x74, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x20, + 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, + 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x3d, 0x3d, 0x27, 0x27, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x22, + 0x25, 0x73, 0x2a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2b, 0x22, + 0x2c, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x20, 0x74, 0x5b, 0x74, 0x79, 0x70, + 0x65, 0x5d, 0x20, 0x3d, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x5f, 0x22, 0x20, 0x2e, 0x2e, + 0x20, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x20, + 0x72, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, + 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, + 0x09, 0x09, 0x72, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, + 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x72, 0x0a, 0x09, 0x09, 0x69, + 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, + 0x69, 0x6e, 0x65, 0x20, 0x6c, 0x75, 0x61, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x76, + 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, + 0x61, 0x64, 0x20, 0x28, 0x29, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x3a, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x28, 0x70, 0x61, 0x72, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x74, 0x72, 0x75, 0x65, 0x20, + 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x20, + 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x61, 0x73, 0x20, 0x69, 0x74, + 0x73, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, + 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x27, 0x3d, 0x27, 0x29, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x61, 0x6c, 0x73, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x20, + 0x69, 0x74, 0x20, 0x68, 0x61, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, + 0x64, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, + 0x3d, 0x28, 0x2e, 0x2a, 0x29, 0x24, 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x69, + 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x7c, 0x22, 0x29, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x20, 0x6c, 0x69, + 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x0a, + 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, + 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, + 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x25, 0x2a, 0x22, 0x29, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x69, 0x74, 0x27, 0x73, + 0x20, 0x61, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x0a, 0x09, 0x09, 0x69, + 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x27, 0x3d, 0x25, 0x73, 0x2a, + 0x6e, 0x65, 0x77, 0x27, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, 0x72, + 0x2c, 0x20, 0x22, 0x25, 0x28, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x2d, 0x2d, 0x20, 0x69, 0x74, 0x27, 0x73, 0x20, 0x61, 0x20, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, + 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, + 0x61, 0x73, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x2e, 0x20, 0x69, + 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x3f, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, + 0x65, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x27, 0x4e, + 0x55, 0x4c, 0x4c, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, + 0x74, 0x68, 0x69, 0x6e, 0x67, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x5b, + 0x25, 0x28, 0x26, 0x5d, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, + 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, + 0x69, 0x73, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x6f, 0x72, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x28, 0x6d, + 0x6f, 0x73, 0x74, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x6c, 0x79, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x29, 0x0a, 0x0a, 0x09, + 0x2d, 0x2d, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x26, + 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, + 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, + 0x69, 0x6e, 0x64, 0x28, 0x64, 0x65, 0x66, 0x2c, 0x20, 0x22, 0x3a, 0x22, + 0x29, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x66, 0x69, 0x6e, 0x64, 0x28, 0x64, 0x65, 0x66, 0x2c, 0x20, 0x22, 0x5e, + 0x25, 0x73, 0x2a, 0x6e, 0x65, 0x77, 0x25, 0x73, 0x2b, 0x22, 0x29, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x09, 0x2d, + 0x2d, 0x20, 0x69, 0x74, 0x27, 0x73, 0x20, 0x61, 0x20, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x73, + 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x6c, 0x69, 0x6b, + 0x65, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3a, 0x3a, 0x6d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x27, 0x6e, 0x65, 0x77, + 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x0a, 0x09, 0x2d, 0x2d, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, + 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x2d, 0x2d, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x20, 0x2d, 0x2d, 0x20, 0x3f, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x5f, 0x6c, 0x61, 0x73, 0x74, + 0x5f, 0x61, 0x72, 0x67, 0x28, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, + 0x73, 0x2c, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x29, + 0x20, 0x2d, 0x2d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x5f, 0x2c, 0x5f, 0x2c, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x2c, 0x20, 0x22, 0x5e, + 0x28, 0x5b, 0x5e, 0x3d, 0x5d, 0x2b, 0x29, 0x22, 0x29, 0x0a, 0x09, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x6c, 0x61, + 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x2c, 0x20, 0x22, 0x28, 0x5b, 0x25, + 0x25, 0x25, 0x28, 0x25, 0x29, 0x5d, 0x29, 0x22, 0x2c, 0x20, 0x22, 0x25, + 0x25, 0x25, 0x31, 0x22, 0x29, 0x3b, 0x0a, 0x09, 0x61, 0x6c, 0x6c, 0x5f, + 0x61, 0x72, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x61, 0x6c, 0x6c, 0x5f, 0x61, + 0x72, 0x67, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x2c, 0x25, 0x73, + 0x2a, 0x22, 0x2e, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, + 0x2e, 0x2e, 0x22, 0x25, 0x73, 0x2a, 0x25, 0x29, 0x25, 0x73, 0x2a, 0x24, + 0x22, 0x2c, 0x20, 0x22, 0x29, 0x22, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, 0x73, + 0x2c, 0x20, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x6f, 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x5f, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, + 0x29, 0x0a, 0x20, 0x73, 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x28, 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x0a, 0x20, 0x69, 0x66, + 0x20, 0x74, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, 0x20, + 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x74, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, 0x20, 0x27, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x28, 0x22, 0x23, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x20, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x27, 0x20, 0x73, 0x70, 0x65, + 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, + 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x74, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x61, 0x70, 0x70, + 0x65, 0x6e, 0x64, 0x28, 0x74, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, + 0x3a, 0x69, 0x6e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x28, 0x29, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x2d, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x20, 0x28, 0x27, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x69, 0x73, + 0x20, 0x27, 0x2e, 0x2e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, + 0x27, 0x2c, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x69, 0x73, 0x20, 0x27, 0x2e, 0x2e, 0x74, 0x2e, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x20, 0x22, 0x25, 0x62, 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, + 0x20, 0x3d, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, + 0x73, 0x75, 0x62, 0x28, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x2e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x25, 0x62, + 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x74, + 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x6e, 0x65, + 0x77, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x2e, 0x5f, 0x6e, 0x65, 0x77, 0x20, 0x3d, 0x20, 0x74, 0x72, + 0x75, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x70, 0x74, + 0x72, 0x20, 0x3d, 0x20, 0x27, 0x2a, 0x27, 0x0a, 0x20, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x20, 0x22, 0x25, 0x62, 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, + 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x7e, 0x27, 0x2e, 0x2e, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2e, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, + 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x74, + 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x20, 0x22, 0x25, 0x62, 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, + 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x64, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x6c, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x27, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x2e, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x3d, 0x20, + 0x74, 0x72, 0x75, 0x65, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x74, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x3d, 0x20, 0x74, 0x3a, 0x63, 0x66, 0x75, 0x6e, 0x63, 0x6e, 0x61, + 0x6d, 0x65, 0x28, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x22, 0x29, 0x2e, + 0x2e, 0x74, 0x3a, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x28, + 0x74, 0x29, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, + 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x2d, 0x2d, 0x20, + 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x73, 0x20, 0x74, 0x68, 0x72, 0x65, + 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x3a, 0x20, 0x6f, + 0x6e, 0x65, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x6e, 0x6f, + 0x74, 0x68, 0x65, 0x72, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, + 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x2c, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x69, + 0x72, 0x64, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, + 0x69, 0x6e, 0x67, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x22, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x46, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x61, 0x2c, 0x63, + 0x29, 0x0a, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, + 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x73, 0x74, 0x72, + 0x73, 0x75, 0x62, 0x28, 0x61, 0x2c, 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x2c, + 0x27, 0x2c, 0x27, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, + 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x62, 0x72, 0x61, 0x63, 0x65, 0x73, + 0x0a, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, + 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x61, 0x2c, + 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5b, 0x27, 0x57, 0x27, + 0x5d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x61, 0x2c, 0x20, 0x22, 0x25, 0x2e, + 0x25, 0x2e, 0x25, 0x2e, 0x25, 0x73, 0x2a, 0x25, 0x29, 0x22, 0x29, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x09, 0x77, 0x61, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x28, 0x22, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x76, 0x61, 0x72, 0x69, + 0x61, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x20, 0x28, 0x60, 0x2e, 0x2e, 0x2e, 0x27, 0x29, 0x20, 0x61, + 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x2e, 0x20, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x69, + 0x6e, 0x67, 0x20, 0x22, 0x2e, 0x2e, 0x64, 0x2e, 0x2e, 0x61, 0x2e, 0x2e, + 0x63, 0x29, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x69, 0x6c, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, + 0x30, 0x7d, 0x0a, 0x0a, 0x20, 0x09, 0x61, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x61, 0x2c, + 0x20, 0x22, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x25, 0x28, 0x25, 0x29, 0x5d, + 0x29, 0x25, 0x73, 0x2a, 0x22, 0x2c, 0x20, 0x22, 0x25, 0x31, 0x22, 0x29, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, 0x73, 0x74, + 0x72, 0x69, 0x70, 0x2c, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x70, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x28, 0x73, 0x74, + 0x72, 0x73, 0x75, 0x62, 0x28, 0x61, 0x2c, 0x32, 0x2c, 0x2d, 0x32, 0x29, + 0x29, 0x3b, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, 0x74, 0x72, 0x73, + 0x75, 0x62, 0x28, 0x61, 0x2c, 0x31, 0x2c, 0x2d, 0x32, 0x29, 0x2c, 0x20, + 0x31, 0x2c, 0x20, 0x2d, 0x28, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x6c, 0x65, 0x6e, 0x28, 0x6c, 0x61, 0x73, 0x74, 0x29, 0x2b, 0x31, 0x29, + 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x73, + 0x20, 0x3d, 0x20, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x74, 0x2c, 0x20, 0x22, + 0x2c, 0x22, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x2d, + 0x31, 0x29, 0x0a, 0x0a, 0x09, 0x09, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x22, + 0x28, 0x22, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, + 0x73, 0x75, 0x62, 0x28, 0x6e, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, + 0x2c, 0x25, 0x73, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x2e, + 0x2e, 0x27, 0x29, 0x27, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x6e, 0x73, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x5f, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x73, 0x28, 0x6e, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x46, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x64, 0x2c, 0x20, 0x6e, 0x73, + 0x2c, 0x20, 0x63, 0x29, 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, + 0x3d, 0x31, 0x2c, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x64, 0x6f, 0x0a, 0x09, + 0x09, 0x09, 0x74, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x5b, 0x69, + 0x5d, 0x2c, 0x20, 0x22, 0x3d, 0x2e, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, + 0x22, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x5b, + 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x6c, 0x2e, 0x6e, 0x20, + 0x3d, 0x20, 0x6c, 0x2e, 0x6e, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x6c, 0x5b, + 0x6c, 0x2e, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x44, 0x65, 0x63, 0x6c, 0x61, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, + 0x27, 0x76, 0x61, 0x72, 0x27, 0x2c, 0x74, 0x72, 0x75, 0x65, 0x29, 0x0a, + 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, + 0x3d, 0x20, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x64, 0x2c, 0x27, 0x66, 0x75, 0x6e, 0x63, 0x27, 0x29, 0x0a, + 0x20, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x6c, 0x0a, + 0x20, 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x63, + 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x46, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x66, 0x29, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x74, 0x2c, 0x20, 0x73, 0x65, 0x70, 0x2c, + 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2c, 0x20, 0x6c, 0x61, 0x73, 0x74, + 0x29, 0x0a, 0x0a, 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x3d, 0x20, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x31, 0x0a, 0x09, + 0x6c, 0x61, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, + 0x6f, 0x72, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x74, + 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x6c, 0x73, 0x65, 0x70, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x22, + 0x22, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x6f, 0x6f, + 0x70, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x66, + 0x6f, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, + 0x2c, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x64, 0x6f, 0x0a, 0x0a, 0x09, 0x09, + 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x6c, + 0x73, 0x65, 0x70, 0x2e, 0x2e, 0x74, 0x5b, 0x69, 0x5d, 0x0a, 0x09, 0x09, + 0x6c, 0x73, 0x65, 0x70, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x70, 0x0a, 0x09, + 0x09, 0x6c, 0x6f, 0x6f, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x6c, 0x6f, 0x6f, 0x70, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, 0x22, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x72, 0x65, 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x70, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x28, 0x73, 0x29, 0x0a, 0x0a, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, + 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, + 0x28, 0x73, 0x2c, 0x20, 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x3d, 0x20, + 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x6c, 0x61, 0x73, 0x74, 0x0a, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, + 0x69, 0x3d, 0x74, 0x2e, 0x6e, 0x2c, 0x31, 0x2c, 0x2d, 0x31, 0x20, 0x64, + 0x6f, 0x0a, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x74, + 0x5b, 0x69, 0x5d, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, + 0x09, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x0a, 0x09, 0x09, + 0x09, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, + 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x2d, 0x2d, + 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x09, 0x74, 0x5b, 0x69, 0x5d, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, 0x20, 0x22, 0x3d, 0x2e, 0x2a, + 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x2d, 0x2d, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2c, 0x73, 0x74, 0x72, 0x69, + 0x70, 0x2c, 0x6c, 0x61, 0x73, 0x74, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x70, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, + 0x28, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, + 0x20, 0x22, 0x5e, 0x25, 0x28, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, + 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x29, 0x24, + 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, + 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, + 0x20, 0x22, 0x2c, 0x22, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x73, 0x65, 0x70, 0x2c, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, + 0x22, 0x22, 0x2c, 0x22, 0x22, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, + 0x3d, 0x31, 0x2c, 0x74, 0x2e, 0x6e, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, + 0x74, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, + 0x20, 0x22, 0x3d, 0x2e, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, + 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x74, + 0x2e, 0x2e, 0x73, 0x65, 0x70, 0x2e, 0x2e, 0x74, 0x5b, 0x69, 0x5d, 0x0a, + 0x09, 0x09, 0x73, 0x65, 0x70, 0x20, 0x3d, 0x20, 0x22, 0x2c, 0x22, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x22, 0x28, 0x22, 0x2e, 0x2e, 0x72, 0x65, 0x74, 0x2e, 0x2e, + 0x22, 0x29, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a +}; +unsigned int lua_function_lua_len = 14494; diff --git a/lib/tolua++/src/bin/lua/basic.lua b/lib/tolua++/src/bin/lua/basic.lua index f651f1fe6..4bff5276b 100644 --- a/lib/tolua++/src/bin/lua/basic.lua +++ b/lib/tolua++/src/bin/lua/basic.lua @@ -23,6 +23,7 @@ _basic = { ['unsigned'] = 'number', ['float'] = 'number', ['double'] = 'number', + ['size_t'] = 'number', ['_cstring'] = 'string', ['_userdata'] = 'userdata', ['char*'] = 'string', @@ -66,6 +67,8 @@ _global_enums = {} -- List of auto renaming _renaming = {} + +_enums = {} function appendrenaming (s) local b,e,old,new = strfind(s,"%s*(.-)%s*@%s*(.-)%s*$") if not b then @@ -145,6 +148,11 @@ function typevar(type) end end +-- is enum +function isenumtype (type) + return _enums[type] +end + -- check if basic type function isbasic (type) local t = gsub(type,'const ','') @@ -382,6 +390,7 @@ end _push_functions = {} _is_functions = {} +_enums = {} _to_functions = {} _base_push_functions = {} @@ -410,5 +419,8 @@ function get_to_function(t) end function get_is_function(t) + if _enums[t] then + return "tolua_is" .. t + end return _is_functions[t] or search_base(t, _base_is_functions) or "tolua_isusertype" end diff --git a/lib/tolua++/src/bin/lua/container.lua b/lib/tolua++/src/bin/lua/container.lua index 2d11db7df..99488479e 100644 --- a/lib/tolua++/src/bin/lua/container.lua +++ b/lib/tolua++/src/bin/lua/container.lua @@ -58,7 +58,7 @@ function classContainer:hasvar () while self[i] do if self[i]:isvariable() then return 1 - end + end i = i+1 end return 0 @@ -568,7 +568,7 @@ function classContainer:doparse (s) -- Enumerate(name,body) -- return strsub(s,e+1) -- end --- end +-- end do local b,e,body,name = strfind(s,"^%s*typedef%s+enum[^{]*(%b{})%s*([%w_][^%s]*)%s*;%s*") @@ -606,14 +606,14 @@ function classContainer:doparse (s) -- try function do --local b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w])%s*(%b())%s*(c?o?n?s?t?)%s*=?%s*0?%s*;%s*") - local b,e,decl,arg,const,virt = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)%s*(=?%s*0?)%s*;%s*") + local b,e,decl,arg,const,virt = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)v?e?r?r?i?d?e?%s*o?v?e?r?r?i?d?e?%s*(=?%s*0?)%s*;%s*") if not b then -- try function with template - b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w]%b<>)%s*(%b())%s*(c?o?n?s?t?)%s*=?%s*0?%s*;%s*") + b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w]%b<>)%s*(%b())%s*(c?o?n?s?t?)v?e?r?r?i?d?e?%s*o?v?e?r?r?i?d?e?%s*=?%s*0?%s*;%s*") end if not b then -- try a single letter function name - b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?)%s*;%s*") + b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?)v?e?r?r?i?d?e?%s*o?v?e?r?r?i?d?e?%s*;%s*") end if not b then -- try function pointer @@ -629,6 +629,9 @@ function classContainer:doparse (s) end end _curr_code = strsub(s,b,e) + if const == 'o' then + const = '' + end Function(decl,arg,const) return strsub(s,e+1) end @@ -636,14 +639,17 @@ function classContainer:doparse (s) -- try inline function do - local b,e,decl,arg,const = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)[^;{]*%b{}%s*;?%s*") + local b,e,decl,arg,const = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)v?e?r?r?i?d?e?%s*o?v?e?r?r?i?d?e?[^;{]*%b{}%s*;?%s*") --local b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w>])%s*(%b())%s*(c?o?n?s?t?)[^;]*%b{}%s*;?%s*") if not b then -- try a single letter function name - b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?).-%b{}%s*;?%s*") + b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?)v?e?r?r?i?d?e?%s*o?v?e?r?r?i?d?e?.-%b{}%s*;?%s*") end if b then _curr_code = strsub(s,b,e) + if const == 'o' then + const = '' + end Function(decl,arg,const) return strsub(s,e+1) end diff --git a/lib/tolua++/src/bin/lua/declaration.lua b/lib/tolua++/src/bin/lua/declaration.lua index 73bbe910e..26ceeba22 100644 --- a/lib/tolua++/src/bin/lua/declaration.lua +++ b/lib/tolua++/src/bin/lua/declaration.lua @@ -227,6 +227,8 @@ function classDeclaration:outchecktype (narg) --else return '!tolua_istable(tolua_S,'..narg..',0,&tolua_err)' --end + elseif isenumtype(self.type) ~= nil then + return '!tolua_is'..self.type..'(tolua_S,'..narg..','..def..',&tolua_err)' elseif t then return '!tolua_is'..t..'(tolua_S,'..narg..','..def..',&tolua_err)' else diff --git a/lib/tolua++/src/bin/lua/enumerate.lua b/lib/tolua++/src/bin/lua/enumerate.lua index 99fe74629..09b22a094 100644 --- a/lib/tolua++/src/bin/lua/enumerate.lua +++ b/lib/tolua++/src/bin/lua/enumerate.lua @@ -48,6 +48,25 @@ function classEnumerate:print (ident,close) print(ident.."}"..close) end +function emitenumprototype(type) + output("int tolua_is" .. string.gsub(type,"::","_") .. " (lua_State* L, int lo, int def, tolua_Error* err);") +end + +_global_output_enums = {} + +-- write support code +function classEnumerate:supcode () + if _global_output_enums[self.name] == nil then + _global_output_enums[self.name] = 1 + output("int tolua_is" .. string.gsub(self.name,"::","_") .. " (lua_State* L, int lo, int def, tolua_Error* err)") + output("{") + output("if (!tolua_isnumber(L,lo,def,err)) return 0;") + output("lua_Number val = tolua_tonumber(L,lo,def);") + output("return val >= " .. self.min .. ".0 && val <= " ..self.max .. ".0;") + output("}") + end +end + -- Internal constructor function _Enumerate (t,varname) setmetatable(t,classEnumerate) @@ -67,40 +86,57 @@ function _Enumerate (t,varname) t.access = parent.curr_member_access t.global_access = t:check_public_access() end -return t + return t end -- Constructor -- Expects a string representing the enumerate body function Enumerate (n,b,varname) b = string.gsub(b, ",[%s\n]*}", "\n}") -- eliminate last ',' - local t = split(strsub(b,2,-2),',') -- eliminate braces - local i = 1 - local e = {n=0} - while t[i] do - local tt = split(t[i],'=') -- discard initial value - e.n = e.n + 1 - e[e.n] = tt[1] - i = i+1 - end - -- set lua names - i = 1 - e.lnames = {} - local ns = getcurrnamespace() - while e[i] do - local t = split(e[i],'@') - e[i] = t[1] + local t = split(strsub(b,2,-2),',') -- eliminate braces + local i = 1 + local e = {n=0} + local value = 0 + local min = 0 + local max = 0 + while t[i] do + local tt = split(t[i],'=') -- discard initial value + e.n = e.n + 1 + e[e.n] = tt[1] + tt[2] = tonumber(tt[2]) + if tt[2] == nil then + tt[2] = value + end + value = tt[2] + 1 -- advance the selected value + if tt[2] > max then + max = tt[2] + end + if tt[2] < min then + min = tt[2] + end + i = i+1 + end + -- set lua names + i = 1 + e.lnames = {} + local ns = getcurrnamespace() + while e[i] do + local t = split(e[i],'@') + e[i] = t[1] if not t[2] then - t[2] = applyrenaming(t[1]) + t[2] = applyrenaming(t[1]) end - e.lnames[i] = t[2] or t[1] - _global_enums[ ns..e[i] ] = (ns..e[i]) - i = i+1 - end + e.lnames[i] = t[2] or t[1] + _global_enums[ ns..e[i] ] = (ns..e[i]) + i = i+1 + end e.name = n + e.min = min + e.max = max if n ~= "" then + _enums[n] = true Typedef("int "..n) end - return _Enumerate(e, varname) + return _Enumerate(e, varname) end diff --git a/lib/tolua++/src/bin/lua/function.lua b/lib/tolua++/src/bin/lua/function.lua index 2358e9ff7..9338e0fbc 100644 --- a/lib/tolua++/src/bin/lua/function.lua +++ b/lib/tolua++/src/bin/lua/function.lua @@ -50,11 +50,20 @@ end -- Write binding function -- Outputs C/C++ binding function. function classFunction:supcode (local_constructor) - local overload = strsub(self.cname,-2,-1) - 1 -- indicate overloaded func local nret = 0 -- number of returned values local class = self:inclass() local _,_,static = strfind(self.mod,'^%s*(static)') + -- prototypes for enum functions + if self.args[1].type ~= 'void' then + local i=1 + while self.args[i] do + if isenumtype(self.args[i].type) then + emitenumprototype(self.args[i].type) + end + i = i+1 + end + end if class then if self.name == 'new' and self.parent.flags.pure_virtual then @@ -449,9 +458,8 @@ end -- Internal constructor function _Function (t) setmetatable(t,classFunction) - if t.const ~= 'const' and t.const ~= '' then - error("#invalid 'const' specification") + error("#invalid 'const' specification: " .. t.const) end append(t) @@ -480,7 +488,6 @@ end function Function (d,a,c) --local t = split(strsub(a,2,-2),',') -- eliminate braces --local t = split_params(strsub(a,2,-2)) - if not flags['W'] and string.find(a, "%.%.%.%s*%)") then warning("Functions with variable arguments (`...') are not supported. Ignoring "..d..a..c) diff --git a/lib/tolua++/src/bin/toluabind.c b/lib/tolua++/src/bin/toluabind.c index bf71cf158..e72b4b13c 100644 --- a/lib/tolua++/src/bin/toluabind.c +++ b/lib/tolua++/src/bin/toluabind.c @@ -384,603 +384,8 @@ TOLUA_API int tolua_tolua_open (lua_State* tolua_S) { /* begin embedded lua code */ int top = lua_gettop(tolua_S); - static unsigned char B[] = { - 45, 45, 32,116,111,108,117, 97, 58, 32, 98, 97,115,105, 99, - 32,117,116,105,108,105,116,121, 32,102,117,110, 99,116,105, - 111,110,115, 10, 45, 45, 32, 87,114,105,116,116,101,110, 32, - 98,121, 32, 87, 97,108,100,101,109, 97,114, 32, 67,101,108, - 101,115, 10, 45, 45, 32, 84,101, 67, 71,114, 97,102, 47, 80, - 85, 67, 45, 82,105,111, 10, 45, 45, 32, 74,117,108, 32, 49, - 57, 57, 56, 10, 45, 45, 32, 76, 97,115,116, 32,117,112,100, - 97,116,101, 58, 32, 65,112,114, 32, 50, 48, 48, 51, 10, 45, - 45, 32, 36, 73,100, 58, 32, 36, 10, 10, 45, 45, 32, 84,104, - 105,115, 32, 99,111,100,101, 32,105,115, 32,102,114,101,101, - 32,115,111,102,116,119, 97,114,101, 59, 32,121,111,117, 32, - 99, 97,110, 32,114,101,100,105,115,116,114,105, 98,117,116, - 101, 32,105,116, 32, 97,110,100, 47,111,114, 32,109,111,100, - 105,102,121, 32,105,116, 46, 10, 45, 45, 32, 84,104,101, 32, - 115,111,102,116,119, 97,114,101, 32,112,114,111,118,105,100, - 101,100, 32,104,101,114,101,117,110,100,101,114, 32,105,115, - 32,111,110, 32, 97,110, 32, 34, 97,115, 32,105,115, 34, 32, - 98, 97,115,105,115, 44, 32, 97,110,100, 10, 45, 45, 32,116, - 104,101, 32, 97,117,116,104,111,114, 32,104, 97,115, 32,110, - 111, 32,111, 98,108,105,103, 97,116,105,111,110, 32,116,111, - 32,112,114,111,118,105,100,101, 32,109, 97,105,110,116,101, - 110, 97,110, 99,101, 44, 32,115,117,112,112,111,114,116, 44, - 32,117,112,100, 97,116,101,115, 44, 10, 45, 45, 32,101,110, - 104, 97,110, 99,101,109,101,110,116,115, 44, 32,111,114, 32, - 109,111,100,105,102,105, 99, 97,116,105,111,110,115, 46, 10, - 10, 10, 45, 45, 32, 66, 97,115,105, 99, 32, 67, 32,116,121, - 112,101,115, 32, 97,110,100, 32,116,104,101,105,114, 32, 99, - 111,114,114,101,115,112,111,110,100,105,110,103, 32, 76,117, - 97, 32,116,121,112,101,115, 10, 45, 45, 32, 65,108,108, 32, - 111, 99, 99,117,114,114,101,110, 99,101,115, 32,111,102, 32, - 34, 99,104, 97,114, 42, 34, 32,119,105,108,108, 32, 98,101, - 32,114,101,112,108, 97, 99,101,100, 32, 98,121, 32, 34, 95, - 99,115,116,114,105,110,103, 34, 44, 10, 45, 45, 32, 97,110, - 100, 32, 97,108,108, 32,111, 99, 99,117,114,114,101,110, 99, - 101,115, 32,111,102, 32, 34,118,111,105,100, 42, 34, 32,119, - 105,108,108, 32, 98,101, 32,114,101,112,108, 97, 99,101,100, - 32, 98,121, 32, 34, 95,117,115,101,114,100, 97,116, 97, 34, - 10, 95, 98, 97,115,105, 99, 32, 61, 32,123, 10, 32, 91, 39, - 118,111,105,100, 39, 93, 32, 61, 32, 39, 39, 44, 10, 32, 91, - 39, 99,104, 97,114, 39, 93, 32, 61, 32, 39,110,117,109, 98, - 101,114, 39, 44, 10, 32, 91, 39,105,110,116, 39, 93, 32, 61, - 32, 39,110,117,109, 98,101,114, 39, 44, 10, 32, 91, 39,115, - 104,111,114,116, 39, 93, 32, 61, 32, 39,110,117,109, 98,101, - 114, 39, 44, 10, 32, 91, 39,108,111,110,103, 39, 93, 32, 61, - 32, 39,110,117,109, 98,101,114, 39, 44, 10, 32, 91, 39,117, - 110,115,105,103,110,101,100, 39, 93, 32, 61, 32, 39,110,117, - 109, 98,101,114, 39, 44, 10, 32, 91, 39,102,108,111, 97,116, - 39, 93, 32, 61, 32, 39,110,117,109, 98,101,114, 39, 44, 10, - 32, 91, 39,100,111,117, 98,108,101, 39, 93, 32, 61, 32, 39, - 110,117,109, 98,101,114, 39, 44, 10, 32, 91, 39, 95, 99,115, - 116,114,105,110,103, 39, 93, 32, 61, 32, 39,115,116,114,105, - 110,103, 39, 44, 10, 32, 91, 39, 95,117,115,101,114,100, 97, - 116, 97, 39, 93, 32, 61, 32, 39,117,115,101,114,100, 97,116, - 97, 39, 44, 10, 32, 91, 39, 99,104, 97,114, 42, 39, 93, 32, - 61, 32, 39,115,116,114,105,110,103, 39, 44, 10, 32, 91, 39, - 118,111,105,100, 42, 39, 93, 32, 61, 32, 39,117,115,101,114, - 100, 97,116, 97, 39, 44, 10, 32, 91, 39, 98,111,111,108, 39, - 93, 32, 61, 32, 39, 98,111,111,108,101, 97,110, 39, 44, 10, - 32, 91, 39,108,117, 97, 95, 79, 98,106,101, 99,116, 39, 93, - 32, 61, 32, 39,118, 97,108,117,101, 39, 44, 10, 32, 91, 39, - 76, 85, 65, 95, 86, 65, 76, 85, 69, 39, 93, 32, 61, 32, 39, - 118, 97,108,117,101, 39, 44, 32, 32, 32, 32, 45, 45, 32,102, - 111,114, 32, 99,111,109,112, 97,116,105, 98,105,108,105,116, - 121, 32,119,105,116,104, 32,116,111,108,117, 97, 32, 52, 46, - 48, 10, 32, 91, 39,108,117, 97, 95, 83,116, 97,116,101, 42, - 39, 93, 32, 61, 32, 39,115,116, 97,116,101, 39, 44, 10, 32, - 91, 39, 95,108,115,116, 97,116,101, 39, 93, 32, 61, 32, 39, - 115,116, 97,116,101, 39, 44, 10, 32, 91, 39,108,117, 97, 95, - 70,117,110, 99,116,105,111,110, 39, 93, 32, 61, 32, 39,118, - 97,108,117,101, 39, 44, 10,125, 10, 10, 95, 98, 97,115,105, - 99, 95, 99,116,121,112,101, 32, 61, 32,123, 10, 32,110,117, - 109, 98,101,114, 32, 61, 32, 34,108,117, 97, 95, 78,117,109, - 98,101,114, 34, 44, 10, 32,115,116,114,105,110,103, 32, 61, - 32, 34, 99,111,110,115,116, 32, 99,104, 97,114, 42, 34, 44, - 10, 32,117,115,101,114,100, 97,116, 97, 32, 61, 32, 34,118, - 111,105,100, 42, 34, 44, 10, 32, 98,111,111,108,101, 97,110, - 32, 61, 32, 34, 98,111,111,108, 34, 44, 10, 32,118, 97,108, - 117,101, 32, 61, 32, 34,105,110,116, 34, 44, 10, 32,115,116, - 97,116,101, 32, 61, 32, 34,108,117, 97, 95, 83,116, 97,116, - 101, 42, 34, 44, 10,125, 10, 10, 45, 45, 32,102,117,110, 99, - 116,105,111,110,115, 32,116,104,101, 32, 97,114,101, 32,117, - 115,101,100, 32,116,111, 32,100,111, 32, 97, 32, 39,114, 97, - 119, 32,112,117,115,104, 39, 32,111,102, 32, 98, 97,115,105, - 99, 32,116,121,112,101,115, 10, 95, 98, 97,115,105, 99, 95, - 114, 97,119, 95,112,117,115,104, 32, 61, 32,123,125, 10, 10, - 45, 45, 32, 76,105,115,116, 32,111,102, 32,117,115,101,114, - 32,100,101,102,105,110,101,100, 32,116,121,112,101,115, 10, - 45, 45, 32, 69, 97, 99,104, 32,116,121,112,101, 32, 99,111, - 114,114,101,115,112,111,110,100,115, 32,116,111, 32, 97, 32, - 118, 97,114,105, 97, 98,108,101, 32,110, 97,109,101, 32,116, - 104, 97,116, 32,115,116,111,114,101,115, 32,105,116,115, 32, - 116, 97,103, 32,118, 97,108,117,101, 46, 10, 95,117,115,101, - 114,116,121,112,101, 32, 61, 32,123,125, 10, 10, 45, 45, 32, - 76,105,115,116, 32,111,102, 32,116,121,112,101,115, 32,116, - 104, 97,116, 32,104, 97,118,101, 32,116,111, 32, 98,101, 32, - 99,111,108,108,101, 99,116,101,100, 10, 95, 99,111,108,108, - 101, 99,116, 32, 61, 32,123,125, 10, 10, 45, 45, 32, 76,105, - 115,116, 32,111,102, 32,116,121,112,101,115, 10, 95,103,108, - 111, 98, 97,108, 95,116,121,112,101,115, 32, 61, 32,123,110, - 61, 48,125, 10, 95,103,108,111, 98, 97,108, 95,116,121,112, - 101,115, 95,104, 97,115,104, 32, 61, 32,123,125, 10, 10, 45, - 45, 32,108,105,115,116, 32,111,102, 32, 99,108, 97,115,115, - 101,115, 10, 95,103,108,111, 98, 97,108, 95, 99,108, 97,115, - 115,101,115, 32, 61, 32,123,125, 10, 10, 45, 45, 32, 76,105, - 115,116, 32,111,102, 32,101,110,117,109, 32, 99,111,110,115, - 116, 97,110,116,115, 10, 95,103,108,111, 98, 97,108, 95,101, - 110,117,109,115, 32, 61, 32,123,125, 10, 10, 45, 45, 32, 76, - 105,115,116, 32,111,102, 32, 97,117,116,111, 32,114,101,110, - 97,109,105,110,103, 10, 95,114,101,110, 97,109,105,110,103, - 32, 61, 32,123,125, 10,102,117,110, 99,116,105,111,110, 32, - 97,112,112,101,110,100,114,101,110, 97,109,105,110,103, 32, - 40,115, 41, 10, 32,108,111, 99, 97,108, 32, 98, 44,101, 44, - 111,108,100, 44,110,101,119, 32, 61, 32,115,116,114,102,105, - 110,100, 40,115, 44, 34, 37,115, 42, 40, 46, 45, 41, 37,115, - 42, 64, 37,115, 42, 40, 46, 45, 41, 37,115, 42, 36, 34, 41, - 10, 9,105,102, 32,110,111,116, 32, 98, 32,116,104,101,110, - 10, 9, 32,101,114,114,111,114, 40, 34, 35, 73,110,118, 97, - 108,105,100, 32,114,101,110, 97,109,105,110,103, 32,115,121, - 110,116, 97,120, 59, 32,105,116, 32,115,104,111,117,108,100, - 32, 98,101, 32,111,102, 32,116,104,101, 32,102,111,114,109, - 58, 32,112, 97,116,116,101,114,110, 64,112, 97,116,116,101, - 114,110, 34, 41, 10, 9,101,110,100, 10, 9,116,105,110,115, - 101,114,116, 40, 95,114,101,110, 97,109,105,110,103, 44,123, - 111,108,100, 61,111,108,100, 44, 32,110,101,119, 61,110,101, - 119,125, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105, - 111,110, 32, 97,112,112,108,121,114,101,110, 97,109,105,110, - 103, 32, 40,115, 41, 10, 9,102,111,114, 32,105, 61, 49, 44, - 103,101,116,110, 40, 95,114,101,110, 97,109,105,110,103, 41, - 32,100,111, 10, 9, 32,108,111, 99, 97,108, 32,109, 44,110, - 32, 61, 32,103,115,117, 98, 40,115, 44, 95,114,101,110, 97, - 109,105,110,103, 91,105, 93, 46,111,108,100, 44, 95,114,101, - 110, 97,109,105,110,103, 91,105, 93, 46,110,101,119, 41, 10, - 9, 9,105,102, 32,110, 32,126, 61, 32, 48, 32,116,104,101, - 110, 10, 9, 9, 32,114,101,116,117,114,110, 32,109, 10, 9, - 9,101,110,100, 10, 9,101,110,100, 10, 9,114,101,116,117, - 114,110, 32,110,105,108, 10,101,110,100, 10, 10, 45, 45, 32, - 69,114,114,111,114, 32,104, 97,110,100,108,101,114, 10,102, - 117,110, 99,116,105,111,110, 32,116,111,108,117, 97, 95,101, - 114,114,111,114, 32, 40,115, 44,102, 41, 10,105,102, 32, 95, - 99,117,114,114, 95, 99,111,100,101, 32,116,104,101,110, 10, - 9,112,114,105,110,116, 40, 34, 42, 42, 42, 99,117,114,114, - 32, 99,111,100,101, 32,102,111,114, 32,101,114,114,111,114, - 32,105,115, 32, 34, 46, 46,116,111,115,116,114,105,110,103, - 40, 95, 99,117,114,114, 95, 99,111,100,101, 41, 41, 10, 9, - 112,114,105,110,116, 40,100,101, 98,117,103, 46,116,114, 97, - 99,101, 98, 97, 99,107, 40, 41, 41, 10,101,110,100, 10, 32, - 108,111, 99, 97,108, 32,111,117,116, 32, 61, 32, 95, 79, 85, - 84, 80, 85, 84, 10, 32, 95, 79, 85, 84, 80, 85, 84, 32, 61, - 32, 95, 83, 84, 68, 69, 82, 82, 10, 32,105,102, 32,115,116, - 114,115,117, 98, 40,115, 44, 49, 44, 49, 41, 32, 61, 61, 32, - 39, 35, 39, 32,116,104,101,110, 10, 32, 32,119,114,105,116, - 101, 40, 34, 92,110, 42, 42, 32,116,111,108,117, 97, 58, 32, - 34, 46, 46,115,116,114,115,117, 98, 40,115, 44, 50, 41, 46, - 46, 34, 46, 92,110, 92,110, 34, 41, 10, 32, 32,105,102, 32, - 95, 99,117,114,114, 95, 99,111,100,101, 32,116,104,101,110, - 10, 32, 32, 32,108,111, 99, 97,108, 32, 95, 44, 95, 44,115, - 32, 61, 32,115,116,114,102,105,110,100, 40, 95, 99,117,114, - 114, 95, 99,111,100,101, 44, 34, 94, 37,115, 42, 40, 46, 45, - 92,110, 41, 34, 41, 32, 45, 45, 32,101,120,116,114, 97, 99, - 116, 32,102,105,114,115,116, 32,108,105,110,101, 10, 32, 32, - 32,105,102, 32,115, 61, 61,110,105,108, 32,116,104,101,110, - 32,115, 32, 61, 32, 95, 99,117,114,114, 95, 99,111,100,101, - 32,101,110,100, 10, 32, 32, 32,115, 32, 61, 32,103,115,117, - 98, 40,115, 44, 34, 95,117,115,101,114,100, 97,116, 97, 34, - 44, 34,118,111,105,100, 42, 34, 41, 32, 45, 45, 32,114,101, - 116,117,114,110, 32,119,105,116,104, 32, 39,118,111,105,100, - 42, 39, 10, 32, 32, 32,115, 32, 61, 32,103,115,117, 98, 40, - 115, 44, 34, 95, 99,115,116,114,105,110,103, 34, 44, 34, 99, - 104, 97,114, 42, 34, 41, 32, 32, 45, 45, 32,114,101,116,117, - 114,110, 32,119,105,116,104, 32, 39, 99,104, 97,114, 42, 39, - 10, 32, 32, 32,115, 32, 61, 32,103,115,117, 98, 40,115, 44, - 34, 95,108,115,116, 97,116,101, 34, 44, 34,108,117, 97, 95, - 83,116, 97,116,101, 42, 34, 41, 32, 32, 45, 45, 32,114,101, - 116,117,114,110, 32,119,105,116,104, 32, 39,108,117, 97, 95, - 83,116, 97,116,101, 42, 39, 10, 32, 32, 32,119,114,105,116, - 101, 40, 34, 67,111,100,101, 32, 98,101,105,110,103, 32,112, - 114,111, 99,101,115,115,101,100, 58, 92,110, 34, 46, 46,115, - 46, 46, 34, 92,110, 34, 41, 10, 32, 32,101,110,100, 10, 32, - 101,108,115,101, 10, 32,105,102, 32,110,111,116, 32,102, 32, - 116,104,101,110, 32,102, 32, 61, 32, 34, 40,102, 32,105,115, - 32,110,105,108, 41, 34, 32,101,110,100, 10, 32, 32,112,114, - 105,110,116, 40, 34, 92,110, 42, 42, 32,116,111,108,117, 97, - 32,105,110,116,101,114,110, 97,108, 32,101,114,114,111,114, - 58, 32, 34, 46, 46,102, 46, 46,115, 46, 46, 34, 46, 92,110, - 92,110, 34, 41, 10, 32, 32,114,101,116,117,114,110, 10, 32, - 101,110,100, 10, 32, 95, 79, 85, 84, 80, 85, 84, 32, 61, 32, - 111,117,116, 10,101,110,100, 10, 10,102,117,110, 99,116,105, - 111,110, 32,119, 97,114,110,105,110,103, 32, 40,109,115,103, - 41, 10, 32,105,102, 32,102,108, 97,103,115, 46,113, 32,116, - 104,101,110, 32,114,101,116,117,114,110, 32,101,110,100, 10, - 32,108,111, 99, 97,108, 32,111,117,116, 32, 61, 32, 95, 79, - 85, 84, 80, 85, 84, 10, 32, 95, 79, 85, 84, 80, 85, 84, 32, - 61, 32, 95, 83, 84, 68, 69, 82, 82, 10, 32,119,114,105,116, - 101, 40, 34, 92,110, 42, 42, 32,116,111,108,117, 97, 32,119, - 97,114,110,105,110,103, 58, 32, 34, 46, 46,109,115,103, 46, - 46, 34, 46, 92,110, 92,110, 34, 41, 10, 32, 95, 79, 85, 84, - 80, 85, 84, 32, 61, 32,111,117,116, 10,101,110,100, 10, 10, - 45, 45, 32,114,101,103,105,115,116,101,114, 32, 97,110, 32, - 117,115,101,114, 32,100,101,102,105,110,101,100, 32,116,121, - 112,101, 58, 32,114,101,116,117,114,110,115, 32,102,117,108, - 108, 32,116,121,112,101, 10,102,117,110, 99,116,105,111,110, - 32,114,101,103,116,121,112,101, 32, 40,116, 41, 10, 9, 45, - 45,105,102, 32,105,115, 98, 97,115,105, 99, 40,116, 41, 32, - 116,104,101,110, 10, 9, 45, 45, 9,114,101,116,117,114,110, - 32,116, 10, 9, 45, 45,101,110,100, 10, 9,108,111, 99, 97, - 108, 32,102,116, 32, 61, 32,102,105,110,100,116,121,112,101, - 40,116, 41, 10, 10, 9,105,102, 32,110,111,116, 32, 95,117, - 115,101,114,116,121,112,101, 91,102,116, 93, 32,116,104,101, - 110, 10, 9, 9,114,101,116,117,114,110, 32, 97,112,112,101, - 110,100,117,115,101,114,116,121,112,101, 40,116, 41, 10, 9, - 101,110,100, 10, 9,114,101,116,117,114,110, 32,102,116, 10, - 101,110,100, 10, 10, 45, 45, 32,114,101,116,117,114,110, 32, - 116,121,112,101, 32,110, 97,109,101, 58, 32,114,101,116,117, - 114,110,115, 32,102,117,108,108, 32,116,121,112,101, 10,102, - 117,110, 99,116,105,111,110, 32,116,121,112,101,118, 97,114, - 40,116,121,112,101, 41, 10, 9,105,102, 32,116,121,112,101, - 32, 61, 61, 32, 39, 39, 32,111,114, 32,116,121,112,101, 32, - 61, 61, 32, 39,118,111,105,100, 39, 32,116,104,101,110, 10, - 9, 9,114,101,116,117,114,110, 32,116,121,112,101, 10, 9, - 101,108,115,101, 10, 9, 9,108,111, 99, 97,108, 32,102,116, - 32, 61, 32,102,105,110,100,116,121,112,101, 40,116,121,112, - 101, 41, 10, 9, 9,105,102, 32,102,116, 32,116,104,101,110, - 10, 9, 9, 9,114,101,116,117,114,110, 32,102,116, 10, 9, - 9,101,110,100, 10, 9, 9, 95,117,115,101,114,116,121,112, - 101, 91,116,121,112,101, 93, 32, 61, 32,116,121,112,101, 10, - 9, 9,114,101,116,117,114,110, 32,116,121,112,101, 10, 9, - 101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,104,101, - 99,107, 32,105,102, 32, 98, 97,115,105, 99, 32,116,121,112, - 101, 10,102,117,110, 99,116,105,111,110, 32,105,115, 98, 97, - 115,105, 99, 32, 40,116,121,112,101, 41, 10, 32,108,111, 99, - 97,108, 32,116, 32, 61, 32,103,115,117, 98, 40,116,121,112, - 101, 44, 39, 99,111,110,115,116, 32, 39, 44, 39, 39, 41, 10, - 32,108,111, 99, 97,108, 32,109, 44,116, 32, 61, 32, 97,112, - 112,108,121,116,121,112,101,100,101,102, 40, 39, 39, 44, 32, - 116, 41, 10, 32,108,111, 99, 97,108, 32, 98, 32, 61, 32, 95, - 98, 97,115,105, 99, 91,116, 93, 10, 32,105,102, 32, 98, 32, - 116,104,101,110, 10, 32, 32,114,101,116,117,114,110, 32, 98, - 44, 95, 98, 97,115,105, 99, 95, 99,116,121,112,101, 91, 98, - 93, 10, 32,101,110,100, 10, 32,114,101,116,117,114,110, 32, - 110,105,108, 10,101,110,100, 10, 10, 45, 45, 32,115,112,108, - 105,116, 32,115,116,114,105,110,103, 32,117,115,105,110,103, - 32, 97, 32,116,111,107,101,110, 10,102,117,110, 99,116,105, - 111,110, 32,115,112,108,105,116, 32, 40,115, 44,116, 41, 10, - 32,108,111, 99, 97,108, 32,108, 32, 61, 32,123,110, 61, 48, - 125, 10, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,102,117, - 110, 99,116,105,111,110, 32, 40,115, 41, 10, 32, 32,108, 46, - 110, 32, 61, 32,108, 46,110, 32, 43, 32, 49, 10, 32, 32,108, - 91,108, 46,110, 93, 32, 61, 32,115, 10, 32, 32,114,101,116, - 117,114,110, 32, 34, 34, 10, 32,101,110,100, 10, 32,108,111, - 99, 97,108, 32,112, 32, 61, 32, 34, 37,115, 42, 40, 46, 45, - 41, 37,115, 42, 34, 46, 46,116, 46, 46, 34, 37,115, 42, 34, - 10, 32,115, 32, 61, 32,103,115,117, 98, 40,115, 44, 34, 94, - 37,115, 43, 34, 44, 34, 34, 41, 10, 32,115, 32, 61, 32,103, - 115,117, 98, 40,115, 44, 34, 37,115, 43, 36, 34, 44, 34, 34, - 41, 10, 32,115, 32, 61, 32,103,115,117, 98, 40,115, 44,112, - 44,102, 41, 10, 32,108, 46,110, 32, 61, 32,108, 46,110, 32, - 43, 32, 49, 10, 32,108, 91,108, 46,110, 93, 32, 61, 32,103, - 115,117, 98, 40,115, 44, 34, 40, 37,115, 37,115, 42, 41, 36, - 34, 44, 34, 34, 41, 10, 32,114,101,116,117,114,110, 32,108, - 10,101,110,100, 10, 10, 45, 45, 32,115,112,108,105,116,115, - 32, 97, 32,115,116,114,105,110,103, 32,117,115,105,110,103, - 32, 97, 32,112, 97,116,116,101,114,110, 44, 32, 99,111,110, - 115,105,100,101,114,105,110,103, 32,116,104,101, 32,115,112, - 97, 99,105, 97,108, 32, 99, 97,115,101,115, 32,111,102, 32, - 67, 32, 99,111,100,101, 32, 40,116,101,109,112,108, 97,116, - 101,115, 44, 32,102,117,110, 99,116,105,111,110, 32,112, 97, - 114, 97,109,101,116,101,114,115, 44, 32,101,116, 99, 41, 10, - 45, 45, 32,112, 97,116,116,101,114,110, 32, 99, 97,110, 39, - 116, 32, 99,111,110,116, 97,105,110, 32,116,104,101, 32, 39, - 94, 39, 32, 40, 97,115, 32,117,115,101,100, 32,116,111, 32, - 105,100,101,110,116,105,102,121, 32,116,104,101, 32, 98,101, - 103,105,110,105,110,103, 32,111,102, 32,116,104,101, 32,108, - 105,110,101, 41, 10, 45, 45, 32, 97,108,115,111, 32,115,116, - 114,105,112,115, 32,119,104,105,116,101,115,112, 97, 99,101, - 10,102,117,110, 99,116,105,111,110, 32,115,112,108,105,116, - 95, 99, 95,116,111,107,101,110,115, 40,115, 44, 32,112, 97, - 116, 41, 10, 10, 9,115, 32, 61, 32,115,116,114,105,110,103, - 46,103,115,117, 98, 40,115, 44, 32, 34, 94, 37,115, 42, 34, - 44, 32, 34, 34, 41, 10, 9,115, 32, 61, 32,115,116,114,105, - 110,103, 46,103,115,117, 98, 40,115, 44, 32, 34, 37,115, 42, - 36, 34, 44, 32, 34, 34, 41, 10, 10, 9,108,111, 99, 97,108, - 32,116,111,107,101,110, 95, 98,101,103,105,110, 32, 61, 32, - 49, 10, 9,108,111, 99, 97,108, 32,116,111,107,101,110, 95, - 101,110,100, 32, 61, 32, 49, 10, 9,108,111, 99, 97,108, 32, - 111,102,115, 32, 61, 32, 49, 10, 9,108,111, 99, 97,108, 32, - 114,101,116, 32, 61, 32,123,110, 61, 48,125, 10, 10, 9,102, - 117,110, 99,116,105,111,110, 32, 97,100,100, 95,116,111,107, - 101,110, 40,111,102,115, 41, 10, 10, 9, 9,108,111, 99, 97, - 108, 32,116, 32, 61, 32,115,116,114,105,110,103, 46,115,117, - 98, 40,115, 44, 32,116,111,107,101,110, 95, 98,101,103,105, - 110, 44, 32,111,102,115, 41, 10, 9, 9,116, 32, 61, 32,115, - 116,114,105,110,103, 46,103,115,117, 98, 40,116, 44, 32, 34, - 94, 37,115, 42, 34, 44, 32, 34, 34, 41, 10, 9, 9,116, 32, - 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,116, - 44, 32, 34, 37,115, 42, 36, 34, 44, 32, 34, 34, 41, 10, 9, - 9,114,101,116, 46,110, 32, 61, 32,114,101,116, 46,110, 32, - 43, 32, 49, 10, 9, 9,114,101,116, 91,114,101,116, 46,110, - 93, 32, 61, 32,116, 10, 9,101,110,100, 10, 10, 9,119,104, - 105,108,101, 32,111,102,115, 32, 60, 61, 32,115,116,114,105, - 110,103, 46,108,101,110, 40,115, 41, 32,100,111, 10, 10, 9, - 9,108,111, 99, 97,108, 32,115,117, 98, 32, 61, 32,115,116, - 114,105,110,103, 46,115,117, 98, 40,115, 44, 32,111,102,115, - 44, 32, 45, 49, 41, 10, 9, 9,108,111, 99, 97,108, 32, 98, - 44,101, 32, 61, 32,115,116,114,105,110,103, 46,102,105,110, - 100, 40,115,117, 98, 44, 32, 34, 94, 34, 46, 46,112, 97,116, - 41, 10, 9, 9,105,102, 32, 98, 32,116,104,101,110, 10, 9, - 9, 9, 97,100,100, 95,116,111,107,101,110, 40,111,102,115, - 45, 49, 41, 10, 9, 9, 9,111,102,115, 32, 61, 32,111,102, - 115, 43,101, 10, 9, 9, 9,116,111,107,101,110, 95, 98,101, - 103,105,110, 32, 61, 32,111,102,115, 10, 9, 9,101,108,115, - 101, 10, 9, 9, 9,108,111, 99, 97,108, 32, 99,104, 97,114, - 32, 61, 32,115,116,114,105,110,103, 46,115,117, 98, 40,115, - 44, 32,111,102,115, 44, 32,111,102,115, 41, 10, 9, 9, 9, - 105,102, 32, 99,104, 97,114, 32, 61, 61, 32, 34, 40, 34, 32, - 111,114, 32, 99,104, 97,114, 32, 61, 61, 32, 34, 60, 34, 32, - 116,104,101,110, 10, 10, 9, 9, 9, 9,108,111, 99, 97,108, - 32, 98,108,111, 99,107, 10, 9, 9, 9, 9,105,102, 32, 99, - 104, 97,114, 32, 61, 61, 32, 34, 40, 34, 32,116,104,101,110, - 32, 98,108,111, 99,107, 32, 61, 32, 34, 94, 37, 98, 40, 41, - 34, 32,101,110,100, 10, 9, 9, 9, 9,105,102, 32, 99,104, - 97,114, 32, 61, 61, 32, 34, 60, 34, 32,116,104,101,110, 32, - 98,108,111, 99,107, 32, 61, 32, 34, 94, 37, 98, 60, 62, 34, - 32,101,110,100, 10, 10, 9, 9, 9, 9, 98, 44,101, 32, 61, - 32,115,116,114,105,110,103, 46,102,105,110,100, 40,115,117, - 98, 44, 32, 98,108,111, 99,107, 41, 10, 9, 9, 9, 9,105, - 102, 32,110,111,116, 32, 98, 32,116,104,101,110, 10, 9, 9, - 9, 9, 9, 45, 45, 32,117,110,116,101,114,109,105,110, 97, - 116,101,100, 32, 98,108,111, 99,107, 63, 10, 9, 9, 9, 9, - 9,111,102,115, 32, 61, 32,111,102,115, 43, 49, 10, 9, 9, - 9, 9,101,108,115,101, 10, 9, 9, 9, 9, 9,111,102,115, - 32, 61, 32,111,102,115, 32, 43, 32,101, 10, 9, 9, 9, 9, - 101,110,100, 10, 10, 9, 9, 9,101,108,115,101, 10, 9, 9, - 9, 9,111,102,115, 32, 61, 32,111,102,115, 43, 49, 10, 9, - 9, 9,101,110,100, 10, 9, 9,101,110,100, 10, 10, 9,101, - 110,100, 10, 9, 97,100,100, 95,116,111,107,101,110, 40,111, - 102,115, 41, 10, 9, 45, 45,105,102, 32,114,101,116, 46,110, - 32, 61, 61, 32, 48, 32,116,104,101,110, 10, 10, 9, 45, 45, - 9,114,101,116, 46,110, 61, 49, 10, 9, 45, 45, 9,114,101, - 116, 91, 49, 93, 32, 61, 32, 34, 34, 10, 9, 45, 45,101,110, - 100, 10, 10, 9,114,101,116,117,114,110, 32,114,101,116, 10, - 10,101,110,100, 10, 10, 45, 45, 32, 99,111,110, 99, 97,116, - 101,110, 97,116,101, 32,115,116,114,105,110,103,115, 32,111, - 102, 32, 97, 32,116, 97, 98,108,101, 10,102,117,110, 99,116, - 105,111,110, 32, 99,111,110, 99, 97,116, 32, 40,116, 44,102, - 44,108, 44,106,115,116,114, 41, 10, 9,106,115,116,114, 32, - 61, 32,106,115,116,114, 32,111,114, 32, 34, 32, 34, 10, 32, - 108,111, 99, 97,108, 32,115, 32, 61, 32, 39, 39, 10, 32,108, - 111, 99, 97,108, 32,105, 61,102, 10, 32,119,104,105,108,101, - 32,105, 60, 61,108, 32,100,111, 10, 32, 32,115, 32, 61, 32, - 115, 46, 46,116, 91,105, 93, 10, 32, 32,105, 32, 61, 32,105, - 43, 49, 10, 32, 32,105,102, 32,105, 32, 60, 61, 32,108, 32, - 116,104,101,110, 32,115, 32, 61, 32,115, 46, 46,106,115,116, - 114, 32,101,110,100, 10, 32,101,110,100, 10, 32,114,101,116, - 117,114,110, 32,115, 10,101,110,100, 10, 10, 45, 45, 32, 99, - 111,110, 99, 97,116,101,110, 97,116,101, 32, 97,108,108, 32, - 112, 97,114, 97,109,101,116,101,114,115, 44, 32,102,111,108, - 108,111,119,105,110,103, 32,111,117,116,112,117,116, 32,114, - 117,108,101,115, 10,102,117,110, 99,116,105,111,110, 32, 99, - 111,110, 99, 97,116,112, 97,114, 97,109, 32, 40,108,105,110, - 101, 44, 32, 46, 46, 46, 41, 10, 32,108,111, 99, 97,108, 32, - 105, 61, 49, 10, 32,119,104,105,108,101, 32,105, 60, 61, 97, - 114,103, 46,110, 32,100,111, 10, 32, 32,105,102, 32, 95, 99, - 111,110,116, 32, 97,110,100, 32,110,111,116, 32,115,116,114, - 102,105,110,100, 40, 95, 99,111,110,116, 44, 39, 91, 37, 40, - 44, 34, 93, 39, 41, 32, 97,110,100, 10, 32, 32, 32, 32, 32, - 115,116,114,102,105,110,100, 40, 97,114,103, 91,105, 93, 44, - 34, 94, 91, 37, 97, 95,126, 93, 34, 41, 32,116,104,101,110, - 10, 9, 32, 32, 32, 32,108,105,110,101, 32, 61, 32,108,105, - 110,101, 32, 46, 46, 32, 39, 32, 39, 10, 32, 32,101,110,100, - 10, 32, 32,108,105,110,101, 32, 61, 32,108,105,110,101, 32, - 46, 46, 32, 97,114,103, 91,105, 93, 10, 32, 32,105,102, 32, - 97,114,103, 91,105, 93, 32,126, 61, 32, 39, 39, 32,116,104, - 101,110, 10, 32, 32, 32, 95, 99,111,110,116, 32, 61, 32,115, - 116,114,115,117, 98, 40, 97,114,103, 91,105, 93, 44, 45, 49, - 44, 45, 49, 41, 10, 32, 32,101,110,100, 10, 32, 32,105, 32, - 61, 32,105, 43, 49, 10, 32,101,110,100, 10, 32,105,102, 32, - 115,116,114,102,105,110,100, 40, 97,114,103, 91, 97,114,103, - 46,110, 93, 44, 34, 91, 37, 47, 37, 41, 37, 59, 37,123, 37, - 125, 93, 36, 34, 41, 32,116,104,101,110, 10, 32, 32, 95, 99, - 111,110,116, 61,110,105,108, 32,108,105,110,101, 32, 61, 32, - 108,105,110,101, 32, 46, 46, 32, 39, 92,110, 39, 10, 32,101, - 110,100, 10, 9,114,101,116,117,114,110, 32,108,105,110,101, - 10,101,110,100, 10, 10, 45, 45, 32,111,117,116,112,117,116, - 32,108,105,110,101, 10,102,117,110, 99,116,105,111,110, 32, - 111,117,116,112,117,116, 32, 40, 46, 46, 46, 41, 10, 32,108, - 111, 99, 97,108, 32,105, 61, 49, 10, 32,119,104,105,108,101, - 32,105, 60, 61, 97,114,103, 46,110, 32,100,111, 10, 32, 32, - 105,102, 32, 95, 99,111,110,116, 32, 97,110,100, 32,110,111, - 116, 32,115,116,114,102,105,110,100, 40, 95, 99,111,110,116, - 44, 39, 91, 37, 40, 44, 34, 93, 39, 41, 32, 97,110,100, 10, - 32, 32, 32, 32, 32,115,116,114,102,105,110,100, 40, 97,114, - 103, 91,105, 93, 44, 34, 94, 91, 37, 97, 95,126, 93, 34, 41, - 32,116,104,101,110, 10, 9, 32, 32, 32, 32,119,114,105,116, - 101, 40, 39, 32, 39, 41, 10, 32, 32,101,110,100, 10, 32, 32, - 119,114,105,116,101, 40, 97,114,103, 91,105, 93, 41, 10, 32, - 32,105,102, 32, 97,114,103, 91,105, 93, 32,126, 61, 32, 39, - 39, 32,116,104,101,110, 10, 32, 32, 32, 95, 99,111,110,116, - 32, 61, 32,115,116,114,115,117, 98, 40, 97,114,103, 91,105, - 93, 44, 45, 49, 44, 45, 49, 41, 10, 32, 32,101,110,100, 10, - 32, 32,105, 32, 61, 32,105, 43, 49, 10, 32,101,110,100, 10, - 32,105,102, 32,115,116,114,102,105,110,100, 40, 97,114,103, - 91, 97,114,103, 46,110, 93, 44, 34, 91, 37, 47, 37, 41, 37, - 59, 37,123, 37,125, 93, 36, 34, 41, 32,116,104,101,110, 10, - 32, 32, 95, 99,111,110,116, 61,110,105,108, 32,119,114,105, - 116,101, 40, 39, 92,110, 39, 41, 10, 32,101,110,100, 10,101, - 110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,103,101, - 116, 95,112,114,111,112,101,114,116,121, 95,109,101,116,104, - 111,100,115, 40,112,116,121,112,101, 44, 32,110, 97,109,101, - 41, 10, 10, 9,105,102, 32,103,101,116, 95,112,114,111,112, - 101,114,116,121, 95,109,101,116,104,111,100,115, 95,104,111, - 111,107, 32, 97,110,100, 32,103,101,116, 95,112,114,111,112, - 101,114,116,121, 95,109,101,116,104,111,100,115, 95,104,111, - 111,107, 40,112,116,121,112,101, 44,110, 97,109,101, 41, 32, - 116,104,101,110, 10, 9, 9,114,101,116,117,114,110, 32,103, - 101,116, 95,112,114,111,112,101,114,116,121, 95,109,101,116, - 104,111,100,115, 95,104,111,111,107, 40,112,116,121,112,101, - 44, 32,110, 97,109,101, 41, 10, 9,101,110,100, 10, 10, 9, - 105,102, 32,112,116,121,112,101, 32, 61, 61, 32, 34,100,101, - 102, 97,117,108,116, 34, 32,116,104,101,110, 32, 45, 45, 32, - 103,101,116, 95,110, 97,109,101, 44, 32,115,101,116, 95,110, - 97,109,101, 10, 9, 9,114,101,116,117,114,110, 32, 34,103, - 101,116, 95, 34, 46, 46,110, 97,109,101, 44, 32, 34,115,101, - 116, 95, 34, 46, 46,110, 97,109,101, 10, 9,101,110,100, 10, - 10, 9,105,102, 32,112,116,121,112,101, 32, 61, 61, 32, 34, - 113,116, 34, 32,116,104,101,110, 32, 45, 45, 32,110, 97,109, - 101, 44, 32,115,101,116, 78, 97,109,101, 10, 9, 9,114,101, - 116,117,114,110, 32,110, 97,109,101, 44, 32, 34,115,101,116, - 34, 46, 46,115,116,114,105,110,103, 46,117,112,112,101,114, - 40,115,116,114,105,110,103, 46,115,117, 98, 40,110, 97,109, - 101, 44, 32, 49, 44, 32, 49, 41, 41, 46, 46,115,116,114,105, - 110,103, 46,115,117, 98, 40,110, 97,109,101, 44, 32, 50, 44, - 32, 45, 49, 41, 10, 9,101,110,100, 10, 10, 9,105,102, 32, - 112,116,121,112,101, 32, 61, 61, 32, 34,111,118,101,114,108, - 111, 97,100, 34, 32,116,104,101,110, 32, 45, 45, 32,110, 97, - 109,101, 44, 32,110, 97,109,101, 10, 9, 9,114,101,116,117, - 114,110, 32,110, 97,109,101, 44,110, 97,109,101, 10, 9,101, - 110,100, 10, 10, 9,114,101,116,117,114,110, 32,110,105,108, - 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 32,116,104,101, 32,104,111,111,107,115, - 10, 10, 45, 45, 32, 99, 97,108,108,101,100, 32,114,105,103, - 104,116, 32, 97,102,116,101,114, 32,112,114,111, 99,101,115, - 115,105,110,103, 32,116,104,101, 32, 36, 91,105, 99,104,108, - 93,102,105,108,101, 32,100,105,114,101, 99,116,105,118,101, - 115, 44, 10, 45, 45, 32,114,105,103,104,116, 32, 98,101,102, - 111,114,101, 32,112,114,111, 99,101,115,115,105,110,103, 32, - 97,110,121,116,104,105,110,103, 32,101,108,115,101, 10, 45, - 45, 32,116, 97,107,101,115, 32,116,104,101, 32,112, 97, 99, - 107, 97,103,101, 32,111, 98,106,101, 99,116, 32, 97,115, 32, - 116,104,101, 32,112, 97,114, 97,109,101,116,101,114, 10,102, - 117,110, 99,116,105,111,110, 32,112,114,101,112,114,111, 99, - 101,115,115, 95,104,111,111,107, 40,112, 41, 10, 9, 45, 45, - 32,112, 46, 99,111,100,101, 32,104, 97,115, 32, 97,108,108, - 32,116,104,101, 32,105,110,112,117,116, 32, 99,111,100,101, - 32,102,114,111,109, 32,116,104,101, 32,112,107,103, 10,101, - 110,100, 10, 10, 10, 45, 45, 32, 99, 97,108,108,101,100, 32, - 102,111,114, 32,101,118,101,114,121, 32, 36,105,102,105,108, - 101, 32,100,105,114,101, 99,116,105,118,101, 10, 45, 45, 32, - 116, 97,107,101,115, 32, 97, 32,116, 97, 98,108,101, 32,119, - 105,116,104, 32, 97, 32,115,116,114,105,110,103, 32, 99, 97, - 108,108,101,100, 32, 39, 99,111,100,101, 39, 32,105,110,115, - 105,100,101, 44, 32,116,104,101, 32,102,105,108,101,110, 97, - 109,101, 44, 32, 97,110,100, 32, 97,110,121, 32,101,120,116, - 114, 97, 32, 97,114,103,117,109,101,110,116,115, 10, 45, 45, - 32,112, 97,115,115,101,100, 32,116,111, 32, 36,105,102,105, - 108,101, 46, 32,110,111, 32,114,101,116,117,114,110, 32,118, - 97,108,117,101, 10,102,117,110, 99,116,105,111,110, 32,105, - 110, 99,108,117,100,101, 95,102,105,108,101, 95,104,111,111, - 107, 40,116, 44, 32,102,105,108,101,110, 97,109,101, 44, 32, - 46, 46, 46, 41, 10, 10,101,110,100, 10, 10, 45, 45, 32, 99, - 97,108,108,101,100, 32, 97,102,116,101,114, 32,112,114,111, - 99,101,115,115,105,110,103, 32, 97,110,121,116,104,105,110, - 103, 32,116,104, 97,116, 39,115, 32,110,111,116, 32, 99,111, - 100,101, 32, 40,108,105,107,101, 32, 39, 36,114,101,110, 97, - 109,105,110,103, 39, 44, 32, 99,111,109,109,101,110,116,115, - 44, 32,101,116, 99, 41, 10, 45, 45, 32, 97,110,100, 32,114, - 105,103,104,116, 32, 98,101,102,111,114,101, 32,112, 97,114, - 115,105,110,103, 32,116,104,101, 32, 97, 99,116,117, 97,108, - 32, 99,111,100,101, 46, 10, 45, 45, 32,116, 97,107,101,115, - 32,116,104,101, 32, 80, 97, 99,107, 97,103,101, 32,111, 98, - 106,101, 99,116, 32,119,105,116,104, 32, 97,108,108, 32,116, - 104,101, 32, 99,111,100,101, 32,111,110, 32,116,104,101, 32, - 39, 99,111,100,101, 39, 32,107,101,121, 46, 32,110,111, 32, - 114,101,116,117,114,110, 32,118, 97,108,117,101, 10,102,117, - 110, 99,116,105,111,110, 32,112,114,101,112, 97,114,115,101, - 95,104,111,111,107, 40,112, 97, 99,107, 97,103,101, 41, 10, - 10,101,110,100, 10, 10, 45, 45, 32, 99, 97,108,108,101,100, - 32, 98,101,102,111,114,101, 32,115,116, 97,114,116,105,110, - 103, 32,111,117,116,112,117,116, 10,102,117,110, 99,116,105, - 111,110, 32,112,114,101, 95,111,117,116,112,117,116, 95,104, - 111,111,107, 40,112, 97, 99,107, 97,103,101, 41, 10, 10,101, - 110,100, 10, 10, 45, 45, 32, 99, 97,108,108,101,100, 32, 97, - 102,116,101,114, 32,119,114,105,116,105,110,103, 32, 97,108, - 108, 32,116,104,101, 32,111,117,116,112,117,116, 46, 10, 45, - 45, 32,116, 97,107,101,115, 32,116,104,101, 32, 80, 97, 99, - 107, 97,103,101, 32,111, 98,106,101, 99,116, 10,102,117,110, - 99,116,105,111,110, 32,112,111,115,116, 95,111,117,116,112, - 117,116, 95,104,111,111,107, 40,112, 97, 99,107, 97,103,101, - 41, 10, 10,101,110,100, 10, 10, 10, 45, 45, 32, 99, 97,108, - 108,101,100, 32,102,114,111,109, 32, 39,103,101,116, 95,112, - 114,111,112,101,114,116,121, 95,109,101,116,104,111,100,115, - 39, 32,116,111, 32,103,101,116, 32,116,104,101, 32,109,101, - 116,104,111,100,115, 32,116,111, 32,114,101,116,114,105,101, - 118,101, 32, 97, 32,112,114,111,112,101,114,116,121, 10, 45, - 45, 32, 97, 99, 99,111,114,100,105,110,103, 32,116,111, 32, - 105,116,115, 32,116,121,112,101, 10,102,117,110, 99,116,105, - 111,110, 32,103,101,116, 95,112,114,111,112,101,114,116,121, - 95,109,101,116,104,111,100,115, 95,104,111,111,107, 40,112, - 114,111,112,101,114,116,121, 95,116,121,112,101, 44, 32,110, - 97,109,101, 41, 10, 10,101,110,100, 10, 10, 45, 45, 32, 99, - 97,108,108,101,100, 32,102,114,111,109, 32, 67,108, 97,115, - 115, 67,111,110,116, 97,105,110,101,114, 58,100,111,112, 97, - 114,115,101, 32,119,105,116,104, 32,116,104,101, 32,115,116, - 114,105,110,103, 32, 98,101,105,110,103, 32,112, 97,114,115, - 101,100, 10, 45, 45, 32,114,101,116,117,114,110, 32,110,105, - 108, 44, 32,111,114, 32, 97, 32,115,117, 98,115,116,114,105, - 110,103, 10,102,117,110, 99,116,105,111,110, 32,112, 97,114, - 115,101,114, 95,104,111,111,107, 40,115, 41, 10, 10, 9,114, - 101,116,117,114,110, 32,110,105,108, 10,101,110,100, 10, 10, - 45, 45, 32, 99, 97,108,108,101,100, 32,102,114,111,109, 32, - 99,108, 97,115,115, 70,117,110, 99,116,105,111,110, 58,115, - 117,112, 99,111,100,101, 44, 32, 98,101,102,111,114,101, 32, - 116,104,101, 32, 99, 97,108,108, 32,116,111, 32,116,104,101, - 32,102,117,110, 99,116,105,111,110, 32,105,115, 32,111,117, - 116,112,117,116, 10,102,117,110, 99,116,105,111,110, 32,112, - 114,101, 95, 99, 97,108,108, 95,104,111,111,107, 40,102, 41, - 10, 10,101,110,100, 10, 10, 45, 45, 32, 99, 97,108,108,101, - 100, 32,102,114,111,109, 32, 99,108, 97,115,115, 70,117,110, - 99,116,105,111,110, 58,115,117,112, 99,111,100,101, 44, 32, - 97,102,116,101,114, 32,116,104,101, 32, 99, 97,108,108, 32, - 116,111, 32,116,104,101, 32,102,117,110, 99,116,105,111,110, - 32,105,115, 32,111,117,116,112,117,116, 10,102,117,110, 99, - 116,105,111,110, 32,112,111,115,116, 95, 99, 97,108,108, 95, - 104,111,111,107, 40,102, 41, 10, 10,101,110,100, 10, 10, 45, - 45, 32, 99, 97,108,108,101,100, 32, 98,101,102,111,114,101, - 32,116,104,101, 32,114,101,103,105,115,116,101,114, 32, 99, - 111,100,101, 32,105,115, 32,111,117,116,112,117,116, 10,102, - 117,110, 99,116,105,111,110, 32,112,114,101, 95,114,101,103, - 105,115,116,101,114, 95,104,111,111,107, 40,112, 97, 99,107, - 97,103,101, 41, 10, 10,101,110,100, 10, 10, 45, 45, 32, 99, - 97,108,108,101,100, 32,116,111, 32,111,117,116,112,117,116, - 32, 97,110, 32,101,114,114,111,114, 32,109,101,115,115, 97, - 103,101, 10,102,117,110, 99,116,105,111,110, 32,111,117,116, - 112,117,116, 95,101,114,114,111,114, 95,104,111,111,107, 40, - 46, 46, 46, 41, 10, 9,114,101,116,117,114,110, 32,115,116, - 114,105,110,103, 46,102,111,114,109, 97,116, 40, 46, 46, 46, - 41, 10,101,110,100, 10, 10, 45, 45, 32, 99,117,115,116,111, - 109, 32,112,117,115,104,101,114,115, 10, 10, 95,112,117,115, - 104, 95,102,117,110, 99,116,105,111,110,115, 32, 61, 32,123, - 125, 10, 95,105,115, 95,102,117,110, 99,116,105,111,110,115, - 32, 61, 32,123,125, 10, 95,116,111, 95,102,117,110, 99,116, - 105,111,110,115, 32, 61, 32,123,125, 10, 10, 95, 98, 97,115, - 101, 95,112,117,115,104, 95,102,117,110, 99,116,105,111,110, - 115, 32, 61, 32,123,125, 10, 95, 98, 97,115,101, 95,105,115, - 95,102,117,110, 99,116,105,111,110,115, 32, 61, 32,123,125, - 10, 95, 98, 97,115,101, 95,116,111, 95,102,117,110, 99,116, - 105,111,110,115, 32, 61, 32,123,125, 10, 10,108,111, 99, 97, - 108, 32,102,117,110, 99,116,105,111,110, 32,115,101, 97,114, - 99,104, 95, 98, 97,115,101, 40,116, 44, 32,102,117,110, 99, - 115, 41, 10, 10, 9,108,111, 99, 97,108, 32, 99,108, 97,115, - 115, 32, 61, 32, 95,103,108,111, 98, 97,108, 95, 99,108, 97, - 115,115,101,115, 91,116, 93, 10, 10, 9,119,104,105,108,101, - 32, 99,108, 97,115,115, 32,100,111, 10, 9, 9,105,102, 32, - 102,117,110, 99,115, 91, 99,108, 97,115,115, 46,116,121,112, - 101, 93, 32,116,104,101,110, 10, 9, 9, 9,114,101,116,117, - 114,110, 32,102,117,110, 99,115, 91, 99,108, 97,115,115, 46, - 116,121,112,101, 93, 10, 9, 9,101,110,100, 10, 9, 9, 99, - 108, 97,115,115, 32, 61, 32, 95,103,108,111, 98, 97,108, 95, - 99,108, 97,115,115,101,115, 91, 99,108, 97,115,115, 46, 98, - 116,121,112,101, 93, 10, 9,101,110,100, 10, 9,114,101,116, - 117,114,110, 32,110,105,108, 10,101,110,100, 10, 10,102,117, - 110, 99,116,105,111,110, 32,103,101,116, 95,112,117,115,104, - 95,102,117,110, 99,116,105,111,110, 40,116, 41, 10, 9,114, - 101,116,117,114,110, 32, 95,112,117,115,104, 95,102,117,110, - 99,116,105,111,110,115, 91,116, 93, 32,111,114, 32,115,101, - 97,114, 99,104, 95, 98, 97,115,101, 40,116, 44, 32, 95, 98, - 97,115,101, 95,112,117,115,104, 95,102,117,110, 99,116,105, - 111,110,115, 41, 32,111,114, 32, 34,116,111,108,117, 97, 95, - 112,117,115,104,117,115,101,114,116,121,112,101, 34, 10,101, - 110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,103,101, - 116, 95,116,111, 95,102,117,110, 99,116,105,111,110, 40,116, - 41, 10, 9,114,101,116,117,114,110, 32, 95,116,111, 95,102, - 117,110, 99,116,105,111,110,115, 91,116, 93, 32,111,114, 32, - 115,101, 97,114, 99,104, 95, 98, 97,115,101, 40,116, 44, 32, - 95, 98, 97,115,101, 95,116,111, 95,102,117,110, 99,116,105, - 111,110,115, 41, 32,111,114, 32, 34,116,111,108,117, 97, 95, - 116,111,117,115,101,114,116,121,112,101, 34, 10,101,110,100, - 10, 10,102,117,110, 99,116,105,111,110, 32,103,101,116, 95, - 105,115, 95,102,117,110, 99,116,105,111,110, 40,116, 41, 10, - 9,114,101,116,117,114,110, 32, 95,105,115, 95,102,117,110, - 99,116,105,111,110,115, 91,116, 93, 32,111,114, 32,115,101, - 97,114, 99,104, 95, 98, 97,115,101, 40,116, 44, 32, 95, 98, - 97,115,101, 95,105,115, 95,102,117,110, 99,116,105,111,110, - 115, 41, 32,111,114, 32, 34,116,111,108,117, 97, 95,105,115, - 117,115,101,114,116,121,112,101, 34, 10,101,110,100,32 - }; - tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua embedded: src/bin/lua/basic.lua"); + #include "basic_lua.h" + tolua_dobuffer(tolua_S,(char*)lua_basic_lua,sizeof(lua_basic_lua),"tolua embedded: src/bin/lua/basic.lua"); lua_settop(tolua_S, top); } /* end of embedded lua code */ @@ -1608,1170 +1013,8 @@ TOLUA_API int tolua_tolua_open (lua_State* tolua_S) { /* begin embedded lua code */ int top = lua_gettop(tolua_S); - static unsigned char B[] = { - 45, 45, 32,116,111,108,117, 97, 58, 32, 99,111,110,116, 97, - 105,110,101,114, 32, 97, 98,115,116,114, 97, 99,116, 32, 99, - 108, 97,115,115, 10, 45, 45, 32, 87,114,105,116,116,101,110, - 32, 98,121, 32, 87, 97,108,100,101,109, 97,114, 32, 67,101, - 108,101,115, 10, 45, 45, 32, 84,101, 67, 71,114, 97,102, 47, - 80, 85, 67, 45, 82,105,111, 10, 45, 45, 32, 74,117,108, 32, - 49, 57, 57, 56, 10, 45, 45, 32, 36, 73,100, 58, 32, 36, 10, - 10, 45, 45, 32, 84,104,105,115, 32, 99,111,100,101, 32,105, - 115, 32,102,114,101,101, 32,115,111,102,116,119, 97,114,101, - 59, 32,121,111,117, 32, 99, 97,110, 32,114,101,100,105,115, - 116,114,105, 98,117,116,101, 32,105,116, 32, 97,110,100, 47, - 111,114, 32,109,111,100,105,102,121, 32,105,116, 46, 10, 45, - 45, 32, 84,104,101, 32,115,111,102,116,119, 97,114,101, 32, - 112,114,111,118,105,100,101,100, 32,104,101,114,101,117,110, - 100,101,114, 32,105,115, 32,111,110, 32, 97,110, 32, 34, 97, - 115, 32,105,115, 34, 32, 98, 97,115,105,115, 44, 32, 97,110, - 100, 10, 45, 45, 32,116,104,101, 32, 97,117,116,104,111,114, - 32,104, 97,115, 32,110,111, 32,111, 98,108,105,103, 97,116, - 105,111,110, 32,116,111, 32,112,114,111,118,105,100,101, 32, - 109, 97,105,110,116,101,110, 97,110, 99,101, 44, 32,115,117, - 112,112,111,114,116, 44, 32,117,112,100, 97,116,101,115, 44, - 10, 45, 45, 32,101,110,104, 97,110, 99,101,109,101,110,116, - 115, 44, 32,111,114, 32,109,111,100,105,102,105, 99, 97,116, - 105,111,110,115, 46, 10, 10, 45, 45, 32,116, 97, 98,108,101, - 32,116,111, 32,115,116,111,114,101, 32,110, 97,109,101,115, - 112, 97, 99,101,100, 32,116,121,112,101,100,101,102,115, 47, - 101,110,117,109,115, 32,105,110, 32,103,108,111, 98, 97,108, - 32,115, 99,111,112,101, 10,103,108,111, 98, 97,108, 95,116, - 121,112,101,100,101,102,115, 32, 61, 32,123,125, 10,103,108, - 111, 98, 97,108, 95,101,110,117,109,115, 32, 61, 32,123,125, - 10, 10, 45, 45, 32, 67,111,110,116, 97,105,110,101,114, 32, - 99,108, 97,115,115, 10, 45, 45, 32, 82,101,112,114,101,115, - 101,110,116,115, 32, 97, 32, 99,111,110,116, 97,105,110,101, - 114, 32,111,102, 32,102,101, 97,116,117,114,101,115, 32,116, - 111, 32, 98,101, 32, 98,111,117,110,100, 10, 45, 45, 32,116, - 111, 32,108,117, 97, 46, 10, 99,108, 97,115,115, 67,111,110, - 116, 97,105,110,101,114, 32, 61, 10,123, 10, 32, 99,117,114, - 114, 32, 61, 32,110,105,108, 44, 10,125, 10, 99,108, 97,115, - 115, 67,111,110,116, 97,105,110,101,114, 46, 95, 95,105,110, - 100,101,120, 32, 61, 32, 99,108, 97,115,115, 67,111,110,116, - 97,105,110,101,114, 10,115,101,116,109,101,116, 97,116, 97, - 98,108,101, 40, 99,108, 97,115,115, 67,111,110,116, 97,105, - 110,101,114, 44, 99,108, 97,115,115, 70,101, 97,116,117,114, - 101, 41, 10, 10, 45, 45, 32,111,117,116,112,117,116, 32,116, - 97,103,115, 10,102,117,110, 99,116,105,111,110, 32, 99,108, - 97,115,115, 67,111,110,116, 97,105,110,101,114, 58,100,101, - 99,108,116,121,112,101, 32, 40, 41, 10, 32,112,117,115,104, - 40,115,101,108,102, 41, 10, 32,108,111, 99, 97,108, 32,105, - 61, 49, 10, 32,119,104,105,108,101, 32,115,101,108,102, 91, - 105, 93, 32,100,111, 10, 32, 32,115,101,108,102, 91,105, 93, - 58,100,101, 99,108,116,121,112,101, 40, 41, 10, 32, 32,105, - 32, 61, 32,105, 43, 49, 10, 32,101,110,100, 10, 32,112,111, - 112, 40, 41, 10,101,110,100, 10, 10, 10, 45, 45, 32,119,114, - 105,116,101, 32,115,117,112,112,111,114,116, 32, 99,111,100, - 101, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,115, - 115, 67,111,110,116, 97,105,110,101,114, 58,115,117,112, 99, - 111,100,101, 32, 40, 41, 10, 10, 9,105,102, 32,110,111,116, - 32,115,101,108,102, 58, 99,104,101, 99,107, 95,112,117, 98, - 108,105, 99, 95, 97, 99, 99,101,115,115, 40, 41, 32,116,104, - 101,110, 10, 9, 9,114,101,116,117,114,110, 10, 9,101,110, - 100, 10, 10, 32,112,117,115,104, 40,115,101,108,102, 41, 10, - 32,108,111, 99, 97,108, 32,105, 61, 49, 10, 32,119,104,105, - 108,101, 32,115,101,108,102, 91,105, 93, 32,100,111, 10, 32, - 32,105,102, 32,115,101,108,102, 91,105, 93, 58, 99,104,101, - 99,107, 95,112,117, 98,108,105, 99, 95, 97, 99, 99,101,115, - 115, 40, 41, 32,116,104,101,110, 10, 32, 32, 9,115,101,108, - 102, 91,105, 93, 58,115,117,112, 99,111,100,101, 40, 41, 10, - 32, 32,101,110,100, 10, 32, 32,105, 32, 61, 32,105, 43, 49, - 10, 32,101,110,100, 10, 32,112,111,112, 40, 41, 10,101,110, - 100, 10, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97, - 115,115, 67,111,110,116, 97,105,110,101,114, 58,104, 97,115, - 118, 97,114, 32, 40, 41, 10, 32,108,111, 99, 97,108, 32,105, - 61, 49, 10, 32,119,104,105,108,101, 32,115,101,108,102, 91, - 105, 93, 32,100,111, 10, 32, 32,105,102, 32,115,101,108,102, - 91,105, 93, 58,105,115,118, 97,114,105, 97, 98,108,101, 40, - 41, 32,116,104,101,110, 10, 9, 9, 32,114,101,116,117,114, - 110, 32, 49, 10, 9, 9,101,110,100, 10, 32, 32,105, 32, 61, - 32,105, 43, 49, 10, 32,101,110,100, 10, 9,114,101,116,117, - 114,110, 32, 48, 10,101,110,100, 10, 10, 45, 45, 32, 73,110, - 116,101,114,110, 97,108, 32, 99,111,110,116, 97,105,110,101, - 114, 32, 99,111,110,115,116,114,117, 99,116,111,114, 10,102, - 117,110, 99,116,105,111,110, 32, 95, 67,111,110,116, 97,105, - 110,101,114, 32, 40,115,101,108,102, 41, 10, 32,115,101,116, - 109,101,116, 97,116, 97, 98,108,101, 40,115,101,108,102, 44, - 99,108, 97,115,115, 67,111,110,116, 97,105,110,101,114, 41, - 10, 32,115,101,108,102, 46,110, 32, 61, 32, 48, 10, 32,115, - 101,108,102, 46,116,121,112,101,100,101,102,115, 32, 61, 32, - 123,116,111,108,117, 97, 95,110, 61, 48,125, 10, 32,115,101, - 108,102, 46,117,115,101,114,116,121,112,101,115, 32, 61, 32, - 123,125, 10, 32,115,101,108,102, 46,101,110,117,109,115, 32, - 61, 32,123,116,111,108,117, 97, 95,110, 61, 48,125, 10, 32, - 115,101,108,102, 46,108,110, 97,109,101,115, 32, 61, 32,123, - 125, 10, 32,114,101,116,117,114,110, 32,115,101,108,102, 10, - 101,110,100, 10, 10, 45, 45, 32,112,117,115,104, 32, 99,111, - 110,116, 97,105,110,101,114, 10,102,117,110, 99,116,105,111, - 110, 32,112,117,115,104, 32, 40,116, 41, 10, 9,116, 46,112, - 114,111,120, 32, 61, 32, 99,108, 97,115,115, 67,111,110,116, - 97,105,110,101,114, 46, 99,117,114,114, 10, 32, 99,108, 97, - 115,115, 67,111,110,116, 97,105,110,101,114, 46, 99,117,114, - 114, 32, 61, 32,116, 10,101,110,100, 10, 10, 45, 45, 32,112, - 111,112, 32, 99,111,110,116, 97,105,110,101,114, 10,102,117, - 110, 99,116,105,111,110, 32,112,111,112, 32, 40, 41, 10, 45, - 45,112,114,105,110,116, 40, 34,110, 97,109,101, 34, 44, 99, - 108, 97,115,115, 67,111,110,116, 97,105,110,101,114, 46, 99, - 117,114,114, 46,110, 97,109,101, 41, 10, 45, 45,102,111,114, - 101, 97, 99,104, 40, 99,108, 97,115,115, 67,111,110,116, 97, - 105,110,101,114, 46, 99,117,114,114, 46,117,115,101,114,116, - 121,112,101,115, 44,112,114,105,110,116, 41, 10, 45, 45,112, - 114,105,110,116, 40, 34, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 34, 41, 10, 32, 99,108, 97,115,115, 67, - 111,110,116, 97,105,110,101,114, 46, 99,117,114,114, 32, 61, - 32, 99,108, 97,115,115, 67,111,110,116, 97,105,110,101,114, - 46, 99,117,114,114, 46,112,114,111,120, 10,101,110,100, 10, - 10, 45, 45, 32,103,101,116, 32, 99,117,114,114,101,110,116, - 32,110, 97,109,101,115,112, 97, 99,101, 10,102,117,110, 99, - 116,105,111,110, 32,103,101,116, 99,117,114,114,110, 97,109, - 101,115,112, 97, 99,101, 32, 40, 41, 10, 9,114,101,116,117, - 114,110, 32,103,101,116,110, 97,109,101,115,112, 97, 99,101, - 40, 99,108, 97,115,115, 67,111,110,116, 97,105,110,101,114, - 46, 99,117,114,114, 41, 10,101,110,100, 10, 10, 45, 45, 32, - 97,112,112,101,110,100, 32,116,111, 32, 99,117,114,114,101, - 110,116, 32, 99,111,110,116, 97,105,110,101,114, 10,102,117, - 110, 99,116,105,111,110, 32, 97,112,112,101,110,100, 32, 40, - 116, 41, 10, 32,114,101,116,117,114,110, 32, 99,108, 97,115, - 115, 67,111,110,116, 97,105,110,101,114, 46, 99,117,114,114, - 58, 97,112,112,101,110,100, 40,116, 41, 10,101,110,100, 10, - 10, 45, 45, 32, 97,112,112,101,110,100, 32,116,121,112,101, - 100,101,102, 32,116,111, 32, 99,117,114,114,101,110,116, 32, - 99,111,110,116, 97,105,110,101,114, 10,102,117,110, 99,116, - 105,111,110, 32, 97,112,112,101,110,100,116,121,112,101,100, - 101,102, 32, 40,116, 41, 10, 32,114,101,116,117,114,110, 32, - 99,108, 97,115,115, 67,111,110,116, 97,105,110,101,114, 46, - 99,117,114,114, 58, 97,112,112,101,110,100,116,121,112,101, - 100,101,102, 40,116, 41, 10,101,110,100, 10, 10, 45, 45, 32, - 97,112,112,101,110,100, 32,117,115,101,114,116,121,112,101, - 32,116,111, 32, 99,117,114,114,101,110,116, 32, 99,111,110, - 116, 97,105,110,101,114, 10,102,117,110, 99,116,105,111,110, - 32, 97,112,112,101,110,100,117,115,101,114,116,121,112,101, - 32, 40,116, 41, 10, 32,114,101,116,117,114,110, 32, 99,108, - 97,115,115, 67,111,110,116, 97,105,110,101,114, 46, 99,117, - 114,114, 58, 97,112,112,101,110,100,117,115,101,114,116,121, - 112,101, 40,116, 41, 10,101,110,100, 10, 10, 45, 45, 32, 97, - 112,112,101,110,100, 32,101,110,117,109, 32,116,111, 32, 99, - 117,114,114,101,110,116, 32, 99,111,110,116, 97,105,110,101, - 114, 10,102,117,110, 99,116,105,111,110, 32, 97,112,112,101, - 110,100,101,110,117,109, 32, 40,116, 41, 10, 32,114,101,116, - 117,114,110, 32, 99,108, 97,115,115, 67,111,110,116, 97,105, - 110,101,114, 46, 99,117,114,114, 58, 97,112,112,101,110,100, - 101,110,117,109, 40,116, 41, 10,101,110,100, 10, 10, 45, 45, - 32,115,117, 98,115,116,105,116,117,116,101, 32,116,121,112, - 101,100,101,102, 10,102,117,110, 99,116,105,111,110, 32, 97, - 112,112,108,121,116,121,112,101,100,101,102, 32, 40,109,111, - 100, 44,116,121,112,101, 41, 10, 32,114,101,116,117,114,110, - 32, 99,108, 97,115,115, 67,111,110,116, 97,105,110,101,114, - 46, 99,117,114,114, 58, 97,112,112,108,121,116,121,112,101, - 100,101,102, 40,109,111,100, 44,116,121,112,101, 41, 10,101, - 110,100, 10, 10, 45, 45, 32, 99,104,101, 99,107, 32,105,102, - 32,105,115, 32,116,121,112,101, 10,102,117,110, 99,116,105, - 111,110, 32,102,105,110,100,116,121,112,101, 32, 40,116,121, - 112,101, 41, 10, 32,108,111, 99, 97,108, 32,116, 32, 61, 32, - 99,108, 97,115,115, 67,111,110,116, 97,105,110,101,114, 46, - 99,117,114,114, 58,102,105,110,100,116,121,112,101, 40,116, - 121,112,101, 41, 10, 9,114,101,116,117,114,110, 32,116, 10, - 101,110,100, 10, 10, 45, 45, 32, 99,104,101, 99,107, 32,105, - 102, 32,105,115, 32,116,121,112,101,100,101,102, 10,102,117, - 110, 99,116,105,111,110, 32,105,115,116,121,112,101,100,101, - 102, 32, 40,116,121,112,101, 41, 10, 32,114,101,116,117,114, - 110, 32, 99,108, 97,115,115, 67,111,110,116, 97,105,110,101, - 114, 46, 99,117,114,114, 58,105,115,116,121,112,101,100,101, - 102, 40,116,121,112,101, 41, 10,101,110,100, 10, 10, 45, 45, - 32,103,101,116, 32,102,117,108,108,116,121,112,101, 32, 40, - 119,105,116,104, 32,110, 97,109,101,115,112, 97, 99,101, 41, - 10,102,117,110, 99,116,105,111,110, 32,102,117,108,108,116, - 121,112,101, 32, 40,116, 41, 10, 32,108,111, 99, 97,108, 32, - 99,117,114,114, 32, 61, 32, 32, 99,108, 97,115,115, 67,111, - 110,116, 97,105,110,101,114, 46, 99,117,114,114, 10, 9,119, - 104,105,108,101, 32, 99,117,114,114, 32,100,111, 10, 9, 32, - 105,102, 32, 99,117,114,114, 32,116,104,101,110, 10, 9, 9, - 32,105,102, 32, 99,117,114,114, 46,116,121,112,101,100,101, - 102,115, 32, 97,110,100, 32, 99,117,114,114, 46,116,121,112, - 101,100,101,102,115, 91,116, 93, 32,116,104,101,110, 10, 9, - 9, 32, 32,114,101,116,117,114,110, 32, 99,117,114,114, 46, - 116,121,112,101,100,101,102,115, 91,116, 93, 10, 9, 9, 32, - 101,108,115,101,105,102, 32, 99,117,114,114, 46,117,115,101, - 114,116,121,112,101,115, 32, 97,110,100, 32, 99,117,114,114, - 46,117,115,101,114,116,121,112,101,115, 91,116, 93, 32,116, - 104,101,110, 10, 9, 9, 32, 32,114,101,116,117,114,110, 32, - 99,117,114,114, 46,117,115,101,114,116,121,112,101,115, 91, - 116, 93, 10, 9, 9, 9,101,110,100, 10, 9, 9,101,110,100, - 10, 9, 32, 99,117,114,114, 32, 61, 32, 99,117,114,114, 46, - 112,114,111,120, 10, 9,101,110,100, 10, 9,114,101,116,117, - 114,110, 32,116, 10,101,110,100, 10, 10, 45, 45, 32, 99,104, - 101, 99,107,115, 32,105,102, 32,105,116, 32,114,101,113,117, - 105,114,101,115, 32, 99,111,108,108,101, 99,116,105,111,110, - 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, - 67,111,110,116, 97,105,110,101,114, 58,114,101,113,117,105, - 114,101, 99,111,108,108,101, 99,116,105,111,110, 32, 40,116, - 41, 10, 32,112,117,115,104, 40,115,101,108,102, 41, 10, 32, - 108,111, 99, 97,108, 32,105, 61, 49, 10, 9,108,111, 99, 97, - 108, 32,114, 32, 61, 32,102, 97,108,115,101, 10, 32,119,104, - 105,108,101, 32,115,101,108,102, 91,105, 93, 32,100,111, 10, - 32, 32,114, 32, 61, 32,115,101,108,102, 91,105, 93, 58,114, - 101,113,117,105,114,101, 99,111,108,108,101, 99,116,105,111, - 110, 40,116, 41, 32,111,114, 32,114, 10, 32, 32,105, 32, 61, - 32,105, 43, 49, 10, 32,101,110,100, 10, 9,112,111,112, 40, - 41, 10, 9,114,101,116,117,114,110, 32,114, 10,101,110,100, - 10, 10, 10, 45, 45, 32,103,101,116, 32,110, 97,109,101,115, - 97,112, 99,101, 10,102,117,110, 99,116,105,111,110, 32,103, - 101,116,110, 97,109,101,115,112, 97, 99,101, 32, 40, 99,117, - 114,114, 41, 10, 9,108,111, 99, 97,108, 32,110, 97,109,101, - 115,112, 97, 99,101, 32, 61, 32, 39, 39, 10, 9,119,104,105, - 108,101, 32, 99,117,114,114, 32,100,111, 10, 9, 32,105,102, - 32, 99,117,114,114, 32, 97,110,100, 10, 9, 9, 32, 32, 32, - 40, 32, 99,117,114,114, 46, 99,108, 97,115,115,116,121,112, - 101, 32, 61, 61, 32, 39, 99,108, 97,115,115, 39, 32,111,114, - 32, 99,117,114,114, 46, 99,108, 97,115,115,116,121,112,101, - 32, 61, 61, 32, 39,110, 97,109,101,115,112, 97, 99,101, 39, - 41, 10, 9, 9,116,104,101,110, 10, 9, 9, 32,110, 97,109, - 101,115,112, 97, 99,101, 32, 61, 32, 40, 99,117,114,114, 46, - 111,114,105,103,105,110, 97,108, 95,110, 97,109,101, 32,111, - 114, 32, 99,117,114,114, 46,110, 97,109,101, 41, 32, 46, 46, - 32, 39, 58, 58, 39, 32, 46, 46, 32,110, 97,109,101,115,112, - 97, 99,101, 10, 9, 9, 32, 45, 45,110, 97,109,101,115,112, - 97, 99,101, 32, 61, 32, 99,117,114,114, 46,110, 97,109,101, - 32, 46, 46, 32, 39, 58, 58, 39, 32, 46, 46, 32,110, 97,109, - 101,115,112, 97, 99,101, 10, 9, 9,101,110,100, 10, 9, 32, - 99,117,114,114, 32, 61, 32, 99,117,114,114, 46,112,114,111, - 120, 10, 9,101,110,100, 10, 9,114,101,116,117,114,110, 32, - 110, 97,109,101,115,112, 97, 99,101, 10,101,110,100, 10, 10, - 45, 45, 32,103,101,116, 32,110, 97,109,101,115,112, 97, 99, - 101, 32, 40,111,110,108,121, 32,110, 97,109,101,115,112, 97, - 99,101, 41, 10,102,117,110, 99,116,105,111,110, 32,103,101, - 116,111,110,108,121,110, 97,109,101,115,112, 97, 99,101, 32, - 40, 41, 10, 32,108,111, 99, 97,108, 32, 99,117,114,114, 32, - 61, 32, 99,108, 97,115,115, 67,111,110,116, 97,105,110,101, - 114, 46, 99,117,114,114, 10, 9,108,111, 99, 97,108, 32,110, - 97,109,101,115,112, 97, 99,101, 32, 61, 32, 39, 39, 10, 9, - 119,104,105,108,101, 32, 99,117,114,114, 32,100,111, 10, 9, - 9,105,102, 32, 99,117,114,114, 46, 99,108, 97,115,115,116, - 121,112,101, 32, 61, 61, 32, 39, 99,108, 97,115,115, 39, 32, - 116,104,101,110, 10, 9, 9, 32,114,101,116,117,114,110, 32, - 110, 97,109,101,115,112, 97, 99,101, 10, 9, 9,101,108,115, - 101,105,102, 32, 99,117,114,114, 46, 99,108, 97,115,115,116, - 121,112,101, 32, 61, 61, 32, 39,110, 97,109,101,115,112, 97, - 99,101, 39, 32,116,104,101,110, 10, 9, 9, 32,110, 97,109, - 101,115,112, 97, 99,101, 32, 61, 32, 99,117,114,114, 46,110, - 97,109,101, 32, 46, 46, 32, 39, 58, 58, 39, 32, 46, 46, 32, - 110, 97,109,101,115,112, 97, 99,101, 10, 9, 9,101,110,100, - 10, 9, 32, 99,117,114,114, 32, 61, 32, 99,117,114,114, 46, - 112,114,111,120, 10, 9,101,110,100, 10, 9,114,101,116,117, - 114,110, 32,110, 97,109,101,115,112, 97, 99,101, 10,101,110, - 100, 10, 10, 45, 45, 32, 99,104,101, 99,107, 32,105,102, 32, - 105,115, 32,101,110,117,109, 10,102,117,110, 99,116,105,111, - 110, 32,105,115,101,110,117,109, 32, 40,116,121,112,101, 41, - 10, 32,114,101,116,117,114,110, 32, 99,108, 97,115,115, 67, - 111,110,116, 97,105,110,101,114, 46, 99,117,114,114, 58,105, - 115,101,110,117,109, 40,116,121,112,101, 41, 10,101,110,100, - 10, 10, 45, 45, 32, 97,112,112,101,110,100, 32,102,101, 97, - 116,117,114,101, 32,116,111, 32, 99,111,110,116, 97,105,110, - 101,114, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97, - 115,115, 67,111,110,116, 97,105,110,101,114, 58, 97,112,112, - 101,110,100, 32, 40,116, 41, 10, 32,115,101,108,102, 46,110, - 32, 61, 32,115,101,108,102, 46,110, 32, 43, 32, 49, 10, 32, - 115,101,108,102, 91,115,101,108,102, 46,110, 93, 32, 61, 32, - 116, 10, 32,116, 46,112, 97,114,101,110,116, 32, 61, 32,115, - 101,108,102, 10,101,110,100, 10, 10, 45, 45, 32, 97,112,112, - 101,110,100, 32,116,121,112,101,100,101,102, 10,102,117,110, - 99,116,105,111,110, 32, 99,108, 97,115,115, 67,111,110,116, - 97,105,110,101,114, 58, 97,112,112,101,110,100,116,121,112, - 101,100,101,102, 32, 40,116, 41, 10, 32,108,111, 99, 97,108, - 32,110, 97,109,101,115,112, 97, 99,101, 32, 61, 32,103,101, - 116,110, 97,109,101,115,112, 97, 99,101, 40, 99,108, 97,115, - 115, 67,111,110,116, 97,105,110,101,114, 46, 99,117,114,114, - 41, 10, 32,115,101,108,102, 46,116,121,112,101,100,101,102, - 115, 46,116,111,108,117, 97, 95,110, 32, 61, 32,115,101,108, - 102, 46,116,121,112,101,100,101,102,115, 46,116,111,108,117, - 97, 95,110, 32, 43, 32, 49, 10, 32,115,101,108,102, 46,116, - 121,112,101,100,101,102,115, 91,115,101,108,102, 46,116,121, - 112,101,100,101,102,115, 46,116,111,108,117, 97, 95,110, 93, - 32, 61, 32,116, 10, 9,115,101,108,102, 46,116,121,112,101, - 100,101,102,115, 91,116, 46,117,116,121,112,101, 93, 32, 61, - 32,110, 97,109,101,115,112, 97, 99,101, 32, 46, 46, 32,116, - 46,117,116,121,112,101, 10, 9,103,108,111, 98, 97,108, 95, - 116,121,112,101,100,101,102,115, 91,110, 97,109,101,115,112, - 97, 99,101, 46, 46,116, 46,117,116,121,112,101, 93, 32, 61, - 32,116, 10, 9,116, 46,102,116,121,112,101, 32, 61, 32,102, - 105,110,100,116,121,112,101, 40,116, 46,116,121,112,101, 41, - 32,111,114, 32,116, 46,116,121,112,101, 10, 9, 45, 45,112, - 114,105,110,116, 40, 34, 97,112,112,101,110,100,105,110,103, - 32,116,121,112,101,100,101,102, 32, 34, 46, 46,116, 46,117, - 116,121,112,101, 46, 46, 34, 32, 97,115, 32, 34, 46, 46,110, - 97,109,101,115,112, 97, 99,101, 46, 46,116, 46,117,116,121, - 112,101, 46, 46, 34, 32,119,105,116,104, 32,102,116,121,112, - 101, 32, 34, 46, 46,116, 46,102,116,121,112,101, 41, 10, 9, - 97,112,112,101,110,100, 95,103,108,111, 98, 97,108, 95,116, - 121,112,101, 40,110, 97,109,101,115,112, 97, 99,101, 46, 46, - 116, 46,117,116,121,112,101, 41, 10, 9,105,102, 32,116, 46, - 102,116,121,112,101, 32, 97,110,100, 32,105,115,101,110,117, - 109, 40,116, 46,102,116,121,112,101, 41, 32,116,104,101,110, - 10, 10, 9, 9,103,108,111, 98, 97,108, 95,101,110,117,109, - 115, 91,110, 97,109,101,115,112, 97, 99,101, 46, 46,116, 46, - 117,116,121,112,101, 93, 32, 61, 32,116,114,117,101, 10, 9, - 101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 97,112,112, - 101,110,100, 32,117,115,101,114,116,121,112,101, 58, 32,114, - 101,116,117,114,110, 32,102,117,108,108, 32,116,121,112,101, - 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, - 67,111,110,116, 97,105,110,101,114, 58, 97,112,112,101,110, - 100,117,115,101,114,116,121,112,101, 32, 40,116, 41, 10, 9, - 108,111, 99, 97,108, 32, 99,111,110,116, 97,105,110,101,114, - 10, 9,105,102, 32,116, 32, 61, 61, 32, 40,115,101,108,102, - 46,111,114,105,103,105,110, 97,108, 95,110, 97,109,101, 32, - 111,114, 32,115,101,108,102, 46,110, 97,109,101, 41, 32,116, - 104,101,110, 10, 9, 9, 99,111,110,116, 97,105,110,101,114, - 32, 61, 32,115,101,108,102, 46,112,114,111,120, 10, 9,101, - 108,115,101, 10, 9, 9, 99,111,110,116, 97,105,110,101,114, - 32, 61, 32,115,101,108,102, 10, 9,101,110,100, 10, 9,108, - 111, 99, 97,108, 32,102,116, 32, 61, 32,103,101,116,110, 97, - 109,101,115,112, 97, 99,101, 40, 99,111,110,116, 97,105,110, - 101,114, 41, 32, 46, 46, 32,116, 10, 9, 99,111,110,116, 97, - 105,110,101,114, 46,117,115,101,114,116,121,112,101,115, 91, - 116, 93, 32, 61, 32,102,116, 10, 9, 95,117,115,101,114,116, - 121,112,101, 91,102,116, 93, 32, 61, 32,102,116, 10, 9,114, - 101,116,117,114,110, 32,102,116, 10,101,110,100, 10, 10, 45, - 45, 32, 97,112,112,101,110,100, 32,101,110,117,109, 10,102, - 117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 67,111, - 110,116, 97,105,110,101,114, 58, 97,112,112,101,110,100,101, - 110,117,109, 32, 40,116, 41, 10, 32,108,111, 99, 97,108, 32, - 110, 97,109,101,115,112, 97, 99,101, 32, 61, 32,103,101,116, - 110, 97,109,101,115,112, 97, 99,101, 40, 99,108, 97,115,115, - 67,111,110,116, 97,105,110,101,114, 46, 99,117,114,114, 41, - 10, 32,115,101,108,102, 46,101,110,117,109,115, 46,116,111, - 108,117, 97, 95,110, 32, 61, 32,115,101,108,102, 46,101,110, - 117,109,115, 46,116,111,108,117, 97, 95,110, 32, 43, 32, 49, - 10, 32,115,101,108,102, 46,101,110,117,109,115, 91,115,101, - 108,102, 46,101,110,117,109,115, 46,116,111,108,117, 97, 95, - 110, 93, 32, 61, 32,116, 10, 9,103,108,111, 98, 97,108, 95, - 101,110,117,109,115, 91,110, 97,109,101,115,112, 97, 99,101, - 46, 46,116, 46,110, 97,109,101, 93, 32, 61, 32,116, 10,101, - 110,100, 10, 10, 45, 45, 32,100,101,116,101,114,109,105,110, - 101, 32,108,117, 97, 32,102,117,110, 99,116,105,111,110, 32, - 110, 97,109,101, 32,111,118,101,114,108,111, 97,100, 10,102, - 117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 67,111, - 110,116, 97,105,110,101,114, 58,111,118,101,114,108,111, 97, - 100, 32, 40,108,110, 97,109,101, 41, 10, 32,105,102, 32,110, - 111,116, 32,115,101,108,102, 46,108,110, 97,109,101,115, 91, - 108,110, 97,109,101, 93, 32,116,104,101,110, 10, 32, 32,115, - 101,108,102, 46,108,110, 97,109,101,115, 91,108,110, 97,109, - 101, 93, 32, 61, 32, 48, 10, 32,101,108,115,101, 10, 32, 32, - 115,101,108,102, 46,108,110, 97,109,101,115, 91,108,110, 97, - 109,101, 93, 32, 61, 32,115,101,108,102, 46,108,110, 97,109, - 101,115, 91,108,110, 97,109,101, 93, 32, 43, 32, 49, 10, 32, - 101,110,100, 10, 32,114,101,116,117,114,110, 32,102,111,114, - 109, 97,116, 40, 34, 37, 48, 50,100, 34, 44,115,101,108,102, - 46,108,110, 97,109,101,115, 91,108,110, 97,109,101, 93, 41, - 10,101,110,100, 10, 10, 45, 45, 32, 97,112,112,108,105,101, - 115, 32,116,121,112,101,100,101,102, 58, 32,114,101,116,117, - 114,110,115, 32,116,104,101, 32, 39,116,104,101, 32,102, 97, - 99,116,111, 39, 32,109,111,100,105,102,105,101,114, 32, 97, - 110,100, 32,116,121,112,101, 10,102,117,110, 99,116,105,111, - 110, 32, 99,108, 97,115,115, 67,111,110,116, 97,105,110,101, - 114, 58, 97,112,112,108,121,116,121,112,101,100,101,102, 32, - 40,109,111,100, 44,116,121,112,101, 41, 10, 9,105,102, 32, - 103,108,111, 98, 97,108, 95,116,121,112,101,100,101,102,115, - 91,116,121,112,101, 93, 32,116,104,101,110, 10, 9, 9, 45, - 45,112,114,105,110,116, 40, 34,102,111,117,110,100, 32,116, - 121,112,101,100,101,102, 32, 34, 46, 46,103,108,111, 98, 97, - 108, 95,116,121,112,101,100,101,102,115, 91,116,121,112,101, - 93, 46,116,121,112,101, 41, 10, 9, 9,108,111, 99, 97,108, - 32,109,111,100, 49, 44, 32,116,121,112,101, 49, 32, 61, 32, - 103,108,111, 98, 97,108, 95,116,121,112,101,100,101,102,115, - 91,116,121,112,101, 93, 46,109,111,100, 44, 32,103,108,111, - 98, 97,108, 95,116,121,112,101,100,101,102,115, 91,116,121, - 112,101, 93, 46,102,116,121,112,101, 10, 9, 9,108,111, 99, - 97,108, 32,109,111,100, 50, 44, 32,116,121,112,101, 50, 32, - 61, 32, 97,112,112,108,121,116,121,112,101,100,101,102, 40, - 109,111,100, 46, 46, 34, 32, 34, 46, 46,109,111,100, 49, 44, - 32,116,121,112,101, 49, 41, 10, 9, 9, 45, 45,114,101,116, - 117,114,110, 32,109,111,100, 50, 32, 46, 46, 32, 39, 32, 39, - 32, 46, 46, 32,109,111,100, 49, 44, 32,116,121,112,101, 50, - 10, 9, 9,114,101,116,117,114,110, 32,109,111,100, 50, 44, - 32,116,121,112,101, 50, 10, 9,101,110,100, 10, 9,100,111, - 32,114,101,116,117,114,110, 32,109,111,100, 44,116,121,112, - 101, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99, - 104,101, 99,107, 32,105,102, 32,105,116, 32,105,115, 32, 97, - 32,116,121,112,101,100,101,102, 10,102,117,110, 99,116,105, - 111,110, 32, 99,108, 97,115,115, 67,111,110,116, 97,105,110, - 101,114, 58,105,115,116,121,112,101,100,101,102, 32, 40,116, - 121,112,101, 41, 10, 32,108,111, 99, 97,108, 32,101,110,118, - 32, 61, 32,115,101,108,102, 10, 32,119,104,105,108,101, 32, - 101,110,118, 32,100,111, 10, 32, 32,105,102, 32,101,110,118, - 46,116,121,112,101,100,101,102,115, 32,116,104,101,110, 10, - 32, 32, 32,108,111, 99, 97,108, 32,105, 61, 49, 10, 32, 32, - 32,119,104,105,108,101, 32,101,110,118, 46,116,121,112,101, - 100,101,102,115, 91,105, 93, 32,100,111, 10, 32, 32, 32, 32, - 105,102, 32,101,110,118, 46,116,121,112,101,100,101,102,115, - 91,105, 93, 46,117,116,121,112,101, 32, 61, 61, 32,116,121, - 112,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32,114,101,116,117,114,110, 32,116,121,112,101, 10, 32, - 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, - 32, 32, 32, 32,105, 32, 61, 32,105, 43, 49, 10, 32, 32, 32, - 101,110,100, 10, 32, 32,101,110,100, 10, 32, 32,101,110,118, - 32, 61, 32,101,110,118, 46,112, 97,114,101,110,116, 10, 32, - 101,110,100, 10, 32,114,101,116,117,114,110, 32,110,105,108, - 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, - 102,105,110,100, 95,101,110,117,109, 95,118, 97,114, 40,118, - 97,114, 41, 10, 10, 9,105,102, 32,116,111,110,117,109, 98, - 101,114, 40,118, 97,114, 41, 32,116,104,101,110, 32,114,101, - 116,117,114,110, 32,118, 97,114, 32,101,110,100, 10, 10, 9, - 108,111, 99, 97,108, 32, 99, 32, 61, 32, 99,108, 97,115,115, - 67,111,110,116, 97,105,110,101,114, 46, 99,117,114,114, 10, - 9,119,104,105,108,101, 32, 99, 32,100,111, 10, 9, 9,108, - 111, 99, 97,108, 32,110,115, 32, 61, 32,103,101,116,110, 97, - 109,101,115,112, 97, 99,101, 40, 99, 41, 10, 9, 9,102,111, - 114, 32,107, 44,118, 32,105,110, 32,112, 97,105,114,115, 40, - 95,103,108,111, 98, 97,108, 95,101,110,117,109,115, 41, 32, - 100,111, 10, 9, 9, 9,105,102, 32,109, 97,116, 99,104, 95, - 116,121,112,101, 40,118, 97,114, 44, 32,118, 44, 32,110,115, - 41, 32,116,104,101,110, 10, 9, 9, 9, 9,114,101,116,117, - 114,110, 32,118, 10, 9, 9, 9,101,110,100, 10, 9, 9,101, - 110,100, 10, 9, 9,105,102, 32, 99, 46, 98, 97,115,101, 32, - 97,110,100, 32, 99, 46, 98, 97,115,101, 32,126, 61, 32, 39, - 39, 32,116,104,101,110, 10, 9, 9, 9, 99, 32, 61, 32, 95, - 103,108,111, 98, 97,108, 95, 99,108, 97,115,115,101,115, 91, - 99, 58,102,105,110,100,116,121,112,101, 40, 99, 46, 98, 97, - 115,101, 41, 93, 10, 9, 9,101,108,115,101, 10, 9, 9, 9, - 99, 32, 61, 32,110,105,108, 10, 9, 9,101,110,100, 10, 9, - 101,110,100, 10, 10, 9,114,101,116,117,114,110, 32,118, 97, - 114, 10,101,110,100, 10, 10, 45, 45, 32, 99,104,101, 99,107, - 32,105,102, 32,105,115, 32, 97, 32,114,101,103,105,115,116, - 101,114,101,100, 32,116,121,112,101, 58, 32,114,101,116,117, - 114,110, 32,102,117,108,108, 32,116,121,112,101, 32,111,114, - 32,110,105,108, 10,102,117,110, 99,116,105,111,110, 32, 99, - 108, 97,115,115, 67,111,110,116, 97,105,110,101,114, 58,102, - 105,110,100,116,121,112,101, 32, 40,116, 41, 10, 10, 9,116, - 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, - 116, 44, 32, 34, 61, 46, 42, 34, 44, 32, 34, 34, 41, 10, 9, - 105,102, 32, 95, 98, 97,115,105, 99, 91,116, 93, 32,116,104, - 101,110, 10, 9, 32,114,101,116,117,114,110, 32,116, 10, 9, - 101,110,100, 10, 10, 9,108,111, 99, 97,108, 32, 95, 44, 95, - 44,101,109, 32, 61, 32,115,116,114,105,110,103, 46,102,105, - 110,100, 40,116, 44, 32, 34, 40, 91, 38, 37, 42, 93, 41, 37, - 115, 42, 36, 34, 41, 10, 9,116, 32, 61, 32,115,116,114,105, - 110,103, 46,103,115,117, 98, 40,116, 44, 32, 34, 37,115, 42, - 40, 91, 38, 37, 42, 93, 41, 37,115, 42, 36, 34, 44, 32, 34, - 34, 41, 10, 9,112, 32, 61, 32,115,101,108,102, 10, 9,119, - 104,105,108,101, 32,112, 32, 97,110,100, 32,116,121,112,101, - 40,112, 41, 61, 61, 39,116, 97, 98,108,101, 39, 32,100,111, - 10, 9, 9,108,111, 99, 97,108, 32,115,116, 32, 61, 32,103, - 101,116,110, 97,109,101,115,112, 97, 99,101, 40,112, 41, 10, - 10, 9, 9,102,111,114, 32,105, 61, 95,103,108,111, 98, 97, - 108, 95,116,121,112,101,115, 46,110, 44, 49, 44, 45, 49, 32, - 100,111, 32, 45, 45, 32,105,110, 32,114,101,118,101,114,115, - 101, 32,111,114,100,101,114, 10, 10, 9, 9, 9,105,102, 32, - 109, 97,116, 99,104, 95,116,121,112,101, 40,116, 44, 32, 95, - 103,108,111, 98, 97,108, 95,116,121,112,101,115, 91,105, 93, - 44, 32,115,116, 41, 32,116,104,101,110, 10, 9, 9, 9, 9, - 114,101,116,117,114,110, 32, 95,103,108,111, 98, 97,108, 95, - 116,121,112,101,115, 91,105, 93, 46, 46, 40,101,109, 32,111, - 114, 32, 34, 34, 41, 10, 9, 9, 9,101,110,100, 10, 9, 9, - 101,110,100, 10, 9, 9,105,102, 32,112, 46, 98, 97,115,101, - 32, 97,110,100, 32,112, 46, 98, 97,115,101, 32,126, 61, 32, - 39, 39, 32, 97,110,100, 32,112, 46, 98, 97,115,101, 32,126, - 61, 32,116, 32,116,104,101,110, 10, 9, 9, 9, 45, 45,112, - 114,105,110,116, 40, 34,116,121,112,101, 32,105,115, 32, 34, - 46, 46,116, 46, 46, 34, 44, 32,112, 32,105,115, 32, 34, 46, - 46,112, 46, 98, 97,115,101, 46, 46, 34, 32,115,101,108,102, - 46,116,121,112,101, 32,105,115, 32, 34, 46, 46,115,101,108, - 102, 46,116,121,112,101, 46, 46, 34, 32,115,101,108,102, 46, - 110, 97,109,101, 32,105,115, 32, 34, 46, 46,115,101,108,102, - 46,110, 97,109,101, 41, 10, 9, 9, 9,112, 32, 61, 32, 95, - 103,108,111, 98, 97,108, 95, 99,108, 97,115,115,101,115, 91, - 112, 58,102,105,110,100,116,121,112,101, 40,112, 46, 98, 97, - 115,101, 41, 93, 10, 9, 9,101,108,115,101, 10, 9, 9, 9, - 112, 32, 61, 32,110,105,108, 10, 9, 9,101,110,100, 10, 9, - 101,110,100, 10, 10, 9,114,101,116,117,114,110, 32,110,105, - 108, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, - 32, 97,112,112,101,110,100, 95,103,108,111, 98, 97,108, 95, - 116,121,112,101, 40,116, 44, 32, 99,108, 97,115,115, 41, 10, - 9, 95,103,108,111, 98, 97,108, 95,116,121,112,101,115, 46, - 110, 32, 61, 32, 95,103,108,111, 98, 97,108, 95,116,121,112, - 101,115, 46,110, 32, 43, 49, 10, 9, 95,103,108,111, 98, 97, - 108, 95,116,121,112,101,115, 91, 95,103,108,111, 98, 97,108, - 95,116,121,112,101,115, 46,110, 93, 32, 61, 32,116, 10, 9, - 95,103,108,111, 98, 97,108, 95,116,121,112,101,115, 95,104, - 97,115,104, 91,116, 93, 32, 61, 32, 49, 10, 9,105,102, 32, - 99,108, 97,115,115, 32,116,104,101,110, 32, 97,112,112,101, - 110,100, 95, 99,108, 97,115,115, 95,116,121,112,101, 40,116, - 44, 32, 99,108, 97,115,115, 41, 32,101,110,100, 10,101,110, - 100, 10, 10,102,117,110, 99,116,105,111,110, 32, 97,112,112, - 101,110,100, 95, 99,108, 97,115,115, 95,116,121,112,101, 40, - 116, 44, 99,108, 97,115,115, 41, 10, 9,105,102, 32, 95,103, - 108,111, 98, 97,108, 95, 99,108, 97,115,115,101,115, 91,116, - 93, 32,116,104,101,110, 10, 9, 9, 99,108, 97,115,115, 46, - 102,108, 97,103,115, 32, 61, 32, 95,103,108,111, 98, 97,108, - 95, 99,108, 97,115,115,101,115, 91,116, 93, 46,102,108, 97, - 103,115, 10, 9, 9, 99,108, 97,115,115, 46,108,110, 97,109, - 101,115, 32, 61, 32, 95,103,108,111, 98, 97,108, 95, 99,108, - 97,115,115,101,115, 91,116, 93, 46,108,110, 97,109,101,115, - 10, 9, 9,105,102, 32, 95,103,108,111, 98, 97,108, 95, 99, - 108, 97,115,115,101,115, 91,116, 93, 46, 98, 97,115,101, 32, - 97,110,100, 32, 40, 95,103,108,111, 98, 97,108, 95, 99,108, - 97,115,115,101,115, 91,116, 93, 46, 98, 97,115,101, 32,126, - 61, 32, 39, 39, 41, 32,116,104,101,110, 10, 9, 9, 9, 99, - 108, 97,115,115, 46, 98, 97,115,101, 32, 61, 32, 95,103,108, - 111, 98, 97,108, 95, 99,108, 97,115,115,101,115, 91,116, 93, - 46, 98, 97,115,101, 32,111,114, 32, 99,108, 97,115,115, 46, - 98, 97,115,101, 10, 9, 9,101,110,100, 10, 9,101,110,100, - 10, 9, 95,103,108,111, 98, 97,108, 95, 99,108, 97,115,115, - 101,115, 91,116, 93, 32, 61, 32, 99,108, 97,115,115, 10, 9, - 99,108, 97,115,115, 46,102,108, 97,103,115, 32, 61, 32, 99, - 108, 97,115,115, 46,102,108, 97,103,115, 32,111,114, 32,123, - 125, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, - 32,109, 97,116, 99,104, 95,116,121,112,101, 40, 99,104,105, - 108,100,116,121,112,101, 44, 32,114,101,103,116,121,112,101, - 44, 32,115,116, 41, 10, 45, 45,112,114,105,110,116, 40, 34, - 102,105,110,100,116,121,112,101, 32, 34, 46, 46, 99,104,105, - 108,100,116,121,112,101, 46, 46, 34, 44, 32, 34, 46, 46,114, - 101,103,116,121,112,101, 46, 46, 34, 44, 32, 34, 46, 46,115, - 116, 41, 10, 9,108,111, 99, 97,108, 32, 98, 44,101, 32, 61, - 32,115,116,114,105,110,103, 46,102,105,110,100, 40,114,101, - 103,116,121,112,101, 44, 32, 99,104,105,108,100,116,121,112, - 101, 44, 32, 45,115,116,114,105,110,103, 46,108,101,110, 40, - 99,104,105,108,100,116,121,112,101, 41, 44, 32,116,114,117, - 101, 41, 10, 9,105,102, 32, 98, 32,116,104,101,110, 10, 10, - 9, 9,105,102, 32,101, 32, 61, 61, 32,115,116,114,105,110, - 103, 46,108,101,110, 40,114,101,103,116,121,112,101, 41, 32, - 97,110,100, 10, 9, 9, 9, 9, 40, 98, 32, 61, 61, 32, 49, - 32,111,114, 32, 40,115,116,114,105,110,103, 46,115,117, 98, - 40,114,101,103,116,121,112,101, 44, 32, 98, 45, 49, 44, 32, - 98, 45, 49, 41, 32, 61, 61, 32, 39, 58, 39, 32, 97,110,100, - 10, 9, 9, 9, 9,115,116,114,105,110,103, 46,115,117, 98, - 40,114,101,103,116,121,112,101, 44, 32, 49, 44, 32, 98, 45, - 49, 41, 32, 61, 61, 32,115,116,114,105,110,103, 46,115,117, - 98, 40,115,116, 44, 32, 49, 44, 32, 98, 45, 49, 41, 41, 41, - 32,116,104,101,110, 10, 9, 9, 9,114,101,116,117,114,110, - 32,116,114,117,101, 10, 9, 9,101,110,100, 10, 9,101,110, - 100, 10, 10, 9,114,101,116,117,114,110, 32,102, 97,108,115, - 101, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, - 32,102,105,110,100,116,121,112,101, 95,111,110, 95, 99,104, - 105,108,100,115, 40,115,101,108,102, 44, 32,116, 41, 10, 10, - 9,108,111, 99, 97,108, 32,116, 99,104,105,108,100, 10, 9, - 105,102, 32,115,101,108,102, 46, 99,108, 97,115,115,116,121, - 112,101, 32, 61, 61, 32, 39, 99,108, 97,115,115, 39, 32,111, - 114, 32,115,101,108,102, 46, 99,108, 97,115,115,116,121,112, - 101, 32, 61, 61, 32, 39,110, 97,109,101,115,112, 97, 99,101, - 39, 32,116,104,101,110, 10, 9, 9,102,111,114, 32,107, 44, - 118, 32,105,110, 32,105,112, 97,105,114,115, 40,115,101,108, - 102, 41, 32,100,111, 10, 9, 9, 9,105,102, 32,118, 46, 99, - 108, 97,115,115,116,121,112,101, 32, 61, 61, 32, 39, 99,108, - 97,115,115, 39, 32,111,114, 32,118, 46, 99,108, 97,115,115, - 116,121,112,101, 32, 61, 61, 32, 39,110, 97,109,101,115,112, - 97, 99,101, 39, 32,116,104,101,110, 10, 9, 9, 9, 9,105, - 102, 32,118, 46,116,121,112,101,100,101,102,115, 32, 97,110, - 100, 32,118, 46,116,121,112,101,100,101,102,115, 91,116, 93, - 32,116,104,101,110, 10, 9, 9, 9, 9, 32,114,101,116,117, - 114,110, 32,118, 46,116,121,112,101,100,101,102,115, 91,116, - 93, 10, 9, 9, 9, 9,101,108,115,101,105,102, 32,118, 46, - 117,115,101,114,116,121,112,101,115, 32, 97,110,100, 32,118, - 46,117,115,101,114,116,121,112,101,115, 91,116, 93, 32,116, - 104,101,110, 10, 9, 9, 9, 9, 32,114,101,116,117,114,110, - 32,118, 46,117,115,101,114,116,121,112,101,115, 91,116, 93, - 10, 9, 9, 9, 9,101,110,100, 10, 9, 9, 9, 9,116, 99, - 104,105,108,100, 32, 61, 32,102,105,110,100,116,121,112,101, - 95,111,110, 95, 99,104,105,108,100,115, 40,118, 44, 32,116, - 41, 10, 9, 9, 9, 9,105,102, 32,116, 99,104,105,108,100, - 32,116,104,101,110, 32,114,101,116,117,114,110, 32,116, 99, - 104,105,108,100, 32,101,110,100, 10, 9, 9, 9,101,110,100, - 10, 9, 9,101,110,100, 10, 9,101,110,100, 10, 9,114,101, - 116,117,114,110, 32,110,105,108, 10, 10,101,110,100, 10, 10, - 102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 67, - 111,110,116, 97,105,110,101,114, 58,105,115,101,110,117,109, - 32, 40,116,121,112,101, 41, 10, 32,105,102, 32,103,108,111, - 98, 97,108, 95,101,110,117,109,115, 91,116,121,112,101, 93, - 32,116,104,101,110, 10, 9,114,101,116,117,114,110, 32,116, - 121,112,101, 10, 32,101,108,115,101, 10, 32, 9,114,101,116, - 117,114,110, 32,102, 97,108,115,101, 10, 32,101,110,100, 10, - 10, 32,108,111, 99, 97,108, 32, 98, 97,115,101,116,121,112, - 101, 32, 61, 32,103,115,117, 98, 40,116,121,112,101, 44, 34, - 94, 46, 42, 58, 58, 34, 44, 34, 34, 41, 10, 32,108,111, 99, - 97,108, 32,101,110,118, 32, 61, 32,115,101,108,102, 10, 32, - 119,104,105,108,101, 32,101,110,118, 32,100,111, 10, 32, 32, - 105,102, 32,101,110,118, 46,101,110,117,109,115, 32,116,104, - 101,110, 10, 32, 32, 32,108,111, 99, 97,108, 32,105, 61, 49, - 10, 32, 32, 32,119,104,105,108,101, 32,101,110,118, 46,101, - 110,117,109,115, 91,105, 93, 32,100,111, 10, 32, 32, 32, 32, - 105,102, 32,101,110,118, 46,101,110,117,109,115, 91,105, 93, - 46,110, 97,109,101, 32, 61, 61, 32, 98, 97,115,101,116,121, - 112,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, - 32, 32,114,101,116,117,114,110, 32,116,114,117,101, 10, 32, - 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, - 32, 32, 32, 32,105, 32, 61, 32,105, 43, 49, 10, 32, 32, 32, - 101,110,100, 10, 32, 32,101,110,100, 10, 32, 32,101,110,118, - 32, 61, 32,101,110,118, 46,112, 97,114,101,110,116, 10, 32, - 101,110,100, 10, 32,114,101,116,117,114,110, 32,102, 97,108, - 115,101, 10,101,110,100, 10, 10,109,101,116,104,111,100,105, - 115,118,105,114,116,117, 97,108, 32, 61, 32,102, 97,108,115, - 101, 32, 45, 45, 32, 97, 32,103,108,111, 98, 97,108, 10, 10, - 45, 45, 32,112, 97,114,115,101, 32, 99,104,117,110,107, 10, - 102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 67, - 111,110,116, 97,105,110,101,114, 58,100,111,112, 97,114,115, - 101, 32, 40,115, 41, 10, 45, 45,112,114,105,110,116, 32, 40, - 34,112, 97,114,115,101, 32, 34, 46, 46,115, 41, 10, 10, 32, - 45, 45, 32,116,114,121, 32,116,104,101, 32,112, 97,114,115, - 101,114, 32,104,111,111,107, 10, 32,100,111, 10, 32, 9,108, - 111, 99, 97,108, 32,115,117, 98, 32, 61, 32,112, 97,114,115, - 101,114, 95,104,111,111,107, 40,115, 41, 10, 32, 9,105,102, - 32,115,117, 98, 32,116,104,101,110, 10, 32, 9, 9,114,101, - 116,117,114,110, 32,115,117, 98, 10, 32, 9,101,110,100, 10, - 32,101,110,100, 10, 10, 32, 45, 45, 32,116,114,121, 32,116, - 104,101, 32,110,117,108,108, 32,115,116, 97,116,101,109,101, - 110,116, 10, 32,100,111, 10, 32, 9,108,111, 99, 97,108, 32, - 98, 44,101, 44, 99,111,100,101, 32, 61, 32,115,116,114,105, - 110,103, 46,102,105,110,100, 40,115, 44, 32, 34, 94, 37,115, - 42, 59, 34, 41, 10, 32, 9,105,102, 32, 98, 32,116,104,101, - 110, 10, 32, 9, 9,114,101,116,117,114,110, 32,115,116,114, - 115,117, 98, 40,115, 44,101, 43, 49, 41, 10, 32, 9,101,110, - 100, 10, 32,101,110,100, 10, 10, 32, 45, 45, 32,116,114,121, - 32,101,109,112,116,121, 32,118,101,114, 98, 97,116,105,109, - 32,108,105,110,101, 10, 32,100,111, 10, 32, 9,108,111, 99, - 97,108, 32, 98, 44,101, 44, 99,111,100,101, 32, 61, 32,115, - 116,114,105,110,103, 46,102,105,110,100, 40,115, 44, 32, 34, - 94, 37,115, 42, 36, 92,110, 34, 41, 10, 32, 9,105,102, 32, - 98, 32,116,104,101,110, 10, 32, 9, 9,114,101,116,117,114, - 110, 32,115,116,114,115,117, 98, 40,115, 44,101, 43, 49, 41, - 10, 32, 9,101,110,100, 10, 32,101,110,100, 10, 10, 32, 45, - 45, 32,116,114,121, 32, 76,117, 97, 32, 99,111,100,101, 10, - 32,100,111, 10, 32, 32,108,111, 99, 97,108, 32, 98, 44,101, - 44, 99,111,100,101, 32, 61, 32,115,116,114,102,105,110,100, - 40,115, 44, 34, 94, 37,115, 42, 40, 37, 98, 92, 49, 92, 50, - 41, 34, 41, 10, 32, 32,105,102, 32, 98, 32,116,104,101,110, - 10, 32, 32, 32, 67,111,100,101, 40,115,116,114,115,117, 98, - 40, 99,111,100,101, 44, 50, 44, 45, 50, 41, 41, 10, 32, 32, - 32,114,101,116,117,114,110, 32,115,116,114,115,117, 98, 40, - 115, 44,101, 43, 49, 41, 10, 32, 32,101,110,100, 10, 32,101, - 110,100, 10, 10, 32, 45, 45, 32,116,114,121, 32, 67, 32, 99, - 111,100,101, 10, 32,100,111, 10, 32, 32,108,111, 99, 97,108, - 32, 98, 44,101, 44, 99,111,100,101, 32, 61, 32,115,116,114, - 102,105,110,100, 40,115, 44, 34, 94, 37,115, 42, 40, 37, 98, - 92, 51, 92, 52, 41, 34, 41, 10, 32, 32,105,102, 32, 98, 32, - 116,104,101,110, 10, 9, 99,111,100,101, 32, 61, 32, 39,123, - 39, 46, 46,115,116,114,115,117, 98, 40, 99,111,100,101, 44, - 50, 44, 45, 50, 41, 46, 46, 39, 92,110,125, 92,110, 39, 10, - 9, 86,101,114, 98, 97,116,105,109, 40, 99,111,100,101, 44, - 39,114, 39, 41, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, - 118,101,114, 98, 97,116,105,109, 32, 99,111,100,101, 32,102, - 111,114, 32, 39,114, 39,101,103,105,115,116,101,114, 32,102, - 114, 97,103,109,101,110,116, 10, 9,114,101,116,117,114,110, - 32,115,116,114,115,117, 98, 40,115, 44,101, 43, 49, 41, 10, - 32, 32,101,110,100, 10, 32,101,110,100, 10, 10, 32, 45, 45, - 32,116,114,121, 32, 67, 32, 99,111,100,101, 32,102,111,114, - 32,112,114,101, 97,109, 98,108,101, 32,115,101, 99,116,105, - 111,110, 10, 32,100,111, 10, 32, 9,108,111, 99, 97,108, 32, - 98, 44,101, 44, 99,111,100,101, 32, 61, 32,115,116,114,105, - 110,103, 46,102,105,110,100, 40,115, 44, 32, 34, 94, 37,115, - 42, 40, 37, 98, 92, 53, 92, 54, 41, 34, 41, 10, 32, 9,105, - 102, 32, 98, 32,116,104,101,110, 10, 32, 9, 9, 99,111,100, - 101, 32, 61, 32,115,116,114,105,110,103, 46,115,117, 98, 40, - 99,111,100,101, 44, 32, 50, 44, 32, 45, 50, 41, 46, 46, 34, - 92,110, 34, 10, 9, 9, 86,101,114, 98, 97,116,105,109, 40, - 99,111,100,101, 44, 32, 39, 39, 41, 10, 9, 9,114,101,116, - 117,114,110, 32,115,116,114,105,110,103, 46,115,117, 98, 40, - 115, 44, 32,101, 43, 49, 41, 10, 32, 9,101,110,100, 10, 32, - 101,110,100, 10, 10, 32, 45, 45, 32,116,114,121, 32,100,101, - 102, 97,117,108,116, 95,112,114,111,112,101,114,116,121, 32, - 100,105,114,101, 99,116,105,118,101, 10, 32,100,111, 10, 32, - 9,108,111, 99, 97,108, 32, 98, 44,101, 44,112,116,121,112, - 101, 32, 61, 32,115,116,114,102,105,110,100, 40,115, 44, 32, - 34, 94, 37,115, 42, 84, 79, 76, 85, 65, 95, 80, 82, 79, 80, - 69, 82, 84, 89, 95, 84, 89, 80, 69, 37,115, 42, 37, 40, 43, - 37,115, 42, 40, 91, 94, 37, 41, 37,115, 93, 42, 41, 37,115, - 42, 37, 41, 43, 37,115, 42, 59, 63, 34, 41, 10, 32, 9,105, - 102, 32, 98, 32,116,104,101,110, 10, 32, 9, 9,105,102, 32, - 110,111,116, 32,112,116,121,112,101, 32,111,114, 32,112,116, - 121,112,101, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 10, - 32, 9, 9, 9,112,116,121,112,101, 32, 61, 32, 34,100,101, - 102, 97,117,108,116, 34, 10, 32, 9, 9,101,110,100, 10, 32, - 9, 9,115,101,108,102, 58,115,101,116, 95,112,114,111,112, - 101,114,116,121, 95,116,121,112,101, 40,112,116,121,112,101, - 41, 10, 9, 32, 9,114,101,116,117,114,110, 32,115,116,114, - 115,117, 98, 40,115, 44, 32,101, 43, 49, 41, 10, 32, 9,101, - 110,100, 10, 32,101,110,100, 10, 10, 32, 45, 45, 32,116,114, - 121, 32,112,114,111,116,101, 99,116,101,100, 95,100,101,115, - 116,114,117, 99,116,111,114, 32,100,105,114,101, 99,116,105, - 118,101, 10, 32,100,111, 10, 32, 9,108,111, 99, 97,108, 32, - 98, 44,101, 32, 61, 32,115,116,114,105,110,103, 46,102,105, - 110,100, 40,115, 44, 32, 34, 94, 37,115, 42, 84, 79, 76, 85, - 65, 95, 80, 82, 79, 84, 69, 67, 84, 69, 68, 95, 68, 69, 83, - 84, 82, 85, 67, 84, 79, 82, 37,115, 42, 59, 63, 34, 41, 10, - 9,105,102, 32, 98, 32,116,104,101,110, 10, 9, 9,105,102, - 32,115,101,108,102, 46,115,101,116, 95,112,114,111,116,101, - 99,116,101,100, 95,100,101,115,116,114,117, 99,116,111,114, - 32,116,104,101,110, 10, 9, 32, 9, 9,115,101,108,102, 58, - 115,101,116, 95,112,114,111,116,101, 99,116,101,100, 95,100, - 101,115,116,114,117, 99,116,111,114, 40,116,114,117,101, 41, - 10, 9, 32, 9,101,110,100, 10, 32, 9, 9,114,101,116,117, - 114,110, 32,115,116,114,115,117, 98, 40,115, 44, 32,101, 43, - 49, 41, 10, 32, 9,101,110,100, 10, 32,101,110,100, 10, 10, - 32, 45, 45, 32,116,114,121, 32, 39,101,120,116,101,114,110, - 39, 32,107,101,121,119,111,114,100, 10, 32,100,111, 10, 32, - 9,108,111, 99, 97,108, 32, 98, 44,101, 32, 61, 32,115,116, - 114,105,110,103, 46,102,105,110,100, 40,115, 44, 32, 34, 94, - 37,115, 42,101,120,116,101,114,110, 37,115, 43, 34, 41, 10, - 32, 9,105,102, 32, 98, 32,116,104,101,110, 10, 9, 9, 45, - 45, 32,100,111, 32,110,111,116,104,105,110,103, 10, 32, 9, - 9,114,101,116,117,114,110, 32,115,116,114,115,117, 98, 40, - 115, 44, 32,101, 43, 49, 41, 10, 32, 9,101,110,100, 10, 32, - 101,110,100, 10, 10, 32, 45, 45, 32,116,114,121, 32, 39,118, - 105,114,116,117, 97,108, 39, 32,107,101,121,119,111,114,107, - 100, 10, 32,100,111, 10, 32, 9,108,111, 99, 97,108, 32, 98, - 44,101, 32, 61, 32,115,116,114,105,110,103, 46,102,105,110, - 100, 40,115, 44, 32, 34, 94, 37,115, 42,118,105,114,116,117, - 97,108, 37,115, 43, 34, 41, 10, 32, 9,105,102, 32, 98, 32, - 116,104,101,110, 10, 32, 9, 9,109,101,116,104,111,100,105, - 115,118,105,114,116,117, 97,108, 32, 61, 32,116,114,117,101, - 10, 32, 9, 9,114,101,116,117,114,110, 32,115,116,114,115, - 117, 98, 40,115, 44, 32,101, 43, 49, 41, 10, 32, 9,101,110, - 100, 10, 32,101,110,100, 10, 10, 32, 45, 45, 32,116,114,121, - 32,108, 97, 98,101,108,115, 32, 40,112,117, 98,108,105, 99, - 44, 32,112,114,105,118, 97,116,101, 44, 32,101,116, 99, 41, - 10, 32,100,111, 10, 32, 9,108,111, 99, 97,108, 32, 98, 44, - 101, 32, 61, 32,115,116,114,105,110,103, 46,102,105,110,100, - 40,115, 44, 32, 34, 94, 37,115, 42, 37,119, 42, 37,115, 42, - 58, 91, 94, 58, 93, 34, 41, 10, 32, 9,105,102, 32, 98, 32, - 116,104,101,110, 10, 32, 9, 9,114,101,116,117,114,110, 32, - 115,116,114,115,117, 98, 40,115, 44, 32,101, 41, 32, 45, 45, - 32,112,114,101,115,101,114,118,101, 32,116,104,101, 32, 91, - 94, 58, 93, 10, 32, 9,101,110,100, 10, 32,101,110,100, 10, - 10, 32, 45, 45, 32,116,114,121, 32,109,111,100,117,108,101, - 10, 32,100,111, 10, 32, 32,108,111, 99, 97,108, 32, 98, 44, - 101, 44,110, 97,109,101, 44, 98,111,100,121, 32, 61, 32,115, - 116,114,102,105,110,100, 40,115, 44, 34, 94, 37,115, 42,109, - 111,100,117,108,101, 37,115, 37,115, 42, 40, 91, 95, 37,119, - 93, 91, 95, 37,119, 93, 42, 41, 37,115, 42, 40, 37, 98,123, - 125, 41, 37,115, 42, 34, 41, 10, 32, 32,105,102, 32, 98, 32, - 116,104,101,110, 10, 32, 32, 32, 95, 99,117,114,114, 95, 99, - 111,100,101, 32, 61, 32,115,116,114,115,117, 98, 40,115, 44, - 98, 44,101, 41, 10, 32, 32, 32, 77,111,100,117,108,101, 40, - 110, 97,109,101, 44, 98,111,100,121, 41, 10, 32, 32, 32,114, - 101,116,117,114,110, 32,115,116,114,115,117, 98, 40,115, 44, - 101, 43, 49, 41, 10, 32, 32,101,110,100, 10, 32,101,110,100, - 10, 10, 32, 45, 45, 32,116,114,121, 32,110, 97,109,101,115, - 97,112, 99,101, 10, 32,100,111, 10, 32, 32,108,111, 99, 97, - 108, 32, 98, 44,101, 44,110, 97,109,101, 44, 98,111,100,121, - 32, 61, 32,115,116,114,102,105,110,100, 40,115, 44, 34, 94, - 37,115, 42,110, 97,109,101,115,112, 97, 99,101, 37,115, 37, - 115, 42, 40, 91, 95, 37,119, 93, 91, 95, 37,119, 93, 42, 41, - 37,115, 42, 40, 37, 98,123,125, 41, 37,115, 42, 59, 63, 34, - 41, 10, 32, 32,105,102, 32, 98, 32,116,104,101,110, 10, 32, - 32, 32, 95, 99,117,114,114, 95, 99,111,100,101, 32, 61, 32, - 115,116,114,115,117, 98, 40,115, 44, 98, 44,101, 41, 10, 32, - 32, 32, 78, 97,109,101,115,112, 97, 99,101, 40,110, 97,109, - 101, 44, 98,111,100,121, 41, 10, 32, 32, 32,114,101,116,117, - 114,110, 32,115,116,114,115,117, 98, 40,115, 44,101, 43, 49, - 41, 10, 32, 32,101,110,100, 10, 32,101,110,100, 10, 10, 32, - 45, 45, 32,116,114,121, 32,100,101,102,105,110,101, 10, 32, - 100,111, 10, 32, 32,108,111, 99, 97,108, 32, 98, 44,101, 44, - 110, 97,109,101, 32, 61, 32,115,116,114,102,105,110,100, 40, - 115, 44, 34, 94, 37,115, 42, 35,100,101,102,105,110,101, 37, - 115, 37,115, 42, 40, 91, 94, 37,115, 93, 42, 41, 91, 94, 92, - 110, 93, 42, 92,110, 37,115, 42, 34, 41, 10, 32, 32,105,102, - 32, 98, 32,116,104,101,110, 10, 32, 32, 32, 95, 99,117,114, - 114, 95, 99,111,100,101, 32, 61, 32,115,116,114,115,117, 98, - 40,115, 44, 98, 44,101, 41, 10, 32, 32, 32, 68,101,102,105, - 110,101, 40,110, 97,109,101, 41, 10, 32, 32, 32,114,101,116, - 117,114,110, 32,115,116,114,115,117, 98, 40,115, 44,101, 43, - 49, 41, 10, 32, 32,101,110,100, 10, 32,101,110,100, 10, 10, - 32, 45, 45, 32,116,114,121, 32,101,110,117,109,101,114, 97, - 116,101,115, 10, 10, 32,100,111, 10, 32, 32,108,111, 99, 97, - 108, 32, 98, 44,101, 44,110, 97,109,101, 44, 98,111,100,121, - 44,118, 97,114,110, 97,109,101, 32, 61, 32,115,116,114,102, - 105,110,100, 40,115, 44, 34, 94, 37,115, 42,101,110,117,109, - 37,115, 43, 40, 37, 83, 42, 41, 37,115, 42, 40, 37, 98,123, - 125, 41, 37,115, 42, 40, 91, 94, 37,115, 59, 93, 42, 41, 37, - 115, 42, 59, 63, 37,115, 42, 34, 41, 10, 32, 32,105,102, 32, - 98, 32,116,104,101,110, 10, 32, 32, 32, 45, 45,101,114,114, - 111,114, 40, 34, 35, 83,111,114,114,121, 44, 32,100,101, 99, - 108, 97,114, 97,116,105,111,110, 32,111,102, 32,101,110,117, - 109,115, 32, 97,110,100, 32,118, 97,114,105, 97, 98,108,101, - 115, 32,111,110, 32,116,104,101, 32,115, 97,109,101, 32,115, - 116, 97,116,101,109,101,110,116, 32,105,115, 32,110,111,116, - 32,115,117,112,112,111,114,116,101,100, 46, 92,110, 68,101, - 99,108, 97,114,101, 32,121,111,117,114, 32,118, 97,114,105, - 97, 98,108,101, 32,115,101,112, 97,114, 97,116,101,108,121, - 32, 40,101,120, 97,109,112,108,101, 58, 32, 39, 34, 46, 46, - 110, 97,109,101, 46, 46, 34, 32, 34, 46, 46,118, 97,114,110, - 97,109,101, 46, 46, 34, 59, 39, 41, 34, 41, 10, 32, 32, 32, - 95, 99,117,114,114, 95, 99,111,100,101, 32, 61, 32,115,116, - 114,115,117, 98, 40,115, 44, 98, 44,101, 41, 10, 32, 32, 32, - 69,110,117,109,101,114, 97,116,101, 40,110, 97,109,101, 44, - 98,111,100,121, 44,118, 97,114,110, 97,109,101, 41, 10, 32, - 32, 32,114,101,116,117,114,110, 32,115,116,114,115,117, 98, - 40,115, 44,101, 43, 49, 41, 10, 32, 32,101,110,100, 10, 32, - 101,110,100, 10, 10, 45, 45, 32,100,111, 10, 45, 45, 32, 32, - 108,111, 99, 97,108, 32, 98, 44,101, 44,110, 97,109,101, 44, - 98,111,100,121, 32, 61, 32,115,116,114,102,105,110,100, 40, - 115, 44, 34, 94, 37,115, 42,101,110,117,109, 37,115, 43, 40, - 37, 83, 42, 41, 37,115, 42, 40, 37, 98,123,125, 41, 37,115, - 42, 59, 63, 37,115, 42, 34, 41, 10, 45, 45, 32, 32,105,102, - 32, 98, 32,116,104,101,110, 10, 45, 45, 32, 32, 32, 95, 99, - 117,114,114, 95, 99,111,100,101, 32, 61, 32,115,116,114,115, - 117, 98, 40,115, 44, 98, 44,101, 41, 10, 45, 45, 32, 32, 32, - 69,110,117,109,101,114, 97,116,101, 40,110, 97,109,101, 44, - 98,111,100,121, 41, 10, 45, 45, 32, 32,114,101,116,117,114, - 110, 32,115,116,114,115,117, 98, 40,115, 44,101, 43, 49, 41, - 10, 45, 45, 32, 32,101,110,100, 10, 45, 45, 32,101,110,100, - 10, 10, 32,100,111, 10, 32, 32,108,111, 99, 97,108, 32, 98, - 44,101, 44, 98,111,100,121, 44,110, 97,109,101, 32, 61, 32, - 115,116,114,102,105,110,100, 40,115, 44, 34, 94, 37,115, 42, - 116,121,112,101,100,101,102, 37,115, 43,101,110,117,109, 91, - 94,123, 93, 42, 40, 37, 98,123,125, 41, 37,115, 42, 40, 91, - 37,119, 95, 93, 91, 94, 37,115, 93, 42, 41, 37,115, 42, 59, - 37,115, 42, 34, 41, 10, 32, 32,105,102, 32, 98, 32,116,104, - 101,110, 10, 32, 32, 32, 95, 99,117,114,114, 95, 99,111,100, - 101, 32, 61, 32,115,116,114,115,117, 98, 40,115, 44, 98, 44, - 101, 41, 10, 32, 32, 32, 69,110,117,109,101,114, 97,116,101, - 40,110, 97,109,101, 44, 98,111,100,121, 41, 10, 32, 32, 32, - 114,101,116,117,114,110, 32,115,116,114,115,117, 98, 40,115, - 44,101, 43, 49, 41, 10, 32, 32,101,110,100, 10, 32,101,110, - 100, 10, 10, 32, 45, 45, 32,116,114,121, 32,111,112,101,114, - 97,116,111,114, 10, 32,100,111, 10, 32, 32,108,111, 99, 97, - 108, 32, 98, 44,101, 44,100,101, 99,108, 44,107,105,110,100, - 44, 97,114,103, 44, 99,111,110,115,116, 32, 61, 32,115,116, - 114,102,105,110,100, 40,115, 44, 34, 94, 37,115, 42, 40, 91, - 95, 37,119, 93, 91, 95, 37,119, 37,115, 37, 42, 38, 58, 60, - 62, 44, 93, 45, 37,115, 43,111,112,101,114, 97,116,111,114, - 41, 37,115, 42, 40, 91, 94, 37,115, 93, 91, 94, 37,115, 93, - 42, 41, 37,115, 42, 40, 37, 98, 40, 41, 41, 37,115, 42, 40, - 99, 63,111, 63,110, 63,115, 63,116, 63, 41, 37,115, 42, 59, - 37,115, 42, 34, 41, 10, 32, 32,105,102, 32,110,111,116, 32, - 98, 32,116,104,101,110, 10, 9, 9, 32, 45, 45, 32,116,114, - 121, 32,105,110,108,105,110,101, 10, 32, 32, 32, 98, 44,101, - 44,100,101, 99,108, 44,107,105,110,100, 44, 97,114,103, 44, - 99,111,110,115,116, 32, 61, 32,115,116,114,102,105,110,100, - 40,115, 44, 34, 94, 37,115, 42, 40, 91, 95, 37,119, 93, 91, - 95, 37,119, 37,115, 37, 42, 38, 58, 60, 62, 44, 93, 45, 37, - 115, 43,111,112,101,114, 97,116,111,114, 41, 37,115, 42, 40, - 91, 94, 37,115, 93, 91, 94, 37,115, 93, 42, 41, 37,115, 42, - 40, 37, 98, 40, 41, 41, 37,115, 42, 40, 99, 63,111, 63,110, - 63,115, 63,116, 63, 41, 91, 37,115, 92,110, 93, 42, 37, 98, - 123,125, 37,115, 42, 59, 63, 37,115, 42, 34, 41, 10, 32, 32, - 101,110,100, 10, 32, 32,105,102, 32,110,111,116, 32, 98, 32, - 116,104,101,110, 10, 32, 32, 9, 45, 45, 32,116,114,121, 32, - 99, 97,115,116, 32,111,112,101,114, 97,116,111,114, 10, 32, - 32, 9, 98, 44,101, 44,100,101, 99,108, 44,107,105,110,100, - 44, 97,114,103, 44, 99,111,110,115,116, 32, 61, 32,115,116, - 114,102,105,110,100, 40,115, 44, 32, 34, 94, 37,115, 42, 40, - 111,112,101,114, 97,116,111,114, 41, 37,115, 43, 40, 91, 37, - 119, 95, 58, 37,100, 60, 62, 37, 42, 37, 38, 37,115, 93, 43, - 41, 37,115, 42, 40, 37, 98, 40, 41, 41, 37,115, 42, 40, 99, - 63,111, 63,110, 63,115, 63,116, 63, 41, 34, 41, 59, 10, 32, - 32, 9,105,102, 32, 98, 32,116,104,101,110, 10, 32, 32, 9, - 9,108,111, 99, 97,108, 32, 95, 44,105,101, 32, 61, 32,115, - 116,114,105,110,103, 46,102,105,110,100, 40,115, 44, 32, 34, - 94, 37,115, 42, 37, 98,123,125, 34, 44, 32,101, 43, 49, 41, - 10, 32, 32, 9, 9,105,102, 32,105,101, 32,116,104,101,110, - 10, 32, 32, 9, 9, 9,101, 32, 61, 32,105,101, 10, 32, 32, - 9, 9,101,110,100, 10, 32, 32, 9,101,110,100, 10, 32, 32, - 101,110,100, 10, 32, 32,105,102, 32, 98, 32,116,104,101,110, - 10, 32, 32, 32, 95, 99,117,114,114, 95, 99,111,100,101, 32, - 61, 32,115,116,114,115,117, 98, 40,115, 44, 98, 44,101, 41, - 10, 32, 32, 32, 79,112,101,114, 97,116,111,114, 40,100,101, - 99,108, 44,107,105,110,100, 44, 97,114,103, 44, 99,111,110, - 115,116, 41, 10, 32, 32, 32,114,101,116,117,114,110, 32,115, - 116,114,115,117, 98, 40,115, 44,101, 43, 49, 41, 10, 32, 32, - 101,110,100, 10, 32,101,110,100, 10, 10, 32, 45, 45, 32,116, - 114,121, 32,102,117,110, 99,116,105,111,110, 10, 32,100,111, - 10, 32, 32, 45, 45,108,111, 99, 97,108, 32, 98, 44,101, 44, - 100,101, 99,108, 44, 97,114,103, 44, 99,111,110,115,116, 32, - 61, 32,115,116,114,102,105,110,100, 40,115, 44, 34, 94, 37, - 115, 42, 40, 91,126, 95, 37,119, 93, 91, 95, 64, 37,119, 37, - 115, 37, 42, 38, 58, 60, 62, 93, 42, 91, 95, 37,119, 93, 41, - 37,115, 42, 40, 37, 98, 40, 41, 41, 37,115, 42, 40, 99, 63, - 111, 63,110, 63,115, 63,116, 63, 41, 37,115, 42, 61, 63, 37, - 115, 42, 48, 63, 37,115, 42, 59, 37,115, 42, 34, 41, 10, 32, - 32,108,111, 99, 97,108, 32, 98, 44,101, 44,100,101, 99,108, - 44, 97,114,103, 44, 99,111,110,115,116, 44,118,105,114,116, - 32, 61, 32,115,116,114,102,105,110,100, 40,115, 44, 34, 94, - 37,115, 42, 40, 91, 94, 37, 40, 92,110, 93, 43, 41, 37,115, - 42, 40, 37, 98, 40, 41, 41, 37,115, 42, 40, 99, 63,111, 63, - 110, 63,115, 63,116, 63, 41, 37,115, 42, 40, 61, 63, 37,115, - 42, 48, 63, 41, 37,115, 42, 59, 37,115, 42, 34, 41, 10, 32, - 32,105,102, 32,110,111,116, 32, 98, 32,116,104,101,110, 10, - 32, 32, 9, 45, 45, 32,116,114,121, 32,102,117,110, 99,116, - 105,111,110, 32,119,105,116,104, 32,116,101,109,112,108, 97, - 116,101, 10, 32, 32, 9, 98, 44,101, 44,100,101, 99,108, 44, - 97,114,103, 44, 99,111,110,115,116, 32, 61, 32,115,116,114, - 102,105,110,100, 40,115, 44, 34, 94, 37,115, 42, 40, 91,126, - 95, 37,119, 93, 91, 95, 64, 37,119, 37,115, 37, 42, 38, 58, - 60, 62, 93, 42, 91, 95, 37,119, 93, 37, 98, 60, 62, 41, 37, - 115, 42, 40, 37, 98, 40, 41, 41, 37,115, 42, 40, 99, 63,111, - 63,110, 63,115, 63,116, 63, 41, 37,115, 42, 61, 63, 37,115, - 42, 48, 63, 37,115, 42, 59, 37,115, 42, 34, 41, 10, 32, 32, - 101,110,100, 10, 32, 32,105,102, 32,110,111,116, 32, 98, 32, - 116,104,101,110, 10, 32, 32, 32, 45, 45, 32,116,114,121, 32, - 97, 32,115,105,110,103,108,101, 32,108,101,116,116,101,114, - 32,102,117,110, 99,116,105,111,110, 32,110, 97,109,101, 10, - 32, 32, 32, 98, 44,101, 44,100,101, 99,108, 44, 97,114,103, - 44, 99,111,110,115,116, 32, 61, 32,115,116,114,102,105,110, - 100, 40,115, 44, 34, 94, 37,115, 42, 40, 91, 95, 37,119, 93, - 41, 37,115, 42, 40, 37, 98, 40, 41, 41, 37,115, 42, 40, 99, - 63,111, 63,110, 63,115, 63,116, 63, 41, 37,115, 42, 59, 37, - 115, 42, 34, 41, 10, 32, 32,101,110,100, 10, 32, 32,105,102, - 32,110,111,116, 32, 98, 32,116,104,101,110, 10, 32, 32, 32, - 45, 45, 32,116,114,121, 32,102,117,110, 99,116,105,111,110, - 32,112,111,105,110,116,101,114, 10, 32, 32, 32, 98, 44,101, - 44,100,101, 99,108, 44, 97,114,103, 44, 99,111,110,115,116, - 32, 61, 32,115,116,114,102,105,110,100, 40,115, 44, 34, 94, - 37,115, 42, 40, 91, 94, 37, 40, 59, 92,110, 93, 43, 37, 98, - 40, 41, 41, 37,115, 42, 40, 37, 98, 40, 41, 41, 37,115, 42, - 59, 37,115, 42, 34, 41, 10, 32, 32, 32,105,102, 32, 98, 32, - 116,104,101,110, 10, 32, 32, 32, 32,100,101, 99,108, 32, 61, - 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,100,101, - 99,108, 44, 32, 34, 37, 40, 37,115, 42, 37, 42, 40, 91, 94, - 37, 41, 93, 42, 41, 37,115, 42, 37, 41, 34, 44, 32, 34, 32, - 37, 49, 32, 34, 41, 10, 32, 32, 32,101,110,100, 10, 32, 32, - 101,110,100, 10, 32, 32,105,102, 32, 98, 32,116,104,101,110, - 10, 32, 32, 9,105,102, 32,118,105,114,116, 32, 97,110,100, - 32,115,116,114,105,110,103, 46,102,105,110,100, 40,118,105, - 114,116, 44, 32, 34, 91, 61, 48, 93, 34, 41, 32,116,104,101, - 110, 10, 32, 32, 9, 9,105,102, 32,115,101,108,102, 46,102, - 108, 97,103,115, 32,116,104,101,110, 10, 32, 32, 9, 9, 9, - 115,101,108,102, 46,102,108, 97,103,115, 46,112,117,114,101, - 95,118,105,114,116,117, 97,108, 32, 61, 32,116,114,117,101, - 10, 32, 32, 9, 9,101,110,100, 10, 32, 32, 9,101,110,100, - 10, 32, 32, 32, 95, 99,117,114,114, 95, 99,111,100,101, 32, - 61, 32,115,116,114,115,117, 98, 40,115, 44, 98, 44,101, 41, - 10, 32, 32, 32, 70,117,110, 99,116,105,111,110, 40,100,101, - 99,108, 44, 97,114,103, 44, 99,111,110,115,116, 41, 10, 32, - 32, 32,114,101,116,117,114,110, 32,115,116,114,115,117, 98, - 40,115, 44,101, 43, 49, 41, 10, 32, 32,101,110,100, 10, 32, - 101,110,100, 10, 10, 32, 45, 45, 32,116,114,121, 32,105,110, - 108,105,110,101, 32,102,117,110, 99,116,105,111,110, 10, 32, - 100,111, 10, 32, 32,108,111, 99, 97,108, 32, 98, 44,101, 44, - 100,101, 99,108, 44, 97,114,103, 44, 99,111,110,115,116, 32, - 61, 32,115,116,114,102,105,110,100, 40,115, 44, 34, 94, 37, - 115, 42, 40, 91, 94, 37, 40, 92,110, 93, 43, 41, 37,115, 42, - 40, 37, 98, 40, 41, 41, 37,115, 42, 40, 99, 63,111, 63,110, - 63,115, 63,116, 63, 41, 91, 94, 59,123, 93, 42, 37, 98,123, - 125, 37,115, 42, 59, 63, 37,115, 42, 34, 41, 10, 32, 32, 45, - 45,108,111, 99, 97,108, 32, 98, 44,101, 44,100,101, 99,108, - 44, 97,114,103, 44, 99,111,110,115,116, 32, 61, 32,115,116, - 114,102,105,110,100, 40,115, 44, 34, 94, 37,115, 42, 40, 91, - 126, 95, 37,119, 93, 91, 95, 64, 37,119, 37,115, 37, 42, 38, - 58, 60, 62, 93, 42, 91, 95, 37,119, 62, 93, 41, 37,115, 42, - 40, 37, 98, 40, 41, 41, 37,115, 42, 40, 99, 63,111, 63,110, - 63,115, 63,116, 63, 41, 91, 94, 59, 93, 42, 37, 98,123,125, - 37,115, 42, 59, 63, 37,115, 42, 34, 41, 10, 32, 32,105,102, - 32,110,111,116, 32, 98, 32,116,104,101,110, 10, 32, 32, 32, - 45, 45, 32,116,114,121, 32, 97, 32,115,105,110,103,108,101, - 32,108,101,116,116,101,114, 32,102,117,110, 99,116,105,111, - 110, 32,110, 97,109,101, 10, 32, 32, 32, 98, 44,101, 44,100, - 101, 99,108, 44, 97,114,103, 44, 99,111,110,115,116, 32, 61, - 32,115,116,114,102,105,110,100, 40,115, 44, 34, 94, 37,115, - 42, 40, 91, 95, 37,119, 93, 41, 37,115, 42, 40, 37, 98, 40, - 41, 41, 37,115, 42, 40, 99, 63,111, 63,110, 63,115, 63,116, - 63, 41, 46, 45, 37, 98,123,125, 37,115, 42, 59, 63, 37,115, - 42, 34, 41, 10, 32, 32,101,110,100, 10, 32, 32,105,102, 32, - 98, 32,116,104,101,110, 10, 32, 32, 32, 95, 99,117,114,114, - 95, 99,111,100,101, 32, 61, 32,115,116,114,115,117, 98, 40, - 115, 44, 98, 44,101, 41, 10, 32, 32, 32, 70,117,110, 99,116, - 105,111,110, 40,100,101, 99,108, 44, 97,114,103, 44, 99,111, - 110,115,116, 41, 10, 32, 32, 32,114,101,116,117,114,110, 32, - 115,116,114,115,117, 98, 40,115, 44,101, 43, 49, 41, 10, 32, - 32,101,110,100, 10, 32,101,110,100, 10, 10, 32, 45, 45, 32, - 116,114,121, 32, 99,108, 97,115,115, 10, 32,100,111, 10, 9, - 32,108,111, 99, 97,108, 32, 98, 44,101, 44,110, 97,109,101, - 44, 98, 97,115,101, 44, 98,111,100,121, 10, 9, 9, 98, 97, - 115,101, 32, 61, 32, 39, 39, 32, 98,111,100,121, 32, 61, 32, - 39, 39, 10, 9, 9, 98, 44,101, 44,110, 97,109,101, 32, 61, - 32,115,116,114,102,105,110,100, 40,115, 44, 34, 94, 37,115, - 42, 99,108, 97,115,115, 37,115, 42, 40, 91, 95, 37,119, 93, - 91, 95, 37,119, 64, 93, 42, 41, 37,115, 42, 59, 34, 41, 32, - 32, 45, 45, 32,100,117,109,109,121, 32, 99,108, 97,115,115, - 10, 9, 9,108,111, 99, 97,108, 32,100,117,109,109,121, 32, - 61, 32,102, 97,108,115,101, 10, 9, 9,105,102, 32,110,111, - 116, 32, 98, 32,116,104,101,110, 10, 9, 9, 9, 98, 44,101, - 44,110, 97,109,101, 32, 61, 32,115,116,114,102,105,110,100, - 40,115, 44, 34, 94, 37,115, 42,115,116,114,117, 99,116, 37, - 115, 42, 40, 91, 95, 37,119, 93, 91, 95, 37,119, 64, 93, 42, - 41, 37,115, 42, 59, 34, 41, 32, 32, 32, 32, 45, 45, 32,100, - 117,109,109,121, 32,115,116,114,117, 99,116, 10, 9, 9, 9, - 105,102, 32,110,111,116, 32, 98, 32,116,104,101,110, 10, 9, - 9, 9, 9, 98, 44,101, 44,110, 97,109,101, 44, 98, 97,115, - 101, 44, 98,111,100,121, 32, 61, 32,115,116,114,102,105,110, - 100, 40,115, 44, 34, 94, 37,115, 42, 99,108, 97,115,115, 37, - 115, 42, 40, 91, 95, 37,119, 93, 91, 95, 37,119, 64, 93, 42, - 41, 37,115, 42, 40, 91, 94,123, 93, 45, 41, 37,115, 42, 40, - 37, 98,123,125, 41, 37,115, 42, 34, 41, 10, 9, 9, 9, 9, - 105,102, 32,110,111,116, 32, 98, 32,116,104,101,110, 10, 9, - 9, 9, 9, 9, 98, 44,101, 44,110, 97,109,101, 44, 98, 97, - 115,101, 44, 98,111,100,121, 32, 61, 32,115,116,114,102,105, - 110,100, 40,115, 44, 34, 94, 37,115, 42,115,116,114,117, 99, - 116, 37,115, 43, 40, 91, 95, 37,119, 93, 91, 95, 37,119, 64, - 93, 42, 41, 37,115, 42, 40, 91, 94,123, 93, 45, 41, 37,115, - 42, 40, 37, 98,123,125, 41, 37,115, 42, 34, 41, 10, 9, 9, - 9, 9, 9,105,102, 32,110,111,116, 32, 98, 32,116,104,101, - 110, 10, 9, 9, 9, 9, 9, 9, 98, 44,101, 44,110, 97,109, - 101, 44, 98, 97,115,101, 44, 98,111,100,121, 32, 61, 32,115, - 116,114,102,105,110,100, 40,115, 44, 34, 94, 37,115, 42,117, - 110,105,111,110, 37,115, 42, 40, 91, 95, 37,119, 93, 91, 95, - 37,119, 64, 93, 42, 41, 37,115, 42, 40, 91, 94,123, 93, 45, - 41, 37,115, 42, 40, 37, 98,123,125, 41, 37,115, 42, 34, 41, - 10, 9, 9, 9, 9, 9, 9,105,102, 32,110,111,116, 32, 98, - 32,116,104,101,110, 10, 9, 9, 9, 9, 9, 9, 9, 98, 97, - 115,101, 32, 61, 32, 39, 39, 10, 9, 9, 9, 9, 9, 9, 9, - 98, 44,101, 44, 98,111,100,121, 44,110, 97,109,101, 32, 61, - 32,115,116,114,102,105,110,100, 40,115, 44, 34, 94, 37,115, - 42,116,121,112,101,100,101,102, 37,115, 37,115, 42,115,116, - 114,117, 99,116, 37,115, 37,115, 42, 91, 95, 37,119, 93, 42, - 37,115, 42, 40, 37, 98,123,125, 41, 37,115, 42, 40, 91, 95, - 37,119, 93, 91, 95, 37,119, 64, 93, 42, 41, 37,115, 42, 59, - 34, 41, 10, 9, 9, 9, 9, 9, 9,101,110,100, 10, 9, 9, - 9, 9, 9,101,110,100, 10, 9, 9, 9, 9,101,110,100, 10, - 9, 9, 9,101,108,115,101, 32,100,117,109,109,121, 32, 61, - 32, 49, 32,101,110,100, 10, 9, 9,101,108,115,101, 32,100, - 117,109,109,121, 32, 61, 32, 49, 32,101,110,100, 10, 9, 9, - 105,102, 32, 98, 32,116,104,101,110, 10, 9, 9, 9,105,102, - 32, 98, 97,115,101, 32,126, 61, 32, 39, 39, 32,116,104,101, - 110, 10, 9, 9, 9, 9, 98, 97,115,101, 32, 61, 32,115,116, - 114,105,110,103, 46,103,115,117, 98, 40, 98, 97,115,101, 44, - 32, 34, 94, 37,115, 42, 58, 37,115, 42, 34, 44, 32, 34, 34, - 41, 10, 9, 9, 9, 9, 98, 97,115,101, 32, 61, 32,115,116, - 114,105,110,103, 46,103,115,117, 98, 40, 98, 97,115,101, 44, - 32, 34, 37,115, 42,112,117, 98,108,105, 99, 37,115, 42, 34, - 44, 32, 34, 34, 41, 10, 9, 9, 9, 9, 98, 97,115,101, 32, - 61, 32,115,112,108,105,116, 40, 98, 97,115,101, 44, 32, 34, - 44, 34, 41, 10, 9, 9, 9, 9, 45, 45,108,111, 99, 97,108, - 32, 98, 44,101, 10, 9, 9, 9, 9, 45, 45, 98, 44,101, 44, - 98, 97,115,101, 32, 61, 32,115,116,114,102,105,110,100, 40, - 98, 97,115,101, 44, 34, 46, 45, 40, 91, 95, 37,119, 93, 91, - 95, 37,119, 60, 62, 44, 58, 93, 42, 41, 36, 34, 41, 10, 9, - 9, 9,101,108,115,101, 10, 9, 9, 9, 9, 98, 97,115,101, - 32, 61, 32,123,125, 10, 9, 9, 9,101,110,100, 10, 9, 9, - 9, 95, 99,117,114,114, 95, 99,111,100,101, 32, 61, 32,115, - 116,114,115,117, 98, 40,115, 44, 98, 44,101, 41, 10, 9, 9, - 9, 67,108, 97,115,115, 40,110, 97,109,101, 44, 98, 97,115, - 101, 44, 98,111,100,121, 41, 10, 9, 9, 9,105,102, 32,110, - 111,116, 32,100,117,109,109,121, 32,116,104,101,110, 10, 9, - 9, 9, 9,118, 97,114, 98, 44,118, 97,114,101, 44,118, 97, - 114,110, 97,109,101, 32, 61, 32,115,116,114,105,110,103, 46, - 102,105,110,100, 40,115, 44, 32, 34, 94, 37,115, 42, 40, 91, - 95, 37,119, 93, 43, 41, 37,115, 42, 59, 34, 44, 32,101, 43, - 49, 41, 10, 9, 9, 9, 9,105,102, 32,118, 97,114, 98, 32, - 116,104,101,110, 10, 9, 9, 9, 9, 9, 86, 97,114,105, 97, - 98,108,101, 40,110, 97,109,101, 46, 46, 34, 32, 34, 46, 46, - 118, 97,114,110, 97,109,101, 41, 10, 9, 9, 9, 9, 9,101, - 32, 61, 32,118, 97,114,101, 10, 9, 9, 9, 9,101,110,100, - 10, 9, 9, 9,101,110,100, 10, 9, 9, 9,114,101,116,117, - 114,110, 32,115,116,114,115,117, 98, 40,115, 44,101, 43, 49, - 41, 10, 9, 9,101,110,100, 10, 9,101,110,100, 10, 10, 32, - 45, 45, 32,116,114,121, 32,116,121,112,101,100,101,102, 10, - 32,100,111, 10, 32, 32,108,111, 99, 97,108, 32, 98, 44,101, - 44,116,121,112,101,115, 32, 61, 32,115,116,114,102,105,110, - 100, 40,115, 44, 34, 94, 37,115, 42,116,121,112,101,100,101, - 102, 37,115, 37,115, 42, 40, 46, 45, 41, 37,115, 42, 59, 37, - 115, 42, 34, 41, 10, 32, 32,105,102, 32, 98, 32,116,104,101, - 110, 10, 32, 32, 32, 95, 99,117,114,114, 95, 99,111,100,101, - 32, 61, 32,115,116,114,115,117, 98, 40,115, 44, 98, 44,101, - 41, 10, 32, 32, 32, 84,121,112,101,100,101,102, 40,116,121, - 112,101,115, 41, 10, 32, 32, 32,114,101,116,117,114,110, 32, - 115,116,114,115,117, 98, 40,115, 44,101, 43, 49, 41, 10, 32, - 32,101,110,100, 10, 32,101,110,100, 10, 10, 32, 45, 45, 32, - 116,114,121, 32,118, 97,114,105, 97, 98,108,101, 10, 32,100, - 111, 10, 32, 32,108,111, 99, 97,108, 32, 98, 44,101, 44,100, - 101, 99,108, 32, 61, 32,115,116,114,102,105,110,100, 40,115, - 44, 34, 94, 37,115, 42, 40, 91, 95, 37,119, 93, 91, 95, 64, - 37,115, 37,119, 37,100, 37, 42, 38, 58, 60, 62, 44, 93, 42, - 91, 95, 37,119, 37,100, 93, 41, 37,115, 42, 59, 37,115, 42, - 34, 41, 10, 32, 32,105,102, 32, 98, 32,116,104,101,110, 10, - 32, 32, 32, 95, 99,117,114,114, 95, 99,111,100,101, 32, 61, - 32,115,116,114,115,117, 98, 40,115, 44, 98, 44,101, 41, 10, - 10, 9,108,111, 99, 97,108, 32,108,105,115,116, 32, 61, 32, - 115,112,108,105,116, 95, 99, 95,116,111,107,101,110,115, 40, - 100,101, 99,108, 44, 32, 34, 44, 34, 41, 10, 9, 86, 97,114, - 105, 97, 98,108,101, 40,108,105,115,116, 91, 49, 93, 41, 10, - 9,105,102, 32,108,105,115,116, 46,110, 32, 62, 32, 49, 32, - 116,104,101,110, 10, 9, 9,108,111, 99, 97,108, 32, 95, 44, - 95, 44,116,121,112,101, 32, 61, 32,115,116,114,102,105,110, - 100, 40,108,105,115,116, 91, 49, 93, 44, 32, 34, 40, 46, 45, - 41, 37,115, 43, 40, 91, 94, 37,115, 93, 42, 41, 36, 34, 41, - 59, 10, 10, 9, 9,108,111, 99, 97,108, 32,105, 32, 61, 50, - 59, 10, 9, 9,119,104,105,108,101, 32,108,105,115,116, 91, - 105, 93, 32,100,111, 10, 9, 9, 9, 86, 97,114,105, 97, 98, - 108,101, 40,116,121,112,101, 46, 46, 34, 32, 34, 46, 46,108, - 105,115,116, 91,105, 93, 41, 10, 9, 9, 9,105, 61,105, 43, - 49, 10, 9, 9,101,110,100, 10, 9,101,110,100, 10, 32, 32, - 32, 45, 45, 86, 97,114,105, 97, 98,108,101, 40,100,101, 99, - 108, 41, 10, 32, 32, 32,114,101,116,117,114,110, 32,115,116, - 114,115,117, 98, 40,115, 44,101, 43, 49, 41, 10, 32, 32,101, - 110,100, 10, 32,101,110,100, 10, 10, 9, 45, 45, 32,116,114, - 121, 32,115,116,114,105,110,103, 10, 32,100,111, 10, 32, 32, - 108,111, 99, 97,108, 32, 98, 44,101, 44,100,101, 99,108, 32, - 61, 32,115,116,114,102,105,110,100, 40,115, 44, 34, 94, 37, - 115, 42, 40, 91, 95, 37,119, 93, 63, 91, 95, 37,115, 37,119, - 37,100, 93, 45, 99,104, 97,114, 37,115, 43, 91, 95, 64, 37, - 119, 37,100, 93, 42, 37,115, 42, 37, 91, 37,115, 42, 37, 83, - 43, 37,115, 42, 37, 93, 41, 37,115, 42, 59, 37,115, 42, 34, - 41, 10, 32, 32,105,102, 32, 98, 32,116,104,101,110, 10, 32, - 32, 32, 95, 99,117,114,114, 95, 99,111,100,101, 32, 61, 32, - 115,116,114,115,117, 98, 40,115, 44, 98, 44,101, 41, 10, 32, - 32, 32, 86, 97,114,105, 97, 98,108,101, 40,100,101, 99,108, - 41, 10, 32, 32, 32,114,101,116,117,114,110, 32,115,116,114, - 115,117, 98, 40,115, 44,101, 43, 49, 41, 10, 32, 32,101,110, - 100, 10, 32,101,110,100, 10, 10, 32, 45, 45, 32,116,114,121, - 32, 97,114,114, 97,121, 10, 32,100,111, 10, 32, 32,108,111, - 99, 97,108, 32, 98, 44,101, 44,100,101, 99,108, 32, 61, 32, - 115,116,114,102,105,110,100, 40,115, 44, 34, 94, 37,115, 42, - 40, 91, 95, 37,119, 93, 91, 93, 91, 95, 64, 37,115, 37,119, - 37,100, 37, 42, 38, 58, 60, 62, 93, 42, 91, 93, 95, 37,119, - 37,100, 93, 41, 37,115, 42, 59, 37,115, 42, 34, 41, 10, 32, - 32,105,102, 32, 98, 32,116,104,101,110, 10, 32, 32, 32, 95, - 99,117,114,114, 95, 99,111,100,101, 32, 61, 32,115,116,114, - 115,117, 98, 40,115, 44, 98, 44,101, 41, 10, 32, 32, 32, 65, - 114,114, 97,121, 40,100,101, 99,108, 41, 10, 32, 32, 32,114, - 101,116,117,114,110, 32,115,116,114,115,117, 98, 40,115, 44, - 101, 43, 49, 41, 10, 32, 32,101,110,100, 10, 32,101,110,100, - 10, 10, 32, 45, 45, 32,110,111, 32,109, 97,116, 99,104,105, - 110,103, 10, 32,105,102, 32,103,115,117, 98, 40,115, 44, 34, - 37,115, 37,115, 42, 34, 44, 34, 34, 41, 32,126, 61, 32, 34, - 34, 32,116,104,101,110, 10, 32, 32, 95, 99,117,114,114, 95, - 99,111,100,101, 32, 61, 32,115, 10, 32, 32,101,114,114,111, - 114, 40, 34, 35,112, 97,114,115,101, 32,101,114,114,111,114, - 34, 41, 10, 32,101,108,115,101, 10, 32, 32,114,101,116,117, - 114,110, 32, 34, 34, 10, 32,101,110,100, 10, 10,101,110,100, - 10, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,115, - 115, 67,111,110,116, 97,105,110,101,114, 58,112, 97,114,115, - 101, 32, 40,115, 41, 10, 10, 9, 45, 45,115,101,108,102, 46, - 99,117,114,114, 95,109,101,109, 98,101,114, 95, 97, 99, 99, - 101,115,115, 32, 61, 32,110,105,108, 10, 10, 32,119,104,105, - 108,101, 32,115, 32,126, 61, 32, 39, 39, 32,100,111, 10, 32, - 32,115, 32, 61, 32,115,101,108,102, 58,100,111,112, 97,114, - 115,101, 40,115, 41, 10, 32, 32,109,101,116,104,111,100,105, - 115,118,105,114,116,117, 97,108, 32, 61, 32,102, 97,108,115, - 101, 10, 32,101,110,100, 10,101,110,100, 10, 10, 10, 45, 45, - 32,112,114,111,112,101,114,116,121, 32,116,121,112,101,115, - 10, 10,102,117,110, 99,116,105,111,110, 32,103,101,116, 95, - 112,114,111,112,101,114,116,121, 95,116,121,112,101, 40, 41, - 10, 10, 9,114,101,116,117,114,110, 32, 99,108, 97,115,115, - 67,111,110,116, 97,105,110,101,114, 46, 99,117,114,114, 58, - 103,101,116, 95,112,114,111,112,101,114,116,121, 95,116,121, - 112,101, 40, 41, 10,101,110,100, 10, 10,102,117,110, 99,116, - 105,111,110, 32, 99,108, 97,115,115, 67,111,110,116, 97,105, - 110,101,114, 58,115,101,116, 95,112,114,111,112,101,114,116, - 121, 95,116,121,112,101, 40,112,116,121,112,101, 41, 10, 9, - 112,116,121,112,101, 32, 61, 32,115,116,114,105,110,103, 46, - 103,115,117, 98, 40,112,116,121,112,101, 44, 32, 34, 94, 37, - 115, 42, 34, 44, 32, 34, 34, 41, 10, 9,112,116,121,112,101, - 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, - 112,116,121,112,101, 44, 32, 34, 37,115, 42, 36, 34, 44, 32, - 34, 34, 41, 10, 10, 9,115,101,108,102, 46,112,114,111,112, - 101,114,116,121, 95,116,121,112,101, 32, 61, 32,112,116,121, - 112,101, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111, - 110, 32, 99,108, 97,115,115, 67,111,110,116, 97,105,110,101, - 114, 58,103,101,116, 95,112,114,111,112,101,114,116,121, 95, - 116,121,112,101, 40, 41, 10, 9,114,101,116,117,114,110, 32, - 115,101,108,102, 46,112,114,111,112,101,114,116,121, 95,116, - 121,112,101, 32,111,114, 32, 40,115,101,108,102, 46,112, 97, - 114,101,110,116, 32, 97,110,100, 32,115,101,108,102, 46,112, - 97,114,101,110,116, 58,103,101,116, 95,112,114,111,112,101, - 114,116,121, 95,116,121,112,101, 40, 41, 41, 32,111,114, 32, - 34,100,101,102, 97,117,108,116, 34, 10,101,110,100,32 - }; - tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua embedded: src/bin/lua/container.lua"); + #include "container_lua.h" + tolua_dobuffer(tolua_S,(char*)lua_container_lua,sizeof(lua_container_lua),"tolua embedded: src/bin/lua/container.lua"); lua_settop(tolua_S, top); } /* end of embedded lua code */ @@ -3788,1191 +2031,19 @@ TOLUA_API int tolua_tolua_open (lua_State* tolua_S) } /* end of embedded lua code */ + { /* begin embedded lua code */ int top = lua_gettop(tolua_S); - static unsigned char B[] = { - 45, 45, 32,116,111,108,117, 97, 58, 32,101,110,117,109,101, - 114, 97,116,101, 32, 99,108, 97,115,115, 10, 45, 45, 32, 87, - 114,105,116,116,101,110, 32, 98,121, 32, 87, 97,108,100,101, - 109, 97,114, 32, 67,101,108,101,115, 10, 45, 45, 32, 84,101, - 67, 71,114, 97,102, 47, 80, 85, 67, 45, 82,105,111, 10, 45, - 45, 32, 74,117,108, 32, 49, 57, 57, 56, 10, 45, 45, 32, 36, - 73,100, 58, 32,101,110,117,109,101,114, 97,116,101, 46,108, - 117, 97, 44,118, 32, 49, 46, 51, 32, 50, 48, 48, 48, 47, 48, - 49, 47, 50, 52, 32, 50, 48, 58, 52, 49, 58, 49, 53, 32, 99, - 101,108,101,115, 32, 69,120,112, 32, 36, 10, 10, 45, 45, 32, - 84,104,105,115, 32, 99,111,100,101, 32,105,115, 32,102,114, - 101,101, 32,115,111,102,116,119, 97,114,101, 59, 32,121,111, - 117, 32, 99, 97,110, 32,114,101,100,105,115,116,114,105, 98, - 117,116,101, 32,105,116, 32, 97,110,100, 47,111,114, 32,109, - 111,100,105,102,121, 32,105,116, 46, 10, 45, 45, 32, 84,104, - 101, 32,115,111,102,116,119, 97,114,101, 32,112,114,111,118, - 105,100,101,100, 32,104,101,114,101,117,110,100,101,114, 32, - 105,115, 32,111,110, 32, 97,110, 32, 34, 97,115, 32,105,115, - 34, 32, 98, 97,115,105,115, 44, 32, 97,110,100, 10, 45, 45, - 32,116,104,101, 32, 97,117,116,104,111,114, 32,104, 97,115, - 32,110,111, 32,111, 98,108,105,103, 97,116,105,111,110, 32, - 116,111, 32,112,114,111,118,105,100,101, 32,109, 97,105,110, - 116,101,110, 97,110, 99,101, 44, 32,115,117,112,112,111,114, - 116, 44, 32,117,112,100, 97,116,101,115, 44, 10, 45, 45, 32, - 101,110,104, 97,110, 99,101,109,101,110,116,115, 44, 32,111, - 114, 32,109,111,100,105,102,105, 99, 97,116,105,111,110,115, - 46, 10, 10, 10, 45, 45, 32, 69,110,117,109,101,114, 97,116, - 101, 32, 99,108, 97,115,115, 10, 45, 45, 32, 82,101,112,114, - 101,115,101,110,116,115, 32,101,110,117,109,101,114, 97,116, - 105,111,110, 10, 45, 45, 32, 84,104,101, 32,102,111,108,108, - 111,119,105,110,103, 32,102,105,101,108,100,115, 32, 97,114, - 101, 32,115,116,111,114,101,100, 58, 10, 45, 45, 32, 32, 32, - 32,123,105,125, 32, 61, 32,108,105,115,116, 32,111,102, 32, - 99,111,110,115,116, 97,110,116, 32,110, 97,109,101,115, 10, - 99,108, 97,115,115, 69,110,117,109,101,114, 97,116,101, 32, - 61, 32,123, 10,125, 10, 99,108, 97,115,115, 69,110,117,109, - 101,114, 97,116,101, 46, 95, 95,105,110,100,101,120, 32, 61, - 32, 99,108, 97,115,115, 69,110,117,109,101,114, 97,116,101, - 10,115,101,116,109,101,116, 97,116, 97, 98,108,101, 40, 99, - 108, 97,115,115, 69,110,117,109,101,114, 97,116,101, 44, 99, - 108, 97,115,115, 70,101, 97,116,117,114,101, 41, 10, 10, 45, - 45, 32,114,101,103,105,115,116,101,114, 32,101,110,117,109, - 101,114, 97,116,105,111,110, 10,102,117,110, 99,116,105,111, - 110, 32, 99,108, 97,115,115, 69,110,117,109,101,114, 97,116, - 101, 58,114,101,103,105,115,116,101,114, 32, 40,112,114,101, - 41, 10, 9,105,102, 32,110,111,116, 32,115,101,108,102, 58, - 99,104,101, 99,107, 95,112,117, 98,108,105, 99, 95, 97, 99, - 99,101,115,115, 40, 41, 32,116,104,101,110, 10, 9, 9,114, - 101,116,117,114,110, 10, 9,101,110,100, 10, 32,112,114,101, - 32, 61, 32,112,114,101, 32,111,114, 32, 39, 39, 10, 32,108, - 111, 99, 97,108, 32,110,115,112, 97, 99,101, 32, 61, 32,103, - 101,116,110, 97,109,101,115,112, 97, 99,101, 40, 99,108, 97, - 115,115, 67,111,110,116, 97,105,110,101,114, 46, 99,117,114, - 114, 41, 10, 32,108,111, 99, 97,108, 32,105, 61, 49, 10, 32, - 119,104,105,108,101, 32,115,101,108,102, 91,105, 93, 32,100, - 111, 10, 32, 9,105,102, 32,115,101,108,102, 46,108,110, 97, - 109,101,115, 91,105, 93, 32, 97,110,100, 32,115,101,108,102, - 46,108,110, 97,109,101,115, 91,105, 93, 32,126, 61, 32, 34, - 34, 32,116,104,101,110, 10, 9, 10, 9, 9,111,117,116,112, - 117,116, 40,112,114,101, 46, 46, 39,116,111,108,117, 97, 95, - 99,111,110,115,116, 97,110,116, 40,116,111,108,117, 97, 95, - 83, 44, 34, 39, 46, 46,115,101,108,102, 46,108,110, 97,109, - 101,115, 91,105, 93, 46, 46, 39, 34, 44, 39, 46, 46,110,115, - 112, 97, 99,101, 46, 46,115,101,108,102, 91,105, 93, 46, 46, - 39, 41, 59, 39, 41, 10, 9,101,110,100, 10, 32, 32,105, 32, - 61, 32,105, 43, 49, 10, 32,101,110,100, 10,101,110,100, 10, - 10, 45, 45, 32, 80,114,105,110,116, 32,109,101,116,104,111, - 100, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,115, - 115, 69,110,117,109,101,114, 97,116,101, 58,112,114,105,110, - 116, 32, 40,105,100,101,110,116, 44, 99,108,111,115,101, 41, - 10, 32,112,114,105,110,116, 40,105,100,101,110,116, 46, 46, - 34, 69,110,117,109,101,114, 97,116,101,123, 34, 41, 10, 32, - 112,114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 32, - 110, 97,109,101, 32, 61, 32, 34, 46, 46,115,101,108,102, 46, - 110, 97,109,101, 41, 10, 32,108,111, 99, 97,108, 32,105, 61, - 49, 10, 32,119,104,105,108,101, 32,115,101,108,102, 91,105, - 93, 32,100,111, 10, 32, 32,112,114,105,110,116, 40,105,100, - 101,110,116, 46, 46, 34, 32, 39, 34, 46, 46,115,101,108,102, - 91,105, 93, 46, 46, 34, 39, 40, 34, 46, 46,115,101,108,102, - 46,108,110, 97,109,101,115, 91,105, 93, 46, 46, 34, 41, 44, - 34, 41, 10, 32, 32,105, 32, 61, 32,105, 43, 49, 10, 32,101, - 110,100, 10, 32,112,114,105,110,116, 40,105,100,101,110,116, - 46, 46, 34,125, 34, 46, 46, 99,108,111,115,101, 41, 10,101, - 110,100, 10, 10, 45, 45, 32, 73,110,116,101,114,110, 97,108, - 32, 99,111,110,115,116,114,117, 99,116,111,114, 10,102,117, - 110, 99,116,105,111,110, 32, 95, 69,110,117,109,101,114, 97, - 116,101, 32, 40,116, 44,118, 97,114,110, 97,109,101, 41, 10, - 32,115,101,116,109,101,116, 97,116, 97, 98,108,101, 40,116, - 44, 99,108, 97,115,115, 69,110,117,109,101,114, 97,116,101, - 41, 10, 32, 97,112,112,101,110,100, 40,116, 41, 10, 32, 97, - 112,112,101,110,100,101,110,117,109, 40,116, 41, 10, 9, 32, - 105,102, 32,118, 97,114,110, 97,109,101, 32, 97,110,100, 32, - 118, 97,114,110, 97,109,101, 32,126, 61, 32, 34, 34, 32,116, - 104,101,110, 10, 9, 9,105,102, 32,116, 46,110, 97,109,101, - 32,126, 61, 32, 34, 34, 32,116,104,101,110, 10, 9, 9, 9, - 86, 97,114,105, 97, 98,108,101, 40,116, 46,110, 97,109,101, - 46, 46, 34, 32, 34, 46, 46,118, 97,114,110, 97,109,101, 41, - 10, 9, 9,101,108,115,101, 10, 9, 9, 9,108,111, 99, 97, - 108, 32,110,115, 32, 61, 32,103,101,116, 99,117,114,114,110, - 97,109,101,115,112, 97, 99,101, 40, 41, 10, 9, 9, 9,119, - 97,114,110,105,110,103, 40, 34, 86, 97,114,105, 97, 98,108, - 101, 32, 34, 46, 46,110,115, 46, 46,118, 97,114,110, 97,109, - 101, 46, 46, 34, 32,111,102, 32,116,121,112,101, 32, 60, 97, - 110,111,110,121,109,111,117,115, 32,101,110,117,109, 62, 32, - 105,115, 32,100,101, 99,108, 97,114,101,100, 32, 97,115, 32, - 114,101, 97,100, 45,111,110,108,121, 34, 41, 10, 9, 9, 9, - 86, 97,114,105, 97, 98,108,101, 40, 34,116,111,108,117, 97, - 95,114,101, 97,100,111,110,108,121, 32,105,110,116, 32, 34, - 46, 46,118, 97,114,110, 97,109,101, 41, 10, 9, 9,101,110, - 100, 10, 9,101,110,100, 10, 9, 32,108,111, 99, 97,108, 32, - 112, 97,114,101,110,116, 32, 61, 32, 99,108, 97,115,115, 67, - 111,110,116, 97,105,110,101,114, 46, 99,117,114,114, 10, 9, - 32,105,102, 32,112, 97,114,101,110,116, 32,116,104,101,110, - 10, 9, 9,116, 46, 97, 99, 99,101,115,115, 32, 61, 32,112, - 97,114,101,110,116, 46, 99,117,114,114, 95,109,101,109, 98, - 101,114, 95, 97, 99, 99,101,115,115, 10, 9, 9,116, 46,103, - 108,111, 98, 97,108, 95, 97, 99, 99,101,115,115, 32, 61, 32, - 116, 58, 99,104,101, 99,107, 95,112,117, 98,108,105, 99, 95, - 97, 99, 99,101,115,115, 40, 41, 10, 9, 32,101,110,100, 10, - 114,101,116,117,114,110, 32,116, 10,101,110,100, 10, 10, 45, - 45, 32, 67,111,110,115,116,114,117, 99,116,111,114, 10, 45, - 45, 32, 69,120,112,101, 99,116,115, 32, 97, 32,115,116,114, - 105,110,103, 32,114,101,112,114,101,115,101,110,116,105,110, - 103, 32,116,104,101, 32,101,110,117,109,101,114, 97,116,101, - 32, 98,111,100,121, 10,102,117,110, 99,116,105,111,110, 32, - 69,110,117,109,101,114, 97,116,101, 32, 40,110, 44, 98, 44, - 118, 97,114,110, 97,109,101, 41, 10, 9, 98, 32, 61, 32,115, - 116,114,105,110,103, 46,103,115,117, 98, 40, 98, 44, 32, 34, - 44, 91, 37,115, 92,110, 93, 42,125, 34, 44, 32, 34, 92,110, - 125, 34, 41, 32, 45, 45, 32,101,108,105,109,105,110, 97,116, - 101, 32,108, 97,115,116, 32, 39, 44, 39, 10, 32,108,111, 99, - 97,108, 32,116, 32, 61, 32,115,112,108,105,116, 40,115,116, - 114,115,117, 98, 40, 98, 44, 50, 44, 45, 50, 41, 44, 39, 44, - 39, 41, 32, 45, 45, 32,101,108,105,109,105,110, 97,116,101, - 32, 98,114, 97, 99,101,115, 10, 32,108,111, 99, 97,108, 32, - 105, 32, 61, 32, 49, 10, 32,108,111, 99, 97,108, 32,101, 32, - 61, 32,123,110, 61, 48,125, 10, 32,119,104,105,108,101, 32, - 116, 91,105, 93, 32,100,111, 10, 32, 32,108,111, 99, 97,108, - 32,116,116, 32, 61, 32,115,112,108,105,116, 40,116, 91,105, - 93, 44, 39, 61, 39, 41, 32, 32, 45, 45, 32,100,105,115, 99, - 97,114,100, 32,105,110,105,116,105, 97,108, 32,118, 97,108, - 117,101, 10, 32, 32,101, 46,110, 32, 61, 32,101, 46,110, 32, - 43, 32, 49, 10, 32, 32,101, 91,101, 46,110, 93, 32, 61, 32, - 116,116, 91, 49, 93, 10, 32, 32,105, 32, 61, 32,105, 43, 49, - 10, 32,101,110,100, 10, 32, 45, 45, 32,115,101,116, 32,108, - 117, 97, 32,110, 97,109,101,115, 10, 32,105, 32, 32, 61, 32, - 49, 10, 32,101, 46,108,110, 97,109,101,115, 32, 61, 32,123, - 125, 10, 32,108,111, 99, 97,108, 32,110,115, 32, 61, 32,103, - 101,116, 99,117,114,114,110, 97,109,101,115,112, 97, 99,101, - 40, 41, 10, 32,119,104,105,108,101, 32,101, 91,105, 93, 32, - 100,111, 10, 32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32, - 115,112,108,105,116, 40,101, 91,105, 93, 44, 39, 64, 39, 41, - 10, 32, 32,101, 91,105, 93, 32, 61, 32,116, 91, 49, 93, 10, - 9, 9,105,102, 32,110,111,116, 32,116, 91, 50, 93, 32,116, - 104,101,110, 10, 9, 9, 32,116, 91, 50, 93, 32, 61, 32, 97, - 112,112,108,121,114,101,110, 97,109,105,110,103, 40,116, 91, - 49, 93, 41, 10, 9, 9,101,110,100, 10, 32, 32,101, 46,108, - 110, 97,109,101,115, 91,105, 93, 32, 61, 32,116, 91, 50, 93, - 32,111,114, 32,116, 91, 49, 93, 10, 32, 32, 95,103,108,111, - 98, 97,108, 95,101,110,117,109,115, 91, 32,110,115, 46, 46, - 101, 91,105, 93, 32, 93, 32, 61, 32, 40,110,115, 46, 46,101, - 91,105, 93, 41, 10, 32, 32,105, 32, 61, 32,105, 43, 49, 10, - 32,101,110,100, 10, 9,101, 46,110, 97,109,101, 32, 61, 32, - 110, 10, 9,105,102, 32,110, 32,126, 61, 32, 34, 34, 32,116, - 104,101,110, 10, 9, 9, 84,121,112,101,100,101,102, 40, 34, - 105,110,116, 32, 34, 46, 46,110, 41, 10, 9,101,110,100, 10, - 32,114,101,116,117,114,110, 32, 95, 69,110,117,109,101,114, - 97,116,101, 40,101, 44, 32,118, 97,114,110, 97,109,101, 41, - 10,101,110,100,32 - }; - tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua embedded: src/bin/lua/enumerate.lua"); + #include "enumerate_lua.h" + tolua_dobuffer(tolua_S,(char*)lua_enumerate_lua,sizeof(lua_enumerate_lua),"tolua embedded: src/bin/lua/enumerate.lua"); lua_settop(tolua_S, top); } /* end of embedded lua code */ { /* begin embedded lua code */ int top = lua_gettop(tolua_S); - static unsigned char B[] = { - 45, 45, 32,116,111,108,117, 97, 58, 32,100,101, 99,108, 97, - 114, 97,116,105,111,110, 32, 99,108, 97,115,115, 10, 45, 45, - 32, 87,114,105,116,116,101,110, 32, 98,121, 32, 87, 97,108, - 100,101,109, 97,114, 32, 67,101,108,101,115, 10, 45, 45, 32, - 84,101, 67, 71,114, 97,102, 47, 80, 85, 67, 45, 82,105,111, - 10, 45, 45, 32, 74,117,108, 32, 49, 57, 57, 56, 10, 45, 45, - 32, 36, 73,100, 58, 32, 36, 10, 10, 45, 45, 32, 84,104,105, - 115, 32, 99,111,100,101, 32,105,115, 32,102,114,101,101, 32, - 115,111,102,116,119, 97,114,101, 59, 32,121,111,117, 32, 99, - 97,110, 32,114,101,100,105,115,116,114,105, 98,117,116,101, - 32,105,116, 32, 97,110,100, 47,111,114, 32,109,111,100,105, - 102,121, 32,105,116, 46, 10, 45, 45, 32, 84,104,101, 32,115, - 111,102,116,119, 97,114,101, 32,112,114,111,118,105,100,101, - 100, 32,104,101,114,101,117,110,100,101,114, 32,105,115, 32, - 111,110, 32, 97,110, 32, 34, 97,115, 32,105,115, 34, 32, 98, - 97,115,105,115, 44, 32, 97,110,100, 10, 45, 45, 32,116,104, - 101, 32, 97,117,116,104,111,114, 32,104, 97,115, 32,110,111, - 32,111, 98,108,105,103, 97,116,105,111,110, 32,116,111, 32, - 112,114,111,118,105,100,101, 32,109, 97,105,110,116,101,110, - 97,110, 99,101, 44, 32,115,117,112,112,111,114,116, 44, 32, - 117,112,100, 97,116,101,115, 44, 10, 45, 45, 32,101,110,104, - 97,110, 99,101,109,101,110,116,115, 44, 32,111,114, 32,109, - 111,100,105,102,105, 99, 97,116,105,111,110,115, 46, 10, 10, - 10, 45, 45, 32, 68,101, 99,108, 97,114, 97,116,105,111,110, - 32, 99,108, 97,115,115, 10, 45, 45, 32, 82,101,112,114,101, - 115,101,110,116,115, 32,118, 97,114,105, 97, 98,108,101, 44, - 32,102,117,110, 99,116,105,111,110, 44, 32,111,114, 32, 97, - 114,103,117,109,101,110,116, 32,100,101, 99,108, 97,114, 97, - 116,105,111,110, 46, 10, 45, 45, 32, 83,116,111,114,101,115, - 32,116,104,101, 32,102,111,108,108,111,119,105,110,103, 32, - 102,105,101,108,100,115, 58, 10, 45, 45, 32, 32,109,111,100, - 32, 32, 61, 32,116,121,112,101, 32,109,111,100,105,102,105, - 101,114,115, 10, 45, 45, 32, 32,116,121,112,101, 32, 61, 32, - 116,121,112,101, 10, 45, 45, 32, 32,112,116,114, 32, 32, 61, - 32, 34, 42, 34, 32,111,114, 32, 34, 38, 34, 44, 32,105,102, - 32,114,101,112,114,101,115,101,110,116,105,110,103, 32, 97, - 32,112,111,105,110,116,101,114, 32,111,114, 32, 97, 32,114, - 101,102,101,114,101,110, 99,101, 10, 45, 45, 32, 32,110, 97, - 109,101, 32, 61, 32,110, 97,109,101, 10, 45, 45, 32, 32,100, - 105,109, 32, 32, 61, 32,100,105,109,101,110,115,105,111,110, - 44, 32,105,102, 32, 97, 32,118,101, 99,116,111,114, 10, 45, - 45, 32, 32,100,101,102, 32, 32, 61, 32,100,101,102, 97,117, - 108,116, 32,118, 97,108,117,101, 44, 32,105,102, 32, 97,110, - 121, 32, 40,111,110,108,121, 32,102,111,114, 32, 97,114,103, - 117,109,101,110,116,115, 41, 10, 45, 45, 32, 32,114,101,116, - 32, 32, 61, 32, 34, 42, 34, 32,111,114, 32, 34, 38, 34, 44, - 32,105,102, 32,118, 97,108,117,101, 32,105,115, 32,116,111, - 32, 98,101, 32,114,101,116,117,114,110,101,100, 32, 40,111, - 110,108,121, 32,102,111,114, 32, 97,114,103,117,109,101,110, - 116,115, 41, 10, 99,108, 97,115,115, 68,101, 99,108, 97,114, - 97,116,105,111,110, 32, 61, 32,123, 10, 32,109,111,100, 32, - 61, 32, 39, 39, 44, 10, 32,116,121,112,101, 32, 61, 32, 39, - 39, 44, 10, 32,112,116,114, 32, 61, 32, 39, 39, 44, 10, 32, - 110, 97,109,101, 32, 61, 32, 39, 39, 44, 10, 32,100,105,109, - 32, 61, 32, 39, 39, 44, 10, 32,114,101,116, 32, 61, 32, 39, - 39, 44, 10, 32,100,101,102, 32, 61, 32, 39, 39, 10,125, 10, - 99,108, 97,115,115, 68,101, 99,108, 97,114, 97,116,105,111, - 110, 46, 95, 95,105,110,100,101,120, 32, 61, 32, 99,108, 97, - 115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, 10,115, - 101,116,109,101,116, 97,116, 97, 98,108,101, 40, 99,108, 97, - 115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, 44, 99, - 108, 97,115,115, 70,101, 97,116,117,114,101, 41, 10, 10, 45, - 45, 32, 67,114,101, 97,116,101, 32, 97,110, 32,117,110,105, - 113,117,101, 32,118, 97,114,105, 97, 98,108,101, 32,110, 97, - 109,101, 10,102,117,110, 99,116,105,111,110, 32, 99,114,101, - 97,116,101, 95,118, 97,114,110, 97,109,101, 32, 40, 41, 10, - 32,105,102, 32,110,111,116, 32, 95,118, 97,114,110,117,109, - 98,101,114, 32,116,104,101,110, 32, 95,118, 97,114,110,117, - 109, 98,101,114, 32, 61, 32, 48, 32,101,110,100, 10, 32, 95, - 118, 97,114,110,117,109, 98,101,114, 32, 61, 32, 95,118, 97, - 114,110,117,109, 98,101,114, 32, 43, 32, 49, 10, 32,114,101, - 116,117,114,110, 32, 34,116,111,108,117, 97, 95,118, 97,114, - 95, 34, 46, 46, 95,118, 97,114,110,117,109, 98,101,114, 10, - 101,110,100, 10, 10, 45, 45, 32, 67,104,101, 99,107, 32,100, - 101, 99,108, 97,114, 97,116,105,111,110, 32,110, 97,109,101, - 10, 45, 45, 32, 73,116, 32, 97,108,115,111, 32,105,100,101, - 110,116,105,102,105,101,115, 32,100,101,102, 97,117,108,116, - 32,118, 97,108,117,101,115, 10,102,117,110, 99,116,105,111, - 110, 32, 99,108, 97,115,115, 68,101, 99,108, 97,114, 97,116, - 105,111,110, 58, 99,104,101, 99,107,110, 97,109,101, 32, 40, - 41, 10, 10, 32,105,102, 32,115,116,114,115,117, 98, 40,115, - 101,108,102, 46,110, 97,109,101, 44, 49, 44, 49, 41, 32, 61, - 61, 32, 39, 91, 39, 32, 97,110,100, 32,110,111,116, 32,102, - 105,110,100,116,121,112,101, 40,115,101,108,102, 46,116,121, - 112,101, 41, 32,116,104,101,110, 10, 32, 32,115,101,108,102, - 46,110, 97,109,101, 32, 61, 32,115,101,108,102, 46,116,121, - 112,101, 46, 46,115,101,108,102, 46,110, 97,109,101, 10, 32, - 32,108,111, 99, 97,108, 32,109, 32, 61, 32,115,112,108,105, - 116, 40,115,101,108,102, 46,109,111,100, 44, 39, 37,115, 37, - 115, 42, 39, 41, 10, 32, 32,115,101,108,102, 46,116,121,112, - 101, 32, 61, 32,109, 91,109, 46,110, 93, 10, 32, 32,115,101, - 108,102, 46,109,111,100, 32, 61, 32, 99,111,110, 99, 97,116, - 40,109, 44, 49, 44,109, 46,110, 45, 49, 41, 10, 32,101,110, - 100, 10, 10, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,115, - 112,108,105,116, 40,115,101,108,102, 46,110, 97,109,101, 44, - 39, 61, 39, 41, 10, 32,105,102, 32,116, 46,110, 61, 61, 50, - 32,116,104,101,110, 10, 32, 32,115,101,108,102, 46,110, 97, - 109,101, 32, 61, 32,116, 91, 49, 93, 10, 32, 32,115,101,108, - 102, 46,100,101,102, 32, 61, 32,102,105,110,100, 95,101,110, - 117,109, 95,118, 97,114, 40,116, 91,116, 46,110, 93, 41, 10, - 32,101,110,100, 10, 10, 32,108,111, 99, 97,108, 32, 98, 44, - 101, 44,100, 32, 61, 32,115,116,114,102,105,110,100, 40,115, - 101,108,102, 46,110, 97,109,101, 44, 34, 37, 91, 40, 46, 45, - 41, 37, 93, 34, 41, 10, 32,105,102, 32, 98, 32,116,104,101, - 110, 10, 32, 32,115,101,108,102, 46,110, 97,109,101, 32, 61, - 32,115,116,114,115,117, 98, 40,115,101,108,102, 46,110, 97, - 109,101, 44, 49, 44, 98, 45, 49, 41, 10, 32, 32,115,101,108, - 102, 46,100,105,109, 32, 61, 32,102,105,110,100, 95,101,110, - 117,109, 95,118, 97,114, 40,100, 41, 10, 32,101,110,100, 10, - 10, 10, 32,105,102, 32,115,101,108,102, 46,116,121,112,101, - 32,126, 61, 32, 39, 39, 32, 97,110,100, 32,115,101,108,102, - 46,116,121,112,101, 32,126, 61, 32, 39,118,111,105,100, 39, - 32, 97,110,100, 32,115,101,108,102, 46,110, 97,109,101, 32, - 61, 61, 32, 39, 39, 32,116,104,101,110, 10, 32, 32,115,101, - 108,102, 46,110, 97,109,101, 32, 61, 32, 99,114,101, 97,116, - 101, 95,118, 97,114,110, 97,109,101, 40, 41, 10, 32,101,108, - 115,101,105,102, 32,115,101,108,102, 46,107,105,110,100, 61, - 61, 39,118, 97,114, 39, 32,116,104,101,110, 10, 32, 32,105, - 102, 32,115,101,108,102, 46,116,121,112,101, 61, 61, 39, 39, - 32, 97,110,100, 32,115,101,108,102, 46,110, 97,109,101,126, - 61, 39, 39, 32,116,104,101,110, 10, 32, 32, 32,115,101,108, - 102, 46,116,121,112,101, 32, 61, 32,115,101,108,102, 46,116, - 121,112,101, 46, 46,115,101,108,102, 46,110, 97,109,101, 10, - 32, 32, 32,115,101,108,102, 46,110, 97,109,101, 32, 61, 32, - 99,114,101, 97,116,101, 95,118, 97,114,110, 97,109,101, 40, - 41, 10, 32, 32,101,108,115,101,105,102, 32,102,105,110,100, - 116,121,112,101, 40,115,101,108,102, 46,110, 97,109,101, 41, - 32,116,104,101,110, 10, 32, 32, 32,105,102, 32,115,101,108, - 102, 46,116,121,112,101, 61, 61, 39, 39, 32,116,104,101,110, - 32,115,101,108,102, 46,116,121,112,101, 32, 61, 32,115,101, - 108,102, 46,110, 97,109,101, 10, 32, 32, 32,101,108,115,101, - 32,115,101,108,102, 46,116,121,112,101, 32, 61, 32,115,101, - 108,102, 46,116,121,112,101, 46, 46, 39, 32, 39, 46, 46,115, - 101,108,102, 46,110, 97,109,101, 32,101,110,100, 10, 32, 32, - 32,115,101,108,102, 46,110, 97,109,101, 32, 61, 32, 99,114, - 101, 97,116,101, 95,118, 97,114,110, 97,109,101, 40, 41, 10, - 32, 32,101,110,100, 10, 32,101,110,100, 10, 10, 32, 45, 45, - 32, 97,100,106,117,115,116, 32,116,121,112,101, 32,111,102, - 32,115,116,114,105,110,103, 10, 32,105,102, 32,115,101,108, - 102, 46,116,121,112,101, 32, 61, 61, 32, 39, 99,104, 97,114, - 39, 32, 97,110,100, 32,115,101,108,102, 46,100,105,109, 32, - 126, 61, 32, 39, 39, 32,116,104,101,110, 10, 9, 32,115,101, - 108,102, 46,116,121,112,101, 32, 61, 32, 39, 99,104, 97,114, - 42, 39, 10, 32,101,110,100, 10, 10, 9,105,102, 32,115,101, - 108,102, 46,107,105,110,100, 32, 97,110,100, 32,115,101,108, - 102, 46,107,105,110,100, 32, 61, 61, 32, 39,118, 97,114, 39, - 32,116,104,101,110, 10, 9, 9,115,101,108,102, 46,110, 97, - 109,101, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, - 98, 40,115,101,108,102, 46,110, 97,109,101, 44, 32, 34, 58, - 46, 42, 36, 34, 44, 32, 34, 34, 41, 32, 45, 45, 32, 63, 63, - 63, 10, 9,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, - 67,104,101, 99,107, 32,100,101, 99,108, 97,114, 97,116,105, - 111,110, 32,116,121,112,101, 10, 45, 45, 32, 83,117, 98,115, - 116,105,116,117,116,101,115, 32,116,121,112,101,100,101,102, - 39,115, 46, 10,102,117,110, 99,116,105,111,110, 32, 99,108, - 97,115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, 58, - 99,104,101, 99,107,116,121,112,101, 32, 40, 41, 10, 10, 32, - 45, 45, 32, 99,104,101, 99,107, 32,105,102, 32,116,104,101, - 114,101, 32,105,115, 32, 97, 32,112,111,105,110,116,101,114, - 32,116,111, 32, 98, 97,115,105, 99, 32,116,121,112,101, 10, - 32,108,111, 99, 97,108, 32, 98, 97,115,105, 99, 32, 61, 32, - 105,115, 98, 97,115,105, 99, 40,115,101,108,102, 46,116,121, - 112,101, 41, 10, 32,105,102, 32,115,101,108,102, 46,107,105, - 110,100, 32, 61, 61, 32, 39,102,117,110, 99, 39, 32, 97,110, - 100, 32, 98, 97,115,105, 99, 61, 61, 39,110,117,109, 98,101, - 114, 39, 32, 97,110,100, 32,115,116,114,105,110,103, 46,102, - 105,110,100, 40,115,101,108,102, 46,112,116,114, 44, 32, 34, - 37, 42, 34, 41, 32,116,104,101,110, 10, 32, 9,115,101,108, - 102, 46,116,121,112,101, 32, 61, 32, 39, 95,117,115,101,114, - 100, 97,116, 97, 39, 10, 32, 9,115,101,108,102, 46,112,116, - 114, 32, 61, 32, 34, 34, 10, 32,101,110,100, 10, 32,105,102, - 32, 98, 97,115,105, 99, 32, 97,110,100, 32,115,101,108,102, - 46,112,116,114,126, 61, 39, 39, 32,116,104,101,110, 10, 32, - 32,115,101,108,102, 46,114,101,116, 32, 61, 32,115,101,108, - 102, 46,112,116,114, 10, 32, 32,115,101,108,102, 46,112,116, - 114, 32, 61, 32,110,105,108, 10, 32, 32,105,102, 32,105,115, - 98, 97,115,105, 99, 40,115,101,108,102, 46,116,121,112,101, - 41, 32, 61, 61, 32, 39,110,117,109, 98,101,114, 39, 32,116, - 104,101,110, 10, 32, 32, 9,115,101,108,102, 46,114,101,116, - 117,114,110, 95,117,115,101,114,100, 97,116, 97, 32, 61, 32, - 116,114,117,101, 10, 32, 32,101,110,100, 10, 32,101,110,100, - 10, 10, 32, 45, 45, 32, 99,104,101, 99,107, 32,105,102, 32, - 116,104,101,114,101, 32,105,115, 32, 97,114,114, 97,121, 32, - 116,111, 32, 98,101, 32,114,101,116,117,114,110,101,100, 10, - 32,105,102, 32,115,101,108,102, 46,100,105,109,126, 61, 39, - 39, 32, 97,110,100, 32,115,101,108,102, 46,114,101,116,126, - 61, 39, 39, 32,116,104,101,110, 10, 32, 32, 32,101,114,114, - 111,114, 40, 39, 35,105,110,118, 97,108,105,100, 32,112, 97, - 114, 97,109,101,116,101,114, 58, 32, 99, 97,110,110,111,116, - 32,114,101,116,117,114,110, 32, 97,110, 32, 97,114,114, 97, - 121, 32,111,102, 32,118, 97,108,117,101,115, 39, 41, 10, 32, - 101,110,100, 10, 32, 45, 45, 32,114,101,115,116,111,114,101, - 32, 39,118,111,105,100, 42, 39, 32, 97,110,100, 32, 39,115, - 116,114,105,110,103, 42, 39, 10, 32,105,102, 32,115,101,108, - 102, 46,116,121,112,101, 32, 61, 61, 32, 39, 95,117,115,101, - 114,100, 97,116, 97, 39, 32,116,104,101,110, 32,115,101,108, - 102, 46,116,121,112,101, 32, 61, 32, 39,118,111,105,100, 42, - 39, 10, 32,101,108,115,101,105,102, 32,115,101,108,102, 46, - 116,121,112,101, 32, 61, 61, 32, 39, 95, 99,115,116,114,105, - 110,103, 39, 32,116,104,101,110, 32,115,101,108,102, 46,116, - 121,112,101, 32, 61, 32, 39, 99,104, 97,114, 42, 39, 10, 32, - 101,108,115,101,105,102, 32,115,101,108,102, 46,116,121,112, - 101, 32, 61, 61, 32, 39, 95,108,115,116, 97,116,101, 39, 32, - 116,104,101,110, 32,115,101,108,102, 46,116,121,112,101, 32, - 61, 32, 39,108,117, 97, 95, 83,116, 97,116,101, 42, 39, 10, - 32,101,110,100, 10, 10, 32, 45, 45, 32,114,101,115,111,108, - 118,101, 32,116,121,112,101,115, 32,105,110,115,105,100,101, - 32,116,104,101, 32,116,101,109,112,108, 97,116,101,115, 10, - 32,105,102, 32,115,101,108,102, 46,116,121,112,101, 32,116, - 104,101,110, 10, 9, 32,115,101,108,102, 46,116,121,112,101, - 32, 61, 32,114,101,115,111,108,118,101, 95,116,101,109,112, - 108, 97,116,101, 95,116,121,112,101,115, 40,115,101,108,102, - 46,116,121,112,101, 41, 10, 32,101,110,100, 10, 10, 45, 45, - 10, 45, 45, 32, 45, 45, 32,105,102, 32,114,101,116,117,114, - 110,105,110,103, 32,118, 97,108,117,101, 44, 32, 97,117,116, - 111,109, 97,116,105, 99, 97,108,108,121, 32,115,101,116, 32, - 100,101,102, 97,117,108,116, 32,118, 97,108,117,101, 10, 45, - 45, 32,105,102, 32,115,101,108,102, 46,114,101,116, 32,126, - 61, 32, 39, 39, 32, 97,110,100, 32,115,101,108,102, 46,100, - 101,102, 32, 61, 61, 32, 39, 39, 32,116,104,101,110, 10, 45, - 45, 32, 32,115,101,108,102, 46,100,101,102, 32, 61, 32, 39, - 48, 39, 10, 45, 45, 32,101,110,100, 10, 45, 45, 10, 10,101, - 110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,114,101, - 115,111,108,118,101, 95,116,101,109,112,108, 97,116,101, 95, - 116,121,112,101,115, 40,116,121,112,101, 41, 10, 10, 9,105, - 102, 32,105,115, 98, 97,115,105, 99, 40,116,121,112,101, 41, - 32,116,104,101,110, 10, 9, 9,114,101,116,117,114,110, 32, - 116,121,112,101, 10, 9,101,110,100, 10, 9,108,111, 99, 97, - 108, 32, 98, 44, 95, 44,109, 32, 61, 32,115,116,114,105,110, - 103, 46,102,105,110,100, 40,116,121,112,101, 44, 32, 34, 40, - 37, 98, 60, 62, 41, 34, 41, 10, 9,105,102, 32, 98, 32,116, - 104,101,110, 10, 10, 9, 9,109, 32, 61, 32,115,112,108,105, - 116, 95, 99, 95,116,111,107,101,110,115, 40,115,116,114,105, - 110,103, 46,115,117, 98, 40,109, 44, 32, 50, 44, 32, 45, 50, - 41, 44, 32, 34, 44, 34, 41, 10, 9, 9,102,111,114, 32,105, - 61, 49, 44, 32,116, 97, 98,108,101, 46,103,101,116,110, 40, - 109, 41, 32,100,111, 10, 9, 9, 9,109, 91,105, 93, 32, 61, - 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,109, 91, - 105, 93, 44, 34, 37,115, 42, 40, 91, 37, 42, 38, 93, 41, 34, - 44, 32, 34, 37, 49, 34, 41, 10, 9, 9, 9,105,102, 32,110, - 111,116, 32,105,115, 98, 97,115,105, 99, 40,109, 91,105, 93, - 41, 32,116,104,101,110, 10, 9, 9, 9, 9,105,102, 32,110, - 111,116, 32,105,115,101,110,117,109, 40,109, 91,105, 93, 41, - 32,116,104,101,110, 32, 95, 44, 32,109, 91,105, 93, 32, 61, - 32, 97,112,112,108,121,116,121,112,101,100,101,102, 40, 34, - 34, 44, 32,109, 91,105, 93, 41, 32,101,110,100, 10, 9, 9, - 9, 9,109, 91,105, 93, 32, 61, 32,102,105,110,100,116,121, - 112,101, 40,109, 91,105, 93, 41, 32,111,114, 32,109, 91,105, - 93, 10, 9, 9, 9, 9,109, 91,105, 93, 32, 61, 32,114,101, - 115,111,108,118,101, 95,116,101,109,112,108, 97,116,101, 95, - 116,121,112,101,115, 40,109, 91,105, 93, 41, 10, 9, 9, 9, - 101,110,100, 10, 9, 9,101,110,100, 10, 10, 9, 9,108,111, - 99, 97,108, 32, 98, 44,105, 10, 9, 9,116,121,112,101, 44, - 98, 44,105, 32, 61, 32, 98,114,101, 97,107, 95,116,101,109, - 112,108, 97,116,101, 40,116,121,112,101, 41, 10, 45, 45,112, - 114,105,110,116, 40, 34, 99,111,110, 99, 97,116, 32,105,115, - 32, 34, 44, 99,111,110, 99, 97,116, 40,109, 44, 32, 49, 44, - 32,109, 46,110, 41, 41, 10, 9, 9,108,111, 99, 97,108, 32, - 116,101,109,112,108, 97,116,101, 95,112, 97,114,116, 32, 61, - 32, 34, 60, 34, 46, 46, 99,111,110, 99, 97,116, 40,109, 44, - 32, 49, 44, 32,109, 46,110, 44, 32, 34, 44, 34, 41, 46, 46, - 34, 62, 34, 10, 9, 9,116,121,112,101, 32, 61, 32,114,101, - 98,117,105,108,100, 95,116,101,109,112,108, 97,116,101, 40, - 116,121,112,101, 44, 32, 98, 44, 32,116,101,109,112,108, 97, - 116,101, 95,112, 97,114,116, 41, 10, 9, 9,116,121,112,101, - 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, - 116,121,112,101, 44, 32, 34, 62, 62, 34, 44, 32, 34, 62, 32, - 62, 34, 41, 10, 9,101,110,100, 10, 9,114,101,116,117,114, - 110, 32,116,121,112,101, 10,101,110,100, 10, 10,102,117,110, - 99,116,105,111,110, 32, 98,114,101, 97,107, 95,116,101,109, - 112,108, 97,116,101, 40,115, 41, 10, 9,108,111, 99, 97,108, - 32, 98, 44,101, 44,116,105,109,112,108, 32, 61, 32,115,116, - 114,105,110,103, 46,102,105,110,100, 40,115, 44, 32, 34, 40, - 37, 98, 60, 62, 41, 34, 41, 10, 9,105,102, 32,116,105,109, - 112,108, 32,116,104,101,110, 10, 9, 9,115, 32, 61, 32,115, - 116,114,105,110,103, 46,103,115,117, 98, 40,115, 44, 32, 34, - 37, 98, 60, 62, 34, 44, 32, 34, 34, 41, 10, 9, 9,114,101, - 116,117,114,110, 32,115, 44, 32, 98, 44, 32,116,105,109,112, - 108, 10, 9,101,108,115,101, 10, 9, 9,114,101,116,117,114, - 110, 32,115, 44, 32, 48, 44, 32,110,105,108, 10, 9,101,110, - 100, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, - 32,114,101, 98,117,105,108,100, 95,116,101,109,112,108, 97, - 116,101, 40,115, 44, 32, 98, 44, 32,116,105,109,112,108, 41, - 10, 10, 9,105,102, 32, 98, 32, 61, 61, 32, 48, 32,116,104, - 101,110, 10, 9, 9,114,101,116,117,114,110, 32,115, 10, 9, - 101,110,100, 10, 10, 9,114,101,116,117,114,110, 32,115,116, - 114,105,110,103, 46,115,117, 98, 40,115, 44, 32, 49, 44, 32, - 98, 45, 49, 41, 46, 46,116,105,109,112,108, 46, 46,115,116, - 114,105,110,103, 46,115,117, 98, 40,115, 44, 32, 98, 44, 32, - 45, 49, 41, 10,101,110,100, 10, 10, 45, 45, 32, 80,114,105, - 110,116, 32,109,101,116,104,111,100, 10,102,117,110, 99,116, - 105,111,110, 32, 99,108, 97,115,115, 68,101, 99,108, 97,114, - 97,116,105,111,110, 58,112,114,105,110,116, 32, 40,105,100, - 101,110,116, 44, 99,108,111,115,101, 41, 10, 32,112,114,105, - 110,116, 40,105,100,101,110,116, 46, 46, 34, 68,101, 99,108, - 97,114, 97,116,105,111,110,123, 34, 41, 10, 32,112,114,105, - 110,116, 40,105,100,101,110,116, 46, 46, 34, 32,109,111,100, - 32, 32, 61, 32, 39, 34, 46, 46,115,101,108,102, 46,109,111, - 100, 46, 46, 34, 39, 44, 34, 41, 10, 32,112,114,105,110,116, - 40,105,100,101,110,116, 46, 46, 34, 32,116,121,112,101, 32, - 61, 32, 39, 34, 46, 46,115,101,108,102, 46,116,121,112,101, - 46, 46, 34, 39, 44, 34, 41, 10, 32,112,114,105,110,116, 40, - 105,100,101,110,116, 46, 46, 34, 32,112,116,114, 32, 32, 61, - 32, 39, 34, 46, 46,115,101,108,102, 46,112,116,114, 46, 46, - 34, 39, 44, 34, 41, 10, 32,112,114,105,110,116, 40,105,100, - 101,110,116, 46, 46, 34, 32,110, 97,109,101, 32, 61, 32, 39, - 34, 46, 46,115,101,108,102, 46,110, 97,109,101, 46, 46, 34, - 39, 44, 34, 41, 10, 32,112,114,105,110,116, 40,105,100,101, - 110,116, 46, 46, 34, 32,100,105,109, 32, 32, 61, 32, 39, 34, - 46, 46,115,101,108,102, 46,100,105,109, 46, 46, 34, 39, 44, - 34, 41, 10, 32,112,114,105,110,116, 40,105,100,101,110,116, - 46, 46, 34, 32,100,101,102, 32, 32, 61, 32, 39, 34, 46, 46, - 115,101,108,102, 46,100,101,102, 46, 46, 34, 39, 44, 34, 41, - 10, 32,112,114,105,110,116, 40,105,100,101,110,116, 46, 46, - 34, 32,114,101,116, 32, 32, 61, 32, 39, 34, 46, 46,115,101, - 108,102, 46,114,101,116, 46, 46, 34, 39, 44, 34, 41, 10, 32, - 112,114,105,110,116, 40,105,100,101,110,116, 46, 46, 34,125, - 34, 46, 46, 99,108,111,115,101, 41, 10,101,110,100, 10, 10, - 45, 45, 32, 99,104,101, 99,107, 32,105,102, 32, 97,114,114, - 97,121, 32,111,102, 32,118, 97,108,117,101,115, 32, 97,114, - 101, 32,114,101,116,117,114,110,101,100, 32,116,111, 32, 76, - 117, 97, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97, - 115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, 58,114, - 101,113,117,105,114,101, 99,111,108,108,101, 99,116,105,111, - 110, 32, 40,116, 41, 10, 32,105,102, 32,115,101,108,102, 46, - 109,111,100, 32,126, 61, 32, 39, 99,111,110,115,116, 39, 32, - 97,110,100, 10, 9, 32, 32, 32, 32,115,101,108,102, 46,100, - 105,109, 32, 97,110,100, 32,115,101,108,102, 46,100,105,109, - 32,126, 61, 32, 39, 39, 32, 97,110,100, 10, 9, 9, 9, 9, - 32,110,111,116, 32,105,115, 98, 97,115,105, 99, 40,115,101, - 108,102, 46,116,121,112,101, 41, 32, 97,110,100, 10, 9, 9, - 9, 9, 32,115,101,108,102, 46,112,116,114, 32, 61, 61, 32, - 39, 39, 32, 97,110,100, 32,115,101,108,102, 58, 99,104,101, - 99,107, 95,112,117, 98,108,105, 99, 95, 97, 99, 99,101,115, - 115, 40, 41, 32,116,104,101,110, 10, 9, 9,108,111, 99, 97, - 108, 32,116,121,112,101, 32, 61, 32,103,115,117, 98, 40,115, - 101,108,102, 46,116,121,112,101, 44, 34, 37,115, 42, 99,111, - 110,115,116, 37,115, 43, 34, 44, 34, 34, 41, 10, 9, 9,116, - 91,116,121,112,101, 93, 32, 61, 32, 34,116,111,108,117, 97, - 95, 99,111,108,108,101, 99,116, 95, 34, 32, 46, 46, 32, 99, - 108,101, 97,110, 95,116,101,109,112,108, 97,116,101, 40,116, - 121,112,101, 41, 10, 9, 9,114,101,116,117,114,110, 32,116, - 114,117,101, 10, 9,101,110,100, 10, 9,114,101,116,117,114, - 110, 32,102, 97,108,115,101, 10,101,110,100, 10, 10, 45, 45, - 32,100,101, 99,108, 97,114,101, 32,116, 97,103, 10,102,117, - 110, 99,116,105,111,110, 32, 99,108, 97,115,115, 68,101, 99, - 108, 97,114, 97,116,105,111,110, 58,100,101, 99,108,116,121, - 112,101, 32, 40, 41, 10, 10, 9,115,101,108,102, 46,116,121, - 112,101, 32, 61, 32,116,121,112,101,118, 97,114, 40,115,101, - 108,102, 46,116,121,112,101, 41, 10, 9,105,102, 32,115,116, - 114,102,105,110,100, 40,115,101,108,102, 46,109,111,100, 44, - 39, 99,111,110,115,116, 39, 41, 32,116,104,101,110, 10, 9, - 9,115,101,108,102, 46,116,121,112,101, 32, 61, 32, 39, 99, - 111,110,115,116, 32, 39, 46, 46,115,101,108,102, 46,116,121, - 112,101, 10, 9, 9,115,101,108,102, 46,109,111,100, 32, 61, - 32,103,115,117, 98, 40,115,101,108,102, 46,109,111,100, 44, - 39, 99,111,110,115,116, 37,115, 42, 39, 44, 39, 39, 41, 10, - 9,101,110,100, 10,101,110,100, 10, 10, 10, 45, 45, 32,111, - 117,116,112,117,116, 32,116,121,112,101, 32, 99,104,101, 99, - 107,105,110,103, 10,102,117,110, 99,116,105,111,110, 32, 99, - 108, 97,115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, - 58,111,117,116, 99,104,101, 99,107,116,121,112,101, 32, 40, - 110, 97,114,103, 41, 10, 32,108,111, 99, 97,108, 32,100,101, - 102, 10, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,105,115, - 98, 97,115,105, 99, 40,115,101,108,102, 46,116,121,112,101, - 41, 10, 32,105,102, 32,115,101,108,102, 46,100,101,102,126, - 61, 39, 39, 32,116,104,101,110, 10, 32, 32,100,101,102, 32, - 61, 32, 49, 10, 32,101,108,115,101, 10, 32, 32,100,101,102, - 32, 61, 32, 48, 10, 32,101,110,100, 10, 32,105,102, 32,115, - 101,108,102, 46,100,105,109, 32,126, 61, 32, 39, 39, 32,116, - 104,101,110, 10, 9, 45, 45,105,102, 32,116, 61, 61, 39,115, - 116,114,105,110,103, 39, 32,116,104,101,110, 10, 9, 45, 45, - 9,114,101,116,117,114,110, 32, 39,116,111,108,117, 97, 95, - 105,115,115,116,114,105,110,103, 97,114,114, 97,121, 40,116, - 111,108,117, 97, 95, 83, 44, 39, 46, 46,110, 97,114,103, 46, - 46, 39, 44, 39, 46, 46,100,101,102, 46, 46, 39, 44, 38,116, - 111,108,117, 97, 95,101,114,114, 41, 39, 10, 9, 45, 45,101, - 108,115,101, 10, 9,114,101,116,117,114,110, 32, 39, 33,116, - 111,108,117, 97, 95,105,115,116, 97, 98,108,101, 40,116,111, - 108,117, 97, 95, 83, 44, 39, 46, 46,110, 97,114,103, 46, 46, - 39, 44, 48, 44, 38,116,111,108,117, 97, 95,101,114,114, 41, - 39, 10, 32, 9, 45, 45,101,110,100, 10, 32,101,108,115,101, - 105,102, 32,116, 32,116,104,101,110, 10, 9,114,101,116,117, - 114,110, 32, 39, 33,116,111,108,117, 97, 95,105,115, 39, 46, - 46,116, 46, 46, 39, 40,116,111,108,117, 97, 95, 83, 44, 39, - 46, 46,110, 97,114,103, 46, 46, 39, 44, 39, 46, 46,100,101, - 102, 46, 46, 39, 44, 38,116,111,108,117, 97, 95,101,114,114, - 41, 39, 10, 32,101,108,115,101, 10, 32, 32,108,111, 99, 97, - 108, 32,105,115, 95,102,117,110, 99, 32, 61, 32,103,101,116, - 95,105,115, 95,102,117,110, 99,116,105,111,110, 40,115,101, - 108,102, 46,116,121,112,101, 41, 10, 32, 32,105,102, 32,115, - 101,108,102, 46,112,116,114, 32, 61, 61, 32, 39, 38, 39, 32, - 111,114, 32,115,101,108,102, 46,112,116,114, 32, 61, 61, 32, - 39, 39, 32,116,104,101,110, 10, 32, 32, 9,114,101,116,117, - 114,110, 32, 39, 40,116,111,108,117, 97, 95,105,115,118, 97, - 108,117,101,110,105,108, 40,116,111,108,117, 97, 95, 83, 44, - 39, 46, 46,110, 97,114,103, 46, 46, 39, 44, 38,116,111,108, - 117, 97, 95,101,114,114, 41, 32,124,124, 32, 33, 39, 46, 46, - 105,115, 95,102,117,110, 99, 46, 46, 39, 40,116,111,108,117, - 97, 95, 83, 44, 39, 46, 46,110, 97,114,103, 46, 46, 39, 44, - 34, 39, 46, 46,115,101,108,102, 46,116,121,112,101, 46, 46, - 39, 34, 44, 39, 46, 46,100,101,102, 46, 46, 39, 44, 38,116, - 111,108,117, 97, 95,101,114,114, 41, 41, 39, 10, 32, 32,101, - 108,115,101, 10, 9,114,101,116,117,114,110, 32, 39, 33, 39, - 46, 46,105,115, 95,102,117,110, 99, 46, 46, 39, 40,116,111, - 108,117, 97, 95, 83, 44, 39, 46, 46,110, 97,114,103, 46, 46, - 39, 44, 34, 39, 46, 46,115,101,108,102, 46,116,121,112,101, - 46, 46, 39, 34, 44, 39, 46, 46,100,101,102, 46, 46, 39, 44, - 38,116,111,108,117, 97, 95,101,114,114, 41, 39, 10, 32, 32, - 101,110,100, 10, 32,101,110,100, 10,101,110,100, 10, 10,102, - 117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 68,101, - 99,108, 97,114, 97,116,105,111,110, 58, 98,117,105,108,100, - 100,101, 99,108, 97,114, 97,116,105,111,110, 32, 40,110, 97, - 114,103, 44, 32, 99,112,108,117,115,112,108,117,115, 41, 10, - 32,108,111, 99, 97,108, 32, 97,114,114, 97,121, 32, 61, 32, - 115,101,108,102, 46,100,105,109, 32,126, 61, 32, 39, 39, 32, - 97,110,100, 32,116,111,110,117,109, 98,101,114, 40,115,101, - 108,102, 46,100,105,109, 41, 61, 61,110,105,108, 10, 9,108, - 111, 99, 97,108, 32,108,105,110,101, 32, 61, 32, 34, 34, 10, - 32,108,111, 99, 97,108, 32,112,116,114, 32, 61, 32, 39, 39, - 10, 32,108,111, 99, 97,108, 32,109,111,100, 10, 32,108,111, - 99, 97,108, 32,116,121,112,101, 32, 61, 32,115,101,108,102, - 46,116,121,112,101, 10, 32,108,111, 99, 97,108, 32,110, 99, - 116,121,112,101, 32, 61, 32,103,115,117, 98, 40,115,101,108, - 102, 46,116,121,112,101, 44, 39, 99,111,110,115,116, 37,115, - 43, 39, 44, 39, 39, 41, 10, 32,105,102, 32,115,101,108,102, - 46,100,105,109, 32,126, 61, 32, 39, 39, 32,116,104,101,110, - 10, 9, 32,116,121,112,101, 32, 61, 32,103,115,117, 98, 40, - 115,101,108,102, 46,116,121,112,101, 44, 39, 99,111,110,115, - 116, 37,115, 43, 39, 44, 39, 39, 41, 32, 32, 45, 45, 32,101, - 108,105,109,105,110, 97,116,101,115, 32, 99,111,110,115,116, - 32,109,111,100,105,102,105,101,114, 32,102,111,114, 32, 97, - 114,114, 97,121,115, 10, 32,101,110,100, 10, 32,105,102, 32, - 115,101,108,102, 46,112,116,114,126, 61, 39, 39, 32, 97,110, - 100, 32,110,111,116, 32,105,115, 98, 97,115,105, 99, 40,116, - 121,112,101, 41, 32,116,104,101,110, 32,112,116,114, 32, 61, - 32, 39, 42, 39, 32,101,110,100, 10, 32,108,105,110,101, 32, - 61, 32, 99,111,110, 99, 97,116,112, 97,114, 97,109, 40,108, - 105,110,101, 44, 34, 32, 34, 44,115,101,108,102, 46,109,111, - 100, 44,116,121,112,101, 44,112,116,114, 41, 10, 32,105,102, - 32, 97,114,114, 97,121, 32,116,104,101,110, 10, 32, 32,108, - 105,110,101, 32, 61, 32, 99,111,110, 99, 97,116,112, 97,114, - 97,109, 40,108,105,110,101, 44, 39, 42, 39, 41, 10, 32,101, - 110,100, 10, 32,108,105,110,101, 32, 61, 32, 99,111,110, 99, - 97,116,112, 97,114, 97,109, 40,108,105,110,101, 44,115,101, - 108,102, 46,110, 97,109,101, 41, 10, 32,105,102, 32,115,101, - 108,102, 46,100,105,109, 32,126, 61, 32, 39, 39, 32,116,104, - 101,110, 10, 32, 32,105,102, 32,116,111,110,117,109, 98,101, - 114, 40,115,101,108,102, 46,100,105,109, 41,126, 61,110,105, - 108, 32,116,104,101,110, 10, 32, 32, 32,108,105,110,101, 32, - 61, 32, 99,111,110, 99, 97,116,112, 97,114, 97,109, 40,108, - 105,110,101, 44, 39, 91, 39, 44,115,101,108,102, 46,100,105, - 109, 44, 39, 93, 59, 39, 41, 10, 32, 32,101,108,115,101, 10, - 9,105,102, 32, 99,112,108,117,115,112,108,117,115, 32,116, - 104,101,110, 10, 9, 9,108,105,110,101, 32, 61, 32, 99,111, - 110, 99, 97,116,112, 97,114, 97,109, 40,108,105,110,101, 44, - 39, 32, 61, 32, 77,116,111,108,117, 97, 95,110,101,119, 95, - 100,105,109, 40, 39, 44,116,121,112,101, 44,112,116,114, 44, - 39, 44, 32, 39, 46, 46,115,101,108,102, 46,100,105,109, 46, - 46, 39, 41, 59, 39, 41, 10, 9,101,108,115,101, 10, 9, 9, - 108,105,110,101, 32, 61, 32, 99,111,110, 99, 97,116,112, 97, - 114, 97,109, 40,108,105,110,101, 44, 39, 32, 61, 32, 40, 39, - 44,116,121,112,101, 44,112,116,114, 44, 39, 42, 41, 39, 44, - 10, 9, 9, 39,109, 97,108,108,111, 99, 40, 40, 39, 44,115, - 101,108,102, 46,100,105,109, 44, 39, 41, 42,115,105,122,101, - 111,102, 40, 39, 44,116,121,112,101, 44,112,116,114, 44, 39, - 41, 41, 59, 39, 41, 10, 9,101,110,100, 10, 32, 32,101,110, - 100, 10, 32,101,108,115,101, 10, 32, 32,108,111, 99, 97,108, - 32,116, 32, 61, 32,105,115, 98, 97,115,105, 99, 40,116,121, - 112,101, 41, 10, 32, 32,108,105,110,101, 32, 61, 32, 99,111, - 110, 99, 97,116,112, 97,114, 97,109, 40,108,105,110,101, 44, - 39, 32, 61, 32, 39, 41, 10, 32, 32,105,102, 32,116, 32, 61, - 61, 32, 39,115,116, 97,116,101, 39, 32,116,104,101,110, 10, - 32, 32, 9,108,105,110,101, 32, 61, 32, 99,111,110, 99, 97, - 116,112, 97,114, 97,109, 40,108,105,110,101, 44, 32, 39,116, - 111,108,117, 97, 95, 83, 59, 39, 41, 10, 32, 32,101,108,115, - 101, 10, 32, 32, 9, 45, 45,112,114,105,110,116, 40, 34,116, - 32,105,115, 32, 34, 46, 46,116,111,115,116,114,105,110,103, - 40,116, 41, 46, 46, 34, 44, 32,112,116,114, 32,105,115, 32, - 34, 46, 46,116,111,115,116,114,105,110,103, 40,115,101,108, - 102, 46,112,116,114, 41, 41, 10, 32, 32, 9,105,102, 32,116, - 32, 61, 61, 32, 39,110,117,109, 98,101,114, 39, 32, 97,110, - 100, 32,115,116,114,105,110,103, 46,102,105,110,100, 40,115, - 101,108,102, 46,112,116,114, 44, 32, 34, 37, 42, 34, 41, 32, - 116,104,101,110, 10, 32, 32, 9, 9,116, 32, 61, 32, 39,117, - 115,101,114,100, 97,116, 97, 39, 10, 32, 32, 9,101,110,100, - 10, 9,105,102, 32,110,111,116, 32,116, 32, 97,110,100, 32, - 112,116,114, 61, 61, 39, 39, 32,116,104,101,110, 32,108,105, - 110,101, 32, 61, 32, 99,111,110, 99, 97,116,112, 97,114, 97, - 109, 40,108,105,110,101, 44, 39, 42, 39, 41, 32,101,110,100, - 10, 9,108,105,110,101, 32, 61, 32, 99,111,110, 99, 97,116, - 112, 97,114, 97,109, 40,108,105,110,101, 44, 39, 40, 40, 39, - 44,115,101,108,102, 46,109,111,100, 44,116,121,112,101, 41, - 10, 9,105,102, 32,110,111,116, 32,116, 32,116,104,101,110, - 10, 9, 9,108,105,110,101, 32, 61, 32, 99,111,110, 99, 97, - 116,112, 97,114, 97,109, 40,108,105,110,101, 44, 39, 42, 39, - 41, 10, 9,101,110,100, 10, 9,108,105,110,101, 32, 61, 32, - 99,111,110, 99, 97,116,112, 97,114, 97,109, 40,108,105,110, - 101, 44, 39, 41, 32, 39, 41, 10, 9,105,102, 32,105,115,101, - 110,117,109, 40,110, 99,116,121,112,101, 41, 32,116,104,101, - 110, 10, 9, 9,108,105,110,101, 32, 61, 32, 99,111,110, 99, - 97,116,112, 97,114, 97,109, 40,108,105,110,101, 44, 39, 40, - 105,110,116, 41, 32, 39, 41, 10, 9,101,110,100, 10, 9,108, - 111, 99, 97,108, 32,100,101,102, 32, 61, 32, 48, 10, 9,105, - 102, 32,115,101,108,102, 46,100,101,102, 32,126, 61, 32, 39, - 39, 32,116,104,101,110, 10, 9, 9,100,101,102, 32, 61, 32, - 115,101,108,102, 46,100,101,102, 10, 9, 9,105,102, 32, 40, - 112,116,114, 32, 61, 61, 32, 39, 39, 32,111,114, 32,115,101, - 108,102, 46,112,116,114, 32, 61, 61, 32, 39, 38, 39, 41, 32, - 97,110,100, 32,110,111,116, 32,116, 32,116,104,101,110, 10, - 9, 9, 9,100,101,102, 32, 61, 32, 34, 40,118,111,105,100, - 42, 41, 38, 40, 99,111,110,115,116, 32, 34, 46, 46,116,121, - 112,101, 46, 46, 34, 41, 34, 46, 46,100,101,102, 10, 9, 9, - 101,110,100, 10, 9,101,110,100, 10, 9,105,102, 32,116, 32, - 116,104,101,110, 10, 9, 9,108,105,110,101, 32, 61, 32, 99, - 111,110, 99, 97,116,112, 97,114, 97,109, 40,108,105,110,101, - 44, 39,116,111,108,117, 97, 95,116,111, 39, 46, 46,116, 44, - 39, 40,116,111,108,117, 97, 95, 83, 44, 39, 44,110, 97,114, - 103, 44, 39, 44, 39, 44,100,101,102, 44, 39, 41, 41, 59, 39, - 41, 10, 9,101,108,115,101, 10, 9, 9,108,111, 99, 97,108, - 32,116,111, 95,102,117,110, 99, 32, 61, 32,103,101,116, 95, - 116,111, 95,102,117,110, 99,116,105,111,110, 40,116,121,112, - 101, 41, 10, 9, 9,108,105,110,101, 32, 61, 32, 99,111,110, - 99, 97,116,112, 97,114, 97,109, 40,108,105,110,101, 44,116, - 111, 95,102,117,110, 99, 46, 46, 39, 40,116,111,108,117, 97, - 95, 83, 44, 39, 44,110, 97,114,103, 44, 39, 44, 39, 44,100, - 101,102, 44, 39, 41, 41, 59, 39, 41, 10, 9,101,110,100, 10, - 32, 32,101,110,100, 10, 32,101,110,100, 10, 9,114,101,116, - 117,114,110, 32,108,105,110,101, 10,101,110,100, 10, 10, 45, - 45, 32, 68,101, 99,108, 97,114,101, 32,118, 97,114,105, 97, - 98,108,101, 10,102,117,110, 99,116,105,111,110, 32, 99,108, - 97,115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, 58, - 100,101, 99,108, 97,114,101, 32, 40,110, 97,114,103, 41, 10, - 32,105,102, 32,115,101,108,102, 46,100,105,109, 32,126, 61, - 32, 39, 39, 32, 97,110,100, 32,116,111,110,117,109, 98,101, - 114, 40,115,101,108,102, 46,100,105,109, 41, 61, 61,110,105, - 108, 32,116,104,101,110, 10, 9, 32,111,117,116,112,117,116, - 40, 39, 35,105,102,100,101,102, 32, 95, 95, 99,112,108,117, - 115,112,108,117,115, 92,110, 39, 41, 10, 9, 9,111,117,116, - 112,117,116, 40,115,101,108,102, 58, 98,117,105,108,100,100, - 101, 99,108, 97,114, 97,116,105,111,110, 40,110, 97,114,103, - 44,116,114,117,101, 41, 41, 10, 9, 9,111,117,116,112,117, - 116, 40, 39, 35,101,108,115,101, 92,110, 39, 41, 10, 9, 9, - 111,117,116,112,117,116, 40,115,101,108,102, 58, 98,117,105, - 108,100,100,101, 99,108, 97,114, 97,116,105,111,110, 40,110, - 97,114,103, 44,102, 97,108,115,101, 41, 41, 10, 9, 32,111, - 117,116,112,117,116, 40, 39, 35,101,110,100,105,102, 92,110, - 39, 41, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,112, - 117,116, 40,115,101,108,102, 58, 98,117,105,108,100,100,101, - 99,108, 97,114, 97,116,105,111,110, 40,110, 97,114,103, 44, - 102, 97,108,115,101, 41, 41, 10, 9,101,110,100, 10,101,110, - 100, 10, 10, 45, 45, 32, 71,101,116, 32,112, 97,114, 97,109, - 101,116,101,114, 32,118, 97,108,117,101, 10,102,117,110, 99, - 116,105,111,110, 32, 99,108, 97,115,115, 68,101, 99,108, 97, - 114, 97,116,105,111,110, 58,103,101,116, 97,114,114, 97,121, - 32, 40,110, 97,114,103, 41, 10, 32,105,102, 32,115,101,108, - 102, 46,100,105,109, 32,126, 61, 32, 39, 39, 32,116,104,101, - 110, 10, 9, 32,108,111, 99, 97,108, 32,116,121,112,101, 32, - 61, 32,103,115,117, 98, 40,115,101,108,102, 46,116,121,112, - 101, 44, 39, 99,111,110,115,116, 32, 39, 44, 39, 39, 41, 10, - 32, 32,111,117,116,112,117,116, 40, 39, 32, 32,123, 39, 41, - 10, 9, 32,111,117,116,112,117,116, 40, 39, 35,105,102,110, - 100,101,102, 32, 84, 79, 76, 85, 65, 95, 82, 69, 76, 69, 65, - 83, 69, 92,110, 39, 41, 10, 32, 32,108,111, 99, 97,108, 32, - 100,101,102, 59, 32,105,102, 32,115,101,108,102, 46,100,101, - 102,126, 61, 39, 39, 32,116,104,101,110, 32,100,101,102, 61, - 49, 32,101,108,115,101, 32,100,101,102, 61, 48, 32,101,110, - 100, 10, 9, 9,108,111, 99, 97,108, 32,116, 32, 61, 32,105, - 115, 98, 97,115,105, 99, 40,116,121,112,101, 41, 10, 9, 9, - 105,102, 32, 40,116, 41, 32,116,104,101,110, 10, 9, 9, 32, - 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32,105,102, - 32, 40, 33,116,111,108,117, 97, 95,105,115, 39, 46, 46,116, - 46, 46, 39, 97,114,114, 97,121, 40,116,111,108,117, 97, 95, - 83, 44, 39, 44,110, 97,114,103, 44, 39, 44, 39, 44,115,101, - 108,102, 46,100,105,109, 44, 39, 44, 39, 44,100,101,102, 44, - 39, 44, 38,116,111,108,117, 97, 95,101,114,114, 41, 41, 39, - 41, 10, 9, 9,101,108,115,101, 10, 9, 9, 32, 32, 32,111, - 117,116,112,117,116, 40, 39, 32, 32, 32,105,102, 32, 40, 33, - 116,111,108,117, 97, 95,105,115,117,115,101,114,116,121,112, - 101, 97,114,114, 97,121, 40,116,111,108,117, 97, 95, 83, 44, - 39, 44,110, 97,114,103, 44, 39, 44, 34, 39, 44,116,121,112, - 101, 44, 39, 34, 44, 39, 44,115,101,108,102, 46,100,105,109, - 44, 39, 44, 39, 44,100,101,102, 44, 39, 44, 38,116,111,108, - 117, 97, 95,101,114,114, 41, 41, 39, 41, 10, 9, 9,101,110, - 100, 10, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, - 32,103,111,116,111, 32,116,111,108,117, 97, 95,108,101,114, - 114,111,114, 59, 39, 41, 10, 32, 32,111,117,116,112,117,116, - 40, 39, 32, 32, 32,101,108,115,101, 92,110, 39, 41, 10, 9, - 32,111,117,116,112,117,116, 40, 39, 35,101,110,100,105,102, - 92,110, 39, 41, 10, 32, 32,111,117,116,112,117,116, 40, 39, - 32, 32, 32,123, 39, 41, 10, 32, 32,111,117,116,112,117,116, - 40, 39, 32, 32, 32, 32,105,110,116, 32,105, 59, 39, 41, 10, - 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, 32,102, - 111,114, 40,105, 61, 48, 59, 32,105, 60, 39, 46, 46,115,101, - 108,102, 46,100,105,109, 46, 46, 39, 59,105, 43, 43, 41, 39, - 41, 10, 32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,105, - 115, 98, 97,115,105, 99, 40,116,121,112,101, 41, 10, 32, 32, - 108,111, 99, 97,108, 32,112,116,114, 32, 61, 32, 39, 39, 10, - 32, 32,105,102, 32,115,101,108,102, 46,112,116,114,126, 61, - 39, 39, 32,116,104,101,110, 32,112,116,114, 32, 61, 32, 39, - 42, 39, 32,101,110,100, 10, 32, 32,111,117,116,112,117,116, - 40, 39, 32, 32, 32, 39, 44,115,101,108,102, 46,110, 97,109, - 101, 46, 46, 39, 91,105, 93, 32, 61, 32, 39, 41, 10, 32, 32, - 105,102, 32,110,111,116, 32,116, 32, 97,110,100, 32,112,116, - 114, 61, 61, 39, 39, 32,116,104,101,110, 32,111,117,116,112, - 117,116, 40, 39, 42, 39, 41, 32,101,110,100, 10, 32, 32,111, - 117,116,112,117,116, 40, 39, 40, 40, 39, 44,116,121,112,101, - 41, 10, 32, 32,105,102, 32,110,111,116, 32,116, 32,116,104, - 101,110, 10, 32, 32, 32,111,117,116,112,117,116, 40, 39, 42, - 39, 41, 10, 32, 32,101,110,100, 10, 32, 32,111,117,116,112, - 117,116, 40, 39, 41, 32, 39, 41, 10, 32, 32,108,111, 99, 97, - 108, 32,100,101,102, 32, 61, 32, 48, 10, 32, 32,105,102, 32, - 115,101,108,102, 46,100,101,102, 32,126, 61, 32, 39, 39, 32, - 116,104,101,110, 32,100,101,102, 32, 61, 32,115,101,108,102, - 46,100,101,102, 32,101,110,100, 10, 32, 32,105,102, 32,116, - 32,116,104,101,110, 10, 32, 32, 32,111,117,116,112,117,116, - 40, 39,116,111,108,117, 97, 95,116,111,102,105,101,108,100, - 39, 46, 46,116, 46, 46, 39, 40,116,111,108,117, 97, 95, 83, - 44, 39, 44,110, 97,114,103, 44, 39, 44,105, 43, 49, 44, 39, - 44,100,101,102, 44, 39, 41, 41, 59, 39, 41, 10, 32, 32,101, - 108,115,101, 10, 32, 32, 32,111,117,116,112,117,116, 40, 39, - 116,111,108,117, 97, 95,116,111,102,105,101,108,100,117,115, - 101,114,116,121,112,101, 40,116,111,108,117, 97, 95, 83, 44, - 39, 44,110, 97,114,103, 44, 39, 44,105, 43, 49, 44, 39, 44, - 100,101,102, 44, 39, 41, 41, 59, 39, 41, 10, 32, 32,101,110, - 100, 10, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, - 125, 39, 41, 10, 32, 32,111,117,116,112,117,116, 40, 39, 32, - 32,125, 39, 41, 10, 32,101,110,100, 10,101,110,100, 10, 10, - 45, 45, 32, 71,101,116, 32,112, 97,114, 97,109,101,116,101, - 114, 32,118, 97,108,117,101, 10,102,117,110, 99,116,105,111, - 110, 32, 99,108, 97,115,115, 68,101, 99,108, 97,114, 97,116, - 105,111,110, 58,115,101,116, 97,114,114, 97,121, 32, 40,110, - 97,114,103, 41, 10, 32,105,102, 32,110,111,116, 32,115,116, - 114,102,105,110,100, 40,115,101,108,102, 46,116,121,112,101, - 44, 39, 99,111,110,115,116, 37,115, 43, 39, 41, 32, 97,110, - 100, 32,115,101,108,102, 46,100,105,109, 32,126, 61, 32, 39, - 39, 32,116,104,101,110, 10, 9, 32,108,111, 99, 97,108, 32, - 116,121,112,101, 32, 61, 32,103,115,117, 98, 40,115,101,108, - 102, 46,116,121,112,101, 44, 39, 99,111,110,115,116, 32, 39, - 44, 39, 39, 41, 10, 32, 32,111,117,116,112,117,116, 40, 39, - 32, 32,123, 39, 41, 10, 32, 32,111,117,116,112,117,116, 40, - 39, 32, 32, 32,105,110,116, 32,105, 59, 39, 41, 10, 32, 32, - 111,117,116,112,117,116, 40, 39, 32, 32, 32,102,111,114, 40, - 105, 61, 48, 59, 32,105, 60, 39, 46, 46,115,101,108,102, 46, - 100,105,109, 46, 46, 39, 59,105, 43, 43, 41, 39, 41, 10, 32, - 32,108,111, 99, 97,108, 32,116, 44, 99,116, 32, 61, 32,105, - 115, 98, 97,115,105, 99, 40,116,121,112,101, 41, 10, 32, 32, - 105,102, 32,116, 32,116,104,101,110, 10, 32, 32, 32,111,117, - 116,112,117,116, 40, 39, 32, 32, 32, 32,116,111,108,117, 97, - 95,112,117,115,104,102,105,101,108,100, 39, 46, 46,116, 46, - 46, 39, 40,116,111,108,117, 97, 95, 83, 44, 39, 44,110, 97, - 114,103, 44, 39, 44,105, 43, 49, 44, 40, 39, 44, 99,116, 44, - 39, 41, 39, 44,115,101,108,102, 46,110, 97,109,101, 44, 39, - 91,105, 93, 41, 59, 39, 41, 10, 32, 32,101,108,115,101, 10, - 32, 32, 32,105,102, 32,115,101,108,102, 46,112,116,114, 32, - 61, 61, 32, 39, 39, 32,116,104,101,110, 10, 32, 32, 32, 32, - 32,111,117,116,112,117,116, 40, 39, 32, 32, 32,123, 39, 41, - 10, 32, 32, 32, 32, 32,111,117,116,112,117,116, 40, 39, 35, - 105,102,100,101,102, 32, 95, 95, 99,112,108,117,115,112,108, - 117,115, 92,110, 39, 41, 10, 32, 32, 32, 32, 32,111,117,116, - 112,117,116, 40, 39, 32, 32, 32, 32,118,111,105,100, 42, 32, - 116,111,108,117, 97, 95,111, 98,106, 32, 61, 32, 77,116,111, - 108,117, 97, 95,110,101,119, 40, 40, 39, 44,116,121,112,101, - 44, 39, 41, 40, 39, 44,115,101,108,102, 46,110, 97,109,101, - 44, 39, 91,105, 93, 41, 41, 59, 39, 41, 10, 32, 32, 32, 32, - 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, 32,116,111, - 108,117, 97, 95,112,117,115,104,102,105,101,108,100,117,115, - 101,114,116,121,112,101, 95, 97,110,100, 95,116, 97,107,101, - 111,119,110,101,114,115,104,105,112, 40,116,111,108,117, 97, - 95, 83, 44, 39, 44,110, 97,114,103, 44, 39, 44,105, 43, 49, - 44,116,111,108,117, 97, 95,111, 98,106, 44, 34, 39, 44,116, - 121,112,101, 44, 39, 34, 41, 59, 39, 41, 10, 32, 32, 32, 32, - 32,111,117,116,112,117,116, 40, 39, 35,101,108,115,101, 92, - 110, 39, 41, 10, 32, 32, 32, 32, 32,111,117,116,112,117,116, - 40, 39, 32, 32, 32, 32,118,111,105,100, 42, 32,116,111,108, - 117, 97, 95,111, 98,106, 32, 61, 32,116,111,108,117, 97, 95, - 99,111,112,121, 40,116,111,108,117, 97, 95, 83, 44, 40,118, - 111,105,100, 42, 41, 38, 39, 44,115,101,108,102, 46,110, 97, - 109,101, 44, 39, 91,105, 93, 44,115,105,122,101,111,102, 40, - 39, 44,116,121,112,101, 44, 39, 41, 41, 59, 39, 41, 10, 32, - 32, 32, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, - 32,116,111,108,117, 97, 95,112,117,115,104,102,105,101,108, - 100,117,115,101,114,116,121,112,101, 40,116,111,108,117, 97, - 95, 83, 44, 39, 44,110, 97,114,103, 44, 39, 44,105, 43, 49, - 44,116,111,108,117, 97, 95,111, 98,106, 44, 34, 39, 44,116, - 121,112,101, 44, 39, 34, 41, 59, 39, 41, 10, 32, 32, 32, 32, - 32,111,117,116,112,117,116, 40, 39, 35,101,110,100,105,102, - 92,110, 39, 41, 10, 32, 32, 32, 32, 32,111,117,116,112,117, - 116, 40, 39, 32, 32, 32,125, 39, 41, 10, 32, 32, 32,101,108, - 115,101, 10, 32, 32, 32, 32,111,117,116,112,117,116, 40, 39, - 32, 32, 32,116,111,108,117, 97, 95,112,117,115,104,102,105, - 101,108,100,117,115,101,114,116,121,112,101, 40,116,111,108, - 117, 97, 95, 83, 44, 39, 44,110, 97,114,103, 44, 39, 44,105, - 43, 49, 44, 40,118,111,105,100, 42, 41, 39, 44,115,101,108, - 102, 46,110, 97,109,101, 44, 39, 91,105, 93, 44, 34, 39, 44, - 116,121,112,101, 44, 39, 34, 41, 59, 39, 41, 10, 32, 32, 32, - 101,110,100, 10, 32, 32,101,110,100, 10, 32, 32,111,117,116, - 112,117,116, 40, 39, 32, 32,125, 39, 41, 10, 32,101,110,100, - 10,101,110,100, 10, 10, 45, 45, 32, 70,114,101,101, 32,100, - 121,110, 97,109,105, 99, 97,108,108,121, 32, 97,108,108,111, - 99, 97,116,101,100, 32, 97,114,114, 97,121, 10,102,117,110, - 99,116,105,111,110, 32, 99,108, 97,115,115, 68,101, 99,108, - 97,114, 97,116,105,111,110, 58,102,114,101,101, 97,114,114, - 97,121, 32, 40, 41, 10, 32,105,102, 32,115,101,108,102, 46, - 100,105,109, 32,126, 61, 32, 39, 39, 32, 97,110,100, 32,116, - 111,110,117,109, 98,101,114, 40,115,101,108,102, 46,100,105, - 109, 41, 61, 61,110,105,108, 32,116,104,101,110, 10, 9, 32, - 111,117,116,112,117,116, 40, 39, 35,105,102,100,101,102, 32, - 95, 95, 99,112,108,117,115,112,108,117,115, 92,110, 39, 41, - 10, 9, 9,111,117,116,112,117,116, 40, 39, 32, 32, 77,116, - 111,108,117, 97, 95,100,101,108,101,116,101, 95,100,105,109, - 40, 39, 44,115,101,108,102, 46,110, 97,109,101, 44, 39, 41, - 59, 39, 41, 10, 9, 32,111,117,116,112,117,116, 40, 39, 35, - 101,108,115,101, 92,110, 39, 41, 10, 32, 32,111,117,116,112, - 117,116, 40, 39, 32, 32,102,114,101,101, 40, 39, 44,115,101, - 108,102, 46,110, 97,109,101, 44, 39, 41, 59, 39, 41, 10, 9, - 32,111,117,116,112,117,116, 40, 39, 35,101,110,100,105,102, - 92,110, 39, 41, 10, 32,101,110,100, 10,101,110,100, 10, 10, - 45, 45, 32, 80, 97,115,115, 32,112, 97,114, 97,109,101,116, - 101,114, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97, - 115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, 58,112, - 97,115,115,112, 97,114, 32, 40, 41, 10, 32,105,102, 32,115, - 101,108,102, 46,112,116,114, 61, 61, 39, 38, 39, 32, 97,110, - 100, 32,110,111,116, 32,105,115, 98, 97,115,105, 99, 40,115, - 101,108,102, 46,116,121,112,101, 41, 32,116,104,101,110, 10, - 32, 32,111,117,116,112,117,116, 40, 39, 42, 39, 46, 46,115, - 101,108,102, 46,110, 97,109,101, 41, 10, 32,101,108,115,101, - 105,102, 32,115,101,108,102, 46,114,101,116, 61, 61, 39, 42, - 39, 32,116,104,101,110, 10, 32, 32,111,117,116,112,117,116, - 40, 39, 38, 39, 46, 46,115,101,108,102, 46,110, 97,109,101, - 41, 10, 32,101,108,115,101, 10, 32, 32,111,117,116,112,117, - 116, 40,115,101,108,102, 46,110, 97,109,101, 41, 10, 32,101, - 110,100, 10,101,110,100, 10, 10, 45, 45, 32, 82,101,116,117, - 114,110, 32,112, 97,114, 97,109,101,116,101,114, 32,118, 97, - 108,117,101, 10,102,117,110, 99,116,105,111,110, 32, 99,108, - 97,115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, 58, - 114,101,116,118, 97,108,117,101, 32, 40, 41, 10, 32,105,102, - 32,115,101,108,102, 46,114,101,116, 32,126, 61, 32, 39, 39, - 32,116,104,101,110, 10, 32, 32,108,111, 99, 97,108, 32,116, - 44, 99,116, 32, 61, 32,105,115, 98, 97,115,105, 99, 40,115, - 101,108,102, 46,116,121,112,101, 41, 10, 32, 32,105,102, 32, - 116, 32, 97,110,100, 32,116,126, 61, 39, 39, 32,116,104,101, - 110, 10, 32, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, - 32,116,111,108,117, 97, 95,112,117,115,104, 39, 46, 46,116, - 46, 46, 39, 40,116,111,108,117, 97, 95, 83, 44, 40, 39, 44, - 99,116, 44, 39, 41, 39, 46, 46,115,101,108,102, 46,110, 97, - 109,101, 46, 46, 39, 41, 59, 39, 41, 10, 32, 32,101,108,115, - 101, 10, 32, 32, 32,108,111, 99, 97,108, 32,112,117,115,104, - 95,102,117,110, 99, 32, 61, 32,103,101,116, 95,112,117,115, - 104, 95,102,117,110, 99,116,105,111,110, 40,115,101,108,102, - 46,116,121,112,101, 41, 10, 32, 32, 32,111,117,116,112,117, - 116, 40, 39, 32, 32, 32, 39, 44,112,117,115,104, 95,102,117, - 110, 99, 44, 39, 40,116,111,108,117, 97, 95, 83, 44, 40,118, - 111,105,100, 42, 41, 39, 46, 46,115,101,108,102, 46,110, 97, - 109,101, 46, 46, 39, 44, 34, 39, 44,115,101,108,102, 46,116, - 121,112,101, 44, 39, 34, 41, 59, 39, 41, 10, 32, 32,101,110, - 100, 10, 32, 32,114,101,116,117,114,110, 32, 49, 10, 32,101, - 110,100, 10, 32,114,101,116,117,114,110, 32, 48, 10,101,110, - 100, 10, 10, 45, 45, 32, 73,110,116,101,114,110, 97,108, 32, - 99,111,110,115,116,114,117, 99,116,111,114, 10,102,117,110, - 99,116,105,111,110, 32, 95, 68,101, 99,108, 97,114, 97,116, - 105,111,110, 32, 40,116, 41, 10, 10, 32,115,101,116,109,101, - 116, 97,116, 97, 98,108,101, 40,116, 44, 99,108, 97,115,115, - 68,101, 99,108, 97,114, 97,116,105,111,110, 41, 10, 32,116, - 58, 98,117,105,108,100,110, 97,109,101,115, 40, 41, 10, 32, - 116, 58, 99,104,101, 99,107,110, 97,109,101, 40, 41, 10, 32, - 116, 58, 99,104,101, 99,107,116,121,112,101, 40, 41, 10, 32, - 108,111, 99, 97,108, 32,102,116, 32, 61, 32,102,105,110,100, - 116,121,112,101, 40,116, 46,116,121,112,101, 41, 32,111,114, - 32,116, 46,116,121,112,101, 10, 32,105,102, 32,110,111,116, - 32,105,115,101,110,117,109, 40,102,116, 41, 32,116,104,101, - 110, 10, 9,116, 46,109,111,100, 44, 32,116, 46,116,121,112, - 101, 32, 61, 32, 97,112,112,108,121,116,121,112,101,100,101, - 102, 40,116, 46,109,111,100, 44, 32,102,116, 41, 10, 32,101, - 110,100, 10, 10, 32,105,102, 32,116, 46,107,105,110,100, 61, - 61, 34,118, 97,114, 34, 32, 97,110,100, 32, 40,115,116,114, - 105,110,103, 46,102,105,110,100, 40,116, 46,109,111,100, 44, - 32, 34,116,111,108,117, 97, 95,112,114,111,112,101,114,116, - 121, 37,115, 34, 41, 32,111,114, 32,115,116,114,105,110,103, - 46,102,105,110,100, 40,116, 46,109,111,100, 44, 32, 34,116, - 111,108,117, 97, 95,112,114,111,112,101,114,116,121, 36, 34, - 41, 41, 32,116,104,101,110, 10, 32, 9,116, 46,109,111,100, - 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, - 116, 46,109,111,100, 44, 32, 34,116,111,108,117, 97, 95,112, - 114,111,112,101,114,116,121, 34, 44, 32, 34,116,111,108,117, - 97, 95,112,114,111,112,101,114,116,121, 95, 95, 34, 46, 46, - 103,101,116, 95,112,114,111,112,101,114,116,121, 95,116,121, - 112,101, 40, 41, 41, 10, 32,101,110,100, 10, 10, 32,114,101, - 116,117,114,110, 32,116, 10,101,110,100, 10, 10, 45, 45, 32, - 67,111,110,115,116,114,117, 99,116,111,114, 10, 45, 45, 32, - 69,120,112,101, 99,116,115, 32,116,104,101, 32,115,116,114, - 105,110,103, 32,100,101, 99,108, 97,114, 97,116,105,111,110, - 46, 10, 45, 45, 32, 84,104,101, 32,107,105,110,100, 32,111, - 102, 32,100,101, 99,108, 97,114, 97,116,105,111,110, 32, 99, - 97,110, 32, 98,101, 32, 34,118, 97,114, 34, 32,111,114, 32, - 34,102,117,110, 99, 34, 46, 10,102,117,110, 99,116,105,111, - 110, 32, 68,101, 99,108, 97,114, 97,116,105,111,110, 32, 40, - 115, 44,107,105,110,100, 44,105,115, 95,112, 97,114, 97,109, - 101,116,101,114, 41, 10, 10, 32, 45, 45, 32,101,108,105,109, - 105,110, 97,116,101, 32,115,112, 97, 99,101,115, 32,105,102, - 32,100,101,102, 97,117,108,116, 32,118, 97,108,117,101, 32, - 105,115, 32,112,114,111,118,105,100,101,100, 10, 32,115, 32, - 61, 32,103,115,117, 98, 40,115, 44, 34, 37,115, 42, 61, 37, - 115, 42, 34, 44, 34, 61, 34, 41, 10, 32,115, 32, 61, 32,103, - 115,117, 98, 40,115, 44, 32, 34, 37,115, 42, 60, 34, 44, 32, - 34, 60, 34, 41, 10, 10, 32,108,111, 99, 97,108, 32,100,101, - 102, 98, 44,116,109,112,100,101,102, 10, 32,100,101,102, 98, - 44, 95, 44,116,109,112,100,101,102, 32, 61, 32,115,116,114, - 105,110,103, 46,102,105,110,100, 40,115, 44, 32, 34, 40, 61, - 46, 42, 41, 36, 34, 41, 10, 32,105,102, 32,100,101,102, 98, - 32,116,104,101,110, 10, 32, 9,115, 32, 61, 32,115,116,114, - 105,110,103, 46,103,115,117, 98, 40,115, 44, 32, 34, 61, 46, - 42, 36, 34, 44, 32, 34, 34, 41, 10, 32,101,108,115,101, 10, - 32, 9,116,109,112,100,101,102, 32, 61, 32, 39, 39, 10, 32, - 101,110,100, 10, 32,105,102, 32,107,105,110,100, 32, 61, 61, - 32, 34,118, 97,114, 34, 32,116,104,101,110, 10, 32, 32, 45, - 45, 32, 99,104,101, 99,107, 32,116,104,101, 32,102,111,114, - 109, 58, 32,118,111,105,100, 10, 32, 32,105,102, 32,115, 32, - 61, 61, 32, 39, 39, 32,111,114, 32,115, 32, 61, 61, 32, 39, - 118,111,105,100, 39, 32,116,104,101,110, 10, 32, 32, 32,114, - 101,116,117,114,110, 32, 95, 68,101, 99,108, 97,114, 97,116, - 105,111,110,123,116,121,112,101, 32, 61, 32, 39,118,111,105, - 100, 39, 44, 32,107,105,110,100, 32, 61, 32,107,105,110,100, - 44, 32,105,115, 95,112, 97,114, 97,109,101,116,101,114, 32, - 61, 32,105,115, 95,112, 97,114, 97,109,101,116,101,114,125, - 10, 32, 32,101,110,100, 10, 32,101,110,100, 10, 10, 32, 45, - 45, 32, 99,104,101, 99,107, 32,116,104,101, 32,102,111,114, - 109, 58, 32,109,111,100, 32,116,121,112,101, 42, 38, 32,110, - 97,109,101, 10, 32,108,111, 99, 97,108, 32,116, 32, 61, 32, - 115,112,108,105,116, 95, 99, 95,116,111,107,101,110,115, 40, - 115, 44, 39, 37, 42, 37,115, 42, 38, 39, 41, 10, 32,105,102, - 32,116, 46,110, 32, 61, 61, 32, 50, 32,116,104,101,110, 10, - 32, 32,105,102, 32,107,105,110,100, 32, 61, 61, 32, 39,102, - 117,110, 99, 39, 32,116,104,101,110, 10, 32, 32, 32,101,114, - 114,111,114, 40, 34, 35,105,110,118, 97,108,105,100, 32,102, - 117,110, 99,116,105,111,110, 32,114,101,116,117,114,110, 32, - 116,121,112,101, 58, 32, 34, 46, 46,115, 41, 10, 32, 32,101, - 110,100, 10, 32, 32, 45, 45,108,111, 99, 97,108, 32,109, 32, - 61, 32,115,112,108,105,116, 40,116, 91, 49, 93, 44, 39, 37, - 115, 37,115, 42, 39, 41, 10, 32, 32,108,111, 99, 97,108, 32, - 109, 32, 61, 32,115,112,108,105,116, 95, 99, 95,116,111,107, - 101,110,115, 40,116, 91, 49, 93, 44, 39, 37,115, 43, 39, 41, - 10, 32, 32,114,101,116,117,114,110, 32, 95, 68,101, 99,108, - 97,114, 97,116,105,111,110,123, 10, 32, 32, 32,110, 97,109, - 101, 32, 61, 32,116, 91, 50, 93, 46, 46,116,109,112,100,101, - 102, 44, 10, 32, 32, 32,112,116,114, 32, 61, 32, 39, 42, 39, - 44, 10, 32, 32, 32,114,101,116, 32, 61, 32, 39, 38, 39, 44, - 10, 32, 32, 32, 45, 45,116,121,112,101, 32, 61, 32,114,101, - 98,117,105,108,100, 95,116,101,109,112,108, 97,116,101, 40, - 109, 91,109, 46,110, 93, 44, 32,116, 98, 44, 32,116,105,109, - 112,108, 41, 44, 10, 32, 32, 32,116,121,112,101, 32, 61, 32, - 109, 91,109, 46,110, 93, 44, 10, 32, 32, 32,109,111,100, 32, - 61, 32, 99,111,110, 99, 97,116, 40,109, 44, 49, 44,109, 46, - 110, 45, 49, 41, 44, 10, 32, 32, 32,105,115, 95,112, 97,114, - 97,109,101,116,101,114, 32, 61, 32,105,115, 95,112, 97,114, - 97,109,101,116,101,114, 44, 10, 32, 32, 32,107,105,110,100, - 32, 61, 32,107,105,110,100, 10, 32, 32,125, 10, 32,101,110, - 100, 10, 10, 32, 45, 45, 32, 99,104,101, 99,107, 32,116,104, - 101, 32,102,111,114,109, 58, 32,109,111,100, 32,116,121,112, - 101, 42, 42, 32,110, 97,109,101, 10, 32,116, 32, 61, 32,115, - 112,108,105,116, 95, 99, 95,116,111,107,101,110,115, 40,115, - 44, 39, 37, 42, 37,115, 42, 37, 42, 39, 41, 10, 32,105,102, - 32,116, 46,110, 32, 61, 61, 32, 50, 32,116,104,101,110, 10, - 32, 32,105,102, 32,107,105,110,100, 32, 61, 61, 32, 39,102, - 117,110, 99, 39, 32,116,104,101,110, 10, 32, 32, 32,101,114, - 114,111,114, 40, 34, 35,105,110,118, 97,108,105,100, 32,102, - 117,110, 99,116,105,111,110, 32,114,101,116,117,114,110, 32, - 116,121,112,101, 58, 32, 34, 46, 46,115, 41, 10, 32, 32,101, - 110,100, 10, 32, 32, 45, 45,108,111, 99, 97,108, 32,109, 32, - 61, 32,115,112,108,105,116, 40,116, 91, 49, 93, 44, 39, 37, - 115, 37,115, 42, 39, 41, 10, 32, 32,108,111, 99, 97,108, 32, - 109, 32, 61, 32,115,112,108,105,116, 95, 99, 95,116,111,107, - 101,110,115, 40,116, 91, 49, 93, 44, 39, 37,115, 43, 39, 41, - 10, 32, 32,114,101,116,117,114,110, 32, 95, 68,101, 99,108, - 97,114, 97,116,105,111,110,123, 10, 32, 32, 32,110, 97,109, - 101, 32, 61, 32,116, 91, 50, 93, 46, 46,116,109,112,100,101, - 102, 44, 10, 32, 32, 32,112,116,114, 32, 61, 32, 39, 42, 39, - 44, 10, 32, 32, 32,114,101,116, 32, 61, 32, 39, 42, 39, 44, - 10, 32, 32, 32, 45, 45,116,121,112,101, 32, 61, 32,114,101, - 98,117,105,108,100, 95,116,101,109,112,108, 97,116,101, 40, - 109, 91,109, 46,110, 93, 44, 32,116, 98, 44, 32,116,105,109, - 112,108, 41, 44, 10, 32, 32, 32,116,121,112,101, 32, 61, 32, - 109, 91,109, 46,110, 93, 44, 10, 32, 32, 32,109,111,100, 32, - 61, 32, 99,111,110, 99, 97,116, 40,109, 44, 49, 44,109, 46, - 110, 45, 49, 41, 44, 10, 32, 32, 32,105,115, 95,112, 97,114, - 97,109,101,116,101,114, 32, 61, 32,105,115, 95,112, 97,114, - 97,109,101,116,101,114, 44, 10, 32, 32, 32,107,105,110,100, - 32, 61, 32,107,105,110,100, 10, 32, 32,125, 10, 32,101,110, - 100, 10, 10, 32, 45, 45, 32, 99,104,101, 99,107, 32,116,104, - 101, 32,102,111,114,109, 58, 32,109,111,100, 32,116,121,112, - 101, 38, 32,110, 97,109,101, 10, 32,116, 32, 61, 32,115,112, - 108,105,116, 95, 99, 95,116,111,107,101,110,115, 40,115, 44, - 39, 38, 39, 41, 10, 32,105,102, 32,116, 46,110, 32, 61, 61, - 32, 50, 32,116,104,101,110, 10, 32, 32, 45, 45,108,111, 99, - 97,108, 32,109, 32, 61, 32,115,112,108,105,116, 40,116, 91, - 49, 93, 44, 39, 37,115, 37,115, 42, 39, 41, 10, 32, 32,108, - 111, 99, 97,108, 32,109, 32, 61, 32,115,112,108,105,116, 95, - 99, 95,116,111,107,101,110,115, 40,116, 91, 49, 93, 44, 39, - 37,115, 43, 39, 41, 10, 32, 32,114,101,116,117,114,110, 32, - 95, 68,101, 99,108, 97,114, 97,116,105,111,110,123, 10, 32, - 32, 32,110, 97,109,101, 32, 61, 32,116, 91, 50, 93, 46, 46, - 116,109,112,100,101,102, 44, 10, 32, 32, 32,112,116,114, 32, - 61, 32, 39, 38, 39, 44, 10, 32, 32, 32, 45, 45,116,121,112, - 101, 32, 61, 32,114,101, 98,117,105,108,100, 95,116,101,109, - 112,108, 97,116,101, 40,109, 91,109, 46,110, 93, 44, 32,116, - 98, 44, 32,116,105,109,112,108, 41, 44, 10, 32, 32, 32,116, - 121,112,101, 32, 61, 32,109, 91,109, 46,110, 93, 44, 10, 32, - 32, 32,109,111,100, 32, 61, 32, 99,111,110, 99, 97,116, 40, - 109, 44, 49, 44,109, 46,110, 45, 49, 41, 44, 10, 32, 32, 32, - 105,115, 95,112, 97,114, 97,109,101,116,101,114, 32, 61, 32, - 105,115, 95,112, 97,114, 97,109,101,116,101,114, 44, 10, 32, - 32, 32,107,105,110,100, 32, 61, 32,107,105,110,100, 10, 32, - 32,125, 10, 32,101,110,100, 10, 10, 32, 45, 45, 32, 99,104, - 101, 99,107, 32,116,104,101, 32,102,111,114,109, 58, 32,109, - 111,100, 32,116,121,112,101, 42, 32,110, 97,109,101, 10, 32, - 108,111, 99, 97,108, 32,115, 49, 32, 61, 32,103,115,117, 98, - 40,115, 44, 34, 40, 37, 98, 92, 91, 92, 93, 41, 34, 44,102, - 117,110, 99,116,105,111,110, 32, 40,110, 41, 32,114,101,116, - 117,114,110, 32,103,115,117, 98, 40,110, 44, 39, 37, 42, 39, - 44, 39, 92, 49, 39, 41, 32,101,110,100, 41, 10, 32,116, 32, - 61, 32,115,112,108,105,116, 95, 99, 95,116,111,107,101,110, - 115, 40,115, 49, 44, 39, 37, 42, 39, 41, 10, 32,105,102, 32, - 116, 46,110, 32, 61, 61, 32, 50, 32,116,104,101,110, 10, 32, - 32,116, 91, 50, 93, 32, 61, 32,103,115,117, 98, 40,116, 91, - 50, 93, 44, 39, 92, 49, 39, 44, 39, 37, 42, 39, 41, 32, 45, - 45, 32,114,101,115,116,111,114,101, 32, 42, 32,105,110, 32, - 100,105,109,101,110,115,105,111,110, 32,101,120,112,114,101, - 115,115,105,111,110, 10, 32, 32, 45, 45,108,111, 99, 97,108, - 32,109, 32, 61, 32,115,112,108,105,116, 40,116, 91, 49, 93, - 44, 39, 37,115, 37,115, 42, 39, 41, 10, 32, 32,108,111, 99, - 97,108, 32,109, 32, 61, 32,115,112,108,105,116, 95, 99, 95, - 116,111,107,101,110,115, 40,116, 91, 49, 93, 44, 39, 37,115, - 43, 39, 41, 10, 32, 32,114,101,116,117,114,110, 32, 95, 68, - 101, 99,108, 97,114, 97,116,105,111,110,123, 10, 32, 32, 32, - 110, 97,109,101, 32, 61, 32,116, 91, 50, 93, 46, 46,116,109, - 112,100,101,102, 44, 10, 32, 32, 32,112,116,114, 32, 61, 32, - 39, 42, 39, 44, 10, 32, 32, 32,116,121,112,101, 32, 61, 32, - 109, 91,109, 46,110, 93, 44, 10, 32, 32, 32, 45, 45,116,121, - 112,101, 32, 61, 32,114,101, 98,117,105,108,100, 95,116,101, - 109,112,108, 97,116,101, 40,109, 91,109, 46,110, 93, 44, 32, - 116, 98, 44, 32,116,105,109,112,108, 41, 44, 10, 32, 32, 32, - 109,111,100, 32, 61, 32, 99,111,110, 99, 97,116, 40,109, 44, - 49, 44,109, 46,110, 45, 49, 41, 32, 32, 32, 44, 10, 32, 32, - 32,105,115, 95,112, 97,114, 97,109,101,116,101,114, 32, 61, - 32,105,115, 95,112, 97,114, 97,109,101,116,101,114, 44, 10, - 32, 32, 32,107,105,110,100, 32, 61, 32,107,105,110,100, 10, - 32, 32,125, 10, 32,101,110,100, 10, 10, 32,105,102, 32,107, - 105,110,100, 32, 61, 61, 32, 39,118, 97,114, 39, 32,116,104, - 101,110, 10, 32, 32, 45, 45, 32, 99,104,101, 99,107, 32,116, - 104,101, 32,102,111,114,109, 58, 32,109,111,100, 32,116,121, - 112,101, 32,110, 97,109,101, 10, 32, 32, 45, 45,116, 32, 61, - 32,115,112,108,105,116, 40,115, 44, 39, 37,115, 37,115, 42, - 39, 41, 10, 32, 32,116, 32, 61, 32,115,112,108,105,116, 95, - 99, 95,116,111,107,101,110,115, 40,115, 44, 39, 37,115, 43, - 39, 41, 10, 32, 32,108,111, 99, 97,108, 32,118, 10, 32, 32, - 105,102, 32,102,105,110,100,116,121,112,101, 40,116, 91,116, - 46,110, 93, 41, 32,116,104,101,110, 32,118, 32, 61, 32, 99, - 114,101, 97,116,101, 95,118, 97,114,110, 97,109,101, 40, 41, - 32,101,108,115,101, 32,118, 32, 61, 32,116, 91,116, 46,110, - 93, 59, 32,116, 46,110, 32, 61, 32,116, 46,110, 45, 49, 32, - 101,110,100, 10, 32, 32,114,101,116,117,114,110, 32, 95, 68, - 101, 99,108, 97,114, 97,116,105,111,110,123, 10, 32, 32, 32, - 110, 97,109,101, 32, 61, 32,118, 46, 46,116,109,112,100,101, - 102, 44, 10, 32, 32, 32, 45, 45,116,121,112,101, 32, 61, 32, - 114,101, 98,117,105,108,100, 95,116,101,109,112,108, 97,116, - 101, 40,116, 91,116, 46,110, 93, 44, 32,116, 98, 44, 32,116, - 105,109,112,108, 41, 44, 10, 32, 32, 32,116,121,112,101, 32, - 61, 32,116, 91,116, 46,110, 93, 44, 10, 32, 32, 32,109,111, - 100, 32, 61, 32, 99,111,110, 99, 97,116, 40,116, 44, 49, 44, - 116, 46,110, 45, 49, 41, 44, 10, 32, 32, 32,105,115, 95,112, - 97,114, 97,109,101,116,101,114, 32, 61, 32,105,115, 95,112, - 97,114, 97,109,101,116,101,114, 44, 10, 32, 32, 32,107,105, - 110,100, 32, 61, 32,107,105,110,100, 10, 32, 32,125, 10, 10, - 32,101,108,115,101, 32, 45, 45, 32,107,105,110,100, 32, 61, - 61, 32, 34,102,117,110, 99, 34, 10, 10, 32, 32, 45, 45, 32, - 99,104,101, 99,107, 32,116,104,101, 32,102,111,114,109, 58, - 32,109,111,100, 32,116,121,112,101, 32,110, 97,109,101, 10, - 32, 32, 45, 45,116, 32, 61, 32,115,112,108,105,116, 40,115, - 44, 39, 37,115, 37,115, 42, 39, 41, 10, 32, 32,116, 32, 61, - 32,115,112,108,105,116, 95, 99, 95,116,111,107,101,110,115, - 40,115, 44, 39, 37,115, 43, 39, 41, 10, 32, 32,108,111, 99, - 97,108, 32,118, 32, 61, 32,116, 91,116, 46,110, 93, 32, 32, - 45, 45, 32,108, 97,115,116, 32,119,111,114,100, 32,105,115, - 32,116,104,101, 32,102,117,110, 99,116,105,111,110, 32,110, - 97,109,101, 10, 32, 32,108,111, 99, 97,108, 32,116,112, 44, - 109,100, 10, 32, 32,105,102, 32,116, 46,110, 62, 49, 32,116, - 104,101,110, 10, 32, 32, 32,116,112, 32, 61, 32,116, 91,116, - 46,110, 45, 49, 93, 10, 32, 32, 32,109,100, 32, 61, 32, 99, - 111,110, 99, 97,116, 40,116, 44, 49, 44,116, 46,110, 45, 50, - 41, 10, 32, 32,101,110,100, 10, 32, 32, 45, 45,105,102, 32, - 116,112, 32,116,104,101,110, 32,116,112, 32, 61, 32,114,101, - 98,117,105,108,100, 95,116,101,109,112,108, 97,116,101, 40, - 116,112, 44, 32,116, 98, 44, 32,116,105,109,112,108, 41, 32, - 101,110,100, 10, 32, 32,114,101,116,117,114,110, 32, 95, 68, - 101, 99,108, 97,114, 97,116,105,111,110,123, 10, 32, 32, 32, - 110, 97,109,101, 32, 61, 32,118, 44, 10, 32, 32, 32,116,121, - 112,101, 32, 61, 32,116,112, 44, 10, 32, 32, 32,109,111,100, - 32, 61, 32,109,100, 44, 10, 32, 32, 32,105,115, 95,112, 97, - 114, 97,109,101,116,101,114, 32, 61, 32,105,115, 95,112, 97, - 114, 97,109,101,116,101,114, 44, 10, 32, 32, 32,107,105,110, - 100, 32, 61, 32,107,105,110,100, 10, 32, 32,125, 10, 32,101, - 110,100, 10, 10,101,110,100,32 - }; - tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua embedded: src/bin/lua/declaration.lua"); + #include "declaration_lua.h" + tolua_dobuffer(tolua_S,(char*)lua_declaration_lua,sizeof(lua_declaration_lua),"tolua embedded: src/bin/lua/declaration.lua"); lua_settop(tolua_S, top); } /* end of embedded lua code */ @@ -5972,960 +3043,8 @@ TOLUA_API int tolua_tolua_open (lua_State* tolua_S) { /* begin embedded lua code */ int top = lua_gettop(tolua_S); - static unsigned char B[] = { - 45, 45, 32,116,111,108,117, 97, 58, 32,102,117,110, 99,116, - 105,111,110, 32, 99,108, 97,115,115, 10, 45, 45, 32, 87,114, - 105,116,116,101,110, 32, 98,121, 32, 87, 97,108,100,101,109, - 97,114, 32, 67,101,108,101,115, 10, 45, 45, 32, 84,101, 67, - 71,114, 97,102, 47, 80, 85, 67, 45, 82,105,111, 10, 45, 45, - 32, 74,117,108, 32, 49, 57, 57, 56, 10, 45, 45, 32, 36, 73, - 100, 58, 32, 36, 10, 10, 45, 45, 32, 84,104,105,115, 32, 99, - 111,100,101, 32,105,115, 32,102,114,101,101, 32,115,111,102, - 116,119, 97,114,101, 59, 32,121,111,117, 32, 99, 97,110, 32, - 114,101,100,105,115,116,114,105, 98,117,116,101, 32,105,116, - 32, 97,110,100, 47,111,114, 32,109,111,100,105,102,121, 32, - 105,116, 46, 10, 45, 45, 32, 84,104,101, 32,115,111,102,116, - 119, 97,114,101, 32,112,114,111,118,105,100,101,100, 32,104, - 101,114,101,117,110,100,101,114, 32,105,115, 32,111,110, 32, - 97,110, 32, 34, 97,115, 32,105,115, 34, 32, 98, 97,115,105, - 115, 44, 32, 97,110,100, 10, 45, 45, 32,116,104,101, 32, 97, - 117,116,104,111,114, 32,104, 97,115, 32,110,111, 32,111, 98, - 108,105,103, 97,116,105,111,110, 32,116,111, 32,112,114,111, - 118,105,100,101, 32,109, 97,105,110,116,101,110, 97,110, 99, - 101, 44, 32,115,117,112,112,111,114,116, 44, 32,117,112,100, - 97,116,101,115, 44, 10, 45, 45, 32,101,110,104, 97,110, 99, - 101,109,101,110,116,115, 44, 32,111,114, 32,109,111,100,105, - 102,105, 99, 97,116,105,111,110,115, 46, 10, 10, 10, 10, 45, - 45, 32, 70,117,110, 99,116,105,111,110, 32, 99,108, 97,115, - 115, 10, 45, 45, 32, 82,101,112,114,101,115,101,110,116,115, - 32, 97, 32,102,117,110, 99,116,105,111,110, 32,111,114, 32, - 97, 32, 99,108, 97,115,115, 32,109,101,116,104,111,100, 46, - 10, 45, 45, 32, 84,104,101, 32,102,111,108,108,111,119,105, - 110,103, 32,102,105,101,108,100,115, 32, 97,114,101, 32,115, - 116,111,114,101,100, 58, 10, 45, 45, 32, 32,109,111,100, 32, - 32, 61, 32,116,121,112,101, 32,109,111,100,105,102,105,101, - 114,115, 10, 45, 45, 32, 32,116,121,112,101, 32, 61, 32,116, - 121,112,101, 10, 45, 45, 32, 32,112,116,114, 32, 32, 61, 32, - 34, 42, 34, 32,111,114, 32, 34, 38, 34, 44, 32,105,102, 32, - 114,101,112,114,101,115,101,110,116,105,110,103, 32, 97, 32, - 112,111,105,110,116,101,114, 32,111,114, 32, 97, 32,114,101, - 102,101,114,101,110, 99,101, 10, 45, 45, 32, 32,110, 97,109, - 101, 32, 61, 32,110, 97,109,101, 10, 45, 45, 32, 32,108,110, - 97,109,101, 32, 61, 32,108,117, 97, 32,110, 97,109,101, 10, - 45, 45, 32, 32, 97,114,103,115, 32, 32, 61, 32,108,105,115, - 116, 32,111,102, 32, 97,114,103,117,109,101,110,116, 32,100, - 101, 99,108, 97,114, 97,116,105,111,110,115, 10, 45, 45, 32, - 32, 99,111,110,115,116, 32, 61, 32,105,102, 32,105,116, 32, - 105,115, 32, 97, 32,109,101,116,104,111,100, 32,114,101, 99, - 101,105,118,105,110,103, 32, 97, 32, 99,111,110,115,116, 32, - 34,116,104,105,115, 34, 46, 10, 99,108, 97,115,115, 70,117, - 110, 99,116,105,111,110, 32, 61, 32,123, 10, 32,109,111,100, - 32, 61, 32, 39, 39, 44, 10, 32,116,121,112,101, 32, 61, 32, - 39, 39, 44, 10, 32,112,116,114, 32, 61, 32, 39, 39, 44, 10, - 32,110, 97,109,101, 32, 61, 32, 39, 39, 44, 10, 32, 97,114, - 103,115, 32, 61, 32,123,110, 61, 48,125, 44, 10, 32, 99,111, - 110,115,116, 32, 61, 32, 39, 39, 44, 10,125, 10, 99,108, 97, - 115,115, 70,117,110, 99,116,105,111,110, 46, 95, 95,105,110, - 100,101,120, 32, 61, 32, 99,108, 97,115,115, 70,117,110, 99, - 116,105,111,110, 10,115,101,116,109,101,116, 97,116, 97, 98, - 108,101, 40, 99,108, 97,115,115, 70,117,110, 99,116,105,111, - 110, 44, 99,108, 97,115,115, 70,101, 97,116,117,114,101, 41, - 10, 10, 45, 45, 32,100,101, 99,108, 97,114,101, 32,116, 97, - 103,115, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97, - 115,115, 70,117,110, 99,116,105,111,110, 58,100,101, 99,108, - 116,121,112,101, 32, 40, 41, 10, 32,115,101,108,102, 46,116, - 121,112,101, 32, 61, 32,116,121,112,101,118, 97,114, 40,115, - 101,108,102, 46,116,121,112,101, 41, 10, 32,105,102, 32,115, - 116,114,102,105,110,100, 40,115,101,108,102, 46,109,111,100, - 44, 39, 99,111,110,115,116, 39, 41, 32,116,104,101,110, 10, - 9, 32,115,101,108,102, 46,116,121,112,101, 32, 61, 32, 39, - 99,111,110,115,116, 32, 39, 46, 46,115,101,108,102, 46,116, - 121,112,101, 10, 9, 9,115,101,108,102, 46,109,111,100, 32, - 61, 32,103,115,117, 98, 40,115,101,108,102, 46,109,111,100, - 44, 39, 99,111,110,115,116, 39, 44, 39, 39, 41, 10, 9,101, - 110,100, 10, 32,108,111, 99, 97,108, 32,105, 61, 49, 10, 32, - 119,104,105,108,101, 32,115,101,108,102, 46, 97,114,103,115, - 91,105, 93, 32,100,111, 10, 32, 32,115,101,108,102, 46, 97, - 114,103,115, 91,105, 93, 58,100,101, 99,108,116,121,112,101, - 40, 41, 10, 32, 32,105, 32, 61, 32,105, 43, 49, 10, 32,101, - 110,100, 10,101,110,100, 10, 10, 10, 45, 45, 32, 87,114,105, - 116,101, 32, 98,105,110,100,105,110,103, 32,102,117,110, 99, - 116,105,111,110, 10, 45, 45, 32, 79,117,116,112,117,116,115, - 32, 67, 47, 67, 43, 43, 32, 98,105,110,100,105,110,103, 32, - 102,117,110, 99,116,105,111,110, 46, 10,102,117,110, 99,116, - 105,111,110, 32, 99,108, 97,115,115, 70,117,110, 99,116,105, - 111,110, 58,115,117,112, 99,111,100,101, 32, 40,108,111, 99, - 97,108, 95, 99,111,110,115,116,114,117, 99,116,111,114, 41, - 10, 10, 32,108,111, 99, 97,108, 32,111,118,101,114,108,111, - 97,100, 32, 61, 32,115,116,114,115,117, 98, 40,115,101,108, - 102, 46, 99,110, 97,109,101, 44, 45, 50, 44, 45, 49, 41, 32, - 45, 32, 49, 32, 32, 45, 45, 32,105,110,100,105, 99, 97,116, - 101, 32,111,118,101,114,108,111, 97,100,101,100, 32,102,117, - 110, 99, 10, 32,108,111, 99, 97,108, 32,110,114,101,116, 32, - 61, 32, 48, 32, 32, 32, 32, 32, 32, 45, 45, 32,110,117,109, - 98,101,114, 32,111,102, 32,114,101,116,117,114,110,101,100, - 32,118, 97,108,117,101,115, 10, 32,108,111, 99, 97,108, 32, - 99,108, 97,115,115, 32, 61, 32,115,101,108,102, 58,105,110, - 99,108, 97,115,115, 40, 41, 10, 32,108,111, 99, 97,108, 32, - 95, 44, 95, 44,115,116, 97,116,105, 99, 32, 61, 32,115,116, - 114,102,105,110,100, 40,115,101,108,102, 46,109,111,100, 44, - 39, 94, 37,115, 42, 40,115,116, 97,116,105, 99, 41, 39, 41, - 10, 32,105,102, 32, 99,108, 97,115,115, 32,116,104,101,110, - 10, 10, 32, 9,105,102, 32,115,101,108,102, 46,110, 97,109, - 101, 32, 61, 61, 32, 39,110,101,119, 39, 32, 97,110,100, 32, - 115,101,108,102, 46,112, 97,114,101,110,116, 46,102,108, 97, - 103,115, 46,112,117,114,101, 95,118,105,114,116,117, 97,108, - 32,116,104,101,110, 10, 32, 9, 9, 45, 45, 32,110,111, 32, - 99,111,110,115,116,114,117, 99,116,111,114, 32,102,111,114, - 32, 99,108, 97,115,115,101,115, 32,119,105,116,104, 32,112, - 117,114,101, 32,118,105,114,116,117, 97,108, 32,109,101,116, - 104,111,100,115, 10, 32, 9, 9,114,101,116,117,114,110, 10, - 32, 9,101,110,100, 10, 10, 32, 9,105,102, 32,108,111, 99, - 97,108, 95, 99,111,110,115,116,114,117, 99,116,111,114, 32, - 116,104,101,110, 10, 9, 9,111,117,116,112,117,116, 40, 34, - 47, 42, 32,109,101,116,104,111,100, 58, 32,110,101,119, 95, - 108,111, 99, 97,108, 32,111,102, 32, 99,108, 97,115,115, 32, - 34, 44, 99,108, 97,115,115, 44, 34, 32, 42, 47, 34, 41, 10, - 9,101,108,115,101, 10, 9, 9,111,117,116,112,117,116, 40, - 34, 47, 42, 32,109,101,116,104,111,100, 58, 34, 44,115,101, - 108,102, 46,110, 97,109,101, 44, 34, 32,111,102, 32, 99,108, - 97,115,115, 32, 34, 44, 99,108, 97,115,115, 44, 34, 32, 42, - 47, 34, 41, 10, 9,101,110,100, 10, 32,101,108,115,101, 10, - 32, 32,111,117,116,112,117,116, 40, 34, 47, 42, 32,102,117, - 110, 99,116,105,111,110, 58, 34, 44,115,101,108,102, 46,110, - 97,109,101, 44, 34, 32, 42, 47, 34, 41, 10, 32,101,110,100, - 10, 10, 32,105,102, 32,108,111, 99, 97,108, 95, 99,111,110, - 115,116,114,117, 99,116,111,114, 32,116,104,101,110, 10, 32, - 32,111,117,116,112,117,116, 40, 34, 35,105,102,110,100,101, - 102, 32, 84, 79, 76, 85, 65, 95, 68, 73, 83, 65, 66, 76, 69, - 95, 34, 46, 46,115,101,108,102, 46, 99,110, 97,109,101, 46, - 46, 34, 95,108,111, 99, 97,108, 34, 41, 10, 32, 32,111,117, - 116,112,117,116, 40, 34, 92,110,115,116, 97,116,105, 99, 32, - 105,110,116, 34, 44,115,101,108,102, 46, 99,110, 97,109,101, - 46, 46, 34, 95,108,111, 99, 97,108, 34, 44, 34, 40,108,117, - 97, 95, 83,116, 97,116,101, 42, 32,116,111,108,117, 97, 95, - 83, 41, 34, 41, 10, 32,101,108,115,101, 10, 32, 32,111,117, - 116,112,117,116, 40, 34, 35,105,102,110,100,101,102, 32, 84, - 79, 76, 85, 65, 95, 68, 73, 83, 65, 66, 76, 69, 95, 34, 46, - 46,115,101,108,102, 46, 99,110, 97,109,101, 41, 10, 32, 32, - 111,117,116,112,117,116, 40, 34, 92,110,115,116, 97,116,105, - 99, 32,105,110,116, 34, 44,115,101,108,102, 46, 99,110, 97, - 109,101, 44, 34, 40,108,117, 97, 95, 83,116, 97,116,101, 42, - 32,116,111,108,117, 97, 95, 83, 41, 34, 41, 10, 32,101,110, - 100, 10, 32,111,117,116,112,117,116, 40, 34,123, 34, 41, 10, - 10, 32, 45, 45, 32, 99,104,101, 99,107, 32,116,121,112,101, - 115, 10, 9,105,102, 32,111,118,101,114,108,111, 97,100, 32, - 60, 32, 48, 32,116,104,101,110, 10, 9, 32,111,117,116,112, - 117,116, 40, 39, 35,105,102,110,100,101,102, 32, 84, 79, 76, - 85, 65, 95, 82, 69, 76, 69, 65, 83, 69, 92,110, 39, 41, 10, - 9,101,110,100, 10, 9,111,117,116,112,117,116, 40, 39, 32, - 116,111,108,117, 97, 95, 69,114,114,111,114, 32,116,111,108, - 117, 97, 95,101,114,114, 59, 39, 41, 10, 32,111,117,116,112, - 117,116, 40, 39, 32,105,102, 32, 40, 92,110, 39, 41, 10, 32, - 45, 45, 32, 99,104,101, 99,107, 32,115,101,108,102, 10, 32, - 108,111, 99, 97,108, 32,110, 97,114,103, 10, 32,105,102, 32, - 99,108, 97,115,115, 32,116,104,101,110, 32,110, 97,114,103, - 61, 50, 32,101,108,115,101, 32,110, 97,114,103, 61, 49, 32, - 101,110,100, 10, 32,105,102, 32, 99,108, 97,115,115, 32,116, - 104,101,110, 10, 9, 9,108,111, 99, 97,108, 32,102,117,110, - 99, 32, 61, 32,103,101,116, 95,105,115, 95,102,117,110, 99, - 116,105,111,110, 40,115,101,108,102, 46,112, 97,114,101,110, - 116, 46,116,121,112,101, 41, 10, 9, 9,108,111, 99, 97,108, - 32,116,121,112,101, 32, 61, 32,115,101,108,102, 46,112, 97, - 114,101,110,116, 46,116,121,112,101, 10, 9, 9,105,102, 32, - 115,101,108,102, 46,110, 97,109,101, 61, 61, 39,110,101,119, - 39, 32,111,114, 32,115,116, 97,116,105, 99,126, 61,110,105, - 108, 32,116,104,101,110, 10, 9, 9, 9,102,117,110, 99, 32, - 61, 32, 39,116,111,108,117, 97, 95,105,115,117,115,101,114, - 116, 97, 98,108,101, 39, 10, 9, 9, 9,116,121,112,101, 32, - 61, 32,115,101,108,102, 46,112, 97,114,101,110,116, 46,116, - 121,112,101, 10, 9, 9,101,110,100, 10, 9, 9,105,102, 32, - 115,101,108,102, 46, 99,111,110,115,116, 32,126, 61, 32, 39, - 39, 32,116,104,101,110, 10, 9, 9, 9,116,121,112,101, 32, - 61, 32, 34, 99,111,110,115,116, 32, 34, 46, 46,116,121,112, - 101, 10, 9, 9,101,110,100, 10, 9, 9,111,117,116,112,117, - 116, 40, 39, 32, 32, 32, 32, 32, 33, 39, 46, 46,102,117,110, - 99, 46, 46, 39, 40,116,111,108,117, 97, 95, 83, 44, 49, 44, - 34, 39, 46, 46,116,121,112,101, 46, 46, 39, 34, 44, 48, 44, - 38,116,111,108,117, 97, 95,101,114,114, 41, 32,124,124, 92, - 110, 39, 41, 10, 32,101,110,100, 10, 32, 45, 45, 32, 99,104, - 101, 99,107, 32, 97,114,103,115, 10, 32,105,102, 32,115,101, - 108,102, 46, 97,114,103,115, 91, 49, 93, 46,116,121,112,101, - 32,126, 61, 32, 39,118,111,105,100, 39, 32,116,104,101,110, - 10, 32, 32,108,111, 99, 97,108, 32,105, 61, 49, 10, 32, 32, - 119,104,105,108,101, 32,115,101,108,102, 46, 97,114,103,115, - 91,105, 93, 32,100,111, 10, 32, 32, 32,108,111, 99, 97,108, - 32, 98,116,121,112,101, 32, 61, 32,105,115, 98, 97,115,105, - 99, 40,115,101,108,102, 46, 97,114,103,115, 91,105, 93, 46, - 116,121,112,101, 41, 10, 32, 32, 32,105,102, 32, 98,116,121, - 112,101, 32,126, 61, 32, 39,118, 97,108,117,101, 39, 32, 97, - 110,100, 32, 98,116,121,112,101, 32,126, 61, 32, 39,115,116, - 97,116,101, 39, 32,116,104,101,110, 10, 32, 32, 32, 32,111, - 117,116,112,117,116, 40, 39, 32, 32, 32, 32, 32, 39, 46, 46, - 115,101,108,102, 46, 97,114,103,115, 91,105, 93, 58,111,117, - 116, 99,104,101, 99,107,116,121,112,101, 40,110, 97,114,103, - 41, 46, 46, 39, 32,124,124, 92,110, 39, 41, 10, 32, 32, 32, - 101,110,100, 10, 32, 32, 32,105,102, 32, 98,116,121,112,101, - 32,126, 61, 32, 39,115,116, 97,116,101, 39, 32,116,104,101, - 110, 10, 9, 32, 32, 32,110, 97,114,103, 32, 61, 32,110, 97, - 114,103, 43, 49, 10, 32, 32, 32,101,110,100, 10, 32, 32, 32, - 105, 32, 61, 32,105, 43, 49, 10, 32, 32,101,110,100, 10, 32, - 101,110,100, 10, 32, 45, 45, 32, 99,104,101, 99,107, 32,101, - 110,100, 32,111,102, 32,108,105,115,116, 10, 32,111,117,116, - 112,117,116, 40, 39, 32, 32, 32, 32, 32, 33,116,111,108,117, - 97, 95,105,115,110,111,111, 98,106, 40,116,111,108,117, 97, - 95, 83, 44, 39, 46, 46,110, 97,114,103, 46, 46, 39, 44, 38, - 116,111,108,117, 97, 95,101,114,114, 41, 92,110, 32, 41, 39, - 41, 10, 9,111,117,116,112,117,116, 40, 39, 32, 32,103,111, - 116,111, 32,116,111,108,117, 97, 95,108,101,114,114,111,114, - 59, 39, 41, 10, 10, 32,111,117,116,112,117,116, 40, 39, 32, - 101,108,115,101, 92,110, 39, 41, 10, 9,105,102, 32,111,118, - 101,114,108,111, 97,100, 32, 60, 32, 48, 32,116,104,101,110, - 10, 9, 32,111,117,116,112,117,116, 40, 39, 35,101,110,100, - 105,102, 92,110, 39, 41, 10, 9,101,110,100, 10, 9,111,117, - 116,112,117,116, 40, 39, 32,123, 39, 41, 10, 10, 32, 45, 45, - 32,100,101, 99,108, 97,114,101, 32,115,101,108,102, 44, 32, - 105,102, 32,116,104,101, 32, 99, 97,115,101, 10, 32,108,111, - 99, 97,108, 32,110, 97,114,103, 10, 32,105,102, 32, 99,108, - 97,115,115, 32,116,104,101,110, 32,110, 97,114,103, 61, 50, - 32,101,108,115,101, 32,110, 97,114,103, 61, 49, 32,101,110, - 100, 10, 32,105,102, 32, 99,108, 97,115,115, 32, 97,110,100, - 32,115,101,108,102, 46,110, 97,109,101,126, 61, 39,110,101, - 119, 39, 32, 97,110,100, 32,115,116, 97,116,105, 99, 61, 61, - 110,105,108, 32,116,104,101,110, 10, 32, 32,111,117,116,112, - 117,116, 40, 39, 32, 39, 44,115,101,108,102, 46, 99,111,110, - 115,116, 44,115,101,108,102, 46,112, 97,114,101,110,116, 46, - 116,121,112,101, 44, 39, 42, 39, 44, 39,115,101,108,102, 32, - 61, 32, 39, 41, 10, 32, 32,111,117,116,112,117,116, 40, 39, - 40, 39, 44,115,101,108,102, 46, 99,111,110,115,116, 44,115, - 101,108,102, 46,112, 97,114,101,110,116, 46,116,121,112,101, - 44, 39, 42, 41, 32, 39, 41, 10, 32, 32,108,111, 99, 97,108, - 32,116,111, 95,102,117,110, 99, 32, 61, 32,103,101,116, 95, - 116,111, 95,102,117,110, 99,116,105,111,110, 40,115,101,108, - 102, 46,112, 97,114,101,110,116, 46,116,121,112,101, 41, 10, - 32, 32,111,117,116,112,117,116, 40,116,111, 95,102,117,110, - 99, 44, 39, 40,116,111,108,117, 97, 95, 83, 44, 49, 44, 48, - 41, 59, 39, 41, 10, 32,101,108,115,101,105,102, 32,115,116, - 97,116,105, 99, 32,116,104,101,110, 10, 32, 32, 95, 44, 95, - 44,115,101,108,102, 46,109,111,100, 32, 61, 32,115,116,114, - 102,105,110,100, 40,115,101,108,102, 46,109,111,100, 44, 39, - 94, 37,115, 42,115,116, 97,116,105, 99, 37,115, 37,115, 42, - 40, 46, 42, 41, 39, 41, 10, 32,101,110,100, 10, 32, 45, 45, - 32,100,101, 99,108, 97,114,101, 32,112, 97,114, 97,109,101, - 116,101,114,115, 10, 32,105,102, 32,115,101,108,102, 46, 97, - 114,103,115, 91, 49, 93, 46,116,121,112,101, 32,126, 61, 32, - 39,118,111,105,100, 39, 32,116,104,101,110, 10, 32, 32,108, - 111, 99, 97,108, 32,105, 61, 49, 10, 32, 32,119,104,105,108, - 101, 32,115,101,108,102, 46, 97,114,103,115, 91,105, 93, 32, - 100,111, 10, 32, 32, 32,115,101,108,102, 46, 97,114,103,115, - 91,105, 93, 58,100,101, 99,108, 97,114,101, 40,110, 97,114, - 103, 41, 10, 32, 32, 32,105,102, 32,105,115, 98, 97,115,105, - 99, 40,115,101,108,102, 46, 97,114,103,115, 91,105, 93, 46, - 116,121,112,101, 41, 32,126, 61, 32, 34,115,116, 97,116,101, - 34, 32,116,104,101,110, 10, 9, 32, 32, 32,110, 97,114,103, - 32, 61, 32,110, 97,114,103, 43, 49, 10, 32, 32, 32,101,110, - 100, 10, 32, 32, 32,105, 32, 61, 32,105, 43, 49, 10, 32, 32, - 101,110,100, 10, 32,101,110,100, 10, 10, 32, 45, 45, 32, 99, - 104,101, 99,107, 32,115,101,108,102, 10, 32,105,102, 32, 99, - 108, 97,115,115, 32, 97,110,100, 32,115,101,108,102, 46,110, - 97,109,101,126, 61, 39,110,101,119, 39, 32, 97,110,100, 32, - 115,116, 97,116,105, 99, 61, 61,110,105,108, 32,116,104,101, - 110, 10, 9, 32,111,117,116,112,117,116, 40, 39, 35,105,102, - 110,100,101,102, 32, 84, 79, 76, 85, 65, 95, 82, 69, 76, 69, - 65, 83, 69, 92,110, 39, 41, 10, 9, 32,111,117,116,112,117, - 116, 40, 39, 32, 32,105,102, 32, 40, 33,115,101,108,102, 41, - 32,116,111,108,117, 97, 95,101,114,114,111,114, 40,116,111, - 108,117, 97, 95, 83, 44, 34, 39, 46, 46,111,117,116,112,117, - 116, 95,101,114,114,111,114, 95,104,111,111,107, 40, 34,105, - 110,118, 97,108,105,100, 32, 92, 39,115,101,108,102, 92, 39, - 32,105,110, 32,102,117,110, 99,116,105,111,110, 32, 92, 39, - 37,115, 92, 39, 34, 44, 32,115,101,108,102, 46,110, 97,109, - 101, 41, 46, 46, 39, 34, 44, 32, 78, 85, 76, 76, 41, 59, 39, - 41, 59, 10, 9, 32,111,117,116,112,117,116, 40, 39, 35,101, - 110,100,105,102, 92,110, 39, 41, 10, 32,101,110,100, 10, 10, - 32, 45, 45, 32,103,101,116, 32, 97,114,114, 97,121, 32,101, - 108,101,109,101,110,116, 32,118, 97,108,117,101,115, 10, 32, - 105,102, 32, 99,108, 97,115,115, 32,116,104,101,110, 32,110, - 97,114,103, 61, 50, 32,101,108,115,101, 32,110, 97,114,103, - 61, 49, 32,101,110,100, 10, 32,105,102, 32,115,101,108,102, - 46, 97,114,103,115, 91, 49, 93, 46,116,121,112,101, 32,126, - 61, 32, 39,118,111,105,100, 39, 32,116,104,101,110, 10, 32, - 32,108,111, 99, 97,108, 32,105, 61, 49, 10, 32, 32,119,104, - 105,108,101, 32,115,101,108,102, 46, 97,114,103,115, 91,105, - 93, 32,100,111, 10, 32, 32, 32,115,101,108,102, 46, 97,114, - 103,115, 91,105, 93, 58,103,101,116, 97,114,114, 97,121, 40, - 110, 97,114,103, 41, 10, 32, 32, 32,110, 97,114,103, 32, 61, - 32,110, 97,114,103, 43, 49, 10, 32, 32, 32,105, 32, 61, 32, - 105, 43, 49, 10, 32, 32,101,110,100, 10, 32,101,110,100, 10, - 10, 32,112,114,101, 95, 99, 97,108,108, 95,104,111,111,107, - 40,115,101,108,102, 41, 10, 10, 32,108,111, 99, 97,108, 32, - 111,117,116, 32, 61, 32,115,116,114,105,110,103, 46,102,105, - 110,100, 40,115,101,108,102, 46,109,111,100, 44, 32, 34,116, - 111,108,117, 97, 95,111,117,116,115,105,100,101, 34, 41, 10, - 32, 45, 45, 32, 99, 97,108,108, 32,102,117,110, 99,116,105, - 111,110, 10, 32,105,102, 32, 99,108, 97,115,115, 32, 97,110, - 100, 32,115,101,108,102, 46,110, 97,109,101, 61, 61, 39,100, - 101,108,101,116,101, 39, 32,116,104,101,110, 10, 32, 32,111, - 117,116,112,117,116, 40, 39, 32, 32, 77,116,111,108,117, 97, - 95,100,101,108,101,116,101, 40,115,101,108,102, 41, 59, 39, - 41, 10, 32,101,108,115,101,105,102, 32, 99,108, 97,115,115, - 32, 97,110,100, 32,115,101,108,102, 46,110, 97,109,101, 32, - 61, 61, 32, 39,111,112,101,114, 97,116,111,114, 38, 91, 93, - 39, 32,116,104,101,110, 10, 32, 32,105,102, 32,102,108, 97, - 103,115, 91, 39, 49, 39, 93, 32,116,104,101,110, 32, 45, 45, - 32,102,111,114, 32, 99,111,109,112, 97,116,105, 98,105,108, - 105,116,121, 32,119,105,116,104, 32,116,111,108,117, 97, 53, - 32, 63, 10, 9,111,117,116,112,117,116, 40, 39, 32, 32,115, - 101,108,102, 45, 62,111,112,101,114, 97,116,111,114, 91, 93, - 40, 39, 44,115,101,108,102, 46, 97,114,103,115, 91, 49, 93, - 46,110, 97,109,101, 44, 39, 45, 49, 41, 32, 61, 32, 39, 44, - 115,101,108,102, 46, 97,114,103,115, 91, 50, 93, 46,110, 97, - 109,101, 44, 39, 59, 39, 41, 10, 32, 32,101,108,115,101, 10, - 32, 32, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32,115, - 101,108,102, 45, 62,111,112,101,114, 97,116,111,114, 91, 93, - 40, 39, 44,115,101,108,102, 46, 97,114,103,115, 91, 49, 93, - 46,110, 97,109,101, 44, 39, 41, 32, 61, 32, 39, 44,115,101, - 108,102, 46, 97,114,103,115, 91, 50, 93, 46,110, 97,109,101, - 44, 39, 59, 39, 41, 10, 32, 32,101,110,100, 10, 32,101,108, - 115,101, 10, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, - 123, 39, 41, 10, 32, 32,105,102, 32,115,101,108,102, 46,116, - 121,112,101, 32,126, 61, 32, 39, 39, 32, 97,110,100, 32,115, - 101,108,102, 46,116,121,112,101, 32,126, 61, 32, 39,118,111, - 105,100, 39, 32,116,104,101,110, 10, 32, 32, 32,111,117,116, - 112,117,116, 40, 39, 32, 32, 39, 44,115,101,108,102, 46,109, - 111,100, 44,115,101,108,102, 46,116,121,112,101, 44,115,101, - 108,102, 46,112,116,114, 44, 39,116,111,108,117, 97, 95,114, - 101,116, 32, 61, 32, 39, 41, 10, 32, 32, 32,111,117,116,112, - 117,116, 40, 39, 40, 39, 44,115,101,108,102, 46,109,111,100, - 44,115,101,108,102, 46,116,121,112,101, 44,115,101,108,102, - 46,112,116,114, 44, 39, 41, 32, 39, 41, 10, 32, 32,101,108, - 115,101, 10, 32, 32, 32,111,117,116,112,117,116, 40, 39, 32, - 32, 39, 41, 10, 32, 32,101,110,100, 10, 32, 32,105,102, 32, - 99,108, 97,115,115, 32, 97,110,100, 32,115,101,108,102, 46, - 110, 97,109,101, 61, 61, 39,110,101,119, 39, 32,116,104,101, - 110, 10, 32, 32, 32,111,117,116,112,117,116, 40, 39, 77,116, - 111,108,117, 97, 95,110,101,119, 40, 40, 39, 44,115,101,108, - 102, 46,116,121,112,101, 44, 39, 41, 40, 39, 41, 10, 32, 32, - 101,108,115,101,105,102, 32, 99,108, 97,115,115, 32, 97,110, - 100, 32,115,116, 97,116,105, 99, 32,116,104,101,110, 10, 9, - 105,102, 32,111,117,116, 32,116,104,101,110, 10, 9, 9,111, - 117,116,112,117,116, 40,115,101,108,102, 46,110, 97,109,101, - 44, 39, 40, 39, 41, 10, 9,101,108,115,101, 10, 9, 9,111, - 117,116,112,117,116, 40, 99,108, 97,115,115, 46, 46, 39, 58, - 58, 39, 46, 46,115,101,108,102, 46,110, 97,109,101, 44, 39, - 40, 39, 41, 10, 9,101,110,100, 10, 32, 32,101,108,115,101, - 105,102, 32, 99,108, 97,115,115, 32,116,104,101,110, 10, 9, - 105,102, 32,111,117,116, 32,116,104,101,110, 10, 9, 9,111, - 117,116,112,117,116, 40,115,101,108,102, 46,110, 97,109,101, - 44, 39, 40, 39, 41, 10, 9,101,108,115,101, 10, 9, 32, 32, - 105,102, 32,115,101,108,102, 46, 99, 97,115,116, 95,111,112, - 101,114, 97,116,111,114, 32,116,104,101,110, 10, 9, 32, 32, - 9, 45, 45,111,117,116,112,117,116, 40, 39,115,116, 97,116, - 105, 99, 95, 99, 97,115,116, 60, 39, 44,115,101,108,102, 46, - 109,111,100, 44,115,101,108,102, 46,116,121,112,101, 44,115, - 101,108,102, 46,112,116,114, 44, 39, 32, 62, 40, 42,115,101, - 108,102, 39, 41, 10, 9, 9,111,117,116,112,117,116, 40, 39, - 115,101,108,102, 45, 62,111,112,101,114, 97,116,111,114, 32, - 39, 44,115,101,108,102, 46,109,111,100, 44,115,101,108,102, - 46,116,121,112,101, 44, 39, 40, 39, 41, 10, 9, 32, 32,101, - 108,115,101, 10, 9, 9,111,117,116,112,117,116, 40, 39,115, - 101,108,102, 45, 62, 39, 46, 46,115,101,108,102, 46,110, 97, - 109,101, 44, 39, 40, 39, 41, 10, 9, 32, 32,101,110,100, 10, - 9,101,110,100, 10, 32, 32,101,108,115,101, 10, 32, 32, 32, - 111,117,116,112,117,116, 40,115,101,108,102, 46,110, 97,109, - 101, 44, 39, 40, 39, 41, 10, 32, 32,101,110,100, 10, 10, 32, - 32,105,102, 32,111,117,116, 32, 97,110,100, 32,110,111,116, - 32,115,116, 97,116,105, 99, 32,116,104,101,110, 10, 32, 32, - 9,111,117,116,112,117,116, 40, 39,115,101,108,102, 39, 41, - 10, 9,105,102, 32,115,101,108,102, 46, 97,114,103,115, 91, - 49, 93, 32, 97,110,100, 32,115,101,108,102, 46, 97,114,103, - 115, 91, 49, 93, 46,110, 97,109,101, 32,126, 61, 32, 39, 39, - 32,116,104,101,110, 10, 9, 9,111,117,116,112,117,116, 40, - 39, 44, 39, 41, 10, 9,101,110,100, 10, 32, 32,101,110,100, - 10, 32, 32, 45, 45, 32,119,114,105,116,101, 32,112, 97,114, - 97,109,101,116,101,114,115, 10, 32, 32,108,111, 99, 97,108, - 32,105, 61, 49, 10, 32, 32,119,104,105,108,101, 32,115,101, - 108,102, 46, 97,114,103,115, 91,105, 93, 32,100,111, 10, 32, - 32, 32,115,101,108,102, 46, 97,114,103,115, 91,105, 93, 58, - 112, 97,115,115,112, 97,114, 40, 41, 10, 32, 32, 32,105, 32, - 61, 32,105, 43, 49, 10, 32, 32, 32,105,102, 32,115,101,108, - 102, 46, 97,114,103,115, 91,105, 93, 32,116,104,101,110, 10, - 32, 32, 32, 32,111,117,116,112,117,116, 40, 39, 44, 39, 41, - 10, 32, 32, 32,101,110,100, 10, 32, 32,101,110,100, 10, 10, - 32, 32,105,102, 32, 99,108, 97,115,115, 32, 97,110,100, 32, - 115,101,108,102, 46,110, 97,109,101, 32, 61, 61, 32, 39,111, - 112,101,114, 97,116,111,114, 91, 93, 39, 32, 97,110,100, 32, - 102,108, 97,103,115, 91, 39, 49, 39, 93, 32,116,104,101,110, - 10, 9,111,117,116,112,117,116, 40, 39, 45, 49, 41, 59, 39, - 41, 10, 32, 32,101,108,115,101, 10, 9,105,102, 32, 99,108, - 97,115,115, 32, 97,110,100, 32,115,101,108,102, 46,110, 97, - 109,101, 61, 61, 39,110,101,119, 39, 32,116,104,101,110, 10, - 9, 9,111,117,116,112,117,116, 40, 39, 41, 41, 59, 39, 41, - 32, 45, 45, 32, 99,108,111,115,101, 32, 77,116,111,108,117, - 97, 95,110,101,119, 40, 10, 9,101,108,115,101, 10, 9, 9, - 111,117,116,112,117,116, 40, 39, 41, 59, 39, 41, 10, 9,101, - 110,100, 10, 32, 32,101,110,100, 10, 10, 32, 32, 45, 45, 32, - 114,101,116,117,114,110, 32,118, 97,108,117,101,115, 10, 32, - 32,105,102, 32,115,101,108,102, 46,116,121,112,101, 32,126, - 61, 32, 39, 39, 32, 97,110,100, 32,115,101,108,102, 46,116, - 121,112,101, 32,126, 61, 32, 39,118,111,105,100, 39, 32,116, - 104,101,110, 10, 32, 32, 32,110,114,101,116, 32, 61, 32,110, - 114,101,116, 32, 43, 32, 49, 10, 32, 32, 32,108,111, 99, 97, - 108, 32,116, 44, 99,116, 32, 61, 32,105,115, 98, 97,115,105, - 99, 40,115,101,108,102, 46,116,121,112,101, 41, 10, 32, 32, - 32,105,102, 32,116, 32, 97,110,100, 32,115,101,108,102, 46, - 110, 97,109,101, 32,126, 61, 32, 34,110,101,119, 34, 32,116, - 104,101,110, 10, 32, 32, 32, 9,105,102, 32,115,101,108,102, - 46, 99, 97,115,116, 95,111,112,101,114, 97,116,111,114, 32, - 97,110,100, 32, 95, 98, 97,115,105, 99, 95,114, 97,119, 95, - 112,117,115,104, 91,116, 93, 32,116,104,101,110, 10, 9, 9, - 111,117,116,112,117,116, 40, 39, 32, 32, 32, 39, 44, 95, 98, - 97,115,105, 99, 95,114, 97,119, 95,112,117,115,104, 91,116, - 93, 44, 39, 40,116,111,108,117, 97, 95, 83, 44, 40, 39, 44, - 99,116, 44, 39, 41,116,111,108,117, 97, 95,114,101,116, 41, - 59, 39, 41, 10, 32, 32, 32, 9,101,108,115,101, 10, 9, 32, - 32, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32,116, - 111,108,117, 97, 95,112,117,115,104, 39, 46, 46,116, 46, 46, - 39, 40,116,111,108,117, 97, 95, 83, 44, 40, 39, 44, 99,116, - 44, 39, 41,116,111,108,117, 97, 95,114,101,116, 41, 59, 39, - 41, 10, 9,101,110,100, 10, 32, 32, 32,101,108,115,101, 10, - 9,116, 32, 61, 32,115,101,108,102, 46,116,121,112,101, 10, - 9,110,101,119, 95,116, 32, 61, 32,115,116,114,105,110,103, - 46,103,115,117, 98, 40,116, 44, 32, 34, 99,111,110,115,116, - 37,115, 43, 34, 44, 32, 34, 34, 41, 10, 9,108,111, 99, 97, - 108, 32,111,119,110,101,100, 32, 61, 32,102, 97,108,115,101, - 10, 9,105,102, 32,115,116,114,105,110,103, 46,102,105,110, - 100, 40,115,101,108,102, 46,109,111,100, 44, 32, 34,116,111, - 108,117, 97, 95,111,119,110,101,100, 34, 41, 32,116,104,101, - 110, 10, 9, 9,111,119,110,101,100, 32, 61, 32,116,114,117, - 101, 10, 9,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97, - 108, 32,112,117,115,104, 95,102,117,110, 99, 32, 61, 32,103, - 101,116, 95,112,117,115,104, 95,102,117,110, 99,116,105,111, - 110, 40,116, 41, 10, 32, 32, 32, 32,105,102, 32,115,101,108, - 102, 46,112,116,114, 32, 61, 61, 32, 39, 39, 32,116,104,101, - 110, 10, 32, 32, 32, 32, 32,111,117,116,112,117,116, 40, 39, - 32, 32, 32,123, 39, 41, 10, 32, 32, 32, 32, 32,111,117,116, - 112,117,116, 40, 39, 35,105,102,100,101,102, 32, 95, 95, 99, - 112,108,117,115,112,108,117,115, 92,110, 39, 41, 10, 32, 32, - 32, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, 32, - 118,111,105,100, 42, 32,116,111,108,117, 97, 95,111, 98,106, - 32, 61, 32, 77,116,111,108,117, 97, 95,110,101,119, 40, 40, - 39, 44,110,101,119, 95,116, 44, 39, 41, 40,116,111,108,117, - 97, 95,114,101,116, 41, 41, 59, 39, 41, 10, 32, 32, 32, 32, - 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, 32, 39, 44, - 112,117,115,104, 95,102,117,110, 99, 44, 39, 40,116,111,108, - 117, 97, 95, 83, 44,116,111,108,117, 97, 95,111, 98,106, 44, - 34, 39, 44,116, 44, 39, 34, 41, 59, 39, 41, 10, 32, 32, 32, - 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, 32,116, - 111,108,117, 97, 95,114,101,103,105,115,116,101,114, 95,103, - 99, 40,116,111,108,117, 97, 95, 83, 44,108,117, 97, 95,103, - 101,116,116,111,112, 40,116,111,108,117, 97, 95, 83, 41, 41, - 59, 39, 41, 10, 32, 32, 32, 32, 32,111,117,116,112,117,116, - 40, 39, 35,101,108,115,101, 92,110, 39, 41, 10, 32, 32, 32, - 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, 32,118, - 111,105,100, 42, 32,116,111,108,117, 97, 95,111, 98,106, 32, - 61, 32,116,111,108,117, 97, 95, 99,111,112,121, 40,116,111, - 108,117, 97, 95, 83, 44, 40,118,111,105,100, 42, 41, 38,116, - 111,108,117, 97, 95,114,101,116, 44,115,105,122,101,111,102, - 40, 39, 44,116, 44, 39, 41, 41, 59, 39, 41, 10, 32, 32, 32, - 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, 32, 39, - 44,112,117,115,104, 95,102,117,110, 99, 44, 39, 40,116,111, - 108,117, 97, 95, 83, 44,116,111,108,117, 97, 95,111, 98,106, - 44, 34, 39, 44,116, 44, 39, 34, 41, 59, 39, 41, 10, 32, 32, - 32, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, 32, - 116,111,108,117, 97, 95,114,101,103,105,115,116,101,114, 95, - 103, 99, 40,116,111,108,117, 97, 95, 83, 44,108,117, 97, 95, - 103,101,116,116,111,112, 40,116,111,108,117, 97, 95, 83, 41, - 41, 59, 39, 41, 10, 32, 32, 32, 32, 32,111,117,116,112,117, - 116, 40, 39, 35,101,110,100,105,102, 92,110, 39, 41, 10, 32, - 32, 32, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, - 125, 39, 41, 10, 32, 32, 32, 32,101,108,115,101,105,102, 32, - 115,101,108,102, 46,112,116,114, 32, 61, 61, 32, 39, 38, 39, - 32,116,104,101,110, 10, 32, 32, 32, 32, 32,111,117,116,112, - 117,116, 40, 39, 32, 32, 32, 39, 44,112,117,115,104, 95,102, - 117,110, 99, 44, 39, 40,116,111,108,117, 97, 95, 83, 44, 40, - 118,111,105,100, 42, 41, 38,116,111,108,117, 97, 95,114,101, - 116, 44, 34, 39, 44,116, 44, 39, 34, 41, 59, 39, 41, 10, 32, - 32, 32, 32,101,108,115,101, 10, 9, 32,111,117,116,112,117, - 116, 40, 39, 32, 32, 32, 39, 44,112,117,115,104, 95,102,117, - 110, 99, 44, 39, 40,116,111,108,117, 97, 95, 83, 44, 40,118, - 111,105,100, 42, 41,116,111,108,117, 97, 95,114,101,116, 44, - 34, 39, 44,116, 44, 39, 34, 41, 59, 39, 41, 10, 9, 32,105, - 102, 32,111,119,110,101,100, 32,111,114, 32,108,111, 99, 97, - 108, 95, 99,111,110,115,116,114,117, 99,116,111,114, 32,116, - 104,101,110, 10, 32, 32, 32, 32, 32, 32,111,117,116,112,117, - 116, 40, 39, 32, 32, 32, 32,116,111,108,117, 97, 95,114,101, - 103,105,115,116,101,114, 95,103, 99, 40,116,111,108,117, 97, - 95, 83, 44,108,117, 97, 95,103,101,116,116,111,112, 40,116, - 111,108,117, 97, 95, 83, 41, 41, 59, 39, 41, 10, 9, 32,101, - 110,100, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32,101, - 110,100, 10, 32, 32,101,110,100, 10, 32, 32,108,111, 99, 97, - 108, 32,105, 61, 49, 10, 32, 32,119,104,105,108,101, 32,115, - 101,108,102, 46, 97,114,103,115, 91,105, 93, 32,100,111, 10, - 32, 32, 32,110,114,101,116, 32, 61, 32,110,114,101,116, 32, - 43, 32,115,101,108,102, 46, 97,114,103,115, 91,105, 93, 58, - 114,101,116,118, 97,108,117,101, 40, 41, 10, 32, 32, 32,105, - 32, 61, 32,105, 43, 49, 10, 32, 32,101,110,100, 10, 32, 32, - 111,117,116,112,117,116, 40, 39, 32, 32,125, 39, 41, 10, 10, - 32, 32, 45, 45, 32,115,101,116, 32, 97,114,114, 97,121, 32, - 101,108,101,109,101,110,116, 32,118, 97,108,117,101,115, 10, - 32, 32,105,102, 32, 99,108, 97,115,115, 32,116,104,101,110, - 32,110, 97,114,103, 61, 50, 32,101,108,115,101, 32,110, 97, - 114,103, 61, 49, 32,101,110,100, 10, 32, 32,105,102, 32,115, - 101,108,102, 46, 97,114,103,115, 91, 49, 93, 46,116,121,112, - 101, 32,126, 61, 32, 39,118,111,105,100, 39, 32,116,104,101, - 110, 10, 32, 32, 32,108,111, 99, 97,108, 32,105, 61, 49, 10, - 32, 32, 32,119,104,105,108,101, 32,115,101,108,102, 46, 97, - 114,103,115, 91,105, 93, 32,100,111, 10, 32, 32, 32, 32,115, - 101,108,102, 46, 97,114,103,115, 91,105, 93, 58,115,101,116, - 97,114,114, 97,121, 40,110, 97,114,103, 41, 10, 32, 32, 32, - 32,110, 97,114,103, 32, 61, 32,110, 97,114,103, 43, 49, 10, - 32, 32, 32, 32,105, 32, 61, 32,105, 43, 49, 10, 32, 32, 32, - 101,110,100, 10, 32, 32,101,110,100, 10, 10, 32, 32, 45, 45, - 32,102,114,101,101, 32,100,121,110, 97,109,105, 99, 97,108, - 108,121, 32, 97,108,108,111, 99, 97,116,101,100, 32, 97,114, - 114, 97,121, 10, 32, 32,105,102, 32,115,101,108,102, 46, 97, - 114,103,115, 91, 49, 93, 46,116,121,112,101, 32,126, 61, 32, - 39,118,111,105,100, 39, 32,116,104,101,110, 10, 32, 32, 32, - 108,111, 99, 97,108, 32,105, 61, 49, 10, 32, 32, 32,119,104, - 105,108,101, 32,115,101,108,102, 46, 97,114,103,115, 91,105, - 93, 32,100,111, 10, 32, 32, 32, 32,115,101,108,102, 46, 97, - 114,103,115, 91,105, 93, 58,102,114,101,101, 97,114,114, 97, - 121, 40, 41, 10, 32, 32, 32, 32,105, 32, 61, 32,105, 43, 49, - 10, 32, 32, 32,101,110,100, 10, 32, 32,101,110,100, 10, 32, - 101,110,100, 10, 10, 32,112,111,115,116, 95, 99, 97,108,108, - 95,104,111,111,107, 40,115,101,108,102, 41, 10, 10, 32,111, - 117,116,112,117,116, 40, 39, 32,125, 39, 41, 10, 32,111,117, - 116,112,117,116, 40, 39, 32,114,101,116,117,114,110, 32, 39, - 46, 46,110,114,101,116, 46, 46, 39, 59, 39, 41, 10, 10, 32, - 45, 45, 32, 99, 97,108,108, 32,111,118,101,114,108,111, 97, - 100,101,100, 32,102,117,110, 99,116,105,111,110, 32,111,114, - 32,103,101,110,101,114, 97,116,101, 32,101,114,114,111,114, - 10, 9,105,102, 32,111,118,101,114,108,111, 97,100, 32, 60, - 32, 48, 32,116,104,101,110, 10, 10, 9, 9,111,117,116,112, - 117,116, 40, 39, 35,105,102,110,100,101,102, 32, 84, 79, 76, - 85, 65, 95, 82, 69, 76, 69, 65, 83, 69, 92,110, 39, 41, 10, - 9, 9,111,117,116,112,117,116, 40, 39,116,111,108,117, 97, - 95,108,101,114,114,111,114, 58, 92,110, 39, 41, 10, 9, 9, - 111,117,116,112,117,116, 40, 39, 32,116,111,108,117, 97, 95, - 101,114,114,111,114, 40,116,111,108,117, 97, 95, 83, 44, 34, - 39, 46, 46,111,117,116,112,117,116, 95,101,114,114,111,114, - 95,104,111,111,107, 40, 34, 35,102,101,114,114,111,114, 32, - 105,110, 32,102,117,110, 99,116,105,111,110, 32, 92, 39, 37, - 115, 92, 39, 46, 34, 44, 32,115,101,108,102, 46,108,110, 97, - 109,101, 41, 46, 46, 39, 34, 44, 38,116,111,108,117, 97, 95, - 101,114,114, 41, 59, 39, 41, 10, 9, 9,111,117,116,112,117, - 116, 40, 39, 32,114,101,116,117,114,110, 32, 48, 59, 39, 41, - 10, 9, 9,111,117,116,112,117,116, 40, 39, 35,101,110,100, - 105,102, 92,110, 39, 41, 10, 9,101,108,115,101, 10, 9, 9, - 108,111, 99, 97,108, 32, 95,108,111, 99, 97,108, 32, 61, 32, - 34, 34, 10, 9, 9,105,102, 32,108,111, 99, 97,108, 95, 99, - 111,110,115,116,114,117, 99,116,111,114, 32,116,104,101,110, - 10, 9, 9, 9, 95,108,111, 99, 97,108, 32, 61, 32, 34, 95, - 108,111, 99, 97,108, 34, 10, 9, 9,101,110,100, 10, 9, 9, - 111,117,116,112,117,116, 40, 39,116,111,108,117, 97, 95,108, - 101,114,114,111,114, 58, 92,110, 39, 41, 10, 9, 9,111,117, - 116,112,117,116, 40, 39, 32,114,101,116,117,114,110, 32, 39, - 46, 46,115,116,114,115,117, 98, 40,115,101,108,102, 46, 99, - 110, 97,109,101, 44, 49, 44, 45, 51, 41, 46, 46,102,111,114, - 109, 97,116, 40, 34, 37, 48, 50,100, 34, 44,111,118,101,114, - 108,111, 97,100, 41, 46, 46, 95,108,111, 99, 97,108, 46, 46, - 39, 40,116,111,108,117, 97, 95, 83, 41, 59, 39, 41, 10, 9, - 101,110,100, 10, 32,111,117,116,112,117,116, 40, 39,125, 39, - 41, 10, 32,111,117,116,112,117,116, 40, 39, 35,101,110,100, - 105,102, 32, 47, 47, 35,105,102,110,100,101,102, 32, 84, 79, - 76, 85, 65, 95, 68, 73, 83, 65, 66, 76, 69, 92,110, 39, 41, - 10, 32,111,117,116,112,117,116, 40, 39, 92,110, 39, 41, 10, - 10, 9, 45, 45, 32,114,101, 99,117,114,115,105,118,101, 32, - 99, 97,108,108, 32,116,111, 32,119,114,105,116,101, 32,108, - 111, 99, 97,108, 32, 99,111,110,115,116,114,117, 99,116,111, - 114, 10, 9,105,102, 32, 99,108, 97,115,115, 32, 97,110,100, - 32,115,101,108,102, 46,110, 97,109,101, 61, 61, 39,110,101, - 119, 39, 32, 97,110,100, 32,110,111,116, 32,108,111, 99, 97, - 108, 95, 99,111,110,115,116,114,117, 99,116,111,114, 32,116, - 104,101,110, 10, 10, 9, 9,115,101,108,102, 58,115,117,112, - 99,111,100,101, 40, 49, 41, 10, 9,101,110,100, 10, 10,101, - 110,100, 10, 10, 10, 45, 45, 32,114,101,103,105,115,116,101, - 114, 32,102,117,110, 99,116,105,111,110, 10,102,117,110, 99, - 116,105,111,110, 32, 99,108, 97,115,115, 70,117,110, 99,116, - 105,111,110, 58,114,101,103,105,115,116,101,114, 32, 40,112, - 114,101, 41, 10, 10, 9,105,102, 32,110,111,116, 32,115,101, - 108,102, 58, 99,104,101, 99,107, 95,112,117, 98,108,105, 99, - 95, 97, 99, 99,101,115,115, 40, 41, 32,116,104,101,110, 10, - 9, 9,114,101,116,117,114,110, 10, 9,101,110,100, 10, 10, - 32, 9,105,102, 32,115,101,108,102, 46,110, 97,109,101, 32, - 61, 61, 32, 39,110,101,119, 39, 32, 97,110,100, 32,115,101, - 108,102, 46,112, 97,114,101,110,116, 46,102,108, 97,103,115, - 46,112,117,114,101, 95,118,105,114,116,117, 97,108, 32,116, - 104,101,110, 10, 32, 9, 9, 45, 45, 32,110,111, 32, 99,111, - 110,115,116,114,117, 99,116,111,114, 32,102,111,114, 32, 99, - 108, 97,115,115,101,115, 32,119,105,116,104, 32,112,117,114, - 101, 32,118,105,114,116,117, 97,108, 32,109,101,116,104,111, - 100,115, 10, 32, 9, 9,114,101,116,117,114,110, 10, 32, 9, - 101,110,100, 10, 10, 32,111,117,116,112,117,116, 40,112,114, - 101, 46, 46, 39,116,111,108,117, 97, 95,102,117,110, 99,116, - 105,111,110, 40,116,111,108,117, 97, 95, 83, 44, 34, 39, 46, - 46,115,101,108,102, 46,108,110, 97,109,101, 46, 46, 39, 34, - 44, 39, 46, 46,115,101,108,102, 46, 99,110, 97,109,101, 46, - 46, 39, 41, 59, 39, 41, 10, 32, 32,105,102, 32,115,101,108, - 102, 46,110, 97,109,101, 32, 61, 61, 32, 39,110,101,119, 39, - 32,116,104,101,110, 10, 9, 32, 32,111,117,116,112,117,116, - 40,112,114,101, 46, 46, 39,116,111,108,117, 97, 95,102,117, - 110, 99,116,105,111,110, 40,116,111,108,117, 97, 95, 83, 44, - 34,110,101,119, 95,108,111, 99, 97,108, 34, 44, 39, 46, 46, - 115,101,108,102, 46, 99,110, 97,109,101, 46, 46, 39, 95,108, - 111, 99, 97,108, 41, 59, 39, 41, 10, 9, 32, 32,111,117,116, - 112,117,116, 40,112,114,101, 46, 46, 39,116,111,108,117, 97, - 95,102,117,110, 99,116,105,111,110, 40,116,111,108,117, 97, - 95, 83, 44, 34, 46, 99, 97,108,108, 34, 44, 39, 46, 46,115, - 101,108,102, 46, 99,110, 97,109,101, 46, 46, 39, 95,108,111, - 99, 97,108, 41, 59, 39, 41, 10, 9, 32, 32, 45, 45,111,117, - 116,112,117,116, 40, 39, 32,116,111,108,117, 97, 95,115,101, - 116, 95, 99, 97,108,108, 95,101,118,101,110,116, 40,116,111, - 108,117, 97, 95, 83, 44, 39, 46, 46,115,101,108,102, 46, 99, - 110, 97,109,101, 46, 46, 39, 95,108,111, 99, 97,108, 44, 32, - 34, 39, 46, 46,115,101,108,102, 46,112, 97,114,101,110,116, - 46,116,121,112,101, 46, 46, 39, 34, 41, 59, 39, 41, 10, 32, - 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 80,114, - 105,110,116, 32,109,101,116,104,111,100, 10,102,117,110, 99, - 116,105,111,110, 32, 99,108, 97,115,115, 70,117,110, 99,116, - 105,111,110, 58,112,114,105,110,116, 32, 40,105,100,101,110, - 116, 44, 99,108,111,115,101, 41, 10, 32,112,114,105,110,116, - 40,105,100,101,110,116, 46, 46, 34, 70,117,110, 99,116,105, - 111,110,123, 34, 41, 10, 32,112,114,105,110,116, 40,105,100, - 101,110,116, 46, 46, 34, 32,109,111,100, 32, 32, 61, 32, 39, - 34, 46, 46,115,101,108,102, 46,109,111,100, 46, 46, 34, 39, - 44, 34, 41, 10, 32,112,114,105,110,116, 40,105,100,101,110, - 116, 46, 46, 34, 32,116,121,112,101, 32, 61, 32, 39, 34, 46, - 46,115,101,108,102, 46,116,121,112,101, 46, 46, 34, 39, 44, - 34, 41, 10, 32,112,114,105,110,116, 40,105,100,101,110,116, - 46, 46, 34, 32,112,116,114, 32, 32, 61, 32, 39, 34, 46, 46, - 115,101,108,102, 46,112,116,114, 46, 46, 34, 39, 44, 34, 41, - 10, 32,112,114,105,110,116, 40,105,100,101,110,116, 46, 46, - 34, 32,110, 97,109,101, 32, 61, 32, 39, 34, 46, 46,115,101, - 108,102, 46,110, 97,109,101, 46, 46, 34, 39, 44, 34, 41, 10, - 32,112,114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, - 32,108,110, 97,109,101, 32, 61, 32, 39, 34, 46, 46,115,101, - 108,102, 46,108,110, 97,109,101, 46, 46, 34, 39, 44, 34, 41, - 10, 32,112,114,105,110,116, 40,105,100,101,110,116, 46, 46, - 34, 32, 99,111,110,115,116, 32, 61, 32, 39, 34, 46, 46,115, - 101,108,102, 46, 99,111,110,115,116, 46, 46, 34, 39, 44, 34, - 41, 10, 32,112,114,105,110,116, 40,105,100,101,110,116, 46, - 46, 34, 32, 99,110, 97,109,101, 32, 61, 32, 39, 34, 46, 46, - 115,101,108,102, 46, 99,110, 97,109,101, 46, 46, 34, 39, 44, - 34, 41, 10, 32,112,114,105,110,116, 40,105,100,101,110,116, - 46, 46, 34, 32,108,110, 97,109,101, 32, 61, 32, 39, 34, 46, - 46,115,101,108,102, 46,108,110, 97,109,101, 46, 46, 34, 39, - 44, 34, 41, 10, 32,112,114,105,110,116, 40,105,100,101,110, - 116, 46, 46, 34, 32, 97,114,103,115, 32, 61, 32,123, 34, 41, - 10, 32,108,111, 99, 97,108, 32,105, 61, 49, 10, 32,119,104, - 105,108,101, 32,115,101,108,102, 46, 97,114,103,115, 91,105, - 93, 32,100,111, 10, 32, 32,115,101,108,102, 46, 97,114,103, - 115, 91,105, 93, 58,112,114,105,110,116, 40,105,100,101,110, - 116, 46, 46, 34, 32, 32, 34, 44, 34, 44, 34, 41, 10, 32, 32, - 105, 32, 61, 32,105, 43, 49, 10, 32,101,110,100, 10, 32,112, - 114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 32,125, - 34, 41, 10, 32,112,114,105,110,116, 40,105,100,101,110,116, - 46, 46, 34,125, 34, 46, 46, 99,108,111,115,101, 41, 10,101, - 110,100, 10, 10, 45, 45, 32, 99,104,101, 99,107, 32,105,102, - 32,105,116, 32,114,101,116,117,114,110,115, 32, 97,110, 32, - 111, 98,106,101, 99,116, 32, 98,121, 32,118, 97,108,117,101, - 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, - 70,117,110, 99,116,105,111,110, 58,114,101,113,117,105,114, - 101, 99,111,108,108,101, 99,116,105,111,110, 32, 40,116, 41, - 10, 9,108,111, 99, 97,108, 32,114, 32, 61, 32,102, 97,108, - 115,101, 10, 9,105,102, 32,115,101,108,102, 46,116,121,112, - 101, 32,126, 61, 32, 39, 39, 32, 97,110,100, 32,110,111,116, - 32,105,115, 98, 97,115,105, 99, 40,115,101,108,102, 46,116, - 121,112,101, 41, 32, 97,110,100, 32,115,101,108,102, 46,112, - 116,114, 61, 61, 39, 39, 32,116,104,101,110, 10, 9, 9,108, - 111, 99, 97,108, 32,116,121,112,101, 32, 61, 32,103,115,117, - 98, 40,115,101,108,102, 46,116,121,112,101, 44, 34, 37,115, - 42, 99,111,110,115,116, 37,115, 43, 34, 44, 34, 34, 41, 10, - 9, 32,116, 91,116,121,112,101, 93, 32, 61, 32, 34,116,111, - 108,117, 97, 95, 99,111,108,108,101, 99,116, 95, 34, 32, 46, - 46, 32, 99,108,101, 97,110, 95,116,101,109,112,108, 97,116, - 101, 40,116,121,112,101, 41, 10, 9, 32,114, 32, 61, 32,116, - 114,117,101, 10, 9,101,110,100, 10, 9,108,111, 99, 97,108, - 32,105, 61, 49, 10, 9,119,104,105,108,101, 32,115,101,108, - 102, 46, 97,114,103,115, 91,105, 93, 32,100,111, 10, 9, 9, - 114, 32, 61, 32,115,101,108,102, 46, 97,114,103,115, 91,105, - 93, 58,114,101,113,117,105,114,101, 99,111,108,108,101, 99, - 116,105,111,110, 40,116, 41, 32,111,114, 32,114, 10, 9, 9, - 105, 32, 61, 32,105, 43, 49, 10, 9,101,110,100, 10, 9,114, - 101,116,117,114,110, 32,114, 10,101,110,100, 10, 10, 45, 45, - 32,100,101,116,101,114,109,105,110,101, 32,108,117, 97, 32, - 102,117,110, 99,116,105,111,110, 32,110, 97,109,101, 32,111, - 118,101,114,108,111, 97,100, 10,102,117,110, 99,116,105,111, - 110, 32, 99,108, 97,115,115, 70,117,110, 99,116,105,111,110, - 58,111,118,101,114,108,111, 97,100, 32, 40, 41, 10, 32,114, - 101,116,117,114,110, 32,115,101,108,102, 46,112, 97,114,101, - 110,116, 58,111,118,101,114,108,111, 97,100, 40,115,101,108, - 102, 46,108,110, 97,109,101, 41, 10,101,110,100, 10, 10, 10, - 102,117,110, 99,116,105,111,110, 32,112, 97,114, 97,109, 95, - 111, 98,106,101, 99,116, 40,112, 97,114, 41, 32, 45, 45, 32, - 114,101,116,117,114,110,115, 32,116,114,117,101, 32,105,102, - 32,116,104,101, 32,112, 97,114, 97,109,101,116,101,114, 32, - 104, 97,115, 32, 97,110, 32,111, 98,106,101, 99,116, 32, 97, - 115, 32,105,116,115, 32,100,101,102, 97,117,108,116, 32,118, - 97,108,117,101, 10, 10, 9,105,102, 32,110,111,116, 32,115, - 116,114,105,110,103, 46,102,105,110,100, 40,112, 97,114, 44, - 32, 39, 61, 39, 41, 32,116,104,101,110, 32,114,101,116,117, - 114,110, 32,102, 97,108,115,101, 32,101,110,100, 32, 45, 45, - 32,105,116, 32,104, 97,115, 32,110,111, 32,100,101,102, 97, - 117,108,116, 32,118, 97,108,117,101, 10, 10, 9,108,111, 99, - 97,108, 32, 95, 44, 95, 44,100,101,102, 32, 61, 32,115,116, - 114,105,110,103, 46,102,105,110,100, 40,112, 97,114, 44, 32, - 34, 61, 40, 46, 42, 41, 36, 34, 41, 10, 10, 9,105,102, 32, - 115,116,114,105,110,103, 46,102,105,110,100, 40,112, 97,114, - 44, 32, 34,124, 34, 41, 32,116,104,101,110, 32, 45, 45, 32, - 97, 32,108,105,115,116, 32,111,102, 32,102,108, 97,103,115, - 10, 10, 9, 9,114,101,116,117,114,110, 32,116,114,117,101, - 10, 9,101,110,100, 10, 10, 9,105,102, 32,115,116,114,105, - 110,103, 46,102,105,110,100, 40,112, 97,114, 44, 32, 34, 37, - 42, 34, 41, 32,116,104,101,110, 32, 45, 45, 32,105,116, 39, - 115, 32, 97, 32,112,111,105,110,116,101,114, 32,119,105,116, - 104, 32, 97, 32,100,101,102, 97,117,108,116, 32,118, 97,108, - 117,101, 10, 10, 9, 9,105,102, 32,115,116,114,105,110,103, - 46,102,105,110,100, 40,112, 97,114, 44, 32, 39, 61, 37,115, - 42,110,101,119, 39, 41, 32,111,114, 32,115,116,114,105,110, - 103, 46,102,105,110,100, 40,112, 97,114, 44, 32, 34, 37, 40, - 34, 41, 32,116,104,101,110, 32, 45, 45, 32,105,116, 39,115, - 32, 97, 32,112,111,105,110,116,101,114, 32,119,105,116,104, - 32, 97,110, 32,105,110,115,116, 97,110, 99,101, 32, 97,115, - 32,100,101,102, 97,117,108,116, 32,112, 97,114, 97,109,101, - 116,101,114, 46, 46, 32,105,115, 32,116,104, 97,116, 32,118, - 97,108,105,100, 63, 10, 9, 9, 9,114,101,116,117,114,110, - 32,116,114,117,101, 10, 9, 9,101,110,100, 10, 9, 9,114, - 101,116,117,114,110, 32,102, 97,108,115,101, 32, 45, 45, 32, - 100,101,102, 97,117,108,116, 32,118, 97,108,117,101, 32,105, - 115, 32, 39, 78, 85, 76, 76, 39, 32,111,114, 32,115,111,109, - 101,116,104,105,110,103, 10, 9,101,110,100, 10, 10, 10, 9, - 105,102, 32,115,116,114,105,110,103, 46,102,105,110,100, 40, - 112, 97,114, 44, 32, 34, 91, 37, 40, 38, 93, 34, 41, 32,116, - 104,101,110, 10, 9, 9,114,101,116,117,114,110, 32,116,114, - 117,101, 10, 9,101,110,100, 32, 45, 45, 32,100,101,102, 97, - 117,108,116, 32,118, 97,108,117,101, 32,105,115, 32, 97, 32, - 99,111,110,115,116,114,117, 99,116,111,114, 32, 99, 97,108, - 108, 32, 40,109,111,115,116, 32,108,105,107,101,108,121, 32, - 102,111,114, 32, 97, 32, 99,111,110,115,116, 32,114,101,102, - 101,114,101,110, 99,101, 41, 10, 10, 9, 45, 45,105,102, 32, - 115,116,114,105,110,103, 46,102,105,110,100, 40,112, 97,114, - 44, 32, 34, 38, 34, 41, 32,116,104,101,110, 10, 10, 9, 45, - 45, 9,105,102, 32,115,116,114,105,110,103, 46,102,105,110, - 100, 40,100,101,102, 44, 32, 34, 58, 34, 41, 32,111,114, 32, - 115,116,114,105,110,103, 46,102,105,110,100, 40,100,101,102, - 44, 32, 34, 94, 37,115, 42,110,101,119, 37,115, 43, 34, 41, - 32,116,104,101,110, 10, 10, 9, 45, 45, 9, 9, 45, 45, 32, - 105,116, 39,115, 32, 97, 32,114,101,102,101,114,101,110, 99, - 101, 32,119,105,116,104, 32,100,101,102, 97,117,108,116, 32, - 116,111, 32,115,111,109,101,116,104,105,110,103, 32,108,105, - 107,101, 32, 67,108, 97,115,115, 58, 58,109,101,109, 98,101, - 114, 44, 32,111,114, 32, 39,110,101,119, 32, 67,108, 97,115, - 115, 39, 10, 9, 45, 45, 9, 9,114,101,116,117,114,110, 32, - 116,114,117,101, 10, 9, 45, 45, 9,101,110,100, 10, 9, 45, - 45,101,110,100, 10, 10, 9,114,101,116,117,114,110, 32,102, - 97,108,115,101, 32, 45, 45, 32, 63, 10,101,110,100, 10, 10, - 102,117,110, 99,116,105,111,110, 32,115,116,114,105,112, 95, - 108, 97,115,116, 95, 97,114,103, 40, 97,108,108, 95, 97,114, - 103,115, 44, 32,108, 97,115,116, 95, 97,114,103, 41, 32, 45, - 45, 32,115,116,114,105,112,115, 32,116,104,101, 32,100,101, - 102, 97,117,108,116, 32,118, 97,108,117,101, 32,102,114,111, - 109, 32,116,104,101, 32,108, 97,115,116, 32, 97,114,103,117, - 109,101,110,116, 10, 10, 9,108,111, 99, 97,108, 32, 95, 44, - 95, 44,115, 95, 97,114,103, 32, 61, 32,115,116,114,105,110, - 103, 46,102,105,110,100, 40,108, 97,115,116, 95, 97,114,103, - 44, 32, 34, 94, 40, 91, 94, 61, 93, 43, 41, 34, 41, 10, 9, - 108, 97,115,116, 95, 97,114,103, 32, 61, 32,115,116,114,105, - 110,103, 46,103,115,117, 98, 40,108, 97,115,116, 95, 97,114, - 103, 44, 32, 34, 40, 91, 37, 37, 37, 40, 37, 41, 93, 41, 34, - 44, 32, 34, 37, 37, 37, 49, 34, 41, 59, 10, 9, 97,108,108, - 95, 97,114,103,115, 32, 61, 32,115,116,114,105,110,103, 46, - 103,115,117, 98, 40, 97,108,108, 95, 97,114,103,115, 44, 32, - 34, 37,115, 42, 44, 37,115, 42, 34, 46, 46,108, 97,115,116, - 95, 97,114,103, 46, 46, 34, 37,115, 42, 37, 41, 37,115, 42, - 36, 34, 44, 32, 34, 41, 34, 41, 10, 9,114,101,116,117,114, - 110, 32, 97,108,108, 95, 97,114,103,115, 44, 32,115, 95, 97, - 114,103, 10,101,110,100, 10, 10, 10, 10, 45, 45, 32, 73,110, - 116,101,114,110, 97,108, 32, 99,111,110,115,116,114,117, 99, - 116,111,114, 10,102,117,110, 99,116,105,111,110, 32, 95, 70, - 117,110, 99,116,105,111,110, 32, 40,116, 41, 10, 32,115,101, - 116,109,101,116, 97,116, 97, 98,108,101, 40,116, 44, 99,108, - 97,115,115, 70,117,110, 99,116,105,111,110, 41, 10, 10, 32, - 105,102, 32,116, 46, 99,111,110,115,116, 32,126, 61, 32, 39, - 99,111,110,115,116, 39, 32, 97,110,100, 32,116, 46, 99,111, - 110,115,116, 32,126, 61, 32, 39, 39, 32,116,104,101,110, 10, - 32, 32,101,114,114,111,114, 40, 34, 35,105,110,118, 97,108, - 105,100, 32, 39, 99,111,110,115,116, 39, 32,115,112,101, 99, - 105,102,105, 99, 97,116,105,111,110, 34, 41, 10, 32,101,110, - 100, 10, 10, 32, 97,112,112,101,110,100, 40,116, 41, 10, 32, - 105,102, 32,116, 58,105,110, 99,108, 97,115,115, 40, 41, 32, - 116,104,101,110, 10, 32, 45, 45,112,114,105,110,116, 32, 40, - 39,116, 46,110, 97,109,101, 32,105,115, 32, 39, 46, 46,116, - 46,110, 97,109,101, 46, 46, 39, 44, 32,112, 97,114,101,110, - 116, 46,110, 97,109,101, 32,105,115, 32, 39, 46, 46,116, 46, - 112, 97,114,101,110,116, 46,110, 97,109,101, 41, 10, 32, 32, - 105,102, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, - 116, 46,110, 97,109,101, 44, 32, 34, 37, 98, 60, 62, 34, 44, - 32, 34, 34, 41, 32, 61, 61, 32,115,116,114,105,110,103, 46, - 103,115,117, 98, 40,116, 46,112, 97,114,101,110,116, 46,111, - 114,105,103,105,110, 97,108, 95,110, 97,109,101, 32,111,114, - 32,116, 46,112, 97,114,101,110,116, 46,110, 97,109,101, 44, - 32, 34, 37, 98, 60, 62, 34, 44, 32, 34, 34, 41, 32,116,104, - 101,110, 10, 32, 32, 32,116, 46,110, 97,109,101, 32, 61, 32, - 39,110,101,119, 39, 10, 32, 32, 32,116, 46,108,110, 97,109, - 101, 32, 61, 32, 39,110,101,119, 39, 10, 32, 32, 32,116, 46, - 112, 97,114,101,110,116, 46, 95,110,101,119, 32, 61, 32,116, - 114,117,101, 10, 32, 32, 32,116, 46,116,121,112,101, 32, 61, - 32,116, 46,112, 97,114,101,110,116, 46,110, 97,109,101, 10, - 32, 32, 32,116, 46,112,116,114, 32, 61, 32, 39, 42, 39, 10, - 32, 32,101,108,115,101,105,102, 32,115,116,114,105,110,103, - 46,103,115,117, 98, 40,116, 46,110, 97,109,101, 44, 32, 34, - 37, 98, 60, 62, 34, 44, 32, 34, 34, 41, 32, 61, 61, 32, 39, - 126, 39, 46, 46,115,116,114,105,110,103, 46,103,115,117, 98, - 40,116, 46,112, 97,114,101,110,116, 46,111,114,105,103,105, - 110, 97,108, 95,110, 97,109,101, 32,111,114, 32,116, 46,112, - 97,114,101,110,116, 46,110, 97,109,101, 44, 32, 34, 37, 98, - 60, 62, 34, 44, 32, 34, 34, 41, 32,116,104,101,110, 10, 32, - 32, 32,116, 46,110, 97,109,101, 32, 61, 32, 39,100,101,108, - 101,116,101, 39, 10, 32, 32, 32,116, 46,108,110, 97,109,101, - 32, 61, 32, 39,100,101,108,101,116,101, 39, 10, 32, 32, 32, - 116, 46,112, 97,114,101,110,116, 46, 95,100,101,108,101,116, - 101, 32, 61, 32,116,114,117,101, 10, 32, 32,101,110,100, 10, - 32,101,110,100, 10, 32,116, 46, 99,110, 97,109,101, 32, 61, - 32,116, 58, 99,102,117,110, 99,110, 97,109,101, 40, 34,116, - 111,108,117, 97, 34, 41, 46, 46,116, 58,111,118,101,114,108, - 111, 97,100, 40,116, 41, 10, 32,114,101,116,117,114,110, 32, - 116, 10,101,110,100, 10, 10, 45, 45, 32, 67,111,110,115,116, - 114,117, 99,116,111,114, 10, 45, 45, 32, 69,120,112,101, 99, - 116,115, 32,116,104,114,101,101, 32,115,116,114,105,110,103, - 115, 58, 32,111,110,101, 32,114,101,112,114,101,115,101,110, - 116,105,110,103, 32,116,104,101, 32,102,117,110, 99,116,105, - 111,110, 32,100,101, 99,108, 97,114, 97,116,105,111,110, 44, - 10, 45, 45, 32, 97,110,111,116,104,101,114, 32,114,101,112, - 114,101,115,101,110,116,105,110,103, 32,116,104,101, 32, 97, - 114,103,117,109,101,110,116, 32,108,105,115,116, 44, 32, 97, - 110,100, 32,116,104,101, 32,116,104,105,114,100, 32,114,101, - 112,114,101,115,101,110,116,105,110,103, 10, 45, 45, 32,116, - 104,101, 32, 34, 99,111,110,115,116, 34, 32,111,114, 32,101, - 109,112,116,121, 32,115,116,114,105,110,103, 46, 10,102,117, - 110, 99,116,105,111,110, 32, 70,117,110, 99,116,105,111,110, - 32, 40,100, 44, 97, 44, 99, 41, 10, 32, 45, 45,108,111, 99, - 97,108, 32,116, 32, 61, 32,115,112,108,105,116, 40,115,116, - 114,115,117, 98, 40, 97, 44, 50, 44, 45, 50, 41, 44, 39, 44, - 39, 41, 32, 45, 45, 32,101,108,105,109,105,110, 97,116,101, - 32, 98,114, 97, 99,101,115, 10, 32, 45, 45,108,111, 99, 97, - 108, 32,116, 32, 61, 32,115,112,108,105,116, 95,112, 97,114, - 97,109,115, 40,115,116,114,115,117, 98, 40, 97, 44, 50, 44, - 45, 50, 41, 41, 10, 10, 9,105,102, 32,110,111,116, 32,102, - 108, 97,103,115, 91, 39, 87, 39, 93, 32, 97,110,100, 32,115, - 116,114,105,110,103, 46,102,105,110,100, 40, 97, 44, 32, 34, - 37, 46, 37, 46, 37, 46, 37,115, 42, 37, 41, 34, 41, 32,116, - 104,101,110, 10, 10, 9, 9,119, 97,114,110,105,110,103, 40, - 34, 70,117,110, 99,116,105,111,110,115, 32,119,105,116,104, - 32,118, 97,114,105, 97, 98,108,101, 32, 97,114,103,117,109, - 101,110,116,115, 32, 40, 96, 46, 46, 46, 39, 41, 32, 97,114, - 101, 32,110,111,116, 32,115,117,112,112,111,114,116,101,100, - 46, 32, 73,103,110,111,114,105,110,103, 32, 34, 46, 46,100, - 46, 46, 97, 46, 46, 99, 41, 10, 9, 9,114,101,116,117,114, - 110, 32,110,105,108, 10, 9,101,110,100, 10, 10, 10, 32,108, - 111, 99, 97,108, 32,105, 61, 49, 10, 32,108,111, 99, 97,108, - 32,108, 32, 61, 32,123,110, 61, 48,125, 10, 10, 32, 9, 97, - 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, - 97, 44, 32, 34, 37,115, 42, 40, 91, 37, 40, 37, 41, 93, 41, - 37,115, 42, 34, 44, 32, 34, 37, 49, 34, 41, 10, 9,108,111, - 99, 97,108, 32,116, 44,115,116,114,105,112, 44,108, 97,115, - 116, 32, 61, 32,115,116,114,105,112, 95,112, 97,114,115, 40, - 115,116,114,115,117, 98, 40, 97, 44, 50, 44, 45, 50, 41, 41, - 59, 10, 9,105,102, 32,115,116,114,105,112, 32,116,104,101, - 110, 10, 9, 9, 45, 45,108,111, 99, 97,108, 32,110,115, 32, - 61, 32,115,116,114,105,110,103, 46,115,117, 98, 40,115,116, - 114,115,117, 98, 40, 97, 44, 49, 44, 45, 50, 41, 44, 32, 49, - 44, 32, 45, 40,115,116,114,105,110,103, 46,108,101,110, 40, - 108, 97,115,116, 41, 43, 49, 41, 41, 10, 9, 9,108,111, 99, - 97,108, 32,110,115, 32, 61, 32,106,111,105,110, 40,116, 44, - 32, 34, 44, 34, 44, 32, 49, 44, 32,108, 97,115,116, 45, 49, - 41, 10, 10, 9, 9,110,115, 32, 61, 32, 34, 40, 34, 46, 46, - 115,116,114,105,110,103, 46,103,115,117, 98, 40,110,115, 44, - 32, 34, 37,115, 42, 44, 37,115, 42, 36, 34, 44, 32, 34, 34, - 41, 46, 46, 39, 41, 39, 10, 9, 9, 45, 45,110,115, 32, 61, - 32,115,116,114,105,112, 95,100,101,102, 97,117,108,116,115, - 40,110,115, 41, 10, 10, 9, 9,108,111, 99, 97,108, 32,102, - 32, 61, 32, 70,117,110, 99,116,105,111,110, 40,100, 44, 32, - 110,115, 44, 32, 99, 41, 10, 9, 9,102,111,114, 32,105, 61, - 49, 44,108, 97,115,116, 32,100,111, 10, 9, 9, 9,116, 91, - 105, 93, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, - 98, 40,116, 91,105, 93, 44, 32, 34, 61, 46, 42, 36, 34, 44, - 32, 34, 34, 41, 10, 9, 9,101,110,100, 10, 9,101,110,100, - 10, 10, 32,119,104,105,108,101, 32,116, 91,105, 93, 32,100, - 111, 10, 32, 32,108, 46,110, 32, 61, 32,108, 46,110, 43, 49, - 10, 32, 32,108, 91,108, 46,110, 93, 32, 61, 32, 68,101, 99, - 108, 97,114, 97,116,105,111,110, 40,116, 91,105, 93, 44, 39, - 118, 97,114, 39, 44,116,114,117,101, 41, 10, 32, 32,105, 32, - 61, 32,105, 43, 49, 10, 32,101,110,100, 10, 32,108,111, 99, - 97,108, 32,102, 32, 61, 32, 68,101, 99,108, 97,114, 97,116, - 105,111,110, 40,100, 44, 39,102,117,110, 99, 39, 41, 10, 32, - 102, 46, 97,114,103,115, 32, 61, 32,108, 10, 32,102, 46, 99, - 111,110,115,116, 32, 61, 32, 99, 10, 32,114,101,116,117,114, - 110, 32, 95, 70,117,110, 99,116,105,111,110, 40,102, 41, 10, - 101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,106, - 111,105,110, 40,116, 44, 32,115,101,112, 44, 32,102,105,114, - 115,116, 44, 32,108, 97,115,116, 41, 10, 10, 9,102,105,114, - 115,116, 32, 61, 32,102,105,114,115,116, 32,111,114, 32, 49, - 10, 9,108, 97,115,116, 32, 61, 32,108, 97,115,116, 32,111, - 114, 32,116, 97, 98,108,101, 46,103,101,116,110, 40,116, 41, - 10, 9,108,111, 99, 97,108, 32,108,115,101,112, 32, 61, 32, - 34, 34, 10, 9,108,111, 99, 97,108, 32,114,101,116, 32, 61, - 32, 34, 34, 10, 9,108,111, 99, 97,108, 32,108,111,111,112, - 32, 61, 32,102, 97,108,115,101, 10, 9,102,111,114, 32,105, - 32, 61, 32,102,105,114,115,116, 44,108, 97,115,116, 32,100, - 111, 10, 10, 9, 9,114,101,116, 32, 61, 32,114,101,116, 46, - 46,108,115,101,112, 46, 46,116, 91,105, 93, 10, 9, 9,108, - 115,101,112, 32, 61, 32,115,101,112, 10, 9, 9,108,111,111, - 112, 32, 61, 32,116,114,117,101, 10, 9,101,110,100, 10, 9, - 105,102, 32,110,111,116, 32,108,111,111,112, 32,116,104,101, - 110, 10, 9, 9,114,101,116,117,114,110, 32, 34, 34, 10, 9, - 101,110,100, 10, 10, 9,114,101,116,117,114,110, 32,114,101, - 116, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, - 32,115,116,114,105,112, 95,112, 97,114,115, 40,115, 41, 10, - 10, 9,108,111, 99, 97,108, 32,116, 32, 61, 32,115,112,108, - 105,116, 95, 99, 95,116,111,107,101,110,115, 40,115, 44, 32, - 39, 44, 39, 41, 10, 9,108,111, 99, 97,108, 32,115,116,114, - 105,112, 32, 61, 32,102, 97,108,115,101, 10, 9,108,111, 99, - 97,108, 32,108, 97,115,116, 10, 10, 9,102,111,114, 32,105, - 61,116, 46,110, 44, 49, 44, 45, 49, 32,100,111, 10, 10, 9, - 9,105,102, 32,110,111,116, 32,115,116,114,105,112, 32, 97, - 110,100, 32,112, 97,114, 97,109, 95,111, 98,106,101, 99,116, - 40,116, 91,105, 93, 41, 32,116,104,101,110, 10, 9, 9, 9, - 108, 97,115,116, 32, 61, 32,105, 10, 9, 9, 9,115,116,114, - 105,112, 32, 61, 32,116,114,117,101, 10, 9, 9,101,110,100, - 10, 9, 9, 45, 45,105,102, 32,115,116,114,105,112, 32,116, - 104,101,110, 10, 9, 9, 45, 45, 9,116, 91,105, 93, 32, 61, - 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,116, 91, - 105, 93, 44, 32, 34, 61, 46, 42, 36, 34, 44, 32, 34, 34, 41, - 10, 9, 9, 45, 45,101,110,100, 10, 9,101,110,100, 10, 10, - 9,114,101,116,117,114,110, 32,116, 44,115,116,114,105,112, - 44,108, 97,115,116, 10, 10,101,110,100, 10, 10,102,117,110, - 99,116,105,111,110, 32,115,116,114,105,112, 95,100,101,102, - 97,117,108,116,115, 40,115, 41, 10, 10, 9,115, 32, 61, 32, - 115,116,114,105,110,103, 46,103,115,117, 98, 40,115, 44, 32, - 34, 94, 37, 40, 34, 44, 32, 34, 34, 41, 10, 9,115, 32, 61, - 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,115, 44, - 32, 34, 37, 41, 36, 34, 44, 32, 34, 34, 41, 10, 10, 9,108, - 111, 99, 97,108, 32,116, 32, 61, 32,115,112,108,105,116, 95, - 99, 95,116,111,107,101,110,115, 40,115, 44, 32, 34, 44, 34, - 41, 10, 9,108,111, 99, 97,108, 32,115,101,112, 44, 32,114, - 101,116, 32, 61, 32, 34, 34, 44, 34, 34, 10, 9,102,111,114, - 32,105, 61, 49, 44,116, 46,110, 32,100,111, 10, 9, 9,116, - 91,105, 93, 32, 61, 32,115,116,114,105,110,103, 46,103,115, - 117, 98, 40,116, 91,105, 93, 44, 32, 34, 61, 46, 42, 36, 34, - 44, 32, 34, 34, 41, 10, 9, 9,114,101,116, 32, 61, 32,114, - 101,116, 46, 46,115,101,112, 46, 46,116, 91,105, 93, 10, 9, - 9,115,101,112, 32, 61, 32, 34, 44, 34, 10, 9,101,110,100, - 10, 10, 9,114,101,116,117,114,110, 32, 34, 40, 34, 46, 46, - 114,101,116, 46, 46, 34, 41, 34, 10,101,110,100,32 - }; - tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua embedded: src/bin/lua/function.lua"); + #include "function_lua.h" + tolua_dobuffer(tolua_S,(char*)lua_function_lua,sizeof(lua_function_lua),"tolua embedded: src/bin/lua/function.lua"); lua_settop(tolua_S, top); } /* end of embedded lua code */ diff --git a/lib/zlib/CMakeLists.txt b/lib/zlib/CMakeLists.txt index b1b74031d..6c52578ee 100644 --- a/lib/zlib/CMakeLists.txt +++ b/lib/zlib/CMakeLists.txt @@ -8,12 +8,14 @@ file(GLOB SOURCE "*.c" ) -add_library(zlib ${SOURCE}) +if(NOT TARGET zlib) + add_library(zlib ${SOURCE}) -if (MSVC) - # Remove SCL warnings, we expect this library to have been tested safe - SET_TARGET_PROPERTIES( - zlib PROPERTIES COMPILE_FLAGS "-D_CRT_SECURE_NO_WARNINGS" - ) + if (MSVC) + # Remove SCL warnings, we expect this library to have been tested safe + SET_TARGET_PROPERTIES( + zlib PROPERTIES COMPILE_FLAGS "-D_CRT_SECURE_NO_WARNINGS" + ) + endif() endif() |