Initial revision
parent
302e64f93b
commit
3a6580b82c
|
|
@ -0,0 +1,3 @@
|
|||
0123456789abcdeffedcba9876543210 0123456789abcde7 7f1d0a77826b8aff
|
||||
0123456789abcdeffedcba987654321089abcdef01234567 0123456789abcde7 de0b7c06ae5e0ed5
|
||||
0123456789ABCDEF01010101010101011011121314151617 94DBE082549A14EF 9011121314151617
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
// 3way.cpp - modifed by Wei Dai from Joan Daemen's 3way.c
|
||||
// The original code and all modifications are in the public domain.
|
||||
|
||||
#include "pch.h"
|
||||
#include "3way.h"
|
||||
#include "misc.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
void ThreeWay_TestInstantiations()
|
||||
{
|
||||
ThreeWay::Encryption x1;
|
||||
ThreeWay::Decryption x2;
|
||||
}
|
||||
|
||||
static const word32 START_E = 0x0b0b; // round constant of first encryption round
|
||||
static const word32 START_D = 0xb1b1; // round constant of first decryption round
|
||||
static const word32 RC_MODULUS = 0x11011;
|
||||
|
||||
static inline word32 reverseBits(word32 a)
|
||||
{
|
||||
a = ((a & 0xAAAAAAAA) >> 1) | ((a & 0x55555555) << 1);
|
||||
a = ((a & 0xCCCCCCCC) >> 2) | ((a & 0x33333333) << 2);
|
||||
return ((a & 0xF0F0F0F0) >> 4) | ((a & 0x0F0F0F0F) << 4);
|
||||
}
|
||||
|
||||
#define mu(a0, a1, a2) \
|
||||
{ \
|
||||
a1 = reverseBits(a1); \
|
||||
word32 t = reverseBits(a0); \
|
||||
a0 = reverseBits(a2); \
|
||||
a2 = t; \
|
||||
}
|
||||
|
||||
#define pi_gamma_pi(a0, a1, a2) \
|
||||
{ \
|
||||
word32 b0, b2; \
|
||||
b2 = rotlFixed(a2, 1U); \
|
||||
b0 = rotlFixed(a0, 22U); \
|
||||
a0 = rotlFixed(b0 ^ (a1|(~b2)), 1U); \
|
||||
a2 = rotlFixed(b2 ^ (b0|(~a1)), 22U);\
|
||||
a1 ^= (b2|(~b0)); \
|
||||
}
|
||||
|
||||
// thanks to Paulo Barreto for this optimized theta()
|
||||
#define theta(a0, a1, a2) \
|
||||
{ \
|
||||
word32 b0, b1, c; \
|
||||
c = a0 ^ a1 ^ a2; \
|
||||
c = rotlFixed(c, 16U) ^ rotlFixed(c, 8U); \
|
||||
b0 = (a0 << 24) ^ (a2 >> 8) ^ (a1 << 8) ^ (a0 >> 24); \
|
||||
b1 = (a1 << 24) ^ (a0 >> 8) ^ (a2 << 8) ^ (a1 >> 24); \
|
||||
a0 ^= c ^ b0; \
|
||||
a1 ^= c ^ b1; \
|
||||
a2 ^= c ^ (b0 >> 16) ^ (b1 << 16); \
|
||||
}
|
||||
|
||||
#define rho(a0, a1, a2) \
|
||||
{ \
|
||||
theta(a0, a1, a2); \
|
||||
pi_gamma_pi(a0, a1, a2); \
|
||||
}
|
||||
|
||||
void ThreeWay::Base::UncheckedSetKey(CipherDir dir, const byte *uk, unsigned int length, unsigned int r)
|
||||
{
|
||||
AssertValidKeyLength(length);
|
||||
AssertValidRounds(r);
|
||||
|
||||
m_rounds = r;
|
||||
|
||||
for (unsigned int i=0; i<3; i++)
|
||||
m_k[i] = (word32)uk[4*i+3] | ((word32)uk[4*i+2]<<8) | ((word32)uk[4*i+1]<<16) | ((word32)uk[4*i]<<24);
|
||||
|
||||
if (dir == DECRYPTION)
|
||||
{
|
||||
theta(m_k[0], m_k[1], m_k[2]);
|
||||
mu(m_k[0], m_k[1], m_k[2]);
|
||||
m_k[0] = ByteReverse(m_k[0]);
|
||||
m_k[1] = ByteReverse(m_k[1]);
|
||||
m_k[2] = ByteReverse(m_k[2]);
|
||||
}
|
||||
}
|
||||
|
||||
void ThreeWay::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
typedef BlockGetAndPut<word32, BigEndian> Block;
|
||||
|
||||
word32 a0, a1, a2;
|
||||
Block::Get(inBlock)(a0)(a1)(a2);
|
||||
|
||||
word32 rc = START_E;
|
||||
|
||||
for(unsigned i=0; i<m_rounds; i++)
|
||||
{
|
||||
a0 ^= m_k[0] ^ (rc<<16);
|
||||
a1 ^= m_k[1];
|
||||
a2 ^= m_k[2] ^ rc;
|
||||
rho(a0, a1, a2);
|
||||
|
||||
rc <<= 1;
|
||||
if (rc&0x10000) rc ^= 0x11011;
|
||||
}
|
||||
a0 ^= m_k[0] ^ (rc<<16);
|
||||
a1 ^= m_k[1];
|
||||
a2 ^= m_k[2] ^ rc;
|
||||
theta(a0, a1, a2);
|
||||
|
||||
Block::Put(xorBlock, outBlock)(a0)(a1)(a2);
|
||||
}
|
||||
|
||||
void ThreeWay::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
typedef BlockGetAndPut<word32, LittleEndian> Block;
|
||||
|
||||
word32 a0, a1, a2;
|
||||
Block::Get(inBlock)(a0)(a1)(a2);
|
||||
|
||||
word32 rc = START_D;
|
||||
|
||||
mu(a0, a1, a2);
|
||||
for(unsigned i=0; i<m_rounds; i++)
|
||||
{
|
||||
a0 ^= m_k[0] ^ (rc<<16);
|
||||
a1 ^= m_k[1];
|
||||
a2 ^= m_k[2] ^ rc;
|
||||
rho(a0, a1, a2);
|
||||
|
||||
rc <<= 1;
|
||||
if (rc&0x10000) rc ^= 0x11011;
|
||||
}
|
||||
a0 ^= m_k[0] ^ (rc<<16);
|
||||
a1 ^= m_k[1];
|
||||
a2 ^= m_k[2] ^ rc;
|
||||
theta(a0, a1, a2);
|
||||
mu(a0, a1, a2);
|
||||
|
||||
Block::Put(xorBlock, outBlock)(a0)(a1)(a2);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
#ifndef CRYPTOPP_THREEWAY_H
|
||||
#define CRYPTOPP_THREEWAY_H
|
||||
|
||||
/** \file
|
||||
*/
|
||||
|
||||
#include "seckey.h"
|
||||
#include "secblock.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
struct ThreeWay_Info : public FixedBlockSize<12>, public FixedKeyLength<12>, public VariableRounds<11>
|
||||
{
|
||||
static const char *StaticAlgorithmName() {return "3-Way";}
|
||||
};
|
||||
|
||||
/// <a href="http://www.weidai.com/scan-mirror/cs.html#3-Way">3-Way</a>
|
||||
class ThreeWay : public ThreeWay_Info, public BlockCipherDocumentation
|
||||
{
|
||||
class Base : public BlockCipherBaseTemplate<ThreeWay_Info>
|
||||
{
|
||||
public:
|
||||
void UncheckedSetKey(CipherDir direction, const byte *key, unsigned int length, unsigned int rounds);
|
||||
|
||||
protected:
|
||||
unsigned int m_rounds;
|
||||
FixedSizeSecBlock<word32, 3> m_k;
|
||||
};
|
||||
|
||||
class Enc : public Base
|
||||
{
|
||||
public:
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
};
|
||||
|
||||
class Dec : public Base
|
||||
{
|
||||
public:
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef BlockCipherTemplate<ENCRYPTION, Enc> Encryption;
|
||||
typedef BlockCipherTemplate<DECRYPTION, Dec> Decryption;
|
||||
};
|
||||
|
||||
typedef ThreeWay::Encryption ThreeWayEncryption;
|
||||
typedef ThreeWay::Decryption ThreeWayDecryption;
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
000000000000000000000000 000000010000000100000001 4059c76e83ae9dc4ad21ecf7
|
||||
000000060000000500000004 000000030000000200000001 d2f05b5ed6144138cab920cd
|
||||
def01234456789abbcdef012 234567899abcdef001234567 0aa55dbb9cdddb6d7cdb76b2
|
||||
d2f05b5ed6144138cab920cd 4059c76e83ae9dc4ad21ecf7 478ea8716b13f17c15b155ed
|
||||
|
||||
|
|
@ -0,0 +1,951 @@
|
|||
# Doxyfile 1.2.15-20020512
|
||||
|
||||
# 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 (" ")
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# General configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# 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
|
||||
|
||||
# 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:
|
||||
# Brazilian, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch,
|
||||
# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Korean,
|
||||
# Norwegian, Polish, Portuguese, Romanian, Russian, Slovak, Slovene,
|
||||
# Spanish, Swedish and Ukrainian.
|
||||
|
||||
OUTPUT_LANGUAGE = English
|
||||
|
||||
# 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
|
||||
|
||||
# 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 class will be included in the various
|
||||
# overviews. This option has no effect if EXTRACT_ALL is enabled.
|
||||
|
||||
HIDE_UNDOC_CLASSES = No
|
||||
|
||||
# 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
|
||||
|
||||
# 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. It is allowed to use relative paths in the argument list.
|
||||
|
||||
STRIP_FROM_PATH =
|
||||
|
||||
# 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
|
||||
|
||||
# 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 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
|
||||
# users are adviced to set this option to NO.
|
||||
|
||||
CASE_SENSE_NAMES = NO
|
||||
|
||||
# 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 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 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
|
||||
|
||||
# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
|
||||
# will put list of the files that are included by a file in the documentation
|
||||
# of that file.
|
||||
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
|
||||
# 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 the Qt-style comments (thus requiring an
|
||||
# explict @brief command for a brief description.
|
||||
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
|
||||
# If the DETAILS_AT_TOP tag is set to YES then Doxygen
|
||||
# will output the detailed description near the top, like JavaDoc.
|
||||
# If set to NO, the detailed description appears after the member
|
||||
# documentation.
|
||||
|
||||
DETAILS_AT_TOP = Yes
|
||||
|
||||
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
|
||||
# member inherits the documentation from any documented member that it
|
||||
# reimplements.
|
||||
|
||||
INHERIT_DOCS = YES
|
||||
|
||||
# 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 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
|
||||
|
||||
# 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
|
||||
|
||||
# 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
|
||||
|
||||
# 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 =
|
||||
|
||||
# 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 consist 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 =
|
||||
|
||||
# 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 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
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# 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
|
||||
|
||||
# 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.
|
||||
|
||||
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 = .
|
||||
|
||||
# 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
|
||||
|
||||
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 =
|
||||
|
||||
# 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.
|
||||
|
||||
EXCLUDE_PATTERNS =
|
||||
|
||||
# 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.
|
||||
|
||||
INPUT_FILTER =
|
||||
|
||||
# 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.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
# If the REFERENCED_BY_RELATION tag is set to YES (the default)
|
||||
# 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 (the default)
|
||||
# then for each documented function all documented entities
|
||||
# called/used by that function will be listed.
|
||||
|
||||
REFERENCES_RELATION = 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
|
||||
|
||||
HTML_STYLESHEET =
|
||||
|
||||
# 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 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 compressed HTML help file (.chm)
|
||||
# of the generated HTML documentation.
|
||||
|
||||
GENERATE_HTMLHELP = YES
|
||||
|
||||
# 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 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
|
||||
|
||||
# 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
|
||||
|
||||
# If the GENERATE_TREEVIEW tag 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 and frames is required (for instance Mozilla, Netscape 4.0+,
|
||||
# or Internet explorer 4.0+). Note that for large projects the tree generation
|
||||
# can take a very long time. In such cases it is better to disable this feature.
|
||||
# Windows users are probably better off using the HTML help feature.
|
||||
|
||||
GENERATE_TREEVIEW = 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
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# 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.
|
||||
|
||||
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
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# 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 optimised 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 assigments. 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. Note that this
|
||||
# feature is still experimental and incomplete at the
|
||||
# moment.
|
||||
|
||||
GENERATE_XML = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# 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 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_PREDEFINED 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.
|
||||
|
||||
PREDEFINED = _WIN32 \
|
||||
_WINDOWS \
|
||||
WORD64_AVAILABLE \
|
||||
__FreeBSD__ \
|
||||
CRYPTOPP_DOXYGEN_PROCESSING
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY 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 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::addtions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The TAGFILES tag can be used to specify one or more tagfiles.
|
||||
|
||||
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 superceded by the HAVE_DOT option below. This is only a fallback. It is
|
||||
# recommended to install and use dot, since it yield more powerful graphs.
|
||||
|
||||
CLASS_DIAGRAMS = YES
|
||||
|
||||
# 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
|
||||
|
||||
# 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 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 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
|
||||
|
||||
# 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 on 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 MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
|
||||
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
|
||||
# this value, doxygen will try to truncate the graph, so that it fits within
|
||||
# the specified constraint. Beware that most browsers cannot cope with very
|
||||
# large images.
|
||||
|
||||
MAX_DOT_GRAPH_WIDTH = 1024
|
||||
|
||||
# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
|
||||
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
|
||||
# this value, doxygen will try to truncate the graph, so that it fits within
|
||||
# the specified constraint. Beware that most browsers cannot cope with very
|
||||
# large images.
|
||||
|
||||
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
|
||||
# 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 intermedate dot files that are used to generate
|
||||
# the various graphs.
|
||||
|
||||
DOT_CLEANUP = YES
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The SEARCHENGINE tag specifies whether or not a search engine should be
|
||||
# used. If set to NO the values of all tags below this one will be ignored.
|
||||
|
||||
SEARCHENGINE = NO
|
||||
|
||||
# The CGI_NAME tag should be the name of the CGI script that
|
||||
# starts the search engine (doxysearch) with the correct parameters.
|
||||
# A script with this name will be generated by doxygen.
|
||||
|
||||
CGI_NAME = search.cgi
|
||||
|
||||
# The CGI_URL tag should be the absolute URL to the directory where the
|
||||
# cgi binaries are located. See the documentation of your http daemon for
|
||||
# details.
|
||||
|
||||
CGI_URL =
|
||||
|
||||
# The DOC_URL tag should be the absolute URL to the directory where the
|
||||
# documentation is located. If left blank the absolute path to the
|
||||
# documentation, with file:// prepended to it, will be used.
|
||||
|
||||
DOC_URL =
|
||||
|
||||
# The DOC_ABSPATH tag should be the absolute path to the directory where the
|
||||
# documentation is located. If left blank the directory on the local machine
|
||||
# will be used.
|
||||
|
||||
DOC_ABSPATH =
|
||||
|
||||
# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
|
||||
# is installed.
|
||||
|
||||
BIN_ABSPATH = /usr/local/bin/
|
||||
|
||||
# The EXT_DOC_PATHS tag can be used to specify one or more paths to
|
||||
# documentation generated for other projects. This allows doxysearch to search
|
||||
# the documentation for these projects as well.
|
||||
|
||||
EXT_DOC_PATHS =
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
# can't use -fno-rtti yet because it causes problems with exception handling in GCC 2.95.2
|
||||
CXXFLAGS = -g
|
||||
# uncomment the next two lines to do a release build
|
||||
# CXXFLAGS = -O2 -DNDEBUG -ffunction-sections -fdata-sections
|
||||
# LDFLAGS = -Wl,--gc-sections
|
||||
ARFLAGS = -cr # ar needs the dash on OpenBSD
|
||||
RANLIB = ranlib
|
||||
UNAME = $(shell uname)
|
||||
|
||||
ifeq ($(UNAME),) # for DJGPP, where uname doesn't exist
|
||||
CXXFLAGS += -mbnu210
|
||||
else
|
||||
CXXFLAGS += -pipe
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME),Darwin) # -fpic conflicts with inline asm in integer.cpp on i386
|
||||
CXX = c++
|
||||
CXXFLAGS += -fno-pic
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME),SunOS)
|
||||
LDLIBS = -lnsl -lsocket
|
||||
endif
|
||||
|
||||
ifeq ($(CXX),gcc) # for some reason CXX is gcc on cygwin 1.1.4
|
||||
CXX = g++
|
||||
endif
|
||||
|
||||
SRCS = $(wildcard *.cpp)
|
||||
|
||||
ifeq ($(SRCS),) # workaround wildcard function bug in GNU Make 3.77
|
||||
SRCS = $(shell ls *.cpp)
|
||||
endif
|
||||
|
||||
OBJS = $(SRCS:.cpp=.o)
|
||||
# test.o needs to be after bench.o for cygwin 1.1.4 (possible ld bug?)
|
||||
TESTOBJS = bench.o test.o validat1.o validat2.o validat3.o
|
||||
LIBOBJS = $(filter-out $(TESTOBJS),$(OBJS))
|
||||
|
||||
all: cryptest.exe
|
||||
|
||||
clean:
|
||||
$(RM) cryptest.exe libcryptopp.a $(LIBOBJS) $(TESTOBJS)
|
||||
|
||||
libcryptopp.a: $(LIBOBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(LIBOBJS)
|
||||
$(RANLIB) $@
|
||||
|
||||
cryptest.exe: libcryptopp.a $(TESTOBJS)
|
||||
$(CXX) -o $@ $(CXXFLAGS) $(TESTOBJS) -L. -lcryptopp $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
nolib: $(OBJS) # makes it faster to test changes
|
||||
$(CXX) -o ct $(CXXFLAGS) $(OBJS) $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
.SUFFIXES: .cpp
|
||||
|
||||
.cpp.o:
|
||||
$(CXX) $(CXXFLAGS) -c $<
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
Compilation Copyright (c) 1995-2002 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.
|
||||
|
||||
The following files are copyrighted by their respective original authors:
|
||||
|
||||
mars.cpp - Copyright 1998 Brian Gladman.
|
||||
serpent.cpp - Copyright 1998, 1999 Brian Gladman and Sam Simpson.
|
||||
|
||||
All other 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
|
||||
Michael Paul Johnson - diamond.cpp, sapphire.cpp
|
||||
Andrew M. Kuchling - md2.cpp, md4.cpp
|
||||
Colin Plumb - md5.cpp, md5mac.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
|
||||
|
||||
Permission to use, copy, modify, and distribute this compilation for
|
||||
any purpose, including commercial applications, is hereby granted
|
||||
without fee, subject to the following restrictions:
|
||||
|
||||
1. Any copy or modification of this compilation in any form, except
|
||||
in object code form as part of an application software, must include
|
||||
the above copyright notice and this license.
|
||||
|
||||
2. Users of this software agree that any modification or extension
|
||||
they provide to Wei Dai will be considered public domain and not
|
||||
copyrighted unless it includes an explicit copyright notice.
|
||||
|
||||
3. Wei Dai makes no warranty or representation that the operation of the
|
||||
software in this compilation will be error-free, and Wei Dai is under no
|
||||
obligation to provide any services, by way of maintenance, update, or
|
||||
otherwise. THE SOFTWARE AND ANY DOCUMENTATION ARE PROVIDED "AS IS"
|
||||
WITHOUT EXPRESS OR IMPLIED WARRANTY INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. IN NO EVENT WILL WEI DAI OR ANY OTHER CONTRIBUTOR BE LIABLE FOR
|
||||
DIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
4. Users will not use Wei Dai or any other contributor's name in any
|
||||
publicity or advertising, without prior written consent in each case.
|
||||
|
||||
5. Export of this software from the United States may require a
|
||||
specific license from the United States Government. It is the
|
||||
responsibility of any person or organization contemplating export
|
||||
to obtain such a license before exporting.
|
||||
|
||||
6. Certain parts of this software may be protected by patents. It
|
||||
is the users' responsibility to obtain the appropriate
|
||||
licenses before using those parts.
|
||||
|
||||
If this compilation is used in object code form in an application
|
||||
software, acknowledgement of the author is not required but would be
|
||||
appreciated. The contribution of any useful modifications or extensions
|
||||
to Wei Dai is not required but would also be appreciated.
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
Crypto++: a C++ Class Library of Cryptographic Primitives
|
||||
Version 5.0 9/11/2002
|
||||
|
||||
This library includes:
|
||||
|
||||
- a class hierarchy with an API defined by abstract base classes
|
||||
- Proposed AES (Rijndael) and other AES candidates: RC6, MARS, Twofish,
|
||||
Serpent, CAST-256
|
||||
- other symmetric block ciphers: IDEA, DES, Triple DES (DES-EDE2 and
|
||||
DES-EDE3), DESX (DES-XEX3), RC2, RC5, Blowfish, Diamond2, TEA, SAFER,
|
||||
3-WAY, GOST, SHARK, CAST-128, Square, Skipjack
|
||||
- generic block cipher modes: ECB, CBC, CBC ciphertext stealing (CTS),
|
||||
CFB, OFB, counter (CTR) mode
|
||||
- stream ciphers: Panama, ARC4, SEAL, WAKE, WAKE-OFB, Sapphire II,
|
||||
BlumBlumShub
|
||||
- public key cryptography: RSA, DSA, ElGamal, Nyberg-Rueppel (NR), Rabin,
|
||||
Rabin-Williams (RW), LUC, LUCELG, DLIES (variants of DHAES), ESIGN
|
||||
- padding schemes for public-key systems: PKCS#1 v2.0, OAEP, PSSR, IEEE
|
||||
P1363 EMSA2
|
||||
- key agreement schemes: Diffie-Hellman (DH), Unified Diffie-Hellman
|
||||
(DH2), Menezes-Qu-Vanstone (MQV), LUCDIF, XTR-DH
|
||||
- elliptic curve cryptography: ECDSA, ECNR, ECIES, ECDH, ECMQV (with
|
||||
optional cofactor multiplication for ECIES, ECDHC, ECMQVC)
|
||||
- one-way hash functions: SHA-1, MD2, MD4, MD5, HAVAL, RIPEMD-160, Tiger,
|
||||
SHA-2 (SHA-256, SHA-384, and SHA-512), Panama
|
||||
- public and private key validation for asymmetric algorithms
|
||||
- message authentication codes: MD5-MAC, HMAC, XOR-MAC, CBC-MAC, DMAC
|
||||
- cipher constructions based on hash functions: Luby-Rackoff, MDC
|
||||
- pseudo random number generators (PRNG): ANSI X9.17 appendix C, PGP's
|
||||
RandPool
|
||||
- Shamir's secret sharing scheme and Rabin's information dispersal
|
||||
algorithm (IDA)
|
||||
- DEFLATE (RFC 1951) compression/decompression with gzip (RFC 1952) and
|
||||
zlib (RFC 1950) format support
|
||||
- fast multi-precision integer (bignum) and polynomial operations
|
||||
- finite field arithmetics, including GF(p) and GF(2^n)
|
||||
- prime number generation and verification
|
||||
- various miscellaneous modules such as base 64 coding and 32-bit CRC
|
||||
- class wrappers for these operating system features (optional):
|
||||
- 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
|
||||
- A high level interface for most of the above, using a filter/pipeline
|
||||
metaphor
|
||||
- benchmarks and validation testing
|
||||
|
||||
You are welcome to use it for any purpose without paying me, but see
|
||||
license.txt for the fine print.
|
||||
|
||||
This version of Crypto++ has been compiled successfully with MSVC 6.0
|
||||
and 7.0 on Windows XP, GCC 2.95.4 on FreeBSD 4.6, GCC 2.95.3 on
|
||||
Linux 2.4 and SunOS 5.8, GCC 3.2 on Cygwin 1.3.12, and Metrowerks
|
||||
CodeWarrior 8.2.
|
||||
|
||||
To compile Crypto++ with MSVC, open the "cryptest.dsw" workspace file
|
||||
and build the "cryptest" project. This will compile Crypto++ as a static
|
||||
library and also build the test driver. Run the test driver and make sure
|
||||
the validation suite passes. Then to use the library simply insert the
|
||||
"cryptlib.dsp" project file into your own application workspace as a
|
||||
dependent project. You may need to check the compiler options to make sure
|
||||
that the library and your application are using the same C++ run-time
|
||||
libraries.
|
||||
|
||||
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.
|
||||
|
||||
Crypto++ is documented mostly through comments in header files. If you are
|
||||
not familiar with cryptography, I suggest that you read an introductory
|
||||
text (such as Bruce Schneier's _Applied Cryptography_) before attempting
|
||||
to use this library. Then, you should start by looking at
|
||||
cryptlib.h, which contains the main abstract base classes and their
|
||||
descriptions, and test.cpp, which contains sample/test code. There
|
||||
should also be a link on http://www.cryptopp.com to an HTML reference
|
||||
manual generated from the inline documentation.
|
||||
|
||||
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 at
|
||||
weidai@eskimo.com, but you will probably get a faster response through
|
||||
the mailing list.
|
||||
|
||||
Finally, a couple of usage notes to keep in mind:
|
||||
|
||||
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.
|
||||
|
||||
Wei Dai
|
||||
|
||||
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 HAVAL and IDEA to use public domain code
|
||||
- implemented SSE2 optimizations for Integer operations
|
||||
- is being evaluated for FIPS 140-2 compliance
|
||||
- fixed a bug in HMAC::TruncatedFinal()
|
||||
- fixed SKIPJACK byte ordering following NIST clarification dated 5/9/02
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
// 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, unsigned int 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, unsigned int 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
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef CRYPTOPP_ADLER32_H
|
||||
#define CRYPTOPP_ADLER32_H
|
||||
|
||||
#include "cryptlib.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! ADLER-32 checksum calculations
|
||||
class Adler32 : public HashTransformation
|
||||
{
|
||||
public:
|
||||
enum {DIGESTSIZE = 4};
|
||||
Adler32() {Reset();}
|
||||
void Update(const byte *input, unsigned int length);
|
||||
void TruncatedFinal(byte *hash, unsigned int size);
|
||||
unsigned int DigestSize() const {return DIGESTSIZE;}
|
||||
|
||||
private:
|
||||
void Reset() {m_s1 = 1; m_s2 = 0;}
|
||||
|
||||
word16 m_s1, m_s2;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef CRYPTOPP_AES_H
|
||||
#define CRYPTOPP_AES_H
|
||||
|
||||
/** \file
|
||||
AES winner announced on 10/2/2000
|
||||
*/
|
||||
|
||||
#include "rijndael.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
#ifdef CRYPTOPP_DOXYGEN_PROCESSING // Use inheritance instead of typedef to get a seperate API reference page for AES
|
||||
//! AES
|
||||
class AES : public Rijndael, public BlockCipherDocumentation {};
|
||||
#else
|
||||
typedef Rijndael AES;
|
||||
#endif
|
||||
|
||||
typedef RijndaelEncryption AESEncryption;
|
||||
typedef RijndaelDecryption AESDecryption;
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,340 @@
|
|||
// algebra.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "algebra.h"
|
||||
#include "integer.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
template <class T> const T& AbstractGroup<T>::Double(const Element &a) const
|
||||
{
|
||||
return 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 Add(a1, Inverse(b));
|
||||
}
|
||||
|
||||
template <class T> T& AbstractGroup<T>::Accumulate(Element &a, const Element &b) const
|
||||
{
|
||||
return a = Add(a, b);
|
||||
}
|
||||
|
||||
template <class T> T& AbstractGroup<T>::Reduce(Element &a, const Element &b) const
|
||||
{
|
||||
return a = Subtract(a, b);
|
||||
}
|
||||
|
||||
template <class T> const T& AbstractRing<T>::Square(const Element &a) const
|
||||
{
|
||||
return 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 Multiply(a1, MultiplicativeInverse(b));
|
||||
}
|
||||
|
||||
template <class T> const T& AbstractEuclideanDomain<T>::Mod(const Element &a, const Element &b) const
|
||||
{
|
||||
Element q;
|
||||
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 (!Equal(g[i1], Identity()))
|
||||
{
|
||||
g[i2] = 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};
|
||||
#ifdef __BCPLUSPLUS__
|
||||
// BC++50 workaround
|
||||
Element v[3];
|
||||
v[0]=m_domain.Identity();
|
||||
v[1]=m_domain.MultiplicativeIdentity();
|
||||
#else
|
||||
Element v[3]={m_domain.Identity(), m_domain.MultiplicativeIdentity()};
|
||||
#endif
|
||||
Element y;
|
||||
unsigned int i0=0, i1=1, i2=2;
|
||||
|
||||
while (!Equal(g[i1], 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;
|
||||
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 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] = Add(x,y);
|
||||
else
|
||||
{
|
||||
powerTable[2] = Double(x);
|
||||
powerTable[2*tableSize] = 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 = Double(result);
|
||||
if (power1 || power2)
|
||||
Accumulate(result, powerTable[(power2<<w) + power1]);
|
||||
}
|
||||
while (squaresAfter--)
|
||||
result = 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 &exp, bool fastNegate, unsigned int windowSizeIn=0)
|
||||
: exp(exp), 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 = exp % (1 << windowSize);
|
||||
|
||||
if (fastNegate && exp.GetBit(windowSize))
|
||||
{
|
||||
negateNext = true;
|
||||
expWindow = (1 << windowSize) - expWindow;
|
||||
exp += windowModulus;
|
||||
}
|
||||
else
|
||||
negateNext = false;
|
||||
}
|
||||
|
||||
Integer exp, windowModulus;
|
||||
unsigned int windowSize, windowBegin, 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 = 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
|
||||
|
|
@ -0,0 +1,275 @@
|
|||
#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 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 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 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);}
|
||||
|
||||
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;
|
||||
|
||||
protected:
|
||||
EuclideanDomain m_domain;
|
||||
Element m_modulus;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// algparam.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "algparam.h"
|
||||
#include "integer.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
const std::type_info &g_typeidInteger = typeid(Integer);
|
||||
|
||||
void AssignIntToInteger(void *pInteger, const void *pInt)
|
||||
{
|
||||
*reinterpret_cast<Integer *>(pInteger) = *reinterpret_cast<const int *>(pInt);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,323 @@
|
|||
#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, unsigned int size, bool deepCopy = false)
|
||||
{
|
||||
Assign(data, size, deepCopy);
|
||||
}
|
||||
template <class T> ConstByteArrayParameter(const T &string, bool deepCopy = false)
|
||||
{
|
||||
CRYPTOPP_COMPILE_ASSERT(sizeof(string[0])==1);
|
||||
Assign((const byte *)string.data(), string.size(), deepCopy);
|
||||
}
|
||||
|
||||
void Assign(const byte *data, unsigned int 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;}
|
||||
unsigned int size() const {return m_deepCopy ? m_block.size() : m_size;}
|
||||
|
||||
private:
|
||||
bool m_deepCopy;
|
||||
const byte *m_data;
|
||||
unsigned int 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;}
|
||||
unsigned int size() const {return m_size;}
|
||||
|
||||
private:
|
||||
byte *m_data;
|
||||
unsigned int m_size;
|
||||
};
|
||||
|
||||
class 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
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
: m_pObject(pObject), m_name(name), m_valueType(&valueType), m_pValue(pValue), m_found(false), m_getValueNames(false)
|
||||
{
|
||||
if (strcmp(name, "ValueNames") == 0)
|
||||
m_found = m_getValueNames = true;
|
||||
|
||||
std::string thisPointerName = std::string("ThisPointer:") + typeid(T).name();
|
||||
|
||||
if (m_getValueNames)
|
||||
{
|
||||
NameValuePairs::ThrowIfTypeMismatch(name, typeid(std::string), *m_valueType);
|
||||
if (typeid(T) != typeid(BASE))
|
||||
pObject->BASE::GetVoidValue(name, valueType, pValue);
|
||||
(*reinterpret_cast<std::string *>(m_pValue) += thisPointerName) += ";";
|
||||
}
|
||||
else if (name == thisPointerName)
|
||||
{
|
||||
NameValuePairs::ThrowIfTypeMismatch(name, typeid(T *), *m_valueType);
|
||||
*reinterpret_cast<const T **>(pValue) = pObject;
|
||||
m_found = true;
|
||||
}
|
||||
else if (typeid(T) != typeid(BASE))
|
||||
m_found = pObject->BASE::GetVoidValue(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) += ";";
|
||||
else 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()
|
||||
{
|
||||
std::string thisObjectName = std::string("ThisObject:") + typeid(T).name();
|
||||
if (m_getValueNames)
|
||||
(*reinterpret_cast<std::string *>(m_pValue) += thisObjectName) += ";";
|
||||
else if (!m_found && m_name == thisObjectName)
|
||||
{
|
||||
NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(T), *m_valueType);
|
||||
*reinterpret_cast<T *>(m_pValue) = *m_pObject;
|
||||
m_found = true;
|
||||
}
|
||||
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, BASE *dummy=NULL)
|
||||
{
|
||||
return GetValueHelperClass<T, BASE>(pObject, name, valueType, pValue);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
GetValueHelperClass<T, T> GetValueHelper(const T *pObject, const char *name, const std::type_info &valueType, void *pValue)
|
||||
{
|
||||
return GetValueHelperClass<T, T>(pObject, name, valueType, pValue);
|
||||
}
|
||||
|
||||
// ********************************************************
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// ********************************************************
|
||||
|
||||
void AssignIntToInteger(void *pInteger, const void *pInt);
|
||||
|
||||
extern const std::type_info &g_typeidInteger;
|
||||
|
||||
template <class BASE, class T>
|
||||
class AlgorithmParameters : public NameValuePairs
|
||||
{
|
||||
public:
|
||||
AlgorithmParameters(const BASE &base, const char *name, const T &value)
|
||||
: m_base(base), m_name(name), m_value(value)
|
||||
#ifndef NDEBUG
|
||||
, m_used(false)
|
||||
#endif
|
||||
{}
|
||||
|
||||
#ifndef NDEBUG
|
||||
AlgorithmParameters(const AlgorithmParameters ©)
|
||||
: m_base(copy.m_base), m_name(copy.m_name), m_value(copy.m_value), m_used(false)
|
||||
{
|
||||
copy.m_used = true;
|
||||
}
|
||||
|
||||
// TODO: revisit after implementing some tracing mechanism, this won't work because of exceptions
|
||||
// ~AlgorithmParameters() {assert(m_used);} // use assert here because we don't want to throw out of a destructor
|
||||
#endif
|
||||
|
||||
template <class R>
|
||||
AlgorithmParameters<AlgorithmParameters<BASE,T>, R> operator()(const char *name, const R &value) const
|
||||
{
|
||||
return AlgorithmParameters<AlgorithmParameters<BASE,T>, R>(*this, name, value);
|
||||
}
|
||||
|
||||
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
|
||||
{
|
||||
if (strcmp(name, "ValueNames") == 0)
|
||||
{
|
||||
ThrowIfTypeMismatch(name, typeid(std::string), valueType);
|
||||
m_base.GetVoidValue(name, valueType, pValue);
|
||||
(*reinterpret_cast<std::string *>(pValue) += m_name) += ";";
|
||||
return true;
|
||||
}
|
||||
else if (strcmp(name, m_name) == 0)
|
||||
{
|
||||
// special case for retrieving an Integer parameter when an int was passed in
|
||||
if (valueType == g_typeidInteger && typeid(T) == typeid(int))
|
||||
AssignIntToInteger(pValue, &m_value);
|
||||
else
|
||||
{
|
||||
ThrowIfTypeMismatch(name, typeid(T), valueType);
|
||||
*reinterpret_cast<T *>(pValue) = m_value;
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
m_used = true;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return m_base.GetVoidValue(name, valueType, pValue);
|
||||
}
|
||||
|
||||
private:
|
||||
BASE m_base;
|
||||
const char *m_name;
|
||||
T m_value;
|
||||
#ifndef NDEBUG
|
||||
mutable bool m_used;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class T>
|
||||
AlgorithmParameters<NullNameValuePairs,T> MakeParameters(const char *name, const T &value)
|
||||
{
|
||||
return AlgorithmParameters<NullNameValuePairs,T>(g_nullNameValuePairs, name, value);
|
||||
}
|
||||
|
||||
#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
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
// arc4.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
// The ARC4 algorithm was first revealed in an anonymous email to the
|
||||
// cypherpunks mailing list. This file originally contained some
|
||||
// code copied from this email. The code has since been rewritten in order
|
||||
// to clarify the copyright status of this file. It should now be
|
||||
// completely in the public domain.
|
||||
|
||||
#include "pch.h"
|
||||
#include "arc4.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
void ARC4_TestInstantiations()
|
||||
{
|
||||
ARC4 x;
|
||||
}
|
||||
|
||||
ARC4_Base::~ARC4_Base()
|
||||
{
|
||||
m_x = m_y = 0;
|
||||
}
|
||||
|
||||
void ARC4_Base::UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int keyLen)
|
||||
{
|
||||
AssertValidKeyLength(keyLen);
|
||||
|
||||
m_x = 1;
|
||||
m_y = 0;
|
||||
|
||||
unsigned int i;
|
||||
for (i=0; i<256; i++)
|
||||
m_state[i] = i;
|
||||
|
||||
unsigned int keyIndex = 0, stateIndex = 0;
|
||||
for (i=0; i<256; i++)
|
||||
{
|
||||
unsigned int a = m_state[i];
|
||||
stateIndex += key[keyIndex] + a;
|
||||
stateIndex &= 0xff;
|
||||
m_state[i] = m_state[stateIndex];
|
||||
m_state[stateIndex] = a;
|
||||
if (++keyIndex >= keyLen)
|
||||
keyIndex = 0;
|
||||
}
|
||||
|
||||
int discardBytes = params.GetIntValueWithDefault("DiscardBytes", GetDefaultDiscardBytes());
|
||||
DiscardBytes(discardBytes);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static inline unsigned int MakeByte(T &x, T &y, byte *s)
|
||||
{
|
||||
unsigned int a = s[x];
|
||||
y = (y+a) & 0xff;
|
||||
unsigned int b = s[y];
|
||||
s[x] = b;
|
||||
s[y] = a;
|
||||
x = (x+1) & 0xff;
|
||||
return s[(a+b) & 0xff];
|
||||
}
|
||||
|
||||
byte ARC4_Base::GenerateByte()
|
||||
{
|
||||
return MakeByte(m_x, m_y, m_state);
|
||||
}
|
||||
|
||||
void ARC4_Base::ProcessData(byte *outString, const byte *inString, unsigned int length)
|
||||
{
|
||||
if (length == 0)
|
||||
return;
|
||||
|
||||
byte *const s = m_state;
|
||||
unsigned int x = m_x;
|
||||
unsigned int y = m_y;
|
||||
|
||||
if (inString == outString)
|
||||
{
|
||||
do
|
||||
{
|
||||
*outString++ ^= MakeByte(x, y, s);
|
||||
} while (--length);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
*outString++ = *inString++ ^ MakeByte(x, y, s);
|
||||
}
|
||||
while(--length);
|
||||
}
|
||||
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
}
|
||||
|
||||
void ARC4_Base::DiscardBytes(unsigned int length)
|
||||
{
|
||||
if (length == 0)
|
||||
return;
|
||||
|
||||
byte *const s = m_state;
|
||||
unsigned int x = m_x;
|
||||
unsigned int y = m_y;
|
||||
|
||||
do
|
||||
{
|
||||
MakeByte(x, y, s);
|
||||
}
|
||||
while(--length);
|
||||
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
#ifndef CRYPTOPP_ARC4_H
|
||||
#define CRYPTOPP_ARC4_H
|
||||
|
||||
#include "strciphr.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! <a href="http://www.weidai.com/scan-mirror/cs.html#RC4">Alleged RC4</a>
|
||||
/*! You can #ARC4 typedef rather than this class directly. */
|
||||
class ARC4_Base : public VariableKeyLength<16, 1, 256>, public RandomNumberGenerator, public SymmetricCipher
|
||||
{
|
||||
public:
|
||||
~ARC4_Base();
|
||||
|
||||
static const char *StaticAlgorithmName() {return "ARC4";}
|
||||
|
||||
byte GenerateByte();
|
||||
void DiscardBytes(unsigned int n);
|
||||
|
||||
void ProcessData(byte *outString, const byte *inString, unsigned int length);
|
||||
|
||||
bool IsRandomAccess() const {return false;}
|
||||
bool IsSelfInverting() const {return true;}
|
||||
bool IsForwardTransformation() const {return true;}
|
||||
|
||||
typedef SymmetricCipherFinalTemplate<ARC4_Base> Encryption;
|
||||
typedef SymmetricCipherFinalTemplate<ARC4_Base> Decryption;
|
||||
|
||||
protected:
|
||||
void UncheckedSetKey(const NameValuePairs ¶ms, const byte *key, unsigned int length);
|
||||
virtual unsigned int GetDefaultDiscardBytes() const {return 0;}
|
||||
|
||||
FixedSizeSecBlock<byte, 256> m_state;
|
||||
byte m_x, m_y;
|
||||
};
|
||||
|
||||
//! .
|
||||
typedef SymmetricCipherFinalTemplate<ARC4_Base> ARC4;
|
||||
|
||||
//! Modified ARC4: it discards the first 256 bytes of keystream which may be weaker than the rest
|
||||
/*! You can #MARC4 typedef rather than this class directly. */
|
||||
class MARC4_Base : public ARC4_Base
|
||||
{
|
||||
public:
|
||||
static const char *StaticAlgorithmName() {return "MARC4";}
|
||||
|
||||
typedef SymmetricCipherFinalTemplate<MARC4_Base> Encryption;
|
||||
typedef SymmetricCipherFinalTemplate<MARC4_Base> Decryption;
|
||||
|
||||
protected:
|
||||
unsigned int GetDefaultDiscardBytes() const {return 256;}
|
||||
};
|
||||
|
||||
//! .
|
||||
typedef SymmetricCipherFinalTemplate<MARC4_Base> MARC4;
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
#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) //!< const byte *
|
||||
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(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(HashVerificationFilterFlags) //!< word32
|
||||
CRYPTOPP_DEFINE_NAME_STRING(SignatureVerificationFilterFlags) //!< word32
|
||||
CRYPTOPP_DEFINE_NAME_STRING(InputBuffer) //!< ConstByteArrayParameter
|
||||
CRYPTOPP_DEFINE_NAME_STRING(OutputBuffer) //!< ByteArrayParameter
|
||||
CRYPTOPP_DEFINE_NAME_STRING(XMACC_Counter) //!< word32
|
||||
|
||||
DOCUMENTED_NAMESPACE_END
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,556 @@
|
|||
// asn.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "asn.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <time.h>
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
USING_NAMESPACE(std)
|
||||
|
||||
/// DER Length
|
||||
unsigned int DERLengthEncode(BufferedTransformation &bt, unsigned int length)
|
||||
{
|
||||
unsigned int 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, unsigned int &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, unsigned int &length)
|
||||
{
|
||||
bool definiteLength;
|
||||
if (!BERLengthDecode(bt, length, definiteLength))
|
||||
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();
|
||||
unsigned int length;
|
||||
if (!BERLengthDecode(in, length) || length != 0)
|
||||
BERDecodeError();
|
||||
}
|
||||
|
||||
/// ASN Strings
|
||||
unsigned int DEREncodeOctetString(BufferedTransformation &bt, const byte *str, unsigned int strLen)
|
||||
{
|
||||
bt.Put(OCTET_STRING);
|
||||
unsigned int lengthBytes = DERLengthEncode(bt, strLen);
|
||||
bt.Put(str, strLen);
|
||||
return 1+lengthBytes+strLen;
|
||||
}
|
||||
|
||||
unsigned int DEREncodeOctetString(BufferedTransformation &bt, const SecByteBlock &str)
|
||||
{
|
||||
return DEREncodeOctetString(bt, str.begin(), str.size());
|
||||
}
|
||||
|
||||
unsigned int BERDecodeOctetString(BufferedTransformation &bt, SecByteBlock &str)
|
||||
{
|
||||
byte b;
|
||||
if (!bt.Get(b) || b != OCTET_STRING)
|
||||
BERDecodeError();
|
||||
|
||||
unsigned int bc;
|
||||
if (!BERLengthDecode(bt, bc))
|
||||
BERDecodeError();
|
||||
|
||||
str.resize(bc);
|
||||
if (bc != bt.Get(str, bc))
|
||||
BERDecodeError();
|
||||
return bc;
|
||||
}
|
||||
|
||||
unsigned int BERDecodeOctetString(BufferedTransformation &bt, BufferedTransformation &str)
|
||||
{
|
||||
byte b;
|
||||
if (!bt.Get(b) || b != OCTET_STRING)
|
||||
BERDecodeError();
|
||||
|
||||
unsigned int bc;
|
||||
if (!BERLengthDecode(bt, bc))
|
||||
BERDecodeError();
|
||||
|
||||
bt.TransferTo(str, bc);
|
||||
return bc;
|
||||
}
|
||||
|
||||
unsigned int DEREncodeTextString(BufferedTransformation &bt, const std::string &str, byte asnTag)
|
||||
{
|
||||
bt.Put(asnTag);
|
||||
unsigned int lengthBytes = DERLengthEncode(bt, str.size());
|
||||
bt.Put((const byte *)str.data(), str.size());
|
||||
return 1+lengthBytes+str.size();
|
||||
}
|
||||
|
||||
unsigned int BERDecodeTextString(BufferedTransformation &bt, std::string &str, byte asnTag)
|
||||
{
|
||||
byte b;
|
||||
if (!bt.Get(b) || b != asnTag)
|
||||
BERDecodeError();
|
||||
|
||||
unsigned int 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
|
||||
unsigned int DEREncodeBitString(BufferedTransformation &bt, const byte *str, unsigned int strLen, unsigned int unusedBits)
|
||||
{
|
||||
bt.Put(BIT_STRING);
|
||||
unsigned int lengthBytes = DERLengthEncode(bt, strLen+1);
|
||||
bt.Put((byte)unusedBits);
|
||||
bt.Put(str, strLen);
|
||||
return 2+lengthBytes+strLen;
|
||||
}
|
||||
|
||||
unsigned int BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits)
|
||||
{
|
||||
byte b;
|
||||
if (!bt.Get(b) || b != BIT_STRING)
|
||||
BERDecodeError();
|
||||
|
||||
unsigned int 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 OID::EncodeValue(BufferedTransformation &bt, unsigned long 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));
|
||||
}
|
||||
|
||||
unsigned int OID::DecodeValue(BufferedTransformation &bt, unsigned long &v)
|
||||
{
|
||||
byte b;
|
||||
unsigned int i=0;
|
||||
v = 0;
|
||||
while (true)
|
||||
{
|
||||
if (!bt.Get(b))
|
||||
BERDecodeError();
|
||||
i++;
|
||||
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 (unsigned int 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();
|
||||
|
||||
unsigned int 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)
|
||||
{
|
||||
unsigned long v;
|
||||
unsigned int 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, unsigned int 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)
|
||||
{
|
||||
byte b;
|
||||
if (!m_inQueue.Get(b) || b != asnTag)
|
||||
BERDecodeError();
|
||||
|
||||
m_definiteLength = BERLengthDecode(m_inQueue, m_length);
|
||||
}
|
||||
|
||||
BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag)
|
||||
: m_inQueue(inQueue), m_finished(false)
|
||||
{
|
||||
byte b;
|
||||
if (!m_inQueue.Get(b) || b != asnTag)
|
||||
BERDecodeError();
|
||||
|
||||
m_definiteLength = BERLengthDecode(m_inQueue, m_length);
|
||||
if (!m_definiteLength && !(asnTag & CONSTRUCTED))
|
||||
BERDecodeError(); // cannot be primitive 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();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int BERGeneralDecoder::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
|
||||
{
|
||||
if (m_definiteLength && transferBytes > m_length)
|
||||
transferBytes = m_length;
|
||||
unsigned int blockedBytes = m_inQueue.TransferTo2(target, transferBytes, channel, blocking);
|
||||
ReduceLength(transferBytes);
|
||||
return blockedBytes;
|
||||
}
|
||||
|
||||
unsigned int BERGeneralDecoder::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
|
||||
{
|
||||
if (m_definiteLength)
|
||||
end = STDMIN((unsigned long)m_length, end);
|
||||
return m_inQueue.CopyRangeTo2(target, begin, end, channel, blocking);
|
||||
}
|
||||
|
||||
unsigned int BERGeneralDecoder::ReduceLength(unsigned int 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;
|
||||
unsigned int length = (unsigned int)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
|
||||
BERDecodeKey2(subjectPublicKey, parametersPresent, 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
|
||||
DEREncodeKey(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 = BERDecodeAlgorithmParameters(algorithm);
|
||||
algorithm.MessageEnd();
|
||||
|
||||
BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING);
|
||||
BERDecodeKey2(octetString, parametersPresent, privateKeyInfo.RemainingLength());
|
||||
octetString.MessageEnd();
|
||||
|
||||
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);
|
||||
DEREncodeKey(octetString);
|
||||
octetString.MessageEnd();
|
||||
|
||||
DEREncodeOptionalAttributes(privateKeyInfo);
|
||||
privateKeyInfo.MessageEnd();
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,344 @@
|
|||
#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 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);
|
||||
unsigned int DERLengthEncode(BufferedTransformation &out, unsigned int length);
|
||||
// returns false if indefinite length
|
||||
bool BERLengthDecode(BufferedTransformation &in, unsigned int &length);
|
||||
|
||||
void DEREncodeNull(BufferedTransformation &out);
|
||||
void BERDecodeNull(BufferedTransformation &in);
|
||||
|
||||
unsigned int DEREncodeOctetString(BufferedTransformation &out, const byte *str, unsigned int strLen);
|
||||
unsigned int DEREncodeOctetString(BufferedTransformation &out, const SecByteBlock &str);
|
||||
unsigned int BERDecodeOctetString(BufferedTransformation &in, SecByteBlock &str);
|
||||
unsigned int BERDecodeOctetString(BufferedTransformation &in, BufferedTransformation &str);
|
||||
|
||||
// for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING
|
||||
unsigned int DEREncodeTextString(BufferedTransformation &out, const std::string &str, byte asnTag);
|
||||
unsigned int BERDecodeTextString(BufferedTransformation &in, std::string &str, byte asnTag);
|
||||
|
||||
unsigned int DEREncodeBitString(BufferedTransformation &out, const byte *str, unsigned int strLen, unsigned int unusedBits=0);
|
||||
unsigned int BERDecodeBitString(BufferedTransformation &in, SecByteBlock &str, unsigned int &unusedBits);
|
||||
|
||||
//! Object Identifier
|
||||
class OID
|
||||
{
|
||||
public:
|
||||
OID() {}
|
||||
OID(unsigned long v) : m_values(1, v) {}
|
||||
OID(BufferedTransformation &bt) {BERDecode(bt);}
|
||||
|
||||
inline OID & operator+=(unsigned long 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<unsigned long> m_values;
|
||||
|
||||
private:
|
||||
static void EncodeValue(BufferedTransformation &bt, unsigned long v);
|
||||
static unsigned int DecodeValue(BufferedTransformation &bt, unsigned long &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, unsigned int 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;
|
||||
unsigned int m_lengthRemaining;
|
||||
};
|
||||
|
||||
//! BER General Decoder
|
||||
class BERGeneralDecoder : public Store
|
||||
{
|
||||
public:
|
||||
explicit BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag);
|
||||
explicit BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag);
|
||||
~BERGeneralDecoder();
|
||||
|
||||
bool IsDefiniteLength() const {return m_definiteLength;}
|
||||
unsigned int RemainingLength() const {assert(m_definiteLength); return m_length;}
|
||||
bool EndReached() const;
|
||||
byte PeekByte() const;
|
||||
void CheckByte(byte b);
|
||||
|
||||
unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
|
||||
unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
|
||||
|
||||
// call this to denote end of sequence
|
||||
void MessageEnd();
|
||||
|
||||
protected:
|
||||
BufferedTransformation &m_inQueue;
|
||||
bool m_finished, m_definiteLength;
|
||||
unsigned int m_length;
|
||||
|
||||
private:
|
||||
void StoreInitialize(const NameValuePairs ¶meters) {assert(false);}
|
||||
unsigned int ReduceLength(unsigned int delta);
|
||||
};
|
||||
|
||||
//! DER General Encoder
|
||||
class 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 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 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 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 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 (get() != NULL)
|
||||
get()->DEREncode(out);
|
||||
}
|
||||
};
|
||||
|
||||
//! .
|
||||
class ASN1Key : public ASN1CryptoMaterial
|
||||
{
|
||||
public:
|
||||
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
|
||||
// one of the following two should be overriden
|
||||
virtual void BERDecodeKey(BufferedTransformation &bt) {assert(false);}
|
||||
virtual void BERDecodeKey2(BufferedTransformation &bt, bool parametersPresent, unsigned int size)
|
||||
{BERDecodeKey(bt);}
|
||||
virtual void DEREncodeKey(BufferedTransformation &bt) const =0;
|
||||
};
|
||||
|
||||
//! .
|
||||
class X509PublicKey : virtual public ASN1Key, public PublicKey
|
||||
{
|
||||
public:
|
||||
void BERDecode(BufferedTransformation &bt);
|
||||
void DEREncode(BufferedTransformation &bt) const;
|
||||
};
|
||||
|
||||
//! .
|
||||
class PKCS8PrivateKey : virtual public ASN1Key, public PrivateKey
|
||||
{
|
||||
public:
|
||||
void BERDecode(BufferedTransformation &bt);
|
||||
void DEREncode(BufferedTransformation &bt) const;
|
||||
|
||||
virtual void BERDecodeOptionalAttributes(BufferedTransformation &bt)
|
||||
{} // TODO: skip optional attributes if present
|
||||
virtual void DEREncodeOptionalAttributes(BufferedTransformation &bt) const
|
||||
{}
|
||||
};
|
||||
|
||||
// ********************************************************
|
||||
|
||||
//! DER Encode Unsigned
|
||||
/*! for INTEGER, BOOLEAN, and ENUM */
|
||||
template <class T>
|
||||
unsigned int 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);
|
||||
unsigned int 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();
|
||||
|
||||
unsigned int 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
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
// 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("InsertLineBreaks", true);
|
||||
int maxLineLength = parameters.GetIntValueWithDefault("MaxLineLength", 72);
|
||||
|
||||
m_filter->Initialize(CombinedNameValuePairs(
|
||||
parameters,
|
||||
MakeParameters("EncodingLookupArray", (const byte *)s_vec)
|
||||
("PaddingByte", s_padding)
|
||||
("Log2Base", 6)
|
||||
("GroupSize", insertLineBreaks ? maxLineLength : 0)
|
||||
("Seperator", ConstByteArrayParameter("\n"))
|
||||
("Terminator", ConstByteArrayParameter("\n"))));
|
||||
}
|
||||
|
||||
const int *Base64Decoder::GetDecodingLookupArray()
|
||||
{
|
||||
static 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
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
#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("InsertLineBreaks", insertLineBreaks)("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 *GetDecodingLookupArray();
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,214 @@
|
|||
// basecode.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "basecode.h"
|
||||
#include "fltrimpl.h"
|
||||
#include <ctype.h>
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
void BaseN_Encoder::IsolatedInitialize(const NameValuePairs ¶meters)
|
||||
{
|
||||
parameters.GetRequiredParameter("BaseN_Encoder", "EncodingLookupArray", m_alphabet);
|
||||
|
||||
parameters.GetRequiredIntParameter("BaseN_Encoder", "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("PaddingByte", padding))
|
||||
pad = parameters.GetValueWithDefault("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);
|
||||
}
|
||||
|
||||
unsigned int BaseN_Encoder::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
|
||||
{
|
||||
FILTER_BEGIN;
|
||||
while (m_inputPosition < length)
|
||||
{
|
||||
if (m_bytePos == 0)
|
||||
memset(m_outBuf, 0, m_outputBlockSize);
|
||||
|
||||
m_outBuf[m_bytePos] |= begin[m_inputPosition] >> (8-m_bitsPerChar+m_bitPos);
|
||||
m_outBuf[m_bytePos+1] |= ((begin[m_inputPosition] << (m_bitsPerChar-m_bitPos)) & 0xff) >> (8-m_bitsPerChar);
|
||||
++m_inputPosition;
|
||||
|
||||
m_bitPos += 8;
|
||||
while (m_bitPos >= m_bitsPerChar)
|
||||
{
|
||||
m_bitPos -= m_bitsPerChar;
|
||||
++m_bytePos;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void BaseN_Decoder::IsolatedInitialize(const NameValuePairs ¶meters)
|
||||
{
|
||||
parameters.GetRequiredParameter("BaseN_Decoder", "DecodingLookupArray", m_lookup);
|
||||
|
||||
parameters.GetRequiredIntParameter("BaseN_Decoder", "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);
|
||||
}
|
||||
|
||||
unsigned int BaseN_Decoder::Put2(const byte *begin, unsigned int 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("GroupSize", 0);
|
||||
ConstByteArrayParameter seperator, terminator;
|
||||
if (m_groupSize)
|
||||
parameters.GetRequiredParameter("Grouper", "Seperator", seperator);
|
||||
else
|
||||
parameters.GetValue("Seperator", seperator);
|
||||
parameters.GetValue("Terminator", terminator);
|
||||
|
||||
m_seperator.Assign(seperator.begin(), seperator.size());
|
||||
m_terminator.Assign(terminator.begin(), terminator.size());
|
||||
m_counter = 0;
|
||||
}
|
||||
|
||||
unsigned int Grouper::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
|
||||
{
|
||||
if (m_groupSize)
|
||||
{
|
||||
FILTER_BEGIN;
|
||||
while (m_inputPosition < length)
|
||||
{
|
||||
if (m_counter == m_groupSize)
|
||||
{
|
||||
FILTER_OUTPUT(1, m_seperator, m_seperator.size(), 0);
|
||||
m_counter = 0;
|
||||
}
|
||||
|
||||
unsigned int len;
|
||||
FILTER_OUTPUT2(2, len = STDMIN(length-m_inputPosition, m_groupSize-m_counter),
|
||||
begin+m_inputPosition, len, 0);
|
||||
m_inputPosition += len;
|
||||
m_counter += len;
|
||||
}
|
||||
if (messageEnd)
|
||||
FILTER_OUTPUT(3, m_terminator, m_terminator.size(), messageEnd);
|
||||
FILTER_END_NO_MESSAGE_END
|
||||
}
|
||||
else
|
||||
return Output(0, begin, length, messageEnd, blocking);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
#ifndef CRYPTOPP_BASECODE_H
|
||||
#define CRYPTOPP_BASECODE_H
|
||||
|
||||
#include "filters.h"
|
||||
#include "algparam.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
class BaseN_Encoder : public Unflushable<Filter>
|
||||
{
|
||||
public:
|
||||
BaseN_Encoder(BufferedTransformation *attachment=NULL)
|
||||
: Unflushable<Filter>(attachment) {}
|
||||
|
||||
BaseN_Encoder(const byte *alphabet, int log2base, BufferedTransformation *attachment=NULL, int padding=-1)
|
||||
: Unflushable<Filter>(attachment)
|
||||
{
|
||||
IsolatedInitialize(MakeParameters("EncodingLookupArray", alphabet)
|
||||
("Log2Base", log2base)
|
||||
("Pad", padding != -1)
|
||||
("PaddingByte", byte(padding)));
|
||||
}
|
||||
|
||||
void IsolatedInitialize(const NameValuePairs ¶meters);
|
||||
unsigned int Put2(const byte *begin, unsigned int 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;
|
||||
};
|
||||
|
||||
class BaseN_Decoder : public Unflushable<Filter>
|
||||
{
|
||||
public:
|
||||
BaseN_Decoder(BufferedTransformation *attachment=NULL)
|
||||
: Unflushable<Filter>(attachment) {}
|
||||
|
||||
BaseN_Decoder(const int *lookup, int log2base, BufferedTransformation *attachment=NULL)
|
||||
: Unflushable<Filter>(attachment)
|
||||
{
|
||||
IsolatedInitialize(MakeParameters("DecodingLookupArray", lookup)("Log2Base", log2base));
|
||||
}
|
||||
|
||||
void IsolatedInitialize(const NameValuePairs ¶meters);
|
||||
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
|
||||
|
||||
static void InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int log2base, bool caseInsensitive);
|
||||
|
||||
private:
|
||||
const int *m_lookup;
|
||||
int m_padding, m_bitsPerChar, m_outputBlockSize;
|
||||
int m_bytePos, m_bitPos;
|
||||
SecByteBlock m_outBuf;
|
||||
};
|
||||
|
||||
class Grouper : public Bufferless<Filter>
|
||||
{
|
||||
public:
|
||||
Grouper(BufferedTransformation *attachment=NULL)
|
||||
: Bufferless<Filter>(attachment) {}
|
||||
|
||||
Grouper(int groupSize, const std::string &seperator, const std::string &terminator, BufferedTransformation *attachment=NULL)
|
||||
: Bufferless<Filter>(attachment)
|
||||
{
|
||||
IsolatedInitialize(MakeParameters("GroupSize", groupSize)
|
||||
("Seperator", ConstByteArrayParameter(seperator))
|
||||
("Terminator", ConstByteArrayParameter(terminator)));
|
||||
}
|
||||
|
||||
void IsolatedInitialize(const NameValuePairs ¶meters);
|
||||
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
|
||||
|
||||
private:
|
||||
SecByteBlock m_seperator, m_terminator;
|
||||
unsigned int m_groupSize, m_counter;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,655 @@
|
|||
// bench.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "crc.h"
|
||||
#include "adler32.h"
|
||||
#include "md2.h"
|
||||
#include "md5.h"
|
||||
#include "md5mac.h"
|
||||
#include "sha.h"
|
||||
#include "haval.h"
|
||||
#include "tiger.h"
|
||||
#include "ripemd.h"
|
||||
#include "panama.h"
|
||||
#include "idea.h"
|
||||
#include "des.h"
|
||||
#include "rc2.h"
|
||||
#include "arc4.h"
|
||||
#include "rc5.h"
|
||||
#include "blowfish.h"
|
||||
#include "diamond.h"
|
||||
#include "wake.h"
|
||||
#include "3way.h"
|
||||
#include "safer.h"
|
||||
#include "gost.h"
|
||||
#include "shark.h"
|
||||
#include "cast.h"
|
||||
#include "square.h"
|
||||
#include "skipjack.h"
|
||||
#include "seal.h"
|
||||
#include "rc6.h"
|
||||
#include "mars.h"
|
||||
#include "rijndael.h"
|
||||
#include "twofish.h"
|
||||
#include "serpent.h"
|
||||
#include "hmac.h"
|
||||
#include "xormac.h"
|
||||
#include "cbcmac.h"
|
||||
#include "dmac.h"
|
||||
#include "blumshub.h"
|
||||
#include "rsa.h"
|
||||
#include "nr.h"
|
||||
#include "dsa.h"
|
||||
#include "luc.h"
|
||||
#include "rabin.h"
|
||||
#include "rw.h"
|
||||
#include "eccrypto.h"
|
||||
#include "ecp.h"
|
||||
#include "ec2n.h"
|
||||
#include "asn.h"
|
||||
#include "rng.h"
|
||||
#include "files.h"
|
||||
#include "hex.h"
|
||||
#include "modes.h"
|
||||
#include "mdc.h"
|
||||
#include "lubyrack.h"
|
||||
#include "sapphire.h"
|
||||
#include "tea.h"
|
||||
#include "dh.h"
|
||||
#include "mqv.h"
|
||||
#include "xtrcrypt.h"
|
||||
#include "esign.h"
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
USING_NAMESPACE(CryptoPP)
|
||||
USING_NAMESPACE(std)
|
||||
|
||||
#ifdef CLOCKS_PER_SEC
|
||||
static const double CLOCK_TICKS_PER_SECOND = (double)CLOCKS_PER_SEC;
|
||||
#elif defined(CLK_TCK)
|
||||
static const double CLOCK_TICKS_PER_SECOND = (double)CLK_TCK;
|
||||
#else
|
||||
static const double CLOCK_TICKS_PER_SECOND = 1000000.0;
|
||||
#endif
|
||||
|
||||
static const byte *const key=(byte *)"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
static double logtotal = 0;
|
||||
static unsigned int logcount = 0;
|
||||
|
||||
void OutputResultBytes(const char *name, unsigned long length, double timeTaken)
|
||||
{
|
||||
double mbs = length / timeTaken / (1024*1024);
|
||||
cout << "<TR><TH>" << name;
|
||||
cout << "<TD>" << length;
|
||||
cout << setiosflags(ios::fixed);
|
||||
cout << "<TD>" << setprecision(3) << timeTaken;
|
||||
cout << "<TD>" << setprecision(3) << mbs << endl;
|
||||
cout << resetiosflags(ios::fixed);
|
||||
logtotal += log(mbs);
|
||||
logcount++;
|
||||
}
|
||||
|
||||
void OutputResultOperations(const char *name, const char *operation, bool pc, unsigned long iterations, double timeTaken)
|
||||
{
|
||||
cout << "<TR><TH>" << name << " " << operation << (pc ? " with precomputation" : "");
|
||||
cout << "<TD>" << iterations;
|
||||
cout << setiosflags(ios::fixed);
|
||||
cout << "<TD>" << setprecision(3) << timeTaken;
|
||||
cout << "<TD>" << setprecision(2) << (1000*timeTaken/iterations) << endl;
|
||||
cout << resetiosflags(ios::fixed);
|
||||
|
||||
logtotal += log(iterations/timeTaken);
|
||||
logcount++;
|
||||
}
|
||||
|
||||
void BenchMark(const char *name, BlockTransformation &cipher, double timeTotal)
|
||||
{
|
||||
const int BUF_SIZE = RoundDownToMultipleOf(1024U, cipher.OptimalNumberOfParallelBlocks() * cipher.BlockSize());
|
||||
SecByteBlock buf(BUF_SIZE);
|
||||
const int nBlocks = BUF_SIZE / cipher.BlockSize();
|
||||
clock_t start = clock();
|
||||
|
||||
unsigned long i=0, length=BUF_SIZE;
|
||||
double timeTaken;
|
||||
do
|
||||
{
|
||||
length *= 2;
|
||||
for (; i<length; i+=BUF_SIZE)
|
||||
cipher.ProcessAndXorMultipleBlocks(buf, NULL, buf, nBlocks);
|
||||
timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND;
|
||||
}
|
||||
while (timeTaken < 2.0/3*timeTotal);
|
||||
|
||||
OutputResultBytes(name, length, timeTaken);
|
||||
}
|
||||
|
||||
void BenchMark(const char *name, StreamTransformation &cipher, double timeTotal)
|
||||
{
|
||||
const int BUF_SIZE=1024;
|
||||
SecByteBlock buf(BUF_SIZE);
|
||||
clock_t start = clock();
|
||||
|
||||
unsigned long i=0, length=BUF_SIZE;
|
||||
double timeTaken;
|
||||
do
|
||||
{
|
||||
length *= 2;
|
||||
for (; i<length; i+=BUF_SIZE)
|
||||
cipher.ProcessString(buf, BUF_SIZE);
|
||||
timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND;
|
||||
}
|
||||
while (timeTaken < 2.0/3*timeTotal);
|
||||
|
||||
OutputResultBytes(name, length, timeTaken);
|
||||
}
|
||||
|
||||
void BenchMark(const char *name, HashTransformation &hash, double timeTotal)
|
||||
{
|
||||
const int BUF_SIZE=1024;
|
||||
SecByteBlock buf(BUF_SIZE);
|
||||
LC_RNG rng(time(NULL));
|
||||
rng.GenerateBlock(buf, BUF_SIZE);
|
||||
clock_t start = clock();
|
||||
|
||||
unsigned long i=0, length=BUF_SIZE;
|
||||
double timeTaken;
|
||||
do
|
||||
{
|
||||
length *= 2;
|
||||
for (; i<length; i+=BUF_SIZE)
|
||||
hash.Update(buf, BUF_SIZE);
|
||||
timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND;
|
||||
}
|
||||
while (timeTaken < 2.0/3*timeTotal);
|
||||
|
||||
OutputResultBytes(name, length, timeTaken);
|
||||
}
|
||||
|
||||
void BenchMark(const char *name, BufferedTransformation &bt, double timeTotal)
|
||||
{
|
||||
const int BUF_SIZE=1024;
|
||||
SecByteBlock buf(BUF_SIZE);
|
||||
LC_RNG rng(time(NULL));
|
||||
rng.GenerateBlock(buf, BUF_SIZE);
|
||||
clock_t start = clock();
|
||||
|
||||
unsigned long i=0, length=BUF_SIZE;
|
||||
double timeTaken;
|
||||
do
|
||||
{
|
||||
length *= 2;
|
||||
for (; i<length; i+=BUF_SIZE)
|
||||
bt.Put(buf, BUF_SIZE);
|
||||
timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND;
|
||||
}
|
||||
while (timeTaken < 2.0/3*timeTotal);
|
||||
|
||||
OutputResultBytes(name, length, timeTaken);
|
||||
}
|
||||
|
||||
void BenchMarkEncryption(const char *name, PK_Encryptor &key, double timeTotal, bool pc=false)
|
||||
{
|
||||
unsigned int len = 16;
|
||||
LC_RNG rng(time(NULL));
|
||||
SecByteBlock plaintext(len), ciphertext(key.CiphertextLength(len));
|
||||
rng.GenerateBlock(plaintext, len);
|
||||
|
||||
clock_t start = clock();
|
||||
unsigned int i;
|
||||
double timeTaken;
|
||||
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
|
||||
key.Encrypt(rng, plaintext, len, ciphertext);
|
||||
|
||||
OutputResultOperations(name, "Encryption", pc, i, timeTaken);
|
||||
|
||||
if (!pc && key.GetMaterial().SupportsPrecomputation())
|
||||
{
|
||||
key.AccessMaterial().Precompute(16);
|
||||
BenchMarkEncryption(name, key, timeTotal, true);
|
||||
}
|
||||
}
|
||||
|
||||
void BenchMarkDecryption(const char *name, PK_Decryptor &priv, PK_Encryptor &pub, double timeTotal)
|
||||
{
|
||||
unsigned int len = 16;
|
||||
LC_RNG rng(time(NULL));
|
||||
SecByteBlock ciphertext(pub.CiphertextLength(len));
|
||||
SecByteBlock plaintext(pub.MaxPlaintextLength(ciphertext.size()));
|
||||
rng.GenerateBlock(plaintext, len);
|
||||
pub.Encrypt(rng, plaintext, len, ciphertext);
|
||||
|
||||
clock_t start = clock();
|
||||
unsigned int i;
|
||||
double timeTaken;
|
||||
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
|
||||
priv.Decrypt(ciphertext, ciphertext.size(), plaintext);
|
||||
|
||||
OutputResultOperations(name, "Decryption", false, i, timeTaken);
|
||||
}
|
||||
|
||||
void BenchMarkSigning(const char *name, PK_Signer &key, double timeTotal, bool pc=false)
|
||||
{
|
||||
unsigned int len = 16;
|
||||
LC_RNG rng(time(NULL));
|
||||
SecByteBlock message(len), signature(key.SignatureLength());
|
||||
rng.GenerateBlock(message, len);
|
||||
|
||||
clock_t start = clock();
|
||||
unsigned int i;
|
||||
double timeTaken;
|
||||
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
|
||||
key.SignMessage(rng, message, len, signature);
|
||||
|
||||
OutputResultOperations(name, "Signature", pc, i, timeTaken);
|
||||
|
||||
if (!pc && key.GetMaterial().SupportsPrecomputation())
|
||||
{
|
||||
key.AccessMaterial().Precompute(16);
|
||||
BenchMarkSigning(name, key, timeTotal, true);
|
||||
}
|
||||
}
|
||||
|
||||
void BenchMarkVerification(const char *name, const PK_Signer &priv, PK_Verifier &pub, double timeTotal, bool pc=false)
|
||||
{
|
||||
unsigned int len = 16;
|
||||
LC_RNG rng(time(NULL));
|
||||
SecByteBlock message(len), signature(pub.SignatureLength());
|
||||
rng.GenerateBlock(message, len);
|
||||
priv.SignMessage(rng, message, len, signature);
|
||||
|
||||
clock_t start = clock();
|
||||
unsigned int i;
|
||||
double timeTaken;
|
||||
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
|
||||
pub.VerifyMessage(message, len, signature);
|
||||
|
||||
OutputResultOperations(name, "Verification", pc, i, timeTaken);
|
||||
|
||||
if (!pc && pub.GetMaterial().SupportsPrecomputation())
|
||||
{
|
||||
pub.AccessMaterial().Precompute(16);
|
||||
BenchMarkVerification(name, priv, pub, timeTotal, true);
|
||||
}
|
||||
}
|
||||
|
||||
void BenchMarkKeyGen(const char *name, SimpleKeyAgreementDomain &d, double timeTotal, bool pc=false)
|
||||
{
|
||||
LC_RNG rng(time(NULL));
|
||||
SecByteBlock priv(d.PrivateKeyLength()), pub(d.PublicKeyLength());
|
||||
|
||||
clock_t start = clock();
|
||||
unsigned int i;
|
||||
double timeTaken;
|
||||
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
|
||||
d.GenerateKeyPair(rng, priv, pub);
|
||||
|
||||
OutputResultOperations(name, "Key-Pair Generation", pc, i, timeTaken);
|
||||
|
||||
if (!pc && d.GetMaterial().SupportsPrecomputation())
|
||||
{
|
||||
d.AccessMaterial().Precompute(16);
|
||||
BenchMarkKeyGen(name, d, timeTotal, true);
|
||||
}
|
||||
}
|
||||
|
||||
void BenchMarkKeyGen(const char *name, AuthenticatedKeyAgreementDomain &d, double timeTotal, bool pc=false)
|
||||
{
|
||||
LC_RNG rng(time(NULL));
|
||||
SecByteBlock priv(d.EphemeralPrivateKeyLength()), pub(d.EphemeralPublicKeyLength());
|
||||
|
||||
clock_t start = clock();
|
||||
unsigned int i;
|
||||
double timeTaken;
|
||||
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++)
|
||||
d.GenerateEphemeralKeyPair(rng, priv, pub);
|
||||
|
||||
OutputResultOperations(name, "Key-Pair Generation", pc, i, timeTaken);
|
||||
|
||||
if (!pc && d.GetMaterial().SupportsPrecomputation())
|
||||
{
|
||||
d.AccessMaterial().Precompute(16);
|
||||
BenchMarkKeyGen(name, d, timeTotal, true);
|
||||
}
|
||||
}
|
||||
|
||||
void BenchMarkAgreement(const char *name, SimpleKeyAgreementDomain &d, double timeTotal, bool pc=false)
|
||||
{
|
||||
LC_RNG rng(time(NULL));
|
||||
SecByteBlock priv1(d.PrivateKeyLength()), priv2(d.PrivateKeyLength());
|
||||
SecByteBlock pub1(d.PublicKeyLength()), pub2(d.PublicKeyLength());
|
||||
d.GenerateKeyPair(rng, priv1, pub1);
|
||||
d.GenerateKeyPair(rng, priv2, pub2);
|
||||
SecByteBlock val(d.AgreedValueLength());
|
||||
|
||||
clock_t start = clock();
|
||||
unsigned int i;
|
||||
double timeTaken;
|
||||
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i+=2)
|
||||
{
|
||||
d.Agree(val, priv1, pub2);
|
||||
d.Agree(val, priv2, pub1);
|
||||
}
|
||||
|
||||
OutputResultOperations(name, "Key Agreement", pc, i, timeTaken);
|
||||
}
|
||||
|
||||
void BenchMarkAgreement(const char *name, AuthenticatedKeyAgreementDomain &d, double timeTotal, bool pc=false)
|
||||
{
|
||||
LC_RNG rng(time(NULL));
|
||||
SecByteBlock spriv1(d.StaticPrivateKeyLength()), spriv2(d.StaticPrivateKeyLength());
|
||||
SecByteBlock epriv1(d.EphemeralPrivateKeyLength()), epriv2(d.EphemeralPrivateKeyLength());
|
||||
SecByteBlock spub1(d.StaticPublicKeyLength()), spub2(d.StaticPublicKeyLength());
|
||||
SecByteBlock epub1(d.EphemeralPublicKeyLength()), epub2(d.EphemeralPublicKeyLength());
|
||||
d.GenerateStaticKeyPair(rng, spriv1, spub1);
|
||||
d.GenerateStaticKeyPair(rng, spriv2, spub2);
|
||||
d.GenerateEphemeralKeyPair(rng, epriv1, epub1);
|
||||
d.GenerateEphemeralKeyPair(rng, epriv2, epub2);
|
||||
SecByteBlock val(d.AgreedValueLength());
|
||||
|
||||
clock_t start = clock();
|
||||
unsigned int i;
|
||||
double timeTaken;
|
||||
for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i+=2)
|
||||
{
|
||||
d.Agree(val, spriv1, epriv1, spub2, epub2);
|
||||
d.Agree(val, spriv2, epriv2, spub1, epub1);
|
||||
}
|
||||
|
||||
OutputResultOperations(name, "Key Agreement", pc, i, timeTaken);
|
||||
}
|
||||
|
||||
//VC60 workaround: compiler bug triggered without the extra dummy parameters
|
||||
template <class T>
|
||||
void BenchMarkKeyed(const char *name, double timeTotal, T *x=NULL)
|
||||
{
|
||||
T c;
|
||||
c.SetKeyWithIV(key, c.DefaultKeyLength(), key);
|
||||
BenchMark(name, c, timeTotal);
|
||||
}
|
||||
|
||||
//VC60 workaround: compiler bug triggered without the extra dummy parameters
|
||||
template <class T>
|
||||
void BenchMarkKeyedVariable(const char *name, double timeTotal, unsigned int keyLength, T *x=NULL)
|
||||
{
|
||||
T c;
|
||||
c.SetKeyWithIV(key, keyLength, key);
|
||||
BenchMark(name, c, timeTotal);
|
||||
}
|
||||
|
||||
//VC60 workaround: compiler bug triggered without the extra dummy parameters
|
||||
template <class T>
|
||||
void BenchMarkKeyless(const char *name, double timeTotal, T *x=NULL)
|
||||
{
|
||||
T c;
|
||||
BenchMark(name, c, timeTotal);
|
||||
}
|
||||
|
||||
//VC60 workaround: compiler bug triggered without the extra dummy parameters
|
||||
template <class SCHEME>
|
||||
void BenchMarkCrypto(const char *filename, const char *name, double timeTotal, SCHEME *x=NULL)
|
||||
{
|
||||
FileSource f(filename, true, new HexDecoder());
|
||||
typename SCHEME::Decryptor priv(f);
|
||||
typename SCHEME::Encryptor pub(priv);
|
||||
BenchMarkEncryption(name, pub, timeTotal);
|
||||
BenchMarkDecryption(name, priv, pub, timeTotal);
|
||||
}
|
||||
|
||||
//VC60 workaround: compiler bug triggered without the extra dummy parameters
|
||||
template <class SCHEME>
|
||||
void BenchMarkSignature(const char *filename, const char *name, double timeTotal, SCHEME *x=NULL)
|
||||
{
|
||||
FileSource f(filename, true, new HexDecoder());
|
||||
typename SCHEME::Signer priv(f);
|
||||
typename SCHEME::Verifier pub(priv);
|
||||
BenchMarkSigning(name, priv, timeTotal);
|
||||
BenchMarkVerification(name, priv, pub, timeTotal);
|
||||
}
|
||||
|
||||
//VC60 workaround: compiler bug triggered without the extra dummy parameters
|
||||
template <class D>
|
||||
void BenchMarkKeyAgreement(const char *filename, const char *name, double timeTotal, D *x=NULL)
|
||||
{
|
||||
FileSource f(filename, true, new HexDecoder());
|
||||
D d(f);
|
||||
BenchMarkKeyGen(name, d, timeTotal);
|
||||
BenchMarkAgreement(name, d, timeTotal);
|
||||
}
|
||||
|
||||
void BenchMarkAll(double t)
|
||||
{
|
||||
#if 1
|
||||
logtotal = 0;
|
||||
logcount = 0;
|
||||
|
||||
cout << "<TABLE border=1><COLGROUP><COL align=left><COL align=right><COL align=right><COL align=right>" << endl;
|
||||
cout << "<THEAD><TR><TH>Algorithm<TH>Bytes Processed<TH>Time Taken<TH>Megabytes(2^20 bytes)/Second\n<TBODY>" << endl;
|
||||
|
||||
BenchMarkKeyless<CRC32>("CRC-32", t);
|
||||
BenchMarkKeyless<Adler32>("Adler-32", t);
|
||||
BenchMarkKeyless<MD2>("MD2", t);
|
||||
BenchMarkKeyless<MD5>("MD5", t);
|
||||
BenchMarkKeyless<SHA>("SHA-1", t);
|
||||
BenchMarkKeyless<SHA256>("SHA-256", t);
|
||||
BenchMarkKeyless<SHA512>("SHA-512", t);
|
||||
BenchMarkKeyless<HAVAL3>("HAVAL (pass=3)", t);
|
||||
BenchMarkKeyless<HAVAL4>("HAVAL (pass=4)", t);
|
||||
BenchMarkKeyless<HAVAL5>("HAVAL (pass=5)", t);
|
||||
#ifdef WORD64_AVAILABLE
|
||||
BenchMarkKeyless<Tiger>("Tiger", t);
|
||||
#endif
|
||||
BenchMarkKeyless<RIPEMD160>("RIPE-MD160", t);
|
||||
BenchMarkKeyless<PanamaHash<LittleEndian> >("Panama Hash (little endian)", t);
|
||||
BenchMarkKeyless<PanamaHash<BigEndian> >("Panama Hash (big endian)", t);
|
||||
BenchMarkKeyed<MDC<MD5>::Encryption>("MDC/MD5", t);
|
||||
BenchMarkKeyed<LR<MD5>::Encryption>("Luby-Rackoff/MD5", t);
|
||||
BenchMarkKeyed<DES::Encryption>("DES", t);
|
||||
BenchMarkKeyed<DES_XEX3::Encryption>("DES-XEX3", t);
|
||||
BenchMarkKeyed<DES_EDE3::Encryption>("DES-EDE3", t);
|
||||
BenchMarkKeyed<IDEA::Encryption>("IDEA", t);
|
||||
BenchMarkKeyed<RC2::Encryption>("RC2", t);
|
||||
BenchMarkKeyed<RC5::Encryption>("RC5 (r=16)", t);
|
||||
BenchMarkKeyed<Blowfish::Encryption>("Blowfish", t);
|
||||
BenchMarkKeyed<Diamond2::Encryption>("Diamond2", t);
|
||||
BenchMarkKeyed<Diamond2Lite::Encryption>("Diamond2 Lite", t);
|
||||
BenchMarkKeyed<ThreeWayDecryption>("3-WAY", t);
|
||||
BenchMarkKeyed<TEA::Encryption>("TEA", t);
|
||||
BenchMarkKeyedVariable<SAFER_SK::Encryption>("SAFER (r=8)", t, 8);
|
||||
BenchMarkKeyed<GOST::Encryption>("GOST", t);
|
||||
#ifdef WORD64_AVAILABLE
|
||||
BenchMarkKeyed<SHARK::Encryption>("SHARK (r=6)", t);
|
||||
#endif
|
||||
BenchMarkKeyed<CAST128::Encryption>("CAST-128", t);
|
||||
BenchMarkKeyed<CAST256::Encryption>("CAST-256", t);
|
||||
BenchMarkKeyed<Square::Encryption>("Square", t);
|
||||
BenchMarkKeyed<SKIPJACK::Encryption>("SKIPJACK", t);
|
||||
BenchMarkKeyed<RC6::Encryption>("RC6", t);
|
||||
BenchMarkKeyed<MARS::Encryption>("MARS", t);
|
||||
BenchMarkKeyedVariable<Rijndael::Encryption>("Rijndael (128-bit key)", t, 16);
|
||||
BenchMarkKeyedVariable<Rijndael::Encryption>("Rijndael (192-bit key)", t, 24);
|
||||
BenchMarkKeyedVariable<Rijndael::Encryption>("Rijndael (256-bit key)", t, 32);
|
||||
BenchMarkKeyedVariable<CTR_Mode<Rijndael>::Encryption>("Rijndael (128) CTR", t, 16);
|
||||
BenchMarkKeyedVariable<OFB_Mode<Rijndael>::Encryption>("Rijndael (128) OFB", t, 16);
|
||||
BenchMarkKeyedVariable<CFB_Mode<Rijndael>::Encryption>("Rijndael (128) CFB", t, 16);
|
||||
BenchMarkKeyedVariable<CBC_Mode<Rijndael>::Encryption>("Rijndael (128) CBC", t, 16);
|
||||
BenchMarkKeyed<Twofish::Encryption>("Twofish", t);
|
||||
BenchMarkKeyed<Serpent::Encryption>("Serpent", t);
|
||||
BenchMarkKeyed<ARC4>("ARC4", t);
|
||||
BenchMarkKeyed<SEAL<BigEndian>::Encryption>("SEAL-3.0-BE", t);
|
||||
BenchMarkKeyed<SEAL<LittleEndian>::Encryption>("SEAL-3.0-LE", t);
|
||||
BenchMarkKeyed<WAKE_CFB<BigEndian>::Encryption>("WAKE-CFB-BE", t);
|
||||
BenchMarkKeyed<WAKE_CFB<LittleEndian>::Encryption>("WAKE-CFB-LE", t);
|
||||
BenchMarkKeyed<WAKE_OFB<BigEndian>::Encryption>("WAKE-OFB-BE", t);
|
||||
BenchMarkKeyed<WAKE_OFB<LittleEndian>::Encryption>("WAKE-OFB-LE", t);
|
||||
BenchMarkKeyed<PanamaCipher<LittleEndian>::Encryption>("Panama Cipher (little endian)", t);
|
||||
BenchMarkKeyed<PanamaCipher<BigEndian>::Encryption>("Panama Cipher (big endian)", t);
|
||||
BenchMarkKeyed<MD5MAC>("MD5-MAC", t);
|
||||
BenchMarkKeyed<XMACC<MD5> >("XMACC/MD5", t);
|
||||
BenchMarkKeyed<HMAC<MD5> >("HMAC/MD5", t);
|
||||
BenchMarkKeyed<CBC_MAC<Rijndael> >("CBC-MAC/Rijndael", t);
|
||||
BenchMarkKeyed<DMAC<Rijndael> >("DMAC/Rijndael", t);
|
||||
|
||||
{
|
||||
Integer p("CB6C,B8CE,6351,164F,5D0C,0C9E,9E31,E231,CF4E,D551,CBD0,E671,5D6A,7B06,D8DF,C4A7h");
|
||||
Integer q("FD2A,8594,A132,20CC,4E6D,DE77,3AAA,CF15,CD9E,E447,8592,FF46,CC77,87BE,9876,A2AFh");
|
||||
Integer s("63239752671357255800299643604761065219897634268887145610573595874544114193025997412441121667211431");
|
||||
BlumBlumShub c(p, q, s);
|
||||
BenchMark("BlumBlumShub 512", c, t);
|
||||
}
|
||||
{
|
||||
Integer p("FD2A,8594,A132,20CC,4E6D,DE77,3AAA,CF15,CD9E,E447,8592,FF46,CC77,87BE,9876,9E2C,"
|
||||
"8572,64C3,4CF4,188A,44D4,2130,1135,7982,6FF6,EDD3,26F0,5FAA,BAF4,A81E,7ADC,B80Bh");
|
||||
Integer q("C8B9,5797,B349,6BA3,FD72,F2C0,A796,8A65,EE0F,B4BA,272F,4FEE,4DB1,06D5,ECEB,7142,"
|
||||
"E8A8,E5A8,6BF9,A32F,BA37,BACC,8A75,8A6B,2DCE,D6EC,B515,980A,4BB1,08FB,6F2C,2383h");
|
||||
Integer s("3578,8F00,2965,71A4,4382,699F,45FD,3922,8238,241B,CEBA,0543,3443,E8D9,12FB,AC46,"
|
||||
"7EC4,8505,EC9E,7EE8,5A23,9B2A,B615,D0C4,9448,F23A,ADEE,E850,1A7A,CA30,0B5B,A408,"
|
||||
"D936,21BA,844E,BDD6,7848,3D1E,9137,CC87,DAA5,773B,D45A,C8BB,5392,1393,108B,6992,"
|
||||
"74E3,C5E2,C235,A321,0111,3BA4,BAB4,1A2F,17EE,C371,DE67,01C9,0F3D,907A,B252,9BDDh");
|
||||
BlumBlumShub c(p, q, s);
|
||||
BenchMark("BlumBlumShub 1024", c, t);
|
||||
}
|
||||
{
|
||||
Integer p("EB56,978A,7BA7,B5D9,1383,4611,94F5,4766,FCEF,CF41,958A,FC41,43D0,839F,C56B,B568,"
|
||||
"4ED3,9E5A,BABB,5ACE,8B11,CEBC,88A2,7C12,FFEE,E6E8,CF0A,E231,5BC2,DEDE,80B7,32F6,"
|
||||
"340E,D8A6,B7DE,C779,7EE5,0E16,9C88,FC9F,2A0E,EE6C,7D47,C5F2,6B06,EB8C,F1C8,2E67,"
|
||||
"5B82,8C28,4FB8,542F,2874,C355,CEEE,7A54,1B06,A8AB,8B66,6A5C,9DB2,72B8,74F3,7BC7h");
|
||||
Integer q("EB6B,3645,4591,8343,7331,7CAC,B02E,4BB9,DEF5,8EDC,1772,DB9B,9571,5FAB,1CDD,4FB1,"
|
||||
"7B9A,07CD,E715,D448,F552,CBBD,D387,C037,DE70,6661,F360,D0E8,D42E,292A,9321,DDCB,"
|
||||
"0BF9,C514,BFAC,3F2C,C06E,DF64,A9B8,50D6,AC4F,B9E4,014B,5624,2B40,A0D4,5D0B,6DD4,"
|
||||
"0989,D00E,0268,99AB,21DB,0BB4,DB38,84DA,594F,575F,95AC,1B70,45E4,96C8,C6AD,CE67h");
|
||||
Integer s("C75A,8A0D,E231,295F,C08A,1716,8611,D5EC,E9EF,B565,90EC,58C0,57D0,DA7D,C6E6,DB00,"
|
||||
"2282,1CA7,EA31,D64E,768C,0B19,8563,36DF,2226,F4EC,74A4,2844,2E8D,37E8,53DC,0172,"
|
||||
"5F56,8CF9,B444,CA02,78B3,17AF,7C78,D320,16AE,AC3D,B97F,7259,1B8F,9C84,6A16,B878,"
|
||||
"0595,70BB,9C52,18B5,9100,9C1F,E85A,4035,06F3,5F38,7462,F01D,0462,BFBC,A4CD,4A45,"
|
||||
"3A77,E7F8,DED1,D6EF,CEF7,0937,CD3F,3AF1,4F88,932D,6D4B,002C,3735,304C,C5D3,B88A,"
|
||||
"B57B,24B6,5346,9B46,5153,B7ED,B216,C181,B1C6,C52E,CD2B,E0AA,B1BB,0A93,C92E,4F79,"
|
||||
"4931,E303,7C8F,A408,8ACF,56CD,6EC0,76A2,5015,6BA4,4C50,C44D,53B9,E168,5F84,B381,"
|
||||
"2514,10B2,00E5,B4D1,4156,A2FE,0BF6,6F33,0A1B,91C6,31B8,1C90,02F1,FB1F,C494,8B65h");
|
||||
BlumBlumShub c(p, q, s);
|
||||
BenchMark("BlumBlumShub 2048", c, t);
|
||||
}
|
||||
cout << "</TABLE>" << endl;
|
||||
|
||||
cout << "<TABLE border=1><COLGROUP><COL align=left><COL align=right><COL align=right><COL align=right>" << endl;
|
||||
cout << "<THEAD><TR><TH>Operation<TH>Iterations<TH>Total Time<TH>Milliseconds/Operation" << endl;
|
||||
|
||||
cout << "<TBODY style=\"background: yellow\">" << endl;
|
||||
BenchMarkCrypto<RSAES<OAEP<SHA> > >("rsa1024.dat", "RSA 1024", t);
|
||||
BenchMarkCrypto<RabinES<OAEP<SHA> > >("rabi1024.dat", "Rabin 1024", t);
|
||||
BenchMarkCrypto<LUCES<OAEP<SHA> > >("luc1024.dat", "LUC 1024", t);
|
||||
BenchMarkCrypto<DLIES<> >("dlie1024.dat", "DLIES 1024", t);
|
||||
BenchMarkCrypto<LUC_IES<> >("lucc512.dat", "LUCELG 512", t);
|
||||
|
||||
cout << "<TBODY style=\"background: white\">" << endl;
|
||||
BenchMarkCrypto<RSAES<OAEP<SHA> > >("rsa2048.dat", "RSA 2048", t);
|
||||
BenchMarkCrypto<RabinES<OAEP<SHA> > >("rabi2048.dat", "Rabin 2048", t);
|
||||
BenchMarkCrypto<LUCES<OAEP<SHA> > >("luc2048.dat", "LUC 2048", t);
|
||||
BenchMarkCrypto<DLIES<> >("dlie2048.dat", "DLIES 2048", t);
|
||||
BenchMarkCrypto<LUC_IES<> >("lucc1024.dat", "LUCELG 1024", t);
|
||||
|
||||
cout << "<TBODY style=\"background: yellow\">" << endl;
|
||||
BenchMarkSignature<RSASSA<PKCS1v15, SHA> >("rsa1024.dat", "RSA 1024", t);
|
||||
BenchMarkSignature<RabinPSSR<SHA> >("rabi1024.dat", "Rabin 1024", t);
|
||||
BenchMarkSignature<RWSSA<SHA> >("rw1024.dat", "RW 1024", t);
|
||||
BenchMarkSignature<LUCSSA<SHA> >("luc1024.dat", "LUC 1024", t);
|
||||
BenchMarkSignature<NR<SHA> >("nr1024.dat", "NR 1024", t);
|
||||
BenchMarkSignature<DSA>("dsa1024.dat", "DSA 1024", t);
|
||||
BenchMarkSignature<LUC_HMP<SHA> >("lucs512.dat", "LUC-HMP 512", t);
|
||||
BenchMarkSignature<ESIGN<SHA> >("esig1023.dat", "ESIGN 1023", t);
|
||||
BenchMarkSignature<ESIGN<SHA> >("esig1536.dat", "ESIGN 1536", t);
|
||||
|
||||
cout << "<TBODY style=\"background: white\">" << endl;
|
||||
BenchMarkSignature<RSASSA<PKCS1v15, SHA> >("rsa2048.dat", "RSA 2048", t);
|
||||
BenchMarkSignature<RabinPSSR<SHA> >("rabi2048.dat", "Rabin 2048", t);
|
||||
BenchMarkSignature<RWSSA<SHA> >("rw2048.dat", "RW 2048", t);
|
||||
BenchMarkSignature<LUCSSA<SHA> >("luc2048.dat", "LUC 2048", t);
|
||||
BenchMarkSignature<NR<SHA> >("nr2048.dat", "NR 2048", t);
|
||||
BenchMarkSignature<LUC_HMP<SHA> >("lucs1024.dat", "LUC-HMP 1024", t);
|
||||
BenchMarkSignature<ESIGN<SHA> >("esig2046.dat", "ESIGN 2046", t);
|
||||
|
||||
cout << "<TBODY style=\"background: yellow\">" << endl;
|
||||
BenchMarkKeyAgreement<XTR_DH>("xtrdh171.dat", "XTR-DH 171", t);
|
||||
BenchMarkKeyAgreement<XTR_DH>("xtrdh342.dat", "XTR-DH 342", t);
|
||||
BenchMarkKeyAgreement<DH>("dh1024.dat", "DH 1024", t);
|
||||
BenchMarkKeyAgreement<DH>("dh2048.dat", "DH 2048", t);
|
||||
BenchMarkKeyAgreement<LUC_DH>("lucd512.dat", "LUCDIF 512", t);
|
||||
BenchMarkKeyAgreement<LUC_DH>("lucd1024.dat", "LUCDIF 1024", t);
|
||||
BenchMarkKeyAgreement<MQV>("mqv1024.dat", "MQV 1024", t);
|
||||
BenchMarkKeyAgreement<MQV>("mqv2048.dat", "MQV 2048", t);
|
||||
|
||||
cout << "<TBODY style=\"background: white\">" << endl;
|
||||
{
|
||||
Integer modulus("199999999999999999999999980586675243082581144187569");
|
||||
Integer a("659942,b7261b,249174,c86bd5,e2a65b,45fe07,37d110h");
|
||||
Integer b("3ece7d,09473d,666000,5baef5,d4e00e,30159d,2df49ah");
|
||||
Integer x("25dd61,4c0667,81abc0,fe6c84,fefaa3,858ca6,96d0e8h");
|
||||
Integer y("4e2477,05aab0,b3497f,d62b5e,78a531,446729,6c3fach");
|
||||
Integer r("100000000000000000000000000000000000000000000000151");
|
||||
Integer k(2);
|
||||
Integer d("76572944925670636209790912427415155085360939712345");
|
||||
|
||||
ECP ec(modulus, a, b);
|
||||
ECP::Point P(x, y);
|
||||
P = ec.Multiply(k, P);
|
||||
ECP::Point Q(ec.Multiply(d, P));
|
||||
ECIES<ECP>::Decryptor cpriv(ec, P, r, d);
|
||||
ECIES<ECP>::Encryptor cpub(cpriv);
|
||||
ECDSA<ECP, SHA>::Signer spriv(cpriv);
|
||||
ECDSA<ECP, SHA>::Verifier spub(spriv);
|
||||
ECDH<ECP>::Domain ecdhc(ec, P, r, k);
|
||||
ECMQV<ECP>::Domain ecmqvc(ec, P, r, k);
|
||||
|
||||
BenchMarkEncryption("ECIES over GF(p) 168", cpub, t);
|
||||
BenchMarkDecryption("ECIES over GF(p) 168", cpriv, cpub, t);
|
||||
BenchMarkSigning("ECNR over GF(p) 168", spriv, t);
|
||||
BenchMarkVerification("ECNR over GF(p) 168", spriv, spub, t);
|
||||
BenchMarkKeyGen("ECDHC over GF(p) 168", ecdhc, t);
|
||||
BenchMarkAgreement("ECDHC over GF(p) 168", ecdhc, t);
|
||||
BenchMarkKeyGen("ECMQVC over GF(p) 168", ecmqvc, t);
|
||||
BenchMarkAgreement("ECMQVC over GF(p) 168", ecmqvc, t);
|
||||
}
|
||||
|
||||
cout << "<TBODY style=\"background: yellow\">" << endl;
|
||||
{
|
||||
Integer r("3805993847215893016155463826195386266397436443");
|
||||
Integer k(12);
|
||||
Integer d("2065729449256706362097909124274151550853609397");
|
||||
|
||||
GF2NT gf2n(155, 62, 0);
|
||||
byte b[]={0x7, 0x33, 0x8f};
|
||||
EC2N ec(gf2n, PolynomialMod2::Zero(), PolynomialMod2(b,3));
|
||||
EC2N::Point P(0x7B, 0x1C8);
|
||||
P = ec.Multiply(k, P);
|
||||
EC2N::Point Q(ec.Multiply(d, P));
|
||||
ECIES<EC2N>::Decryptor cpriv(ec, P, r, d);
|
||||
ECIES<EC2N>::Encryptor cpub(cpriv);
|
||||
ECDSA<EC2N, SHA>::Signer spriv(cpriv);
|
||||
ECDSA<EC2N, SHA>::Verifier spub(spriv);
|
||||
ECDH<EC2N>::Domain ecdhc(ec, P, r, k);
|
||||
ECMQV<EC2N>::Domain ecmqvc(ec, P, r, k);
|
||||
|
||||
BenchMarkEncryption("ECIES over GF(2^n) 155", cpub, t);
|
||||
BenchMarkDecryption("ECIES over GF(2^n) 155", cpriv, cpub, t);
|
||||
BenchMarkSigning("ECNR over GF(2^n) 155", spriv, t);
|
||||
BenchMarkVerification("ECNR over GF(2^n) 155", spriv, spub, t);
|
||||
BenchMarkKeyGen("ECDHC over GF(2^n) 155", ecdhc, t);
|
||||
BenchMarkAgreement("ECDHC over GF(2^n) 155", ecdhc, t);
|
||||
BenchMarkKeyGen("ECMQVC over GF(2^n) 155", ecmqvc, t);
|
||||
BenchMarkAgreement("ECMQVC over GF(2^n) 155", ecmqvc, t);
|
||||
}
|
||||
cout << "</TABLE>" << endl;
|
||||
|
||||
cout << "Throughput Geometric Average: " << setiosflags(ios::fixed) << exp(logtotal/logcount) << endl;
|
||||
|
||||
time_t endTime = time(NULL);
|
||||
cout << "\nTest ended at " << asctime(localtime(&endTime));
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef CRYPTOPP_BENCH_H
|
||||
#define CRYPTOPP_BENCH_H
|
||||
|
||||
#include "cryptlib.h"
|
||||
|
||||
void BenchMarkAll(double t=1.0);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,277 @@
|
|||
#include "pch.h"
|
||||
#include "blowfish.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
const word32 Blowfish::Base::p_init[Blowfish::ROUNDS+2] =
|
||||
{
|
||||
608135816U, 2242054355U, 320440878U, 57701188U,
|
||||
2752067618U, 698298832U, 137296536U, 3964562569U,
|
||||
1160258022U, 953160567U, 3193202383U, 887688300U,
|
||||
3232508343U, 3380367581U, 1065670069U, 3041331479U,
|
||||
2450970073U, 2306472731U
|
||||
} ;
|
||||
|
||||
const word32 Blowfish::Base::s_init[4*256] = {
|
||||
3509652390U, 2564797868U, 805139163U, 3491422135U,
|
||||
3101798381U, 1780907670U, 3128725573U, 4046225305U,
|
||||
614570311U, 3012652279U, 134345442U, 2240740374U,
|
||||
1667834072U, 1901547113U, 2757295779U, 4103290238U,
|
||||
227898511U, 1921955416U, 1904987480U, 2182433518U,
|
||||
2069144605U, 3260701109U, 2620446009U, 720527379U,
|
||||
3318853667U, 677414384U, 3393288472U, 3101374703U,
|
||||
2390351024U, 1614419982U, 1822297739U, 2954791486U,
|
||||
3608508353U, 3174124327U, 2024746970U, 1432378464U,
|
||||
3864339955U, 2857741204U, 1464375394U, 1676153920U,
|
||||
1439316330U, 715854006U, 3033291828U, 289532110U,
|
||||
2706671279U, 2087905683U, 3018724369U, 1668267050U,
|
||||
732546397U, 1947742710U, 3462151702U, 2609353502U,
|
||||
2950085171U, 1814351708U, 2050118529U, 680887927U,
|
||||
999245976U, 1800124847U, 3300911131U, 1713906067U,
|
||||
1641548236U, 4213287313U, 1216130144U, 1575780402U,
|
||||
4018429277U, 3917837745U, 3693486850U, 3949271944U,
|
||||
596196993U, 3549867205U, 258830323U, 2213823033U,
|
||||
772490370U, 2760122372U, 1774776394U, 2652871518U,
|
||||
566650946U, 4142492826U, 1728879713U, 2882767088U,
|
||||
1783734482U, 3629395816U, 2517608232U, 2874225571U,
|
||||
1861159788U, 326777828U, 3124490320U, 2130389656U,
|
||||
2716951837U, 967770486U, 1724537150U, 2185432712U,
|
||||
2364442137U, 1164943284U, 2105845187U, 998989502U,
|
||||
3765401048U, 2244026483U, 1075463327U, 1455516326U,
|
||||
1322494562U, 910128902U, 469688178U, 1117454909U,
|
||||
936433444U, 3490320968U, 3675253459U, 1240580251U,
|
||||
122909385U, 2157517691U, 634681816U, 4142456567U,
|
||||
3825094682U, 3061402683U, 2540495037U, 79693498U,
|
||||
3249098678U, 1084186820U, 1583128258U, 426386531U,
|
||||
1761308591U, 1047286709U, 322548459U, 995290223U,
|
||||
1845252383U, 2603652396U, 3431023940U, 2942221577U,
|
||||
3202600964U, 3727903485U, 1712269319U, 422464435U,
|
||||
3234572375U, 1170764815U, 3523960633U, 3117677531U,
|
||||
1434042557U, 442511882U, 3600875718U, 1076654713U,
|
||||
1738483198U, 4213154764U, 2393238008U, 3677496056U,
|
||||
1014306527U, 4251020053U, 793779912U, 2902807211U,
|
||||
842905082U, 4246964064U, 1395751752U, 1040244610U,
|
||||
2656851899U, 3396308128U, 445077038U, 3742853595U,
|
||||
3577915638U, 679411651U, 2892444358U, 2354009459U,
|
||||
1767581616U, 3150600392U, 3791627101U, 3102740896U,
|
||||
284835224U, 4246832056U, 1258075500U, 768725851U,
|
||||
2589189241U, 3069724005U, 3532540348U, 1274779536U,
|
||||
3789419226U, 2764799539U, 1660621633U, 3471099624U,
|
||||
4011903706U, 913787905U, 3497959166U, 737222580U,
|
||||
2514213453U, 2928710040U, 3937242737U, 1804850592U,
|
||||
3499020752U, 2949064160U, 2386320175U, 2390070455U,
|
||||
2415321851U, 4061277028U, 2290661394U, 2416832540U,
|
||||
1336762016U, 1754252060U, 3520065937U, 3014181293U,
|
||||
791618072U, 3188594551U, 3933548030U, 2332172193U,
|
||||
3852520463U, 3043980520U, 413987798U, 3465142937U,
|
||||
3030929376U, 4245938359U, 2093235073U, 3534596313U,
|
||||
375366246U, 2157278981U, 2479649556U, 555357303U,
|
||||
3870105701U, 2008414854U, 3344188149U, 4221384143U,
|
||||
3956125452U, 2067696032U, 3594591187U, 2921233993U,
|
||||
2428461U, 544322398U, 577241275U, 1471733935U,
|
||||
610547355U, 4027169054U, 1432588573U, 1507829418U,
|
||||
2025931657U, 3646575487U, 545086370U, 48609733U,
|
||||
2200306550U, 1653985193U, 298326376U, 1316178497U,
|
||||
3007786442U, 2064951626U, 458293330U, 2589141269U,
|
||||
3591329599U, 3164325604U, 727753846U, 2179363840U,
|
||||
146436021U, 1461446943U, 4069977195U, 705550613U,
|
||||
3059967265U, 3887724982U, 4281599278U, 3313849956U,
|
||||
1404054877U, 2845806497U, 146425753U, 1854211946U,
|
||||
|
||||
1266315497U, 3048417604U, 3681880366U, 3289982499U,
|
||||
2909710000U, 1235738493U, 2632868024U, 2414719590U,
|
||||
3970600049U, 1771706367U, 1449415276U, 3266420449U,
|
||||
422970021U, 1963543593U, 2690192192U, 3826793022U,
|
||||
1062508698U, 1531092325U, 1804592342U, 2583117782U,
|
||||
2714934279U, 4024971509U, 1294809318U, 4028980673U,
|
||||
1289560198U, 2221992742U, 1669523910U, 35572830U,
|
||||
157838143U, 1052438473U, 1016535060U, 1802137761U,
|
||||
1753167236U, 1386275462U, 3080475397U, 2857371447U,
|
||||
1040679964U, 2145300060U, 2390574316U, 1461121720U,
|
||||
2956646967U, 4031777805U, 4028374788U, 33600511U,
|
||||
2920084762U, 1018524850U, 629373528U, 3691585981U,
|
||||
3515945977U, 2091462646U, 2486323059U, 586499841U,
|
||||
988145025U, 935516892U, 3367335476U, 2599673255U,
|
||||
2839830854U, 265290510U, 3972581182U, 2759138881U,
|
||||
3795373465U, 1005194799U, 847297441U, 406762289U,
|
||||
1314163512U, 1332590856U, 1866599683U, 4127851711U,
|
||||
750260880U, 613907577U, 1450815602U, 3165620655U,
|
||||
3734664991U, 3650291728U, 3012275730U, 3704569646U,
|
||||
1427272223U, 778793252U, 1343938022U, 2676280711U,
|
||||
2052605720U, 1946737175U, 3164576444U, 3914038668U,
|
||||
3967478842U, 3682934266U, 1661551462U, 3294938066U,
|
||||
4011595847U, 840292616U, 3712170807U, 616741398U,
|
||||
312560963U, 711312465U, 1351876610U, 322626781U,
|
||||
1910503582U, 271666773U, 2175563734U, 1594956187U,
|
||||
70604529U, 3617834859U, 1007753275U, 1495573769U,
|
||||
4069517037U, 2549218298U, 2663038764U, 504708206U,
|
||||
2263041392U, 3941167025U, 2249088522U, 1514023603U,
|
||||
1998579484U, 1312622330U, 694541497U, 2582060303U,
|
||||
2151582166U, 1382467621U, 776784248U, 2618340202U,
|
||||
3323268794U, 2497899128U, 2784771155U, 503983604U,
|
||||
4076293799U, 907881277U, 423175695U, 432175456U,
|
||||
1378068232U, 4145222326U, 3954048622U, 3938656102U,
|
||||
3820766613U, 2793130115U, 2977904593U, 26017576U,
|
||||
3274890735U, 3194772133U, 1700274565U, 1756076034U,
|
||||
4006520079U, 3677328699U, 720338349U, 1533947780U,
|
||||
354530856U, 688349552U, 3973924725U, 1637815568U,
|
||||
332179504U, 3949051286U, 53804574U, 2852348879U,
|
||||
3044236432U, 1282449977U, 3583942155U, 3416972820U,
|
||||
4006381244U, 1617046695U, 2628476075U, 3002303598U,
|
||||
1686838959U, 431878346U, 2686675385U, 1700445008U,
|
||||
1080580658U, 1009431731U, 832498133U, 3223435511U,
|
||||
2605976345U, 2271191193U, 2516031870U, 1648197032U,
|
||||
4164389018U, 2548247927U, 300782431U, 375919233U,
|
||||
238389289U, 3353747414U, 2531188641U, 2019080857U,
|
||||
1475708069U, 455242339U, 2609103871U, 448939670U,
|
||||
3451063019U, 1395535956U, 2413381860U, 1841049896U,
|
||||
1491858159U, 885456874U, 4264095073U, 4001119347U,
|
||||
1565136089U, 3898914787U, 1108368660U, 540939232U,
|
||||
1173283510U, 2745871338U, 3681308437U, 4207628240U,
|
||||
3343053890U, 4016749493U, 1699691293U, 1103962373U,
|
||||
3625875870U, 2256883143U, 3830138730U, 1031889488U,
|
||||
3479347698U, 1535977030U, 4236805024U, 3251091107U,
|
||||
2132092099U, 1774941330U, 1199868427U, 1452454533U,
|
||||
157007616U, 2904115357U, 342012276U, 595725824U,
|
||||
1480756522U, 206960106U, 497939518U, 591360097U,
|
||||
863170706U, 2375253569U, 3596610801U, 1814182875U,
|
||||
2094937945U, 3421402208U, 1082520231U, 3463918190U,
|
||||
2785509508U, 435703966U, 3908032597U, 1641649973U,
|
||||
2842273706U, 3305899714U, 1510255612U, 2148256476U,
|
||||
2655287854U, 3276092548U, 4258621189U, 236887753U,
|
||||
3681803219U, 274041037U, 1734335097U, 3815195456U,
|
||||
3317970021U, 1899903192U, 1026095262U, 4050517792U,
|
||||
356393447U, 2410691914U, 3873677099U, 3682840055U,
|
||||
|
||||
3913112168U, 2491498743U, 4132185628U, 2489919796U,
|
||||
1091903735U, 1979897079U, 3170134830U, 3567386728U,
|
||||
3557303409U, 857797738U, 1136121015U, 1342202287U,
|
||||
507115054U, 2535736646U, 337727348U, 3213592640U,
|
||||
1301675037U, 2528481711U, 1895095763U, 1721773893U,
|
||||
3216771564U, 62756741U, 2142006736U, 835421444U,
|
||||
2531993523U, 1442658625U, 3659876326U, 2882144922U,
|
||||
676362277U, 1392781812U, 170690266U, 3921047035U,
|
||||
1759253602U, 3611846912U, 1745797284U, 664899054U,
|
||||
1329594018U, 3901205900U, 3045908486U, 2062866102U,
|
||||
2865634940U, 3543621612U, 3464012697U, 1080764994U,
|
||||
553557557U, 3656615353U, 3996768171U, 991055499U,
|
||||
499776247U, 1265440854U, 648242737U, 3940784050U,
|
||||
980351604U, 3713745714U, 1749149687U, 3396870395U,
|
||||
4211799374U, 3640570775U, 1161844396U, 3125318951U,
|
||||
1431517754U, 545492359U, 4268468663U, 3499529547U,
|
||||
1437099964U, 2702547544U, 3433638243U, 2581715763U,
|
||||
2787789398U, 1060185593U, 1593081372U, 2418618748U,
|
||||
4260947970U, 69676912U, 2159744348U, 86519011U,
|
||||
2512459080U, 3838209314U, 1220612927U, 3339683548U,
|
||||
133810670U, 1090789135U, 1078426020U, 1569222167U,
|
||||
845107691U, 3583754449U, 4072456591U, 1091646820U,
|
||||
628848692U, 1613405280U, 3757631651U, 526609435U,
|
||||
236106946U, 48312990U, 2942717905U, 3402727701U,
|
||||
1797494240U, 859738849U, 992217954U, 4005476642U,
|
||||
2243076622U, 3870952857U, 3732016268U, 765654824U,
|
||||
3490871365U, 2511836413U, 1685915746U, 3888969200U,
|
||||
1414112111U, 2273134842U, 3281911079U, 4080962846U,
|
||||
172450625U, 2569994100U, 980381355U, 4109958455U,
|
||||
2819808352U, 2716589560U, 2568741196U, 3681446669U,
|
||||
3329971472U, 1835478071U, 660984891U, 3704678404U,
|
||||
4045999559U, 3422617507U, 3040415634U, 1762651403U,
|
||||
1719377915U, 3470491036U, 2693910283U, 3642056355U,
|
||||
3138596744U, 1364962596U, 2073328063U, 1983633131U,
|
||||
926494387U, 3423689081U, 2150032023U, 4096667949U,
|
||||
1749200295U, 3328846651U, 309677260U, 2016342300U,
|
||||
1779581495U, 3079819751U, 111262694U, 1274766160U,
|
||||
443224088U, 298511866U, 1025883608U, 3806446537U,
|
||||
1145181785U, 168956806U, 3641502830U, 3584813610U,
|
||||
1689216846U, 3666258015U, 3200248200U, 1692713982U,
|
||||
2646376535U, 4042768518U, 1618508792U, 1610833997U,
|
||||
3523052358U, 4130873264U, 2001055236U, 3610705100U,
|
||||
2202168115U, 4028541809U, 2961195399U, 1006657119U,
|
||||
2006996926U, 3186142756U, 1430667929U, 3210227297U,
|
||||
1314452623U, 4074634658U, 4101304120U, 2273951170U,
|
||||
1399257539U, 3367210612U, 3027628629U, 1190975929U,
|
||||
2062231137U, 2333990788U, 2221543033U, 2438960610U,
|
||||
1181637006U, 548689776U, 2362791313U, 3372408396U,
|
||||
3104550113U, 3145860560U, 296247880U, 1970579870U,
|
||||
3078560182U, 3769228297U, 1714227617U, 3291629107U,
|
||||
3898220290U, 166772364U, 1251581989U, 493813264U,
|
||||
448347421U, 195405023U, 2709975567U, 677966185U,
|
||||
3703036547U, 1463355134U, 2715995803U, 1338867538U,
|
||||
1343315457U, 2802222074U, 2684532164U, 233230375U,
|
||||
2599980071U, 2000651841U, 3277868038U, 1638401717U,
|
||||
4028070440U, 3237316320U, 6314154U, 819756386U,
|
||||
300326615U, 590932579U, 1405279636U, 3267499572U,
|
||||
3150704214U, 2428286686U, 3959192993U, 3461946742U,
|
||||
1862657033U, 1266418056U, 963775037U, 2089974820U,
|
||||
2263052895U, 1917689273U, 448879540U, 3550394620U,
|
||||
3981727096U, 150775221U, 3627908307U, 1303187396U,
|
||||
508620638U, 2975983352U, 2726630617U, 1817252668U,
|
||||
1876281319U, 1457606340U, 908771278U, 3720792119U,
|
||||
3617206836U, 2455994898U, 1729034894U, 1080033504U,
|
||||
|
||||
976866871U, 3556439503U, 2881648439U, 1522871579U,
|
||||
1555064734U, 1336096578U, 3548522304U, 2579274686U,
|
||||
3574697629U, 3205460757U, 3593280638U, 3338716283U,
|
||||
3079412587U, 564236357U, 2993598910U, 1781952180U,
|
||||
1464380207U, 3163844217U, 3332601554U, 1699332808U,
|
||||
1393555694U, 1183702653U, 3581086237U, 1288719814U,
|
||||
691649499U, 2847557200U, 2895455976U, 3193889540U,
|
||||
2717570544U, 1781354906U, 1676643554U, 2592534050U,
|
||||
3230253752U, 1126444790U, 2770207658U, 2633158820U,
|
||||
2210423226U, 2615765581U, 2414155088U, 3127139286U,
|
||||
673620729U, 2805611233U, 1269405062U, 4015350505U,
|
||||
3341807571U, 4149409754U, 1057255273U, 2012875353U,
|
||||
2162469141U, 2276492801U, 2601117357U, 993977747U,
|
||||
3918593370U, 2654263191U, 753973209U, 36408145U,
|
||||
2530585658U, 25011837U, 3520020182U, 2088578344U,
|
||||
530523599U, 2918365339U, 1524020338U, 1518925132U,
|
||||
3760827505U, 3759777254U, 1202760957U, 3985898139U,
|
||||
3906192525U, 674977740U, 4174734889U, 2031300136U,
|
||||
2019492241U, 3983892565U, 4153806404U, 3822280332U,
|
||||
352677332U, 2297720250U, 60907813U, 90501309U,
|
||||
3286998549U, 1016092578U, 2535922412U, 2839152426U,
|
||||
457141659U, 509813237U, 4120667899U, 652014361U,
|
||||
1966332200U, 2975202805U, 55981186U, 2327461051U,
|
||||
676427537U, 3255491064U, 2882294119U, 3433927263U,
|
||||
1307055953U, 942726286U, 933058658U, 2468411793U,
|
||||
3933900994U, 4215176142U, 1361170020U, 2001714738U,
|
||||
2830558078U, 3274259782U, 1222529897U, 1679025792U,
|
||||
2729314320U, 3714953764U, 1770335741U, 151462246U,
|
||||
3013232138U, 1682292957U, 1483529935U, 471910574U,
|
||||
1539241949U, 458788160U, 3436315007U, 1807016891U,
|
||||
3718408830U, 978976581U, 1043663428U, 3165965781U,
|
||||
1927990952U, 4200891579U, 2372276910U, 3208408903U,
|
||||
3533431907U, 1412390302U, 2931980059U, 4132332400U,
|
||||
1947078029U, 3881505623U, 4168226417U, 2941484381U,
|
||||
1077988104U, 1320477388U, 886195818U, 18198404U,
|
||||
3786409000U, 2509781533U, 112762804U, 3463356488U,
|
||||
1866414978U, 891333506U, 18488651U, 661792760U,
|
||||
1628790961U, 3885187036U, 3141171499U, 876946877U,
|
||||
2693282273U, 1372485963U, 791857591U, 2686433993U,
|
||||
3759982718U, 3167212022U, 3472953795U, 2716379847U,
|
||||
445679433U, 3561995674U, 3504004811U, 3574258232U,
|
||||
54117162U, 3331405415U, 2381918588U, 3769707343U,
|
||||
4154350007U, 1140177722U, 4074052095U, 668550556U,
|
||||
3214352940U, 367459370U, 261225585U, 2610173221U,
|
||||
4209349473U, 3468074219U, 3265815641U, 314222801U,
|
||||
3066103646U, 3808782860U, 282218597U, 3406013506U,
|
||||
3773591054U, 379116347U, 1285071038U, 846784868U,
|
||||
2669647154U, 3771962079U, 3550491691U, 2305946142U,
|
||||
453669953U, 1268987020U, 3317592352U, 3279303384U,
|
||||
3744833421U, 2610507566U, 3859509063U, 266596637U,
|
||||
3847019092U, 517658769U, 3462560207U, 3443424879U,
|
||||
370717030U, 4247526661U, 2224018117U, 4143653529U,
|
||||
4112773975U, 2788324899U, 2477274417U, 1456262402U,
|
||||
2901442914U, 1517677493U, 1846949527U, 2295493580U,
|
||||
3734397586U, 2176403920U, 1280348187U, 1908823572U,
|
||||
3871786941U, 846861322U, 1172426758U, 3287448474U,
|
||||
3383383037U, 1655181056U, 3139813346U, 901632758U,
|
||||
1897031941U, 2986607138U, 3066810236U, 3447102507U,
|
||||
1393639104U, 373351379U, 950779232U, 625454576U,
|
||||
3124240540U, 4148612726U, 2007998917U, 544563296U,
|
||||
2244738638U, 2330496472U, 2058025392U, 1291430526U,
|
||||
424198748U, 50039436U, 29584100U, 3605783033U,
|
||||
2429876329U, 2791104160U, 1057563949U, 3255363231U,
|
||||
3075367218U, 3463963227U, 1469046755U, 985887462U
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
// blowfish.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "blowfish.h"
|
||||
#include "misc.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
void Blowfish::Base::UncheckedSetKey(CipherDir dir, const byte *key_string, unsigned int keylength)
|
||||
{
|
||||
AssertValidKeyLength(keylength);
|
||||
|
||||
unsigned i, j=0, k;
|
||||
word32 data, dspace[2] = {0, 0};
|
||||
|
||||
memcpy(pbox, p_init, sizeof(p_init));
|
||||
memcpy(sbox, s_init, sizeof(s_init));
|
||||
|
||||
// Xor key string into encryption key vector
|
||||
for (i=0 ; i<ROUNDS+2 ; ++i)
|
||||
{
|
||||
data = 0 ;
|
||||
for (k=0 ; k<4 ; ++k )
|
||||
data = (data << 8) | key_string[j++ % keylength];
|
||||
pbox[i] ^= data;
|
||||
}
|
||||
|
||||
crypt_block(dspace, pbox);
|
||||
|
||||
for (i=0; i<ROUNDS; i+=2)
|
||||
crypt_block(pbox+i, pbox+i+2);
|
||||
|
||||
crypt_block(pbox+ROUNDS, sbox);
|
||||
|
||||
for (i=0; i<4*256-2; i+=2)
|
||||
crypt_block(sbox+i, sbox+i+2);
|
||||
|
||||
if (dir==DECRYPTION)
|
||||
for (i=0; i<(ROUNDS+2)/2; i++)
|
||||
std::swap(pbox[i], pbox[ROUNDS+1-i]);
|
||||
}
|
||||
|
||||
// this version is only used to make pbox and sbox
|
||||
void Blowfish::Base::crypt_block(const word32 in[2], word32 out[2]) const
|
||||
{
|
||||
word32 left = in[0];
|
||||
word32 right = in[1];
|
||||
|
||||
const word32 *const s=sbox;
|
||||
const word32 *p=pbox;
|
||||
|
||||
left ^= p[0];
|
||||
|
||||
for (unsigned i=0; i<ROUNDS/2; i++)
|
||||
{
|
||||
right ^= (((s[GETBYTE(left,3)] + s[256+GETBYTE(left,2)])
|
||||
^ s[2*256+GETBYTE(left,1)]) + s[3*256+GETBYTE(left,0)])
|
||||
^ p[2*i+1];
|
||||
|
||||
left ^= (((s[GETBYTE(right,3)] + s[256+GETBYTE(right,2)])
|
||||
^ s[2*256+GETBYTE(right,1)]) + s[3*256+GETBYTE(right,0)])
|
||||
^ p[2*i+2];
|
||||
}
|
||||
|
||||
right ^= p[ROUNDS+1];
|
||||
|
||||
out[0] = right;
|
||||
out[1] = left;
|
||||
}
|
||||
|
||||
void Blowfish::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
typedef BlockGetAndPut<word32, BigEndian> Block;
|
||||
|
||||
word32 left, right;
|
||||
Block::Get(inBlock)(left)(right);
|
||||
|
||||
const word32 *const s=sbox;
|
||||
const word32 *p=pbox;
|
||||
|
||||
left ^= p[0];
|
||||
|
||||
for (unsigned i=0; i<ROUNDS/2; i++)
|
||||
{
|
||||
right ^= (((s[GETBYTE(left,3)] + s[256+GETBYTE(left,2)])
|
||||
^ s[2*256+GETBYTE(left,1)]) + s[3*256+GETBYTE(left,0)])
|
||||
^ p[2*i+1];
|
||||
|
||||
left ^= (((s[GETBYTE(right,3)] + s[256+GETBYTE(right,2)])
|
||||
^ s[2*256+GETBYTE(right,1)]) + s[3*256+GETBYTE(right,0)])
|
||||
^ p[2*i+2];
|
||||
}
|
||||
|
||||
right ^= p[ROUNDS+1];
|
||||
|
||||
Block::Put(xorBlock, outBlock)(right)(left);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef CRYPTOPP_BLOWFISH_H
|
||||
#define CRYPTOPP_BLOWFISH_H
|
||||
|
||||
/** \file */
|
||||
|
||||
#include "seckey.h"
|
||||
#include "secblock.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
struct Blowfish_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 1, 56>, public FixedRounds<16>
|
||||
{
|
||||
static const char *StaticAlgorithmName() {return "Blowfish";}
|
||||
};
|
||||
|
||||
//! <a href="http://www.weidai.com/scan-mirror/cs.html#Blowfish">Blowfish</a>
|
||||
class Blowfish : public Blowfish_Info, public BlockCipherDocumentation
|
||||
{
|
||||
class Base : public BlockCipherBaseTemplate<Blowfish_Info>
|
||||
{
|
||||
public:
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
void UncheckedSetKey(CipherDir direction, const byte *key_string, unsigned int keylength);
|
||||
|
||||
private:
|
||||
void crypt_block(const word32 in[2], word32 out[2]) const;
|
||||
|
||||
static const word32 p_init[ROUNDS+2];
|
||||
static const word32 s_init[4*256];
|
||||
|
||||
FixedSizeSecBlock<word32, ROUNDS+2> pbox;
|
||||
FixedSizeSecBlock<word32, 4*256> sbox;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef BlockCipherTemplate<ENCRYPTION, Base> Encryption;
|
||||
typedef BlockCipherTemplate<DECRYPTION, Base> Decryption;
|
||||
};
|
||||
|
||||
typedef Blowfish::Encryption BlowfishEncryption;
|
||||
typedef Blowfish::Decryption BlowfishDecryption;
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
// blumshub.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "blumshub.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
PublicBlumBlumShub::PublicBlumBlumShub(const Integer &n, const Integer &seed)
|
||||
: modn(n),
|
||||
maxBits(BitPrecision(n.BitCount())-1)
|
||||
{
|
||||
current = modn.Square(modn.Square(seed));
|
||||
bitsLeft = maxBits;
|
||||
}
|
||||
|
||||
unsigned int PublicBlumBlumShub::GenerateBit()
|
||||
{
|
||||
if (bitsLeft==0)
|
||||
{
|
||||
current = modn.Square(current);
|
||||
bitsLeft = maxBits;
|
||||
}
|
||||
|
||||
return current.GetBit(--bitsLeft);
|
||||
}
|
||||
|
||||
byte PublicBlumBlumShub::GenerateByte()
|
||||
{
|
||||
byte b=0;
|
||||
for (int i=0; i<8; i++)
|
||||
b = (b << 1) | PublicBlumBlumShub::GenerateBit();
|
||||
return b;
|
||||
}
|
||||
|
||||
BlumBlumShub::BlumBlumShub(const Integer &p, const Integer &q, const Integer &seed)
|
||||
: PublicBlumBlumShub(p*q, seed),
|
||||
p(p), q(q),
|
||||
x0(modn.Square(seed))
|
||||
{
|
||||
}
|
||||
|
||||
void BlumBlumShub::Seek(dword index)
|
||||
{
|
||||
Integer e = a_exp_b_mod_c (2, ((index*8) / maxBits + 1), (p-1)*(q-1));
|
||||
current = modn.Exponentiate(x0, e);
|
||||
bitsLeft = maxBits - int((index*8) % maxBits);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
#ifndef CRYPTOPP_BLUMSHUB_H
|
||||
#define CRYPTOPP_BLUMSHUB_H
|
||||
|
||||
#include "modarith.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
class BlumGoldwasserPublicKey;
|
||||
class BlumGoldwasserPrivateKey;
|
||||
|
||||
//! BlumBlumShub without factorization of the modulus
|
||||
class PublicBlumBlumShub : public RandomNumberGenerator,
|
||||
public StreamTransformation
|
||||
{
|
||||
public:
|
||||
PublicBlumBlumShub(const Integer &n, const Integer &seed);
|
||||
|
||||
unsigned int GenerateBit();
|
||||
byte GenerateByte();
|
||||
|
||||
void ProcessData(byte *outString, const byte *inString, unsigned int length)
|
||||
{
|
||||
while (length--)
|
||||
*outString++ = *inString ^ GenerateByte();
|
||||
}
|
||||
|
||||
bool IsSelfInverting() const {return true;}
|
||||
bool IsForwardTransformation() const {return true;}
|
||||
|
||||
protected:
|
||||
const ModularArithmetic modn;
|
||||
const int maxBits;
|
||||
Integer current;
|
||||
int bitsLeft;
|
||||
|
||||
friend class BlumGoldwasserPublicKey;
|
||||
friend class BlumGoldwasserPrivateKey;
|
||||
};
|
||||
|
||||
//! BlumBlumShub with factorization of the modulus
|
||||
class BlumBlumShub : public PublicBlumBlumShub
|
||||
{
|
||||
public:
|
||||
// Make sure p and q are both primes congruent to 3 mod 4 and at least 512 bits long,
|
||||
// seed is the secret key and should be about as big as p*q
|
||||
BlumBlumShub(const Integer &p, const Integer &q, const Integer &seed);
|
||||
|
||||
bool IsRandomAccess() const {return true;}
|
||||
void Seek(dword index);
|
||||
|
||||
protected:
|
||||
const Integer p, q;
|
||||
const Integer x0;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,296 @@
|
|||
// cast.cpp - written and placed in the public domain by Wei Dai and Leonard Janke
|
||||
// based on Steve Reid's public domain cast.c
|
||||
|
||||
#include "pch.h"
|
||||
#include "cast.h"
|
||||
#include "misc.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
/* Macros to access 8-bit bytes out of a 32-bit word */
|
||||
#define U8a(x) GETBYTE(x,3)
|
||||
#define U8b(x) GETBYTE(x,2)
|
||||
#define U8c(x) GETBYTE(x,1)
|
||||
#define U8d(x) GETBYTE(x,0)
|
||||
|
||||
/* CAST uses three different round functions */
|
||||
#define f1(l, r, km, kr) \
|
||||
t = rotlVariable(km + r, kr); \
|
||||
l ^= ((S[0][U8a(t)] ^ S[1][U8b(t)]) - \
|
||||
S[2][U8c(t)]) + S[3][U8d(t)];
|
||||
#define f2(l, r, km, kr) \
|
||||
t = rotlVariable(km ^ r, kr); \
|
||||
l ^= ((S[0][U8a(t)] - S[1][U8b(t)]) + \
|
||||
S[2][U8c(t)]) ^ S[3][U8d(t)];
|
||||
#define f3(l, r, km, kr) \
|
||||
t = rotlVariable(km - r, kr); \
|
||||
l ^= ((S[0][U8a(t)] + S[1][U8b(t)]) ^ \
|
||||
S[2][U8c(t)]) - S[3][U8d(t)];
|
||||
|
||||
#define F1(l, r, i, j) f1(l, r, K[i], K[i+j])
|
||||
#define F2(l, r, i, j) f2(l, r, K[i], K[i+j])
|
||||
#define F3(l, r, i, j) f3(l, r, K[i], K[i+j])
|
||||
|
||||
typedef BlockGetAndPut<word32, BigEndian> Block;
|
||||
|
||||
void CAST128::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
word32 t, l, r;
|
||||
|
||||
/* Get inblock into l,r */
|
||||
Block::Get(inBlock)(l)(r);
|
||||
/* Do the work */
|
||||
F1(l, r, 0, 16);
|
||||
F2(r, l, 1, 16);
|
||||
F3(l, r, 2, 16);
|
||||
F1(r, l, 3, 16);
|
||||
F2(l, r, 4, 16);
|
||||
F3(r, l, 5, 16);
|
||||
F1(l, r, 6, 16);
|
||||
F2(r, l, 7, 16);
|
||||
F3(l, r, 8, 16);
|
||||
F1(r, l, 9, 16);
|
||||
F2(l, r, 10, 16);
|
||||
F3(r, l, 11, 16);
|
||||
/* Only do full 16 rounds if key length > 80 bits */
|
||||
if (!reduced) {
|
||||
F1(l, r, 12, 16);
|
||||
F2(r, l, 13, 16);
|
||||
F3(l, r, 14, 16);
|
||||
F1(r, l, 15, 16);
|
||||
}
|
||||
/* Put l,r into outblock */
|
||||
Block::Put(xorBlock, outBlock)(r)(l);
|
||||
}
|
||||
|
||||
void CAST128::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
word32 t, l, r;
|
||||
|
||||
/* Get inblock into l,r */
|
||||
Block::Get(inBlock)(r)(l);
|
||||
/* Only do full 16 rounds if key length > 80 bits */
|
||||
if (!reduced) {
|
||||
F1(r, l, 15, 16);
|
||||
F3(l, r, 14, 16);
|
||||
F2(r, l, 13, 16);
|
||||
F1(l, r, 12, 16);
|
||||
}
|
||||
F3(r, l, 11, 16);
|
||||
F2(l, r, 10, 16);
|
||||
F1(r, l, 9, 16);
|
||||
F3(l, r, 8, 16);
|
||||
F2(r, l, 7, 16);
|
||||
F1(l, r, 6, 16);
|
||||
F3(r, l, 5, 16);
|
||||
F2(l, r, 4, 16);
|
||||
F1(r, l, 3, 16);
|
||||
F3(l, r, 2, 16);
|
||||
F2(r, l, 1, 16);
|
||||
F1(l, r, 0, 16);
|
||||
/* Put l,r into outblock */
|
||||
Block::Put(xorBlock, outBlock)(l)(r);
|
||||
/* Wipe clean */
|
||||
t = l = r = 0;
|
||||
}
|
||||
|
||||
void CAST128::Base::UncheckedSetKey(CipherDir dir, const byte *userKey, unsigned int keylength)
|
||||
{
|
||||
AssertValidKeyLength(keylength);
|
||||
|
||||
reduced = (keylength <= 10);
|
||||
|
||||
word32 X[4], Z[4];
|
||||
GetUserKey(BIG_ENDIAN_ORDER, X, 4, userKey, keylength);
|
||||
|
||||
#define x(i) GETBYTE(X[i/4], 3-i%4)
|
||||
#define z(i) GETBYTE(Z[i/4], 3-i%4)
|
||||
|
||||
unsigned int i;
|
||||
for (i=0; i<=16; i+=16)
|
||||
{
|
||||
// this part is copied directly from RFC 2144 (with some search and replace) by Wei Dai
|
||||
Z[0] = X[0] ^ S[4][x(0xD)] ^ S[5][x(0xF)] ^ S[6][x(0xC)] ^ S[7][x(0xE)] ^ S[6][x(0x8)];
|
||||
Z[1] = X[2] ^ S[4][z(0x0)] ^ S[5][z(0x2)] ^ S[6][z(0x1)] ^ S[7][z(0x3)] ^ S[7][x(0xA)];
|
||||
Z[2] = X[3] ^ S[4][z(0x7)] ^ S[5][z(0x6)] ^ S[6][z(0x5)] ^ S[7][z(0x4)] ^ S[4][x(0x9)];
|
||||
Z[3] = X[1] ^ S[4][z(0xA)] ^ S[5][z(0x9)] ^ S[6][z(0xB)] ^ S[7][z(0x8)] ^ S[5][x(0xB)];
|
||||
K[i+0] = S[4][z(0x8)] ^ S[5][z(0x9)] ^ S[6][z(0x7)] ^ S[7][z(0x6)] ^ S[4][z(0x2)];
|
||||
K[i+1] = S[4][z(0xA)] ^ S[5][z(0xB)] ^ S[6][z(0x5)] ^ S[7][z(0x4)] ^ S[5][z(0x6)];
|
||||
K[i+2] = S[4][z(0xC)] ^ S[5][z(0xD)] ^ S[6][z(0x3)] ^ S[7][z(0x2)] ^ S[6][z(0x9)];
|
||||
K[i+3] = S[4][z(0xE)] ^ S[5][z(0xF)] ^ S[6][z(0x1)] ^ S[7][z(0x0)] ^ S[7][z(0xC)];
|
||||
X[0] = Z[2] ^ S[4][z(0x5)] ^ S[5][z(0x7)] ^ S[6][z(0x4)] ^ S[7][z(0x6)] ^ S[6][z(0x0)];
|
||||
X[1] = Z[0] ^ S[4][x(0x0)] ^ S[5][x(0x2)] ^ S[6][x(0x1)] ^ S[7][x(0x3)] ^ S[7][z(0x2)];
|
||||
X[2] = Z[1] ^ S[4][x(0x7)] ^ S[5][x(0x6)] ^ S[6][x(0x5)] ^ S[7][x(0x4)] ^ S[4][z(0x1)];
|
||||
X[3] = Z[3] ^ S[4][x(0xA)] ^ S[5][x(0x9)] ^ S[6][x(0xB)] ^ S[7][x(0x8)] ^ S[5][z(0x3)];
|
||||
K[i+4] = S[4][x(0x3)] ^ S[5][x(0x2)] ^ S[6][x(0xC)] ^ S[7][x(0xD)] ^ S[4][x(0x8)];
|
||||
K[i+5] = S[4][x(0x1)] ^ S[5][x(0x0)] ^ S[6][x(0xE)] ^ S[7][x(0xF)] ^ S[5][x(0xD)];
|
||||
K[i+6] = S[4][x(0x7)] ^ S[5][x(0x6)] ^ S[6][x(0x8)] ^ S[7][x(0x9)] ^ S[6][x(0x3)];
|
||||
K[i+7] = S[4][x(0x5)] ^ S[5][x(0x4)] ^ S[6][x(0xA)] ^ S[7][x(0xB)] ^ S[7][x(0x7)];
|
||||
Z[0] = X[0] ^ S[4][x(0xD)] ^ S[5][x(0xF)] ^ S[6][x(0xC)] ^ S[7][x(0xE)] ^ S[6][x(0x8)];
|
||||
Z[1] = X[2] ^ S[4][z(0x0)] ^ S[5][z(0x2)] ^ S[6][z(0x1)] ^ S[7][z(0x3)] ^ S[7][x(0xA)];
|
||||
Z[2] = X[3] ^ S[4][z(0x7)] ^ S[5][z(0x6)] ^ S[6][z(0x5)] ^ S[7][z(0x4)] ^ S[4][x(0x9)];
|
||||
Z[3] = X[1] ^ S[4][z(0xA)] ^ S[5][z(0x9)] ^ S[6][z(0xB)] ^ S[7][z(0x8)] ^ S[5][x(0xB)];
|
||||
K[i+8] = S[4][z(0x3)] ^ S[5][z(0x2)] ^ S[6][z(0xC)] ^ S[7][z(0xD)] ^ S[4][z(0x9)];
|
||||
K[i+9] = S[4][z(0x1)] ^ S[5][z(0x0)] ^ S[6][z(0xE)] ^ S[7][z(0xF)] ^ S[5][z(0xC)];
|
||||
K[i+10] = S[4][z(0x7)] ^ S[5][z(0x6)] ^ S[6][z(0x8)] ^ S[7][z(0x9)] ^ S[6][z(0x2)];
|
||||
K[i+11] = S[4][z(0x5)] ^ S[5][z(0x4)] ^ S[6][z(0xA)] ^ S[7][z(0xB)] ^ S[7][z(0x6)];
|
||||
X[0] = Z[2] ^ S[4][z(0x5)] ^ S[5][z(0x7)] ^ S[6][z(0x4)] ^ S[7][z(0x6)] ^ S[6][z(0x0)];
|
||||
X[1] = Z[0] ^ S[4][x(0x0)] ^ S[5][x(0x2)] ^ S[6][x(0x1)] ^ S[7][x(0x3)] ^ S[7][z(0x2)];
|
||||
X[2] = Z[1] ^ S[4][x(0x7)] ^ S[5][x(0x6)] ^ S[6][x(0x5)] ^ S[7][x(0x4)] ^ S[4][z(0x1)];
|
||||
X[3] = Z[3] ^ S[4][x(0xA)] ^ S[5][x(0x9)] ^ S[6][x(0xB)] ^ S[7][x(0x8)] ^ S[5][z(0x3)];
|
||||
K[i+12] = S[4][x(0x8)] ^ S[5][x(0x9)] ^ S[6][x(0x7)] ^ S[7][x(0x6)] ^ S[4][x(0x3)];
|
||||
K[i+13] = S[4][x(0xA)] ^ S[5][x(0xB)] ^ S[6][x(0x5)] ^ S[7][x(0x4)] ^ S[5][x(0x7)];
|
||||
K[i+14] = S[4][x(0xC)] ^ S[5][x(0xD)] ^ S[6][x(0x3)] ^ S[7][x(0x2)] ^ S[6][x(0x8)];
|
||||
K[i+15] = S[4][x(0xE)] ^ S[5][x(0xF)] ^ S[6][x(0x1)] ^ S[7][x(0x0)] ^ S[7][x(0xD)];
|
||||
}
|
||||
|
||||
for (i=16; i<32; i++)
|
||||
K[i] &= 0x1f;
|
||||
}
|
||||
|
||||
// The following CAST-256 implementation was contributed by Leonard Janke
|
||||
|
||||
const word32 CAST256::Base::t_m[8][24]={
|
||||
0x5a827999, 0xd151d6a1, 0x482133a9, 0xbef090b1, 0x35bfedb9, 0xac8f4ac1,
|
||||
0x235ea7c9, 0x9a2e04d1, 0x10fd61d9, 0x87ccbee1, 0xfe9c1be9, 0x756b78f1,
|
||||
0xec3ad5f9, 0x630a3301, 0xd9d99009, 0x50a8ed11, 0xc7784a19, 0x3e47a721,
|
||||
0xb5170429, 0x2be66131, 0xa2b5be39, 0x19851b41, 0x90547849, 0x0723d551,
|
||||
0xc95c653a, 0x402bc242, 0xb6fb1f4a, 0x2dca7c52, 0xa499d95a, 0x1b693662,
|
||||
0x9238936a, 0x0907f072, 0x7fd74d7a, 0xf6a6aa82, 0x6d76078a, 0xe4456492,
|
||||
0x5b14c19a, 0xd1e41ea2, 0x48b37baa, 0xbf82d8b2, 0x365235ba, 0xad2192c2,
|
||||
0x23f0efca, 0x9ac04cd2, 0x118fa9da, 0x885f06e2, 0xff2e63ea, 0x75fdc0f2,
|
||||
0x383650db, 0xaf05ade3, 0x25d50aeb, 0x9ca467f3, 0x1373c4fb, 0x8a432203,
|
||||
0x01127f0b, 0x77e1dc13, 0xeeb1391b, 0x65809623, 0xdc4ff32b, 0x531f5033,
|
||||
0xc9eead3b, 0x40be0a43, 0xb78d674b, 0x2e5cc453, 0xa52c215b, 0x1bfb7e63,
|
||||
0x92cadb6b, 0x099a3873, 0x8069957b, 0xf738f283, 0x6e084f8b, 0xe4d7ac93,
|
||||
0xa7103c7c, 0x1ddf9984, 0x94aef68c, 0x0b7e5394, 0x824db09c, 0xf91d0da4,
|
||||
0x6fec6aac, 0xe6bbc7b4, 0x5d8b24bc, 0xd45a81c4, 0x4b29decc, 0xc1f93bd4,
|
||||
0x38c898dc, 0xaf97f5e4, 0x266752ec, 0x9d36aff4, 0x14060cfc, 0x8ad56a04,
|
||||
0x01a4c70c, 0x78742414, 0xef43811c, 0x6612de24, 0xdce23b2c, 0x53b19834,
|
||||
0x15ea281d, 0x8cb98525, 0x0388e22d, 0x7a583f35, 0xf1279c3d, 0x67f6f945,
|
||||
0xdec6564d, 0x5595b355, 0xcc65105d, 0x43346d65, 0xba03ca6d, 0x30d32775,
|
||||
0xa7a2847d, 0x1e71e185, 0x95413e8d, 0x0c109b95, 0x82dff89d, 0xf9af55a5,
|
||||
0x707eb2ad, 0xe74e0fb5, 0x5e1d6cbd, 0xd4ecc9c5, 0x4bbc26cd, 0xc28b83d5,
|
||||
0x84c413be, 0xfb9370c6, 0x7262cdce, 0xe9322ad6, 0x600187de, 0xd6d0e4e6,
|
||||
0x4da041ee, 0xc46f9ef6, 0x3b3efbfe, 0xb20e5906, 0x28ddb60e, 0x9fad1316,
|
||||
0x167c701e, 0x8d4bcd26, 0x041b2a2e, 0x7aea8736, 0xf1b9e43e, 0x68894146,
|
||||
0xdf589e4e, 0x5627fb56, 0xccf7585e, 0x43c6b566, 0xba96126e, 0x31656f76,
|
||||
0xf39dff5f, 0x6a6d5c67, 0xe13cb96f, 0x580c1677, 0xcedb737f, 0x45aad087,
|
||||
0xbc7a2d8f, 0x33498a97, 0xaa18e79f, 0x20e844a7, 0x97b7a1af, 0x0e86feb7,
|
||||
0x85565bbf, 0xfc25b8c7, 0x72f515cf, 0xe9c472d7, 0x6093cfdf, 0xd7632ce7,
|
||||
0x4e3289ef, 0xc501e6f7, 0x3bd143ff, 0xb2a0a107, 0x296ffe0f, 0xa03f5b17,
|
||||
0x6277eb00, 0xd9474808, 0x5016a510, 0xc6e60218, 0x3db55f20, 0xb484bc28,
|
||||
0x2b541930, 0xa2237638, 0x18f2d340, 0x8fc23048, 0x06918d50, 0x7d60ea58,
|
||||
0xf4304760, 0x6affa468, 0xe1cf0170, 0x589e5e78, 0xcf6dbb80, 0x463d1888,
|
||||
0xbd0c7590, 0x33dbd298, 0xaaab2fa0, 0x217a8ca8, 0x9849e9b0, 0x0f1946b8
|
||||
};
|
||||
|
||||
const unsigned int CAST256::Base::t_r[8][24]={
|
||||
19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11,
|
||||
4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28,
|
||||
21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13,
|
||||
6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30,
|
||||
23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15,
|
||||
8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0,
|
||||
25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17,
|
||||
10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2
|
||||
};
|
||||
|
||||
#define Q(i) \
|
||||
F1(block[2],block[3],8*i+4,-4); \
|
||||
F2(block[1],block[2],8*i+5,-4); \
|
||||
F3(block[0],block[1],8*i+6,-4); \
|
||||
F1(block[3],block[0],8*i+7,-4);
|
||||
|
||||
#define QBar(i) \
|
||||
F1(block[3],block[0],8*i+7,-4); \
|
||||
F3(block[0],block[1],8*i+6,-4); \
|
||||
F2(block[1],block[2],8*i+5,-4); \
|
||||
F1(block[2],block[3],8*i+4,-4);
|
||||
|
||||
/* CAST256's encrypt/decrypt functions are identical except for the order that
|
||||
the keys are used */
|
||||
|
||||
void CAST256::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
word32 t, block[4];
|
||||
Block::Get(inBlock)(block[0])(block[1])(block[2])(block[3]);
|
||||
|
||||
// Perform 6 forward quad rounds
|
||||
Q(0);
|
||||
Q(1);
|
||||
Q(2);
|
||||
Q(3);
|
||||
Q(4);
|
||||
Q(5);
|
||||
|
||||
// Perform 6 reverse quad rounds
|
||||
QBar(6);
|
||||
QBar(7);
|
||||
QBar(8);
|
||||
QBar(9);
|
||||
QBar(10);
|
||||
QBar(11);
|
||||
|
||||
Block::Put(xorBlock, outBlock)(block[0])(block[1])(block[2])(block[3]);
|
||||
}
|
||||
|
||||
/* Set up a CAST-256 key */
|
||||
|
||||
void CAST256::Base::Omega(int i, word32 kappa[8])
|
||||
{
|
||||
word32 t;
|
||||
|
||||
f1(kappa[6],kappa[7],t_m[0][i],t_r[0][i]);
|
||||
f2(kappa[5],kappa[6],t_m[1][i],t_r[1][i]);
|
||||
f3(kappa[4],kappa[5],t_m[2][i],t_r[2][i]);
|
||||
f1(kappa[3],kappa[4],t_m[3][i],t_r[3][i]);
|
||||
f2(kappa[2],kappa[3],t_m[4][i],t_r[4][i]);
|
||||
f3(kappa[1],kappa[2],t_m[5][i],t_r[5][i]);
|
||||
f1(kappa[0],kappa[1],t_m[6][i],t_r[6][i]);
|
||||
f2(kappa[7],kappa[0],t_m[7][i],t_r[7][i]);
|
||||
}
|
||||
|
||||
void CAST256::Base::UncheckedSetKey(CipherDir dir, const byte *userKey, unsigned int keylength)
|
||||
{
|
||||
AssertValidKeyLength(keylength);
|
||||
|
||||
word32 kappa[8];
|
||||
GetUserKey(BIG_ENDIAN_ORDER, kappa, 8, userKey, keylength);
|
||||
|
||||
for(int i=0; i<12; ++i)
|
||||
{
|
||||
Omega(2*i,kappa);
|
||||
Omega(2*i+1,kappa);
|
||||
|
||||
K[8*i]=kappa[0] & 31;
|
||||
K[8*i+1]=kappa[2] & 31;
|
||||
K[8*i+2]=kappa[4] & 31;
|
||||
K[8*i+3]=kappa[6] & 31;
|
||||
K[8*i+4]=kappa[7];
|
||||
K[8*i+5]=kappa[5];
|
||||
K[8*i+6]=kappa[3];
|
||||
K[8*i+7]=kappa[1];
|
||||
}
|
||||
|
||||
if (dir == DECRYPTION)
|
||||
{
|
||||
for(int j=0; j<6; ++j)
|
||||
{
|
||||
for(int i=0; i<4; ++i)
|
||||
{
|
||||
int i1=8*j+i;
|
||||
int i2=8*(11-j)+i;
|
||||
|
||||
assert(i1<i2);
|
||||
|
||||
std::swap(K[i1],K[i2]);
|
||||
std::swap(K[i1+4],K[i2+4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset(kappa, 0, sizeof(kappa));
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
#ifndef CRYPTOPP_CAST_H
|
||||
#define CRYPTOPP_CAST_H
|
||||
|
||||
/** \file
|
||||
*/
|
||||
|
||||
#include "seckey.h"
|
||||
#include "secblock.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
class CAST
|
||||
{
|
||||
protected:
|
||||
static const word32 S[8][256];
|
||||
};
|
||||
|
||||
//! .
|
||||
struct CAST128_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 5, 16>
|
||||
{
|
||||
static const char *StaticAlgorithmName() {return "CAST-128";}
|
||||
};
|
||||
|
||||
/// <a href="http://www.weidai.com/scan-mirror/cs.html#CAST-128">CAST-128</a>
|
||||
class CAST128 : public CAST128_Info, public BlockCipherDocumentation
|
||||
{
|
||||
class Base : public CAST, public BlockCipherBaseTemplate<CAST128_Info>
|
||||
{
|
||||
public:
|
||||
void UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length);
|
||||
|
||||
protected:
|
||||
bool reduced;
|
||||
FixedSizeSecBlock<word32, 32> K;
|
||||
};
|
||||
|
||||
class Enc : public Base
|
||||
{
|
||||
public:
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
};
|
||||
|
||||
class Dec : public Base
|
||||
{
|
||||
public:
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef BlockCipherTemplate<ENCRYPTION, Enc> Encryption;
|
||||
typedef BlockCipherTemplate<DECRYPTION, Dec> Decryption;
|
||||
};
|
||||
|
||||
//! .
|
||||
struct CAST256_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 16, 32>
|
||||
{
|
||||
static const char *StaticAlgorithmName() {return "CAST-256";}
|
||||
};
|
||||
|
||||
//! <a href="http://www.weidai.com/scan-mirror/cs.html#CAST-256">CAST-256</a>
|
||||
class CAST256 : public CAST256_Info, public BlockCipherDocumentation
|
||||
{
|
||||
class Base : public CAST, public BlockCipherBaseTemplate<CAST256_Info>
|
||||
{
|
||||
public:
|
||||
void UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length = 8);
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
|
||||
protected:
|
||||
static const word32 t_m[8][24];
|
||||
static const unsigned int t_r[8][24];
|
||||
|
||||
static void Omega(int i, word32 kappa[8]);
|
||||
|
||||
FixedSizeSecBlock<word32, 8*12> K;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef BlockCipherTemplate<ENCRYPTION, Base> Encryption;
|
||||
typedef BlockCipherTemplate<DECRYPTION, Base> Decryption;
|
||||
};
|
||||
|
||||
typedef CAST128::Encryption CAST128Encryption;
|
||||
typedef CAST128::Decryption CAST128Decryption;
|
||||
|
||||
typedef CAST256::Encryption CAST256Encryption;
|
||||
typedef CAST256::Decryption CAST256Decryption;
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A
|
||||
01 23 45 67 89 AB CD EF
|
||||
23 8B 4F E5 84 7E 44 B2
|
||||
|
||||
01 23 45 67 12 34 56 78 23 45
|
||||
01 23 45 67 89 AB CD EF
|
||||
EB 6A 71 1A 2C 02 27 1B
|
||||
|
||||
01 23 45 67 12
|
||||
01 23 45 67 89 AB CD EF
|
||||
7A C8 16 D1 6E 9B 30 2E
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
2342bb9efa38542c0af75647f29f615d
|
||||
00000000000000000000000000000000
|
||||
c842a08972b43d20836c91d1b7530f6b
|
||||
|
||||
2342bb9efa38542cbed0ac83940ac298bac77a7717942863
|
||||
00000000000000000000000000000000
|
||||
1b386c0210dcadcbdd0e41aa08a7a7e8
|
||||
|
||||
2342bb9efa38542cbed0ac83940ac2988d7c47ce264908461cc1b5137ae6b604
|
||||
00000000000000000000000000000000
|
||||
4f6a2038286897b9c9870136553317fa
|
||||
|
|
@ -0,0 +1,545 @@
|
|||
#include "pch.h"
|
||||
#include "cast.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
// CAST S-boxes
|
||||
|
||||
const word32 CAST::S[8][256] = {
|
||||
{
|
||||
0x30FB40D4UL, 0x9FA0FF0BUL, 0x6BECCD2FUL, 0x3F258C7AUL,
|
||||
0x1E213F2FUL, 0x9C004DD3UL, 0x6003E540UL, 0xCF9FC949UL,
|
||||
0xBFD4AF27UL, 0x88BBBDB5UL, 0xE2034090UL, 0x98D09675UL,
|
||||
0x6E63A0E0UL, 0x15C361D2UL, 0xC2E7661DUL, 0x22D4FF8EUL,
|
||||
0x28683B6FUL, 0xC07FD059UL, 0xFF2379C8UL, 0x775F50E2UL,
|
||||
0x43C340D3UL, 0xDF2F8656UL, 0x887CA41AUL, 0xA2D2BD2DUL,
|
||||
0xA1C9E0D6UL, 0x346C4819UL, 0x61B76D87UL, 0x22540F2FUL,
|
||||
0x2ABE32E1UL, 0xAA54166BUL, 0x22568E3AUL, 0xA2D341D0UL,
|
||||
0x66DB40C8UL, 0xA784392FUL, 0x004DFF2FUL, 0x2DB9D2DEUL,
|
||||
0x97943FACUL, 0x4A97C1D8UL, 0x527644B7UL, 0xB5F437A7UL,
|
||||
0xB82CBAEFUL, 0xD751D159UL, 0x6FF7F0EDUL, 0x5A097A1FUL,
|
||||
0x827B68D0UL, 0x90ECF52EUL, 0x22B0C054UL, 0xBC8E5935UL,
|
||||
0x4B6D2F7FUL, 0x50BB64A2UL, 0xD2664910UL, 0xBEE5812DUL,
|
||||
0xB7332290UL, 0xE93B159FUL, 0xB48EE411UL, 0x4BFF345DUL,
|
||||
0xFD45C240UL, 0xAD31973FUL, 0xC4F6D02EUL, 0x55FC8165UL,
|
||||
0xD5B1CAADUL, 0xA1AC2DAEUL, 0xA2D4B76DUL, 0xC19B0C50UL,
|
||||
0x882240F2UL, 0x0C6E4F38UL, 0xA4E4BFD7UL, 0x4F5BA272UL,
|
||||
0x564C1D2FUL, 0xC59C5319UL, 0xB949E354UL, 0xB04669FEUL,
|
||||
0xB1B6AB8AUL, 0xC71358DDUL, 0x6385C545UL, 0x110F935DUL,
|
||||
0x57538AD5UL, 0x6A390493UL, 0xE63D37E0UL, 0x2A54F6B3UL,
|
||||
0x3A787D5FUL, 0x6276A0B5UL, 0x19A6FCDFUL, 0x7A42206AUL,
|
||||
0x29F9D4D5UL, 0xF61B1891UL, 0xBB72275EUL, 0xAA508167UL,
|
||||
0x38901091UL, 0xC6B505EBUL, 0x84C7CB8CUL, 0x2AD75A0FUL,
|
||||
0x874A1427UL, 0xA2D1936BUL, 0x2AD286AFUL, 0xAA56D291UL,
|
||||
0xD7894360UL, 0x425C750DUL, 0x93B39E26UL, 0x187184C9UL,
|
||||
0x6C00B32DUL, 0x73E2BB14UL, 0xA0BEBC3CUL, 0x54623779UL,
|
||||
0x64459EABUL, 0x3F328B82UL, 0x7718CF82UL, 0x59A2CEA6UL,
|
||||
0x04EE002EUL, 0x89FE78E6UL, 0x3FAB0950UL, 0x325FF6C2UL,
|
||||
0x81383F05UL, 0x6963C5C8UL, 0x76CB5AD6UL, 0xD49974C9UL,
|
||||
0xCA180DCFUL, 0x380782D5UL, 0xC7FA5CF6UL, 0x8AC31511UL,
|
||||
0x35E79E13UL, 0x47DA91D0UL, 0xF40F9086UL, 0xA7E2419EUL,
|
||||
0x31366241UL, 0x051EF495UL, 0xAA573B04UL, 0x4A805D8DUL,
|
||||
0x548300D0UL, 0x00322A3CUL, 0xBF64CDDFUL, 0xBA57A68EUL,
|
||||
0x75C6372BUL, 0x50AFD341UL, 0xA7C13275UL, 0x915A0BF5UL,
|
||||
0x6B54BFABUL, 0x2B0B1426UL, 0xAB4CC9D7UL, 0x449CCD82UL,
|
||||
0xF7FBF265UL, 0xAB85C5F3UL, 0x1B55DB94UL, 0xAAD4E324UL,
|
||||
0xCFA4BD3FUL, 0x2DEAA3E2UL, 0x9E204D02UL, 0xC8BD25ACUL,
|
||||
0xEADF55B3UL, 0xD5BD9E98UL, 0xE31231B2UL, 0x2AD5AD6CUL,
|
||||
0x954329DEUL, 0xADBE4528UL, 0xD8710F69UL, 0xAA51C90FUL,
|
||||
0xAA786BF6UL, 0x22513F1EUL, 0xAA51A79BUL, 0x2AD344CCUL,
|
||||
0x7B5A41F0UL, 0xD37CFBADUL, 0x1B069505UL, 0x41ECE491UL,
|
||||
0xB4C332E6UL, 0x032268D4UL, 0xC9600ACCUL, 0xCE387E6DUL,
|
||||
0xBF6BB16CUL, 0x6A70FB78UL, 0x0D03D9C9UL, 0xD4DF39DEUL,
|
||||
0xE01063DAUL, 0x4736F464UL, 0x5AD328D8UL, 0xB347CC96UL,
|
||||
0x75BB0FC3UL, 0x98511BFBUL, 0x4FFBCC35UL, 0xB58BCF6AUL,
|
||||
0xE11F0ABCUL, 0xBFC5FE4AUL, 0xA70AEC10UL, 0xAC39570AUL,
|
||||
0x3F04442FUL, 0x6188B153UL, 0xE0397A2EUL, 0x5727CB79UL,
|
||||
0x9CEB418FUL, 0x1CACD68DUL, 0x2AD37C96UL, 0x0175CB9DUL,
|
||||
0xC69DFF09UL, 0xC75B65F0UL, 0xD9DB40D8UL, 0xEC0E7779UL,
|
||||
0x4744EAD4UL, 0xB11C3274UL, 0xDD24CB9EUL, 0x7E1C54BDUL,
|
||||
0xF01144F9UL, 0xD2240EB1UL, 0x9675B3FDUL, 0xA3AC3755UL,
|
||||
0xD47C27AFUL, 0x51C85F4DUL, 0x56907596UL, 0xA5BB15E6UL,
|
||||
0x580304F0UL, 0xCA042CF1UL, 0x011A37EAUL, 0x8DBFAADBUL,
|
||||
0x35BA3E4AUL, 0x3526FFA0UL, 0xC37B4D09UL, 0xBC306ED9UL,
|
||||
0x98A52666UL, 0x5648F725UL, 0xFF5E569DUL, 0x0CED63D0UL,
|
||||
0x7C63B2CFUL, 0x700B45E1UL, 0xD5EA50F1UL, 0x85A92872UL,
|
||||
0xAF1FBDA7UL, 0xD4234870UL, 0xA7870BF3UL, 0x2D3B4D79UL,
|
||||
0x42E04198UL, 0x0CD0EDE7UL, 0x26470DB8UL, 0xF881814CUL,
|
||||
0x474D6AD7UL, 0x7C0C5E5CUL, 0xD1231959UL, 0x381B7298UL,
|
||||
0xF5D2F4DBUL, 0xAB838653UL, 0x6E2F1E23UL, 0x83719C9EUL,
|
||||
0xBD91E046UL, 0x9A56456EUL, 0xDC39200CUL, 0x20C8C571UL,
|
||||
0x962BDA1CUL, 0xE1E696FFUL, 0xB141AB08UL, 0x7CCA89B9UL,
|
||||
0x1A69E783UL, 0x02CC4843UL, 0xA2F7C579UL, 0x429EF47DUL,
|
||||
0x427B169CUL, 0x5AC9F049UL, 0xDD8F0F00UL, 0x5C8165BFUL
|
||||
},
|
||||
|
||||
{
|
||||
0x1F201094UL, 0xEF0BA75BUL, 0x69E3CF7EUL, 0x393F4380UL,
|
||||
0xFE61CF7AUL, 0xEEC5207AUL, 0x55889C94UL, 0x72FC0651UL,
|
||||
0xADA7EF79UL, 0x4E1D7235UL, 0xD55A63CEUL, 0xDE0436BAUL,
|
||||
0x99C430EFUL, 0x5F0C0794UL, 0x18DCDB7DUL, 0xA1D6EFF3UL,
|
||||
0xA0B52F7BUL, 0x59E83605UL, 0xEE15B094UL, 0xE9FFD909UL,
|
||||
0xDC440086UL, 0xEF944459UL, 0xBA83CCB3UL, 0xE0C3CDFBUL,
|
||||
0xD1DA4181UL, 0x3B092AB1UL, 0xF997F1C1UL, 0xA5E6CF7BUL,
|
||||
0x01420DDBUL, 0xE4E7EF5BUL, 0x25A1FF41UL, 0xE180F806UL,
|
||||
0x1FC41080UL, 0x179BEE7AUL, 0xD37AC6A9UL, 0xFE5830A4UL,
|
||||
0x98DE8B7FUL, 0x77E83F4EUL, 0x79929269UL, 0x24FA9F7BUL,
|
||||
0xE113C85BUL, 0xACC40083UL, 0xD7503525UL, 0xF7EA615FUL,
|
||||
0x62143154UL, 0x0D554B63UL, 0x5D681121UL, 0xC866C359UL,
|
||||
0x3D63CF73UL, 0xCEE234C0UL, 0xD4D87E87UL, 0x5C672B21UL,
|
||||
0x071F6181UL, 0x39F7627FUL, 0x361E3084UL, 0xE4EB573BUL,
|
||||
0x602F64A4UL, 0xD63ACD9CUL, 0x1BBC4635UL, 0x9E81032DUL,
|
||||
0x2701F50CUL, 0x99847AB4UL, 0xA0E3DF79UL, 0xBA6CF38CUL,
|
||||
0x10843094UL, 0x2537A95EUL, 0xF46F6FFEUL, 0xA1FF3B1FUL,
|
||||
0x208CFB6AUL, 0x8F458C74UL, 0xD9E0A227UL, 0x4EC73A34UL,
|
||||
0xFC884F69UL, 0x3E4DE8DFUL, 0xEF0E0088UL, 0x3559648DUL,
|
||||
0x8A45388CUL, 0x1D804366UL, 0x721D9BFDUL, 0xA58684BBUL,
|
||||
0xE8256333UL, 0x844E8212UL, 0x128D8098UL, 0xFED33FB4UL,
|
||||
0xCE280AE1UL, 0x27E19BA5UL, 0xD5A6C252UL, 0xE49754BDUL,
|
||||
0xC5D655DDUL, 0xEB667064UL, 0x77840B4DUL, 0xA1B6A801UL,
|
||||
0x84DB26A9UL, 0xE0B56714UL, 0x21F043B7UL, 0xE5D05860UL,
|
||||
0x54F03084UL, 0x066FF472UL, 0xA31AA153UL, 0xDADC4755UL,
|
||||
0xB5625DBFUL, 0x68561BE6UL, 0x83CA6B94UL, 0x2D6ED23BUL,
|
||||
0xECCF01DBUL, 0xA6D3D0BAUL, 0xB6803D5CUL, 0xAF77A709UL,
|
||||
0x33B4A34CUL, 0x397BC8D6UL, 0x5EE22B95UL, 0x5F0E5304UL,
|
||||
0x81ED6F61UL, 0x20E74364UL, 0xB45E1378UL, 0xDE18639BUL,
|
||||
0x881CA122UL, 0xB96726D1UL, 0x8049A7E8UL, 0x22B7DA7BUL,
|
||||
0x5E552D25UL, 0x5272D237UL, 0x79D2951CUL, 0xC60D894CUL,
|
||||
0x488CB402UL, 0x1BA4FE5BUL, 0xA4B09F6BUL, 0x1CA815CFUL,
|
||||
0xA20C3005UL, 0x8871DF63UL, 0xB9DE2FCBUL, 0x0CC6C9E9UL,
|
||||
0x0BEEFF53UL, 0xE3214517UL, 0xB4542835UL, 0x9F63293CUL,
|
||||
0xEE41E729UL, 0x6E1D2D7CUL, 0x50045286UL, 0x1E6685F3UL,
|
||||
0xF33401C6UL, 0x30A22C95UL, 0x31A70850UL, 0x60930F13UL,
|
||||
0x73F98417UL, 0xA1269859UL, 0xEC645C44UL, 0x52C877A9UL,
|
||||
0xCDFF33A6UL, 0xA02B1741UL, 0x7CBAD9A2UL, 0x2180036FUL,
|
||||
0x50D99C08UL, 0xCB3F4861UL, 0xC26BD765UL, 0x64A3F6ABUL,
|
||||
0x80342676UL, 0x25A75E7BUL, 0xE4E6D1FCUL, 0x20C710E6UL,
|
||||
0xCDF0B680UL, 0x17844D3BUL, 0x31EEF84DUL, 0x7E0824E4UL,
|
||||
0x2CCB49EBUL, 0x846A3BAEUL, 0x8FF77888UL, 0xEE5D60F6UL,
|
||||
0x7AF75673UL, 0x2FDD5CDBUL, 0xA11631C1UL, 0x30F66F43UL,
|
||||
0xB3FAEC54UL, 0x157FD7FAUL, 0xEF8579CCUL, 0xD152DE58UL,
|
||||
0xDB2FFD5EUL, 0x8F32CE19UL, 0x306AF97AUL, 0x02F03EF8UL,
|
||||
0x99319AD5UL, 0xC242FA0FUL, 0xA7E3EBB0UL, 0xC68E4906UL,
|
||||
0xB8DA230CUL, 0x80823028UL, 0xDCDEF3C8UL, 0xD35FB171UL,
|
||||
0x088A1BC8UL, 0xBEC0C560UL, 0x61A3C9E8UL, 0xBCA8F54DUL,
|
||||
0xC72FEFFAUL, 0x22822E99UL, 0x82C570B4UL, 0xD8D94E89UL,
|
||||
0x8B1C34BCUL, 0x301E16E6UL, 0x273BE979UL, 0xB0FFEAA6UL,
|
||||
0x61D9B8C6UL, 0x00B24869UL, 0xB7FFCE3FUL, 0x08DC283BUL,
|
||||
0x43DAF65AUL, 0xF7E19798UL, 0x7619B72FUL, 0x8F1C9BA4UL,
|
||||
0xDC8637A0UL, 0x16A7D3B1UL, 0x9FC393B7UL, 0xA7136EEBUL,
|
||||
0xC6BCC63EUL, 0x1A513742UL, 0xEF6828BCUL, 0x520365D6UL,
|
||||
0x2D6A77ABUL, 0x3527ED4BUL, 0x821FD216UL, 0x095C6E2EUL,
|
||||
0xDB92F2FBUL, 0x5EEA29CBUL, 0x145892F5UL, 0x91584F7FUL,
|
||||
0x5483697BUL, 0x2667A8CCUL, 0x85196048UL, 0x8C4BACEAUL,
|
||||
0x833860D4UL, 0x0D23E0F9UL, 0x6C387E8AUL, 0x0AE6D249UL,
|
||||
0xB284600CUL, 0xD835731DUL, 0xDCB1C647UL, 0xAC4C56EAUL,
|
||||
0x3EBD81B3UL, 0x230EABB0UL, 0x6438BC87UL, 0xF0B5B1FAUL,
|
||||
0x8F5EA2B3UL, 0xFC184642UL, 0x0A036B7AUL, 0x4FB089BDUL,
|
||||
0x649DA589UL, 0xA345415EUL, 0x5C038323UL, 0x3E5D3BB9UL,
|
||||
0x43D79572UL, 0x7E6DD07CUL, 0x06DFDF1EUL, 0x6C6CC4EFUL,
|
||||
0x7160A539UL, 0x73BFBE70UL, 0x83877605UL, 0x4523ECF1UL
|
||||
},
|
||||
|
||||
{
|
||||
0x8DEFC240UL, 0x25FA5D9FUL, 0xEB903DBFUL, 0xE810C907UL,
|
||||
0x47607FFFUL, 0x369FE44BUL, 0x8C1FC644UL, 0xAECECA90UL,
|
||||
0xBEB1F9BFUL, 0xEEFBCAEAUL, 0xE8CF1950UL, 0x51DF07AEUL,
|
||||
0x920E8806UL, 0xF0AD0548UL, 0xE13C8D83UL, 0x927010D5UL,
|
||||
0x11107D9FUL, 0x07647DB9UL, 0xB2E3E4D4UL, 0x3D4F285EUL,
|
||||
0xB9AFA820UL, 0xFADE82E0UL, 0xA067268BUL, 0x8272792EUL,
|
||||
0x553FB2C0UL, 0x489AE22BUL, 0xD4EF9794UL, 0x125E3FBCUL,
|
||||
0x21FFFCEEUL, 0x825B1BFDUL, 0x9255C5EDUL, 0x1257A240UL,
|
||||
0x4E1A8302UL, 0xBAE07FFFUL, 0x528246E7UL, 0x8E57140EUL,
|
||||
0x3373F7BFUL, 0x8C9F8188UL, 0xA6FC4EE8UL, 0xC982B5A5UL,
|
||||
0xA8C01DB7UL, 0x579FC264UL, 0x67094F31UL, 0xF2BD3F5FUL,
|
||||
0x40FFF7C1UL, 0x1FB78DFCUL, 0x8E6BD2C1UL, 0x437BE59BUL,
|
||||
0x99B03DBFUL, 0xB5DBC64BUL, 0x638DC0E6UL, 0x55819D99UL,
|
||||
0xA197C81CUL, 0x4A012D6EUL, 0xC5884A28UL, 0xCCC36F71UL,
|
||||
0xB843C213UL, 0x6C0743F1UL, 0x8309893CUL, 0x0FEDDD5FUL,
|
||||
0x2F7FE850UL, 0xD7C07F7EUL, 0x02507FBFUL, 0x5AFB9A04UL,
|
||||
0xA747D2D0UL, 0x1651192EUL, 0xAF70BF3EUL, 0x58C31380UL,
|
||||
0x5F98302EUL, 0x727CC3C4UL, 0x0A0FB402UL, 0x0F7FEF82UL,
|
||||
0x8C96FDADUL, 0x5D2C2AAEUL, 0x8EE99A49UL, 0x50DA88B8UL,
|
||||
0x8427F4A0UL, 0x1EAC5790UL, 0x796FB449UL, 0x8252DC15UL,
|
||||
0xEFBD7D9BUL, 0xA672597DUL, 0xADA840D8UL, 0x45F54504UL,
|
||||
0xFA5D7403UL, 0xE83EC305UL, 0x4F91751AUL, 0x925669C2UL,
|
||||
0x23EFE941UL, 0xA903F12EUL, 0x60270DF2UL, 0x0276E4B6UL,
|
||||
0x94FD6574UL, 0x927985B2UL, 0x8276DBCBUL, 0x02778176UL,
|
||||
0xF8AF918DUL, 0x4E48F79EUL, 0x8F616DDFUL, 0xE29D840EUL,
|
||||
0x842F7D83UL, 0x340CE5C8UL, 0x96BBB682UL, 0x93B4B148UL,
|
||||
0xEF303CABUL, 0x984FAF28UL, 0x779FAF9BUL, 0x92DC560DUL,
|
||||
0x224D1E20UL, 0x8437AA88UL, 0x7D29DC96UL, 0x2756D3DCUL,
|
||||
0x8B907CEEUL, 0xB51FD240UL, 0xE7C07CE3UL, 0xE566B4A1UL,
|
||||
0xC3E9615EUL, 0x3CF8209DUL, 0x6094D1E3UL, 0xCD9CA341UL,
|
||||
0x5C76460EUL, 0x00EA983BUL, 0xD4D67881UL, 0xFD47572CUL,
|
||||
0xF76CEDD9UL, 0xBDA8229CUL, 0x127DADAAUL, 0x438A074EUL,
|
||||
0x1F97C090UL, 0x081BDB8AUL, 0x93A07EBEUL, 0xB938CA15UL,
|
||||
0x97B03CFFUL, 0x3DC2C0F8UL, 0x8D1AB2ECUL, 0x64380E51UL,
|
||||
0x68CC7BFBUL, 0xD90F2788UL, 0x12490181UL, 0x5DE5FFD4UL,
|
||||
0xDD7EF86AUL, 0x76A2E214UL, 0xB9A40368UL, 0x925D958FUL,
|
||||
0x4B39FFFAUL, 0xBA39AEE9UL, 0xA4FFD30BUL, 0xFAF7933BUL,
|
||||
0x6D498623UL, 0x193CBCFAUL, 0x27627545UL, 0x825CF47AUL,
|
||||
0x61BD8BA0UL, 0xD11E42D1UL, 0xCEAD04F4UL, 0x127EA392UL,
|
||||
0x10428DB7UL, 0x8272A972UL, 0x9270C4A8UL, 0x127DE50BUL,
|
||||
0x285BA1C8UL, 0x3C62F44FUL, 0x35C0EAA5UL, 0xE805D231UL,
|
||||
0x428929FBUL, 0xB4FCDF82UL, 0x4FB66A53UL, 0x0E7DC15BUL,
|
||||
0x1F081FABUL, 0x108618AEUL, 0xFCFD086DUL, 0xF9FF2889UL,
|
||||
0x694BCC11UL, 0x236A5CAEUL, 0x12DECA4DUL, 0x2C3F8CC5UL,
|
||||
0xD2D02DFEUL, 0xF8EF5896UL, 0xE4CF52DAUL, 0x95155B67UL,
|
||||
0x494A488CUL, 0xB9B6A80CUL, 0x5C8F82BCUL, 0x89D36B45UL,
|
||||
0x3A609437UL, 0xEC00C9A9UL, 0x44715253UL, 0x0A874B49UL,
|
||||
0xD773BC40UL, 0x7C34671CUL, 0x02717EF6UL, 0x4FEB5536UL,
|
||||
0xA2D02FFFUL, 0xD2BF60C4UL, 0xD43F03C0UL, 0x50B4EF6DUL,
|
||||
0x07478CD1UL, 0x006E1888UL, 0xA2E53F55UL, 0xB9E6D4BCUL,
|
||||
0xA2048016UL, 0x97573833UL, 0xD7207D67UL, 0xDE0F8F3DUL,
|
||||
0x72F87B33UL, 0xABCC4F33UL, 0x7688C55DUL, 0x7B00A6B0UL,
|
||||
0x947B0001UL, 0x570075D2UL, 0xF9BB88F8UL, 0x8942019EUL,
|
||||
0x4264A5FFUL, 0x856302E0UL, 0x72DBD92BUL, 0xEE971B69UL,
|
||||
0x6EA22FDEUL, 0x5F08AE2BUL, 0xAF7A616DUL, 0xE5C98767UL,
|
||||
0xCF1FEBD2UL, 0x61EFC8C2UL, 0xF1AC2571UL, 0xCC8239C2UL,
|
||||
0x67214CB8UL, 0xB1E583D1UL, 0xB7DC3E62UL, 0x7F10BDCEUL,
|
||||
0xF90A5C38UL, 0x0FF0443DUL, 0x606E6DC6UL, 0x60543A49UL,
|
||||
0x5727C148UL, 0x2BE98A1DUL, 0x8AB41738UL, 0x20E1BE24UL,
|
||||
0xAF96DA0FUL, 0x68458425UL, 0x99833BE5UL, 0x600D457DUL,
|
||||
0x282F9350UL, 0x8334B362UL, 0xD91D1120UL, 0x2B6D8DA0UL,
|
||||
0x642B1E31UL, 0x9C305A00UL, 0x52BCE688UL, 0x1B03588AUL,
|
||||
0xF7BAEFD5UL, 0x4142ED9CUL, 0xA4315C11UL, 0x83323EC5UL,
|
||||
0xDFEF4636UL, 0xA133C501UL, 0xE9D3531CUL, 0xEE353783UL
|
||||
},
|
||||
|
||||
{
|
||||
0x9DB30420UL, 0x1FB6E9DEUL, 0xA7BE7BEFUL, 0xD273A298UL,
|
||||
0x4A4F7BDBUL, 0x64AD8C57UL, 0x85510443UL, 0xFA020ED1UL,
|
||||
0x7E287AFFUL, 0xE60FB663UL, 0x095F35A1UL, 0x79EBF120UL,
|
||||
0xFD059D43UL, 0x6497B7B1UL, 0xF3641F63UL, 0x241E4ADFUL,
|
||||
0x28147F5FUL, 0x4FA2B8CDUL, 0xC9430040UL, 0x0CC32220UL,
|
||||
0xFDD30B30UL, 0xC0A5374FUL, 0x1D2D00D9UL, 0x24147B15UL,
|
||||
0xEE4D111AUL, 0x0FCA5167UL, 0x71FF904CUL, 0x2D195FFEUL,
|
||||
0x1A05645FUL, 0x0C13FEFEUL, 0x081B08CAUL, 0x05170121UL,
|
||||
0x80530100UL, 0xE83E5EFEUL, 0xAC9AF4F8UL, 0x7FE72701UL,
|
||||
0xD2B8EE5FUL, 0x06DF4261UL, 0xBB9E9B8AUL, 0x7293EA25UL,
|
||||
0xCE84FFDFUL, 0xF5718801UL, 0x3DD64B04UL, 0xA26F263BUL,
|
||||
0x7ED48400UL, 0x547EEBE6UL, 0x446D4CA0UL, 0x6CF3D6F5UL,
|
||||
0x2649ABDFUL, 0xAEA0C7F5UL, 0x36338CC1UL, 0x503F7E93UL,
|
||||
0xD3772061UL, 0x11B638E1UL, 0x72500E03UL, 0xF80EB2BBUL,
|
||||
0xABE0502EUL, 0xEC8D77DEUL, 0x57971E81UL, 0xE14F6746UL,
|
||||
0xC9335400UL, 0x6920318FUL, 0x081DBB99UL, 0xFFC304A5UL,
|
||||
0x4D351805UL, 0x7F3D5CE3UL, 0xA6C866C6UL, 0x5D5BCCA9UL,
|
||||
0xDAEC6FEAUL, 0x9F926F91UL, 0x9F46222FUL, 0x3991467DUL,
|
||||
0xA5BF6D8EUL, 0x1143C44FUL, 0x43958302UL, 0xD0214EEBUL,
|
||||
0x022083B8UL, 0x3FB6180CUL, 0x18F8931EUL, 0x281658E6UL,
|
||||
0x26486E3EUL, 0x8BD78A70UL, 0x7477E4C1UL, 0xB506E07CUL,
|
||||
0xF32D0A25UL, 0x79098B02UL, 0xE4EABB81UL, 0x28123B23UL,
|
||||
0x69DEAD38UL, 0x1574CA16UL, 0xDF871B62UL, 0x211C40B7UL,
|
||||
0xA51A9EF9UL, 0x0014377BUL, 0x041E8AC8UL, 0x09114003UL,
|
||||
0xBD59E4D2UL, 0xE3D156D5UL, 0x4FE876D5UL, 0x2F91A340UL,
|
||||
0x557BE8DEUL, 0x00EAE4A7UL, 0x0CE5C2ECUL, 0x4DB4BBA6UL,
|
||||
0xE756BDFFUL, 0xDD3369ACUL, 0xEC17B035UL, 0x06572327UL,
|
||||
0x99AFC8B0UL, 0x56C8C391UL, 0x6B65811CUL, 0x5E146119UL,
|
||||
0x6E85CB75UL, 0xBE07C002UL, 0xC2325577UL, 0x893FF4ECUL,
|
||||
0x5BBFC92DUL, 0xD0EC3B25UL, 0xB7801AB7UL, 0x8D6D3B24UL,
|
||||
0x20C763EFUL, 0xC366A5FCUL, 0x9C382880UL, 0x0ACE3205UL,
|
||||
0xAAC9548AUL, 0xECA1D7C7UL, 0x041AFA32UL, 0x1D16625AUL,
|
||||
0x6701902CUL, 0x9B757A54UL, 0x31D477F7UL, 0x9126B031UL,
|
||||
0x36CC6FDBUL, 0xC70B8B46UL, 0xD9E66A48UL, 0x56E55A79UL,
|
||||
0x026A4CEBUL, 0x52437EFFUL, 0x2F8F76B4UL, 0x0DF980A5UL,
|
||||
0x8674CDE3UL, 0xEDDA04EBUL, 0x17A9BE04UL, 0x2C18F4DFUL,
|
||||
0xB7747F9DUL, 0xAB2AF7B4UL, 0xEFC34D20UL, 0x2E096B7CUL,
|
||||
0x1741A254UL, 0xE5B6A035UL, 0x213D42F6UL, 0x2C1C7C26UL,
|
||||
0x61C2F50FUL, 0x6552DAF9UL, 0xD2C231F8UL, 0x25130F69UL,
|
||||
0xD8167FA2UL, 0x0418F2C8UL, 0x001A96A6UL, 0x0D1526ABUL,
|
||||
0x63315C21UL, 0x5E0A72ECUL, 0x49BAFEFDUL, 0x187908D9UL,
|
||||
0x8D0DBD86UL, 0x311170A7UL, 0x3E9B640CUL, 0xCC3E10D7UL,
|
||||
0xD5CAD3B6UL, 0x0CAEC388UL, 0xF73001E1UL, 0x6C728AFFUL,
|
||||
0x71EAE2A1UL, 0x1F9AF36EUL, 0xCFCBD12FUL, 0xC1DE8417UL,
|
||||
0xAC07BE6BUL, 0xCB44A1D8UL, 0x8B9B0F56UL, 0x013988C3UL,
|
||||
0xB1C52FCAUL, 0xB4BE31CDUL, 0xD8782806UL, 0x12A3A4E2UL,
|
||||
0x6F7DE532UL, 0x58FD7EB6UL, 0xD01EE900UL, 0x24ADFFC2UL,
|
||||
0xF4990FC5UL, 0x9711AAC5UL, 0x001D7B95UL, 0x82E5E7D2UL,
|
||||
0x109873F6UL, 0x00613096UL, 0xC32D9521UL, 0xADA121FFUL,
|
||||
0x29908415UL, 0x7FBB977FUL, 0xAF9EB3DBUL, 0x29C9ED2AUL,
|
||||
0x5CE2A465UL, 0xA730F32CUL, 0xD0AA3FE8UL, 0x8A5CC091UL,
|
||||
0xD49E2CE7UL, 0x0CE454A9UL, 0xD60ACD86UL, 0x015F1919UL,
|
||||
0x77079103UL, 0xDEA03AF6UL, 0x78A8565EUL, 0xDEE356DFUL,
|
||||
0x21F05CBEUL, 0x8B75E387UL, 0xB3C50651UL, 0xB8A5C3EFUL,
|
||||
0xD8EEB6D2UL, 0xE523BE77UL, 0xC2154529UL, 0x2F69EFDFUL,
|
||||
0xAFE67AFBUL, 0xF470C4B2UL, 0xF3E0EB5BUL, 0xD6CC9876UL,
|
||||
0x39E4460CUL, 0x1FDA8538UL, 0x1987832FUL, 0xCA007367UL,
|
||||
0xA99144F8UL, 0x296B299EUL, 0x492FC295UL, 0x9266BEABUL,
|
||||
0xB5676E69UL, 0x9BD3DDDAUL, 0xDF7E052FUL, 0xDB25701CUL,
|
||||
0x1B5E51EEUL, 0xF65324E6UL, 0x6AFCE36CUL, 0x0316CC04UL,
|
||||
0x8644213EUL, 0xB7DC59D0UL, 0x7965291FUL, 0xCCD6FD43UL,
|
||||
0x41823979UL, 0x932BCDF6UL, 0xB657C34DUL, 0x4EDFD282UL,
|
||||
0x7AE5290CUL, 0x3CB9536BUL, 0x851E20FEUL, 0x9833557EUL,
|
||||
0x13ECF0B0UL, 0xD3FFB372UL, 0x3F85C5C1UL, 0x0AEF7ED2UL
|
||||
},
|
||||
|
||||
{
|
||||
0x7EC90C04UL, 0x2C6E74B9UL, 0x9B0E66DFUL, 0xA6337911UL,
|
||||
0xB86A7FFFUL, 0x1DD358F5UL, 0x44DD9D44UL, 0x1731167FUL,
|
||||
0x08FBF1FAUL, 0xE7F511CCUL, 0xD2051B00UL, 0x735ABA00UL,
|
||||
0x2AB722D8UL, 0x386381CBUL, 0xACF6243AUL, 0x69BEFD7AUL,
|
||||
0xE6A2E77FUL, 0xF0C720CDUL, 0xC4494816UL, 0xCCF5C180UL,
|
||||
0x38851640UL, 0x15B0A848UL, 0xE68B18CBUL, 0x4CAADEFFUL,
|
||||
0x5F480A01UL, 0x0412B2AAUL, 0x259814FCUL, 0x41D0EFE2UL,
|
||||
0x4E40B48DUL, 0x248EB6FBUL, 0x8DBA1CFEUL, 0x41A99B02UL,
|
||||
0x1A550A04UL, 0xBA8F65CBUL, 0x7251F4E7UL, 0x95A51725UL,
|
||||
0xC106ECD7UL, 0x97A5980AUL, 0xC539B9AAUL, 0x4D79FE6AUL,
|
||||
0xF2F3F763UL, 0x68AF8040UL, 0xED0C9E56UL, 0x11B4958BUL,
|
||||
0xE1EB5A88UL, 0x8709E6B0UL, 0xD7E07156UL, 0x4E29FEA7UL,
|
||||
0x6366E52DUL, 0x02D1C000UL, 0xC4AC8E05UL, 0x9377F571UL,
|
||||
0x0C05372AUL, 0x578535F2UL, 0x2261BE02UL, 0xD642A0C9UL,
|
||||
0xDF13A280UL, 0x74B55BD2UL, 0x682199C0UL, 0xD421E5ECUL,
|
||||
0x53FB3CE8UL, 0xC8ADEDB3UL, 0x28A87FC9UL, 0x3D959981UL,
|
||||
0x5C1FF900UL, 0xFE38D399UL, 0x0C4EFF0BUL, 0x062407EAUL,
|
||||
0xAA2F4FB1UL, 0x4FB96976UL, 0x90C79505UL, 0xB0A8A774UL,
|
||||
0xEF55A1FFUL, 0xE59CA2C2UL, 0xA6B62D27UL, 0xE66A4263UL,
|
||||
0xDF65001FUL, 0x0EC50966UL, 0xDFDD55BCUL, 0x29DE0655UL,
|
||||
0x911E739AUL, 0x17AF8975UL, 0x32C7911CUL, 0x89F89468UL,
|
||||
0x0D01E980UL, 0x524755F4UL, 0x03B63CC9UL, 0x0CC844B2UL,
|
||||
0xBCF3F0AAUL, 0x87AC36E9UL, 0xE53A7426UL, 0x01B3D82BUL,
|
||||
0x1A9E7449UL, 0x64EE2D7EUL, 0xCDDBB1DAUL, 0x01C94910UL,
|
||||
0xB868BF80UL, 0x0D26F3FDUL, 0x9342EDE7UL, 0x04A5C284UL,
|
||||
0x636737B6UL, 0x50F5B616UL, 0xF24766E3UL, 0x8ECA36C1UL,
|
||||
0x136E05DBUL, 0xFEF18391UL, 0xFB887A37UL, 0xD6E7F7D4UL,
|
||||
0xC7FB7DC9UL, 0x3063FCDFUL, 0xB6F589DEUL, 0xEC2941DAUL,
|
||||
0x26E46695UL, 0xB7566419UL, 0xF654EFC5UL, 0xD08D58B7UL,
|
||||
0x48925401UL, 0xC1BACB7FUL, 0xE5FF550FUL, 0xB6083049UL,
|
||||
0x5BB5D0E8UL, 0x87D72E5AUL, 0xAB6A6EE1UL, 0x223A66CEUL,
|
||||
0xC62BF3CDUL, 0x9E0885F9UL, 0x68CB3E47UL, 0x086C010FUL,
|
||||
0xA21DE820UL, 0xD18B69DEUL, 0xF3F65777UL, 0xFA02C3F6UL,
|
||||
0x407EDAC3UL, 0xCBB3D550UL, 0x1793084DUL, 0xB0D70EBAUL,
|
||||
0x0AB378D5UL, 0xD951FB0CUL, 0xDED7DA56UL, 0x4124BBE4UL,
|
||||
0x94CA0B56UL, 0x0F5755D1UL, 0xE0E1E56EUL, 0x6184B5BEUL,
|
||||
0x580A249FUL, 0x94F74BC0UL, 0xE327888EUL, 0x9F7B5561UL,
|
||||
0xC3DC0280UL, 0x05687715UL, 0x646C6BD7UL, 0x44904DB3UL,
|
||||
0x66B4F0A3UL, 0xC0F1648AUL, 0x697ED5AFUL, 0x49E92FF6UL,
|
||||
0x309E374FUL, 0x2CB6356AUL, 0x85808573UL, 0x4991F840UL,
|
||||
0x76F0AE02UL, 0x083BE84DUL, 0x28421C9AUL, 0x44489406UL,
|
||||
0x736E4CB8UL, 0xC1092910UL, 0x8BC95FC6UL, 0x7D869CF4UL,
|
||||
0x134F616FUL, 0x2E77118DUL, 0xB31B2BE1UL, 0xAA90B472UL,
|
||||
0x3CA5D717UL, 0x7D161BBAUL, 0x9CAD9010UL, 0xAF462BA2UL,
|
||||
0x9FE459D2UL, 0x45D34559UL, 0xD9F2DA13UL, 0xDBC65487UL,
|
||||
0xF3E4F94EUL, 0x176D486FUL, 0x097C13EAUL, 0x631DA5C7UL,
|
||||
0x445F7382UL, 0x175683F4UL, 0xCDC66A97UL, 0x70BE0288UL,
|
||||
0xB3CDCF72UL, 0x6E5DD2F3UL, 0x20936079UL, 0x459B80A5UL,
|
||||
0xBE60E2DBUL, 0xA9C23101UL, 0xEBA5315CUL, 0x224E42F2UL,
|
||||
0x1C5C1572UL, 0xF6721B2CUL, 0x1AD2FFF3UL, 0x8C25404EUL,
|
||||
0x324ED72FUL, 0x4067B7FDUL, 0x0523138EUL, 0x5CA3BC78UL,
|
||||
0xDC0FD66EUL, 0x75922283UL, 0x784D6B17UL, 0x58EBB16EUL,
|
||||
0x44094F85UL, 0x3F481D87UL, 0xFCFEAE7BUL, 0x77B5FF76UL,
|
||||
0x8C2302BFUL, 0xAAF47556UL, 0x5F46B02AUL, 0x2B092801UL,
|
||||
0x3D38F5F7UL, 0x0CA81F36UL, 0x52AF4A8AUL, 0x66D5E7C0UL,
|
||||
0xDF3B0874UL, 0x95055110UL, 0x1B5AD7A8UL, 0xF61ED5ADUL,
|
||||
0x6CF6E479UL, 0x20758184UL, 0xD0CEFA65UL, 0x88F7BE58UL,
|
||||
0x4A046826UL, 0x0FF6F8F3UL, 0xA09C7F70UL, 0x5346ABA0UL,
|
||||
0x5CE96C28UL, 0xE176EDA3UL, 0x6BAC307FUL, 0x376829D2UL,
|
||||
0x85360FA9UL, 0x17E3FE2AUL, 0x24B79767UL, 0xF5A96B20UL,
|
||||
0xD6CD2595UL, 0x68FF1EBFUL, 0x7555442CUL, 0xF19F06BEUL,
|
||||
0xF9E0659AUL, 0xEEB9491DUL, 0x34010718UL, 0xBB30CAB8UL,
|
||||
0xE822FE15UL, 0x88570983UL, 0x750E6249UL, 0xDA627E55UL,
|
||||
0x5E76FFA8UL, 0xB1534546UL, 0x6D47DE08UL, 0xEFE9E7D4UL
|
||||
},
|
||||
|
||||
{
|
||||
0xF6FA8F9DUL, 0x2CAC6CE1UL, 0x4CA34867UL, 0xE2337F7CUL,
|
||||
0x95DB08E7UL, 0x016843B4UL, 0xECED5CBCUL, 0x325553ACUL,
|
||||
0xBF9F0960UL, 0xDFA1E2EDUL, 0x83F0579DUL, 0x63ED86B9UL,
|
||||
0x1AB6A6B8UL, 0xDE5EBE39UL, 0xF38FF732UL, 0x8989B138UL,
|
||||
0x33F14961UL, 0xC01937BDUL, 0xF506C6DAUL, 0xE4625E7EUL,
|
||||
0xA308EA99UL, 0x4E23E33CUL, 0x79CBD7CCUL, 0x48A14367UL,
|
||||
0xA3149619UL, 0xFEC94BD5UL, 0xA114174AUL, 0xEAA01866UL,
|
||||
0xA084DB2DUL, 0x09A8486FUL, 0xA888614AUL, 0x2900AF98UL,
|
||||
0x01665991UL, 0xE1992863UL, 0xC8F30C60UL, 0x2E78EF3CUL,
|
||||
0xD0D51932UL, 0xCF0FEC14UL, 0xF7CA07D2UL, 0xD0A82072UL,
|
||||
0xFD41197EUL, 0x9305A6B0UL, 0xE86BE3DAUL, 0x74BED3CDUL,
|
||||
0x372DA53CUL, 0x4C7F4448UL, 0xDAB5D440UL, 0x6DBA0EC3UL,
|
||||
0x083919A7UL, 0x9FBAEED9UL, 0x49DBCFB0UL, 0x4E670C53UL,
|
||||
0x5C3D9C01UL, 0x64BDB941UL, 0x2C0E636AUL, 0xBA7DD9CDUL,
|
||||
0xEA6F7388UL, 0xE70BC762UL, 0x35F29ADBUL, 0x5C4CDD8DUL,
|
||||
0xF0D48D8CUL, 0xB88153E2UL, 0x08A19866UL, 0x1AE2EAC8UL,
|
||||
0x284CAF89UL, 0xAA928223UL, 0x9334BE53UL, 0x3B3A21BFUL,
|
||||
0x16434BE3UL, 0x9AEA3906UL, 0xEFE8C36EUL, 0xF890CDD9UL,
|
||||
0x80226DAEUL, 0xC340A4A3UL, 0xDF7E9C09UL, 0xA694A807UL,
|
||||
0x5B7C5ECCUL, 0x221DB3A6UL, 0x9A69A02FUL, 0x68818A54UL,
|
||||
0xCEB2296FUL, 0x53C0843AUL, 0xFE893655UL, 0x25BFE68AUL,
|
||||
0xB4628ABCUL, 0xCF222EBFUL, 0x25AC6F48UL, 0xA9A99387UL,
|
||||
0x53BDDB65UL, 0xE76FFBE7UL, 0xE967FD78UL, 0x0BA93563UL,
|
||||
0x8E342BC1UL, 0xE8A11BE9UL, 0x4980740DUL, 0xC8087DFCUL,
|
||||
0x8DE4BF99UL, 0xA11101A0UL, 0x7FD37975UL, 0xDA5A26C0UL,
|
||||
0xE81F994FUL, 0x9528CD89UL, 0xFD339FEDUL, 0xB87834BFUL,
|
||||
0x5F04456DUL, 0x22258698UL, 0xC9C4C83BUL, 0x2DC156BEUL,
|
||||
0x4F628DAAUL, 0x57F55EC5UL, 0xE2220ABEUL, 0xD2916EBFUL,
|
||||
0x4EC75B95UL, 0x24F2C3C0UL, 0x42D15D99UL, 0xCD0D7FA0UL,
|
||||
0x7B6E27FFUL, 0xA8DC8AF0UL, 0x7345C106UL, 0xF41E232FUL,
|
||||
0x35162386UL, 0xE6EA8926UL, 0x3333B094UL, 0x157EC6F2UL,
|
||||
0x372B74AFUL, 0x692573E4UL, 0xE9A9D848UL, 0xF3160289UL,
|
||||
0x3A62EF1DUL, 0xA787E238UL, 0xF3A5F676UL, 0x74364853UL,
|
||||
0x20951063UL, 0x4576698DUL, 0xB6FAD407UL, 0x592AF950UL,
|
||||
0x36F73523UL, 0x4CFB6E87UL, 0x7DA4CEC0UL, 0x6C152DAAUL,
|
||||
0xCB0396A8UL, 0xC50DFE5DUL, 0xFCD707ABUL, 0x0921C42FUL,
|
||||
0x89DFF0BBUL, 0x5FE2BE78UL, 0x448F4F33UL, 0x754613C9UL,
|
||||
0x2B05D08DUL, 0x48B9D585UL, 0xDC049441UL, 0xC8098F9BUL,
|
||||
0x7DEDE786UL, 0xC39A3373UL, 0x42410005UL, 0x6A091751UL,
|
||||
0x0EF3C8A6UL, 0x890072D6UL, 0x28207682UL, 0xA9A9F7BEUL,
|
||||
0xBF32679DUL, 0xD45B5B75UL, 0xB353FD00UL, 0xCBB0E358UL,
|
||||
0x830F220AUL, 0x1F8FB214UL, 0xD372CF08UL, 0xCC3C4A13UL,
|
||||
0x8CF63166UL, 0x061C87BEUL, 0x88C98F88UL, 0x6062E397UL,
|
||||
0x47CF8E7AUL, 0xB6C85283UL, 0x3CC2ACFBUL, 0x3FC06976UL,
|
||||
0x4E8F0252UL, 0x64D8314DUL, 0xDA3870E3UL, 0x1E665459UL,
|
||||
0xC10908F0UL, 0x513021A5UL, 0x6C5B68B7UL, 0x822F8AA0UL,
|
||||
0x3007CD3EUL, 0x74719EEFUL, 0xDC872681UL, 0x073340D4UL,
|
||||
0x7E432FD9UL, 0x0C5EC241UL, 0x8809286CUL, 0xF592D891UL,
|
||||
0x08A930F6UL, 0x957EF305UL, 0xB7FBFFBDUL, 0xC266E96FUL,
|
||||
0x6FE4AC98UL, 0xB173ECC0UL, 0xBC60B42AUL, 0x953498DAUL,
|
||||
0xFBA1AE12UL, 0x2D4BD736UL, 0x0F25FAABUL, 0xA4F3FCEBUL,
|
||||
0xE2969123UL, 0x257F0C3DUL, 0x9348AF49UL, 0x361400BCUL,
|
||||
0xE8816F4AUL, 0x3814F200UL, 0xA3F94043UL, 0x9C7A54C2UL,
|
||||
0xBC704F57UL, 0xDA41E7F9UL, 0xC25AD33AUL, 0x54F4A084UL,
|
||||
0xB17F5505UL, 0x59357CBEUL, 0xEDBD15C8UL, 0x7F97C5ABUL,
|
||||
0xBA5AC7B5UL, 0xB6F6DEAFUL, 0x3A479C3AUL, 0x5302DA25UL,
|
||||
0x653D7E6AUL, 0x54268D49UL, 0x51A477EAUL, 0x5017D55BUL,
|
||||
0xD7D25D88UL, 0x44136C76UL, 0x0404A8C8UL, 0xB8E5A121UL,
|
||||
0xB81A928AUL, 0x60ED5869UL, 0x97C55B96UL, 0xEAEC991BUL,
|
||||
0x29935913UL, 0x01FDB7F1UL, 0x088E8DFAUL, 0x9AB6F6F5UL,
|
||||
0x3B4CBF9FUL, 0x4A5DE3ABUL, 0xE6051D35UL, 0xA0E1D855UL,
|
||||
0xD36B4CF1UL, 0xF544EDEBUL, 0xB0E93524UL, 0xBEBB8FBDUL,
|
||||
0xA2D762CFUL, 0x49C92F54UL, 0x38B5F331UL, 0x7128A454UL,
|
||||
0x48392905UL, 0xA65B1DB8UL, 0x851C97BDUL, 0xD675CF2FUL
|
||||
},
|
||||
|
||||
{
|
||||
0x85E04019UL, 0x332BF567UL, 0x662DBFFFUL, 0xCFC65693UL,
|
||||
0x2A8D7F6FUL, 0xAB9BC912UL, 0xDE6008A1UL, 0x2028DA1FUL,
|
||||
0x0227BCE7UL, 0x4D642916UL, 0x18FAC300UL, 0x50F18B82UL,
|
||||
0x2CB2CB11UL, 0xB232E75CUL, 0x4B3695F2UL, 0xB28707DEUL,
|
||||
0xA05FBCF6UL, 0xCD4181E9UL, 0xE150210CUL, 0xE24EF1BDUL,
|
||||
0xB168C381UL, 0xFDE4E789UL, 0x5C79B0D8UL, 0x1E8BFD43UL,
|
||||
0x4D495001UL, 0x38BE4341UL, 0x913CEE1DUL, 0x92A79C3FUL,
|
||||
0x089766BEUL, 0xBAEEADF4UL, 0x1286BECFUL, 0xB6EACB19UL,
|
||||
0x2660C200UL, 0x7565BDE4UL, 0x64241F7AUL, 0x8248DCA9UL,
|
||||
0xC3B3AD66UL, 0x28136086UL, 0x0BD8DFA8UL, 0x356D1CF2UL,
|
||||
0x107789BEUL, 0xB3B2E9CEUL, 0x0502AA8FUL, 0x0BC0351EUL,
|
||||
0x166BF52AUL, 0xEB12FF82UL, 0xE3486911UL, 0xD34D7516UL,
|
||||
0x4E7B3AFFUL, 0x5F43671BUL, 0x9CF6E037UL, 0x4981AC83UL,
|
||||
0x334266CEUL, 0x8C9341B7UL, 0xD0D854C0UL, 0xCB3A6C88UL,
|
||||
0x47BC2829UL, 0x4725BA37UL, 0xA66AD22BUL, 0x7AD61F1EUL,
|
||||
0x0C5CBAFAUL, 0x4437F107UL, 0xB6E79962UL, 0x42D2D816UL,
|
||||
0x0A961288UL, 0xE1A5C06EUL, 0x13749E67UL, 0x72FC081AUL,
|
||||
0xB1D139F7UL, 0xF9583745UL, 0xCF19DF58UL, 0xBEC3F756UL,
|
||||
0xC06EBA30UL, 0x07211B24UL, 0x45C28829UL, 0xC95E317FUL,
|
||||
0xBC8EC511UL, 0x38BC46E9UL, 0xC6E6FA14UL, 0xBAE8584AUL,
|
||||
0xAD4EBC46UL, 0x468F508BUL, 0x7829435FUL, 0xF124183BUL,
|
||||
0x821DBA9FUL, 0xAFF60FF4UL, 0xEA2C4E6DUL, 0x16E39264UL,
|
||||
0x92544A8BUL, 0x009B4FC3UL, 0xABA68CEDUL, 0x9AC96F78UL,
|
||||
0x06A5B79AUL, 0xB2856E6EUL, 0x1AEC3CA9UL, 0xBE838688UL,
|
||||
0x0E0804E9UL, 0x55F1BE56UL, 0xE7E5363BUL, 0xB3A1F25DUL,
|
||||
0xF7DEBB85UL, 0x61FE033CUL, 0x16746233UL, 0x3C034C28UL,
|
||||
0xDA6D0C74UL, 0x79AAC56CUL, 0x3CE4E1ADUL, 0x51F0C802UL,
|
||||
0x98F8F35AUL, 0x1626A49FUL, 0xEED82B29UL, 0x1D382FE3UL,
|
||||
0x0C4FB99AUL, 0xBB325778UL, 0x3EC6D97BUL, 0x6E77A6A9UL,
|
||||
0xCB658B5CUL, 0xD45230C7UL, 0x2BD1408BUL, 0x60C03EB7UL,
|
||||
0xB9068D78UL, 0xA33754F4UL, 0xF430C87DUL, 0xC8A71302UL,
|
||||
0xB96D8C32UL, 0xEBD4E7BEUL, 0xBE8B9D2DUL, 0x7979FB06UL,
|
||||
0xE7225308UL, 0x8B75CF77UL, 0x11EF8DA4UL, 0xE083C858UL,
|
||||
0x8D6B786FUL, 0x5A6317A6UL, 0xFA5CF7A0UL, 0x5DDA0033UL,
|
||||
0xF28EBFB0UL, 0xF5B9C310UL, 0xA0EAC280UL, 0x08B9767AUL,
|
||||
0xA3D9D2B0UL, 0x79D34217UL, 0x021A718DUL, 0x9AC6336AUL,
|
||||
0x2711FD60UL, 0x438050E3UL, 0x069908A8UL, 0x3D7FEDC4UL,
|
||||
0x826D2BEFUL, 0x4EEB8476UL, 0x488DCF25UL, 0x36C9D566UL,
|
||||
0x28E74E41UL, 0xC2610ACAUL, 0x3D49A9CFUL, 0xBAE3B9DFUL,
|
||||
0xB65F8DE6UL, 0x92AEAF64UL, 0x3AC7D5E6UL, 0x9EA80509UL,
|
||||
0xF22B017DUL, 0xA4173F70UL, 0xDD1E16C3UL, 0x15E0D7F9UL,
|
||||
0x50B1B887UL, 0x2B9F4FD5UL, 0x625ABA82UL, 0x6A017962UL,
|
||||
0x2EC01B9CUL, 0x15488AA9UL, 0xD716E740UL, 0x40055A2CUL,
|
||||
0x93D29A22UL, 0xE32DBF9AUL, 0x058745B9UL, 0x3453DC1EUL,
|
||||
0xD699296EUL, 0x496CFF6FUL, 0x1C9F4986UL, 0xDFE2ED07UL,
|
||||
0xB87242D1UL, 0x19DE7EAEUL, 0x053E561AUL, 0x15AD6F8CUL,
|
||||
0x66626C1CUL, 0x7154C24CUL, 0xEA082B2AUL, 0x93EB2939UL,
|
||||
0x17DCB0F0UL, 0x58D4F2AEUL, 0x9EA294FBUL, 0x52CF564CUL,
|
||||
0x9883FE66UL, 0x2EC40581UL, 0x763953C3UL, 0x01D6692EUL,
|
||||
0xD3A0C108UL, 0xA1E7160EUL, 0xE4F2DFA6UL, 0x693ED285UL,
|
||||
0x74904698UL, 0x4C2B0EDDUL, 0x4F757656UL, 0x5D393378UL,
|
||||
0xA132234FUL, 0x3D321C5DUL, 0xC3F5E194UL, 0x4B269301UL,
|
||||
0xC79F022FUL, 0x3C997E7EUL, 0x5E4F9504UL, 0x3FFAFBBDUL,
|
||||
0x76F7AD0EUL, 0x296693F4UL, 0x3D1FCE6FUL, 0xC61E45BEUL,
|
||||
0xD3B5AB34UL, 0xF72BF9B7UL, 0x1B0434C0UL, 0x4E72B567UL,
|
||||
0x5592A33DUL, 0xB5229301UL, 0xCFD2A87FUL, 0x60AEB767UL,
|
||||
0x1814386BUL, 0x30BCC33DUL, 0x38A0C07DUL, 0xFD1606F2UL,
|
||||
0xC363519BUL, 0x589DD390UL, 0x5479F8E6UL, 0x1CB8D647UL,
|
||||
0x97FD61A9UL, 0xEA7759F4UL, 0x2D57539DUL, 0x569A58CFUL,
|
||||
0xE84E63ADUL, 0x462E1B78UL, 0x6580F87EUL, 0xF3817914UL,
|
||||
0x91DA55F4UL, 0x40A230F3UL, 0xD1988F35UL, 0xB6E318D2UL,
|
||||
0x3FFA50BCUL, 0x3D40F021UL, 0xC3C0BDAEUL, 0x4958C24CUL,
|
||||
0x518F36B2UL, 0x84B1D370UL, 0x0FEDCE83UL, 0x878DDADAUL,
|
||||
0xF2A279C7UL, 0x94E01BE8UL, 0x90716F4BUL, 0x954B8AA3UL
|
||||
},
|
||||
|
||||
{
|
||||
0xE216300DUL, 0xBBDDFFFCUL, 0xA7EBDABDUL, 0x35648095UL,
|
||||
0x7789F8B7UL, 0xE6C1121BUL, 0x0E241600UL, 0x052CE8B5UL,
|
||||
0x11A9CFB0UL, 0xE5952F11UL, 0xECE7990AUL, 0x9386D174UL,
|
||||
0x2A42931CUL, 0x76E38111UL, 0xB12DEF3AUL, 0x37DDDDFCUL,
|
||||
0xDE9ADEB1UL, 0x0A0CC32CUL, 0xBE197029UL, 0x84A00940UL,
|
||||
0xBB243A0FUL, 0xB4D137CFUL, 0xB44E79F0UL, 0x049EEDFDUL,
|
||||
0x0B15A15DUL, 0x480D3168UL, 0x8BBBDE5AUL, 0x669DED42UL,
|
||||
0xC7ECE831UL, 0x3F8F95E7UL, 0x72DF191BUL, 0x7580330DUL,
|
||||
0x94074251UL, 0x5C7DCDFAUL, 0xABBE6D63UL, 0xAA402164UL,
|
||||
0xB301D40AUL, 0x02E7D1CAUL, 0x53571DAEUL, 0x7A3182A2UL,
|
||||
0x12A8DDECUL, 0xFDAA335DUL, 0x176F43E8UL, 0x71FB46D4UL,
|
||||
0x38129022UL, 0xCE949AD4UL, 0xB84769ADUL, 0x965BD862UL,
|
||||
0x82F3D055UL, 0x66FB9767UL, 0x15B80B4EUL, 0x1D5B47A0UL,
|
||||
0x4CFDE06FUL, 0xC28EC4B8UL, 0x57E8726EUL, 0x647A78FCUL,
|
||||
0x99865D44UL, 0x608BD593UL, 0x6C200E03UL, 0x39DC5FF6UL,
|
||||
0x5D0B00A3UL, 0xAE63AFF2UL, 0x7E8BD632UL, 0x70108C0CUL,
|
||||
0xBBD35049UL, 0x2998DF04UL, 0x980CF42AUL, 0x9B6DF491UL,
|
||||
0x9E7EDD53UL, 0x06918548UL, 0x58CB7E07UL, 0x3B74EF2EUL,
|
||||
0x522FFFB1UL, 0xD24708CCUL, 0x1C7E27CDUL, 0xA4EB215BUL,
|
||||
0x3CF1D2E2UL, 0x19B47A38UL, 0x424F7618UL, 0x35856039UL,
|
||||
0x9D17DEE7UL, 0x27EB35E6UL, 0xC9AFF67BUL, 0x36BAF5B8UL,
|
||||
0x09C467CDUL, 0xC18910B1UL, 0xE11DBF7BUL, 0x06CD1AF8UL,
|
||||
0x7170C608UL, 0x2D5E3354UL, 0xD4DE495AUL, 0x64C6D006UL,
|
||||
0xBCC0C62CUL, 0x3DD00DB3UL, 0x708F8F34UL, 0x77D51B42UL,
|
||||
0x264F620FUL, 0x24B8D2BFUL, 0x15C1B79EUL, 0x46A52564UL,
|
||||
0xF8D7E54EUL, 0x3E378160UL, 0x7895CDA5UL, 0x859C15A5UL,
|
||||
0xE6459788UL, 0xC37BC75FUL, 0xDB07BA0CUL, 0x0676A3ABUL,
|
||||
0x7F229B1EUL, 0x31842E7BUL, 0x24259FD7UL, 0xF8BEF472UL,
|
||||
0x835FFCB8UL, 0x6DF4C1F2UL, 0x96F5B195UL, 0xFD0AF0FCUL,
|
||||
0xB0FE134CUL, 0xE2506D3DUL, 0x4F9B12EAUL, 0xF215F225UL,
|
||||
0xA223736FUL, 0x9FB4C428UL, 0x25D04979UL, 0x34C713F8UL,
|
||||
0xC4618187UL, 0xEA7A6E98UL, 0x7CD16EFCUL, 0x1436876CUL,
|
||||
0xF1544107UL, 0xBEDEEE14UL, 0x56E9AF27UL, 0xA04AA441UL,
|
||||
0x3CF7C899UL, 0x92ECBAE6UL, 0xDD67016DUL, 0x151682EBUL,
|
||||
0xA842EEDFUL, 0xFDBA60B4UL, 0xF1907B75UL, 0x20E3030FUL,
|
||||
0x24D8C29EUL, 0xE139673BUL, 0xEFA63FB8UL, 0x71873054UL,
|
||||
0xB6F2CF3BUL, 0x9F326442UL, 0xCB15A4CCUL, 0xB01A4504UL,
|
||||
0xF1E47D8DUL, 0x844A1BE5UL, 0xBAE7DFDCUL, 0x42CBDA70UL,
|
||||
0xCD7DAE0AUL, 0x57E85B7AUL, 0xD53F5AF6UL, 0x20CF4D8CUL,
|
||||
0xCEA4D428UL, 0x79D130A4UL, 0x3486EBFBUL, 0x33D3CDDCUL,
|
||||
0x77853B53UL, 0x37EFFCB5UL, 0xC5068778UL, 0xE580B3E6UL,
|
||||
0x4E68B8F4UL, 0xC5C8B37EUL, 0x0D809EA2UL, 0x398FEB7CUL,
|
||||
0x132A4F94UL, 0x43B7950EUL, 0x2FEE7D1CUL, 0x223613BDUL,
|
||||
0xDD06CAA2UL, 0x37DF932BUL, 0xC4248289UL, 0xACF3EBC3UL,
|
||||
0x5715F6B7UL, 0xEF3478DDUL, 0xF267616FUL, 0xC148CBE4UL,
|
||||
0x9052815EUL, 0x5E410FABUL, 0xB48A2465UL, 0x2EDA7FA4UL,
|
||||
0xE87B40E4UL, 0xE98EA084UL, 0x5889E9E1UL, 0xEFD390FCUL,
|
||||
0xDD07D35BUL, 0xDB485694UL, 0x38D7E5B2UL, 0x57720101UL,
|
||||
0x730EDEBCUL, 0x5B643113UL, 0x94917E4FUL, 0x503C2FBAUL,
|
||||
0x646F1282UL, 0x7523D24AUL, 0xE0779695UL, 0xF9C17A8FUL,
|
||||
0x7A5B2121UL, 0xD187B896UL, 0x29263A4DUL, 0xBA510CDFUL,
|
||||
0x81F47C9FUL, 0xAD1163EDUL, 0xEA7B5965UL, 0x1A00726EUL,
|
||||
0x11403092UL, 0x00DA6D77UL, 0x4A0CDD61UL, 0xAD1F4603UL,
|
||||
0x605BDFB0UL, 0x9EEDC364UL, 0x22EBE6A8UL, 0xCEE7D28AUL,
|
||||
0xA0E736A0UL, 0x5564A6B9UL, 0x10853209UL, 0xC7EB8F37UL,
|
||||
0x2DE705CAUL, 0x8951570FUL, 0xDF09822BUL, 0xBD691A6CUL,
|
||||
0xAA12E4F2UL, 0x87451C0FUL, 0xE0F6A27AUL, 0x3ADA4819UL,
|
||||
0x4CF1764FUL, 0x0D771C2BUL, 0x67CDB156UL, 0x350D8384UL,
|
||||
0x5938FA0FUL, 0x42399EF3UL, 0x36997B07UL, 0x0E84093DUL,
|
||||
0x4AA93E61UL, 0x8360D87BUL, 0x1FA98B0CUL, 0x1149382CUL,
|
||||
0xE97625A5UL, 0x0614D1B7UL, 0x0E25244BUL, 0x0C768347UL,
|
||||
0x589E8D82UL, 0x0D2059D1UL, 0xA466BB1EUL, 0xF8DA0A82UL,
|
||||
0x04F19130UL, 0xBA6E4EC0UL, 0x99265164UL, 0x1EE7230DUL,
|
||||
0x50B2AD80UL, 0xEAEE6801UL, 0x8DB2A283UL, 0xEA8BF59EUL
|
||||
}};
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
#ifndef CRYPTOPP_CBCMAC_H
|
||||
#define CRYPTOPP_CBCMAC_H
|
||||
|
||||
#include "seckey.h"
|
||||
#include "secblock.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
template <class T>
|
||||
class CBC_MAC_Base : public SameKeyLengthAs<T>, public MessageAuthenticationCode
|
||||
{
|
||||
public:
|
||||
static std::string StaticAlgorithmName() {return std::string("CBC-MAC(") + T::StaticAlgorithmName() + ")";}
|
||||
|
||||
CBC_MAC_Base() {}
|
||||
|
||||
void CheckedSetKey(void *, Empty empty, const byte *key, unsigned int length, const NameValuePairs ¶ms);
|
||||
void Update(const byte *input, unsigned int length);
|
||||
void TruncatedFinal(byte *mac, unsigned int size);
|
||||
unsigned int DigestSize() const {return m_cipher.BlockSize();}
|
||||
|
||||
private:
|
||||
void ProcessBuf();
|
||||
typename T::Encryption m_cipher;
|
||||
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 an encryption class.
|
||||
Secure only for fixed length messages. For variable length
|
||||
messages use DMAC.
|
||||
*/
|
||||
template <class T>
|
||||
class CBC_MAC : public MessageAuthenticationCodeTemplate<CBC_MAC_Base<T> >
|
||||
{
|
||||
public:
|
||||
CBC_MAC() {}
|
||||
CBC_MAC(const byte *key, unsigned int length=CBC_MAC_Base<T>::DEFAULT_KEYLENGTH)
|
||||
{SetKey(key, length);}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void CBC_MAC_Base<T>::CheckedSetKey(void *, Empty empty, const byte *key, unsigned int length, const NameValuePairs ¶ms)
|
||||
{
|
||||
m_cipher.SetKey(key, length, params);
|
||||
m_reg.CleanNew(m_cipher.BlockSize());
|
||||
m_counter = 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CBC_MAC_Base<T>::Update(const byte *input, unsigned int length)
|
||||
{
|
||||
while (m_counter && length)
|
||||
{
|
||||
m_reg[m_counter++] ^= *input++;
|
||||
if (m_counter == T::BLOCKSIZE)
|
||||
ProcessBuf();
|
||||
length--;
|
||||
}
|
||||
|
||||
while (length >= T::BLOCKSIZE)
|
||||
{
|
||||
xorbuf(m_reg, input, T::BLOCKSIZE);
|
||||
ProcessBuf();
|
||||
input += T::BLOCKSIZE;
|
||||
length -= T::BLOCKSIZE;
|
||||
}
|
||||
|
||||
while (length--)
|
||||
{
|
||||
m_reg[m_counter++] ^= *input++;
|
||||
if (m_counter == T::BLOCKSIZE)
|
||||
ProcessBuf();
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CBC_MAC_Base<T>::TruncatedFinal(byte *mac, unsigned int size)
|
||||
{
|
||||
ThrowIfInvalidTruncatedSize(size);
|
||||
|
||||
if (m_counter)
|
||||
ProcessBuf();
|
||||
|
||||
memcpy(mac, m_reg, size);
|
||||
memset(m_reg, 0, T::BLOCKSIZE);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CBC_MAC_Base<T>::ProcessBuf()
|
||||
{
|
||||
m_cipher.ProcessBlock(m_reg);
|
||||
m_counter = 0;
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,282 @@
|
|||
// channels.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#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
|
||||
|
||||
class ChannelRouteIterator
|
||||
{
|
||||
public:
|
||||
typedef ChannelSwitch::RouteMap::const_iterator MapIterator;
|
||||
typedef ChannelSwitch::DefaultRouteList::const_iterator ListIterator;
|
||||
|
||||
const std::string m_channel;
|
||||
bool m_useDefault;
|
||||
MapIterator m_itMapCurrent, m_itMapEnd;
|
||||
ListIterator m_itListCurrent, m_itListEnd;
|
||||
|
||||
ChannelRouteIterator(ChannelSwitch &cs, 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 & Channel()
|
||||
{
|
||||
if (m_useDefault)
|
||||
return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel;
|
||||
else
|
||||
return m_itMapCurrent->second.second;
|
||||
}
|
||||
};
|
||||
|
||||
unsigned int ChannelSwitch::ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
|
||||
{
|
||||
if (!blocking)
|
||||
throw BlockingInputOnly("ChannelSwitch");
|
||||
|
||||
ChannelRouteIterator it(*this, channel);
|
||||
while (!it.End())
|
||||
{
|
||||
it.Destination().ChannelPut2(it.Channel(), begin, length, messageEnd, blocking);
|
||||
it.Next();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ChannelSwitch::ChannelInitialize(const std::string &channel, const NameValuePairs ¶meters/* =g_nullNameValuePairs */, int propagation/* =-1 */)
|
||||
{
|
||||
if (channel.empty())
|
||||
{
|
||||
m_routeMap.clear();
|
||||
m_defaultRoutes.clear();
|
||||
}
|
||||
|
||||
ChannelRouteIterator it(*this, channel);
|
||||
while (!it.End())
|
||||
{
|
||||
it.Destination().ChannelInitialize(it.Channel(), parameters, propagation);
|
||||
it.Next();
|
||||
}
|
||||
}
|
||||
|
||||
bool ChannelSwitch::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking)
|
||||
{
|
||||
if (!blocking)
|
||||
throw BlockingInputOnly("ChannelSwitch");
|
||||
|
||||
ChannelRouteIterator it(*this, channel);
|
||||
while (!it.End())
|
||||
{
|
||||
it.Destination().ChannelFlush(it.Channel(), completeFlush, propagation, blocking);
|
||||
it.Next();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ChannelSwitch::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
|
||||
{
|
||||
if (!blocking)
|
||||
throw BlockingInputOnly("ChannelSwitch");
|
||||
|
||||
ChannelRouteIterator it(*this, channel);
|
||||
while (!it.End())
|
||||
{
|
||||
it.Destination().ChannelMessageSeriesEnd(it.Channel(), propagation);
|
||||
it.Next();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
byte * ChannelSwitch::ChannelCreatePutSpace(const std::string &channel, unsigned int &size)
|
||||
{
|
||||
ChannelRouteIterator it(*this, channel);
|
||||
if (!it.End())
|
||||
{
|
||||
BufferedTransformation &target = it.Destination();
|
||||
it.Next();
|
||||
if (it.End()) // there is only one target channel
|
||||
return target.ChannelCreatePutSpace(it.Channel(), size);
|
||||
}
|
||||
size = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int ChannelSwitch::ChannelPutModifiable2(const std::string &channel, byte *inString, unsigned int length, int messageEnd, bool blocking)
|
||||
{
|
||||
if (!blocking)
|
||||
throw BlockingInputOnly("ChannelSwitch");
|
||||
|
||||
ChannelRouteIterator it(*this, 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);
|
||||
}
|
||||
ChannelPut2(channel, inString, length, messageEnd, blocking);
|
||||
return false;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
#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
|
||||
|
||||
//! Route input to different and/or multiple channels based on channel ID
|
||||
class ChannelSwitch : public Multichannel<Sink>
|
||||
{
|
||||
public:
|
||||
ChannelSwitch() {}
|
||||
ChannelSwitch(BufferedTransformation &destination)
|
||||
{
|
||||
AddDefaultRoute(destination);
|
||||
}
|
||||
ChannelSwitch(BufferedTransformation &destination, const std::string &outChannel)
|
||||
{
|
||||
AddDefaultRoute(destination, outChannel);
|
||||
}
|
||||
|
||||
unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking);
|
||||
unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking);
|
||||
|
||||
void ChannelInitialize(const std::string &channel, const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1);
|
||||
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, unsigned int &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:
|
||||
typedef std::pair<BufferedTransformation *, std::string> Route;
|
||||
typedef std::multimap<std::string, Route> RouteMap;
|
||||
RouteMap m_routeMap;
|
||||
|
||||
typedef std::pair<BufferedTransformation *, value_ptr<std::string> > DefaultRoute;
|
||||
typedef std::list<DefaultRoute> DefaultRouteList;
|
||||
DefaultRouteList m_defaultRoutes;
|
||||
|
||||
friend class ChannelRouteIterator;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
#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(__sparc) || defined(__sparc__) || defined(__hppa__) || defined(__PPC__) || defined(__mips__) || (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
|
||||
|
||||
// Try this if you have a large cache or your CPU is slow manipulating
|
||||
// individual bytes.
|
||||
// #define DIAMOND_USE_PERMTABLE
|
||||
|
||||
// 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
|
||||
|
||||
// ***************** 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
|
||||
|
||||
// Avoid putting "CryptoPP::" in front of everything in Doxygen output
|
||||
#ifdef CRYPTOPP_DOXYGEN_PROCESSING
|
||||
# define CryptoPP
|
||||
# define NAMESPACE_BEGIN(x)
|
||||
# define NAMESPACE_END
|
||||
#else
|
||||
# define NAMESPACE_BEGIN(x) namespace x {
|
||||
# define NAMESPACE_END }
|
||||
#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; // moved outside namespace for Borland C++Builder 5
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
typedef unsigned short word16;
|
||||
#if defined(__alpha) && !defined(_MSC_VER)
|
||||
typedef unsigned int word32;
|
||||
#else
|
||||
typedef unsigned long word32;
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || defined(__MWERKS__)
|
||||
# define WORD64_AVAILABLE
|
||||
typedef unsigned long long word64;
|
||||
# define W64LIT(x) x##LL
|
||||
#elif defined(_MSC_VER) || defined(__BCPLUSPLUS__)
|
||||
# define WORD64_AVAILABLE
|
||||
typedef unsigned __int64 word64;
|
||||
# define W64LIT(x) x##ui64
|
||||
#endif
|
||||
|
||||
// defined this if your CPU is not 64-bit
|
||||
#if defined(WORD64_AVAILABLE) && !defined(__alpha)
|
||||
# define SLOW_WORD64
|
||||
#endif
|
||||
|
||||
// word should have the same size as your CPU registers
|
||||
// dword should be twice as big as word
|
||||
|
||||
#if (defined(__GNUC__) && !defined(__alpha)) || defined(__MWERKS__)
|
||||
typedef unsigned long word;
|
||||
typedef unsigned long long dword;
|
||||
#elif defined(_MSC_VER) || defined(__BCPLUSPLUS__)
|
||||
typedef unsigned __int32 word;
|
||||
typedef unsigned __int64 dword;
|
||||
#else
|
||||
typedef unsigned int word;
|
||||
typedef unsigned long dword;
|
||||
#endif
|
||||
|
||||
const unsigned int WORD_SIZE = sizeof(word);
|
||||
const unsigned int WORD_BITS = WORD_SIZE * 8;
|
||||
|
||||
#define LOW_WORD(x) (word)(x)
|
||||
|
||||
union dword_union
|
||||
{
|
||||
dword_union (const dword &dw) : dw(dw) {}
|
||||
dword dw;
|
||||
word w[2];
|
||||
};
|
||||
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
# define HIGH_WORD(x) (dword_union(x).w[1])
|
||||
#else
|
||||
# define HIGH_WORD(x) (dword_union(x).w[0])
|
||||
#endif
|
||||
|
||||
// if the above HIGH_WORD macro doesn't work (if you are not sure, compile it
|
||||
// and run the validation tests), try this:
|
||||
// #define HIGH_WORD(x) (word)((x)>>WORD_BITS)
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BCPLUSPLUS__)
|
||||
# define INTEL_INTRINSICS
|
||||
# define FAST_ROTATE
|
||||
#elif defined(__MWERKS__) && TARGET_CPU_PPC
|
||||
# define PPC_INTRINSICS
|
||||
# define FAST_ROTATE
|
||||
#elif defined(__GNUC__) && defined(__i386__)
|
||||
// GCC does peephole optimizations which should result in using rotate instructions
|
||||
# define FAST_ROTATE
|
||||
#endif
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
// VC60 workaround: it doesn't allow typename in some places
|
||||
#ifdef _MSC_VER
|
||||
#define CPP_TYPENAME
|
||||
#else
|
||||
#define CPP_TYPENAME typename
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// 4250: dominance
|
||||
// 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
|
||||
# pragma warning(disable: 4250 4660 4661 4786 4355)
|
||||
#endif
|
||||
|
||||
// ***************** determine availability of OS features ********************
|
||||
|
||||
#ifndef NO_OS_DEPENDENCE
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#define CRYPTOPP_WIN32_AVAILABLE
|
||||
#endif
|
||||
|
||||
#if !defined(NO_OS_DEPENDENCE) && defined(WORD64_AVAILABLE) && (defined(_WIN32) || defined(__unix__) || defined(macintosh))
|
||||
# define HIGHRES_TIMER_AVAILABLE
|
||||
#endif
|
||||
|
||||
#if defined(__unix__)
|
||||
# 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(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(__FreeBSD__) || defined(__linux__) || defined(__MACH__))
|
||||
# define NONBLOCKING_RNG_AVAILABLE
|
||||
# define BLOCKING_RNG_AVAILABLE
|
||||
# define OS_RNG_AVAILABLE
|
||||
#endif
|
||||
|
||||
#ifdef __unix__
|
||||
# define HAS_PTHREADS
|
||||
# define THREADS_AVAILABLE
|
||||
#endif
|
||||
|
||||
#ifdef CRYPTOPP_WIN32_AVAILABLE
|
||||
# define HAS_WINTHREADS
|
||||
# define THREADS_AVAILABLE
|
||||
#endif
|
||||
|
||||
#endif // NO_OS_DEPENDENCE
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
// 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, unsigned int 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, unsigned int size)
|
||||
{
|
||||
ThrowIfInvalidTruncatedSize(size);
|
||||
|
||||
m_crc ^= CRC32_NEGL;
|
||||
for (unsigned int i=0; i<size; i++)
|
||||
hash[i] = GetCrcByte(i);
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#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:
|
||||
enum {DIGESTSIZE = 4};
|
||||
CRC32();
|
||||
void Update(const byte *input, unsigned int length);
|
||||
void TruncatedFinal(byte *hash, unsigned int size);
|
||||
unsigned int DigestSize() const {return DIGESTSIZE;}
|
||||
|
||||
void UpdateByte(byte b) {m_crc = m_tab[CRC32_INDEX(m_crc) ^ b] ^ CRC32_SHIFTED(m_crc);}
|
||||
byte GetCrcByte(unsigned int 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
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
#include "pch.h"
|
||||
|
||||
#ifdef __BCPLUSPLUS__
|
||||
#include <condefs.h>
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
USEUNIT("3way.cpp");
|
||||
USEUNIT("algebra.cpp");
|
||||
USEUNIT("asn.cpp");
|
||||
USEUNIT("base64.cpp");
|
||||
USEUNIT("bench.cpp");
|
||||
USEUNIT("bfinit.cpp");
|
||||
USEUNIT("blowfish.cpp");
|
||||
USEUNIT("blumgold.cpp");
|
||||
USEUNIT("blumshub.cpp");
|
||||
USEUNIT("cast.cpp");
|
||||
USEUNIT("cast128s.cpp");
|
||||
USEUNIT("crc.cpp");
|
||||
USEUNIT("cryptlib.cpp");
|
||||
USEUNIT("default.cpp");
|
||||
USEUNIT("des.cpp");
|
||||
USEUNIT("dessp.cpp");
|
||||
USEUNIT("dh.cpp");
|
||||
USEUNIT("diamond.cpp");
|
||||
USEUNIT("diamondt.cpp");
|
||||
USEUNIT("dsa.cpp");
|
||||
USEUNIT("ec2n.cpp");
|
||||
USEUNIT("eccrypto.cpp");
|
||||
USEUNIT("ecp.cpp");
|
||||
USEUNIT("elgamal.cpp");
|
||||
USEUNIT("eprecomp.cpp");
|
||||
USEUNIT("files.cpp");
|
||||
USEUNIT("filters.cpp");
|
||||
USEUNIT("forkjoin.cpp");
|
||||
USEUNIT("gf2_32.cpp");
|
||||
USEUNIT("gf256.cpp");
|
||||
USEUNIT("gf2n.cpp");
|
||||
USEUNIT("gost.cpp");
|
||||
USEUNIT("gzip.cpp");
|
||||
USEUNIT("haval.cpp");
|
||||
USEUNIT("hex.cpp");
|
||||
USEUNIT("idea.cpp");
|
||||
USEUNIT("integer.cpp");
|
||||
USEUNIT("iterhash.cpp");
|
||||
USEUNIT("luc.cpp");
|
||||
USEUNIT("md5.cpp");
|
||||
USEUNIT("md5mac.cpp");
|
||||
USEUNIT("misc.cpp");
|
||||
USEUNIT("modes.cpp");
|
||||
USEUNIT("nbtheory.cpp");
|
||||
USEUNIT("oaep.cpp");
|
||||
USEUNIT("pch.cpp");
|
||||
USEUNIT("pkcspad.cpp");
|
||||
USEUNIT("polynomi.cpp");
|
||||
USEUNIT("pubkey.cpp");
|
||||
USEUNIT("queue.cpp");
|
||||
USEUNIT("rabin.cpp");
|
||||
USEUNIT("randpool.cpp");
|
||||
USEUNIT("rc5.cpp");
|
||||
USEUNIT("ripemd.cpp");
|
||||
USEUNIT("rng.cpp");
|
||||
USEUNIT("rsa.cpp");
|
||||
USEUNIT("safer.cpp");
|
||||
USEUNIT("sapphire.cpp");
|
||||
USEUNIT("seal.cpp");
|
||||
USEUNIT("secshare.cpp");
|
||||
USEUNIT("secsplit.cpp");
|
||||
USEUNIT("sha.cpp");
|
||||
USEUNIT("shark.cpp");
|
||||
USEUNIT("sharkbox.cpp");
|
||||
USEUNIT("square.cpp");
|
||||
USEUNIT("squaretb.cpp");
|
||||
USEUNIT("tea.cpp");
|
||||
USEUNIT("test.cpp");
|
||||
USEUNIT("tiger.cpp");
|
||||
USEUNIT("tigertab.cpp");
|
||||
USEUNIT("validat1.cpp");
|
||||
USEUNIT("validat2.cpp");
|
||||
USEUNIT("validat3.cpp");
|
||||
USEUNIT("wake.cpp");
|
||||
USEUNIT("zbits.cpp");
|
||||
USEUNIT("zdeflate.cpp");
|
||||
USEUNIT("zinflate.cpp");
|
||||
USEUNIT("ztrees.cpp");
|
||||
USEUNIT("cbc.cpp");
|
||||
USEUNIT("arc4.cpp");
|
||||
USEUNIT("modexppc.cpp");
|
||||
USEUNIT("md2.cpp");
|
||||
USEUNIT("rc2.cpp");
|
||||
USEUNIT("rc6.cpp");
|
||||
USEUNIT("mars.cpp");
|
||||
USEUNIT("rw.cpp");
|
||||
USEUNIT("marss.cpp");
|
||||
USEUNIT("nr.cpp");
|
||||
USEUNIT("mqv.cpp");
|
||||
USEUNIT("rijndael.cpp");
|
||||
USEUNIT("twofish.cpp");
|
||||
USEUNIT("serpent.cpp");
|
||||
USEUNIT("rdtables.cpp");
|
||||
USEUNIT("tftables.cpp");
|
||||
USEUNIT("xtr.cpp");
|
||||
USEUNIT("skipjack.cpp");
|
||||
USEUNIT("mqueue.cpp");
|
||||
USEUNIT("xtrcrypt.cpp");
|
||||
USEUNIT("network.cpp");
|
||||
USEUNIT("osrng.cpp");
|
||||
USEUNIT("socketft.cpp");
|
||||
//---------------------------------------------------------------------------
|
||||
int cmain(int argc, char **argv);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
return cmain(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,392 @@
|
|||
# Microsoft Developer Studio Project File - Name="cryptest" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=cryptest - Win32 FIPS 140 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "cryptest.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "cryptest.mak" CFG="cryptest - Win32 FIPS 140 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "cryptest - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "cryptest - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "cryptest - Win32 FIPS 140 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "cryptest - Win32 FIPS 140 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""$/cryptlib", BAAAAAAA"
|
||||
# PROP Scc_LocalPath "."
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "cryptest - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "cryptes0"
|
||||
# PROP BASE Intermediate_Dir "cryptes0"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "CTRelease"
|
||||
# PROP Intermediate_Dir "CTRelease"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /GB /Gd /MT /W3 /GX /Zi /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /Zm200 /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /OPT:NOWIN98
|
||||
|
||||
!ELSEIF "$(CFG)" == "cryptest - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "cryptes1"
|
||||
# PROP BASE Intermediate_Dir "cryptes1"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "CTDebug"
|
||||
# PROP Intermediate_Dir "CTDebug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /Zm200 /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /OPT:NOWIN98
|
||||
|
||||
!ELSEIF "$(CFG)" == "cryptest - Win32 FIPS 140 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "cryptest___Win32_FIPS_140_Release"
|
||||
# PROP BASE Intermediate_Dir "cryptest___Win32_FIPS_140_Release"
|
||||
# PROP BASE Ignore_Export_Lib 0
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "CT_FIPS_140_Release"
|
||||
# PROP Intermediate_Dir "CT_FIPS_140_Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /G5 /Gz /MT /W3 /GX /Zi /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /Zm200 /c
|
||||
# ADD CPP /nologo /G5 /Gz /MT /W3 /GX /Zi /O2 /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "WIN32" /YX /FD /Zm200 /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /OPT:NOWIN98
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /OPT:NOWIN98
|
||||
|
||||
!ELSEIF "$(CFG)" == "cryptest - Win32 FIPS 140 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "cryptest___Win32_FIPS_140_Debug"
|
||||
# PROP BASE Intermediate_Dir "cryptest___Win32_FIPS_140_Debug"
|
||||
# PROP BASE Ignore_Export_Lib 0
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "CT_FIPS_140_Debug"
|
||||
# PROP Intermediate_Dir "CT_FIPS_140_Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /Zm200 /c
|
||||
# ADD CPP /nologo /G5 /Gz /MTd /W3 /GX /ZI /Od /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "WIN32" /YX /FD /Zm200 /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /OPT:NOWIN98
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /OPT:NOWIN98
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "cryptest - Win32 Release"
|
||||
# Name "cryptest - Win32 Debug"
|
||||
# Name "cryptest - Win32 FIPS 140 Release"
|
||||
# Name "cryptest - Win32 FIPS 140 Debug"
|
||||
# Begin Group "Test Data"
|
||||
|
||||
# PROP Default_Filter ".dat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\3desval.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\3wayval.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cast128v.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cast256v.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\descert.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\dh1024.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\dh2048.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\diamond.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\digest.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\dsa1024.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\dsa1024b.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\dsa512.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\elgc1024.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\esig1023.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\esig1536.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\esig2046.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\gostval.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\havalcer.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ideaval.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\luc1024.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\luc2048.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lucc1024.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lucc512.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lucd1024.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lucd512.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lucs1024.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lucs512.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\marsval.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\mqv1024.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\mqv2048.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nr1024.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nr2048.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rabi1024.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rabi2048.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rc2val.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rc5val.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rc6val.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rijndael.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rsa1024.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rsa2048.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rsa400pb.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rsa400pv.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rsa512a.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rw1024.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rw2048.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\saferval.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\serpentv.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sharkval.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\skipjack.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\squareva.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\twofishv.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\usage.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\xtrdh171.dat
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\xtrdh342.dat
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Source Code"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bench.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bench.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\test.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\validat1.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\validat2.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\validat3.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\validate.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "cryptest"=.\cryptest.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name cryptlib
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "cryptlib"=.\cryptlib.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
|
@ -0,0 +1,660 @@
|
|||
// cryptlib.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "cryptlib.h"
|
||||
#include "misc.h"
|
||||
#include "filters.h"
|
||||
#include "algparam.h"
|
||||
#include "fips140.h"
|
||||
#include "argnames.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
CRYPTOPP_COMPILE_ASSERT(sizeof(byte) == 1);
|
||||
CRYPTOPP_COMPILE_ASSERT(sizeof(word16) == 2);
|
||||
CRYPTOPP_COMPILE_ASSERT(sizeof(word32) == 4);
|
||||
#ifdef WORD64_AVAILABLE
|
||||
CRYPTOPP_COMPILE_ASSERT(sizeof(word64) == 8);
|
||||
#endif
|
||||
CRYPTOPP_COMPILE_ASSERT(sizeof(dword) == 2*sizeof(word));
|
||||
|
||||
const std::string BufferedTransformation::NULL_CHANNEL;
|
||||
const NullNameValuePairs g_nullNameValuePairs;
|
||||
|
||||
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 power-up a self test failed.");
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleKeyingInterface::SetKeyWithRounds(const byte *key, unsigned int length, int rounds)
|
||||
{
|
||||
SetKey(key, length, MakeParameters(Name::Rounds(), rounds));
|
||||
}
|
||||
|
||||
void SimpleKeyingInterface::SetKeyWithIV(const byte *key, unsigned int length, const byte *iv)
|
||||
{
|
||||
SetKey(key, length, MakeParameters(Name::IV(), iv));
|
||||
}
|
||||
|
||||
void SimpleKeyingInterface::ThrowIfInvalidKeyLength(const Algorithm &algorithm, unsigned int length)
|
||||
{
|
||||
if (!IsValidKeyLength(length))
|
||||
throw InvalidKeyLength(algorithm.AlgorithmName(), length);
|
||||
}
|
||||
|
||||
void BlockTransformation::ProcessAndXorMultipleBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, unsigned int numberOfBlocks) const
|
||||
{
|
||||
unsigned int blockSize = BlockSize();
|
||||
while (numberOfBlocks--)
|
||||
{
|
||||
ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks);
|
||||
inBlocks += blockSize;
|
||||
outBlocks += blockSize;
|
||||
if (xorBlocks)
|
||||
xorBlocks += blockSize;
|
||||
}
|
||||
}
|
||||
|
||||
void StreamTransformation::ProcessLastBlock(byte *outString, const byte *inString, unsigned int length)
|
||||
{
|
||||
assert(MinLastBlockSize() == 0); // this function should be overriden otherwise
|
||||
|
||||
if (length == MandatoryBlockSize())
|
||||
ProcessData(outString, inString, length);
|
||||
else if (length != 0)
|
||||
throw NotImplemented("StreamTransformation: this object does't support a special last block");
|
||||
}
|
||||
|
||||
unsigned int RandomNumberGenerator::GenerateBit()
|
||||
{
|
||||
return Parity(GenerateByte());
|
||||
}
|
||||
|
||||
void RandomNumberGenerator::GenerateBlock(byte *output, unsigned int size)
|
||||
{
|
||||
while (size--)
|
||||
*output++ = GenerateByte();
|
||||
}
|
||||
|
||||
word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max)
|
||||
{
|
||||
word32 range = max-min;
|
||||
const int maxBytes = BytePrecision(range);
|
||||
const int maxBits = BitPrecision(range);
|
||||
|
||||
word32 value;
|
||||
|
||||
do
|
||||
{
|
||||
value = 0;
|
||||
for (int i=0; i<maxBytes; i++)
|
||||
value = (value << 8) | GenerateByte();
|
||||
|
||||
value = Crop(value, maxBits);
|
||||
} while (value > range);
|
||||
|
||||
return value+min;
|
||||
}
|
||||
|
||||
void RandomNumberGenerator::DiscardBytes(unsigned int n)
|
||||
{
|
||||
while (n--)
|
||||
GenerateByte();
|
||||
}
|
||||
|
||||
RandomNumberGenerator & NullRNG()
|
||||
{
|
||||
class NullRNG : public RandomNumberGenerator
|
||||
{
|
||||
public:
|
||||
std::string AlgorithmName() const {return "NullRNG";}
|
||||
byte GenerateByte() {throw NotImplemented("NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes");}
|
||||
};
|
||||
|
||||
static NullRNG s_nullRNG;
|
||||
return s_nullRNG;
|
||||
}
|
||||
|
||||
bool HashTransformation::TruncatedVerify(const byte *digestIn, unsigned int digestLength)
|
||||
{
|
||||
ThrowIfInvalidTruncatedSize(digestLength);
|
||||
SecByteBlock digest(digestLength);
|
||||
TruncatedFinal(digest, digestLength);
|
||||
return memcmp(digest, digestIn, digestLength) == 0;
|
||||
}
|
||||
|
||||
void HashTransformation::ThrowIfInvalidTruncatedSize(unsigned int 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)
|
||||
{
|
||||
BufferedTransformation *t = AttachedTransformation();
|
||||
if (t)
|
||||
t->GetWaitObjects(container);
|
||||
}
|
||||
|
||||
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, unsigned int &size)
|
||||
{
|
||||
if (channel.empty())
|
||||
return CreatePutSpace(size);
|
||||
else
|
||||
throw NoChannelSupport();
|
||||
}
|
||||
|
||||
unsigned int BufferedTransformation::ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
|
||||
{
|
||||
if (channel.empty())
|
||||
return Put2(begin, length, messageEnd, blocking);
|
||||
else
|
||||
throw NoChannelSupport();
|
||||
}
|
||||
|
||||
unsigned int BufferedTransformation::ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking)
|
||||
{
|
||||
if (channel.empty())
|
||||
return PutModifiable2(begin, length, messageEnd, blocking);
|
||||
else
|
||||
return ChannelPut2(channel, begin, length, messageEnd, blocking);
|
||||
}
|
||||
|
||||
void BufferedTransformation::ChannelInitialize(const std::string &channel, const NameValuePairs ¶meters, int propagation)
|
||||
{
|
||||
if (channel.empty())
|
||||
Initialize(parameters, propagation);
|
||||
else
|
||||
throw NoChannelSupport();
|
||||
}
|
||||
|
||||
bool BufferedTransformation::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking)
|
||||
{
|
||||
if (channel.empty())
|
||||
return Flush(completeFlush, propagation, blocking);
|
||||
else
|
||||
throw NoChannelSupport();
|
||||
}
|
||||
|
||||
bool BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
|
||||
{
|
||||
if (channel.empty())
|
||||
return MessageSeriesEnd(propagation, blocking);
|
||||
else
|
||||
throw NoChannelSupport();
|
||||
}
|
||||
|
||||
unsigned long 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;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int BufferedTransformation::Get(byte &outByte)
|
||||
{
|
||||
if (AttachedTransformation())
|
||||
return AttachedTransformation()->Get(outByte);
|
||||
else
|
||||
return Get(&outByte, 1);
|
||||
}
|
||||
|
||||
unsigned int BufferedTransformation::Get(byte *outString, unsigned int getMax)
|
||||
{
|
||||
if (AttachedTransformation())
|
||||
return AttachedTransformation()->Get(outString, getMax);
|
||||
else
|
||||
{
|
||||
ArraySink arraySink(outString, getMax);
|
||||
return TransferTo(arraySink, getMax);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int BufferedTransformation::Peek(byte &outByte) const
|
||||
{
|
||||
if (AttachedTransformation())
|
||||
return AttachedTransformation()->Peek(outByte);
|
||||
else
|
||||
return Peek(&outByte, 1);
|
||||
}
|
||||
|
||||
unsigned int BufferedTransformation::Peek(byte *outString, unsigned int peekMax) const
|
||||
{
|
||||
if (AttachedTransformation())
|
||||
return AttachedTransformation()->Peek(outString, peekMax);
|
||||
else
|
||||
{
|
||||
ArraySink arraySink(outString, peekMax);
|
||||
return CopyTo(arraySink, peekMax);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long BufferedTransformation::Skip(unsigned long skipMax)
|
||||
{
|
||||
if (AttachedTransformation())
|
||||
return AttachedTransformation()->Skip(skipMax);
|
||||
else
|
||||
return TransferTo(TheBitBucket(), skipMax);
|
||||
}
|
||||
|
||||
unsigned long 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);
|
||||
}
|
||||
|
||||
unsigned int 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++)
|
||||
{
|
||||
unsigned int blockedBytes;
|
||||
unsigned long transferedBytes;
|
||||
|
||||
while (AnyRetrievable())
|
||||
{
|
||||
transferedBytes = ULONG_MAX;
|
||||
blockedBytes = TransferTo2(target, transferedBytes, 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()) {}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int 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;
|
||||
unsigned int blockedBytes = TransferMessagesTo2(target, messageCount, channel, blocking);
|
||||
if (blockedBytes)
|
||||
return blockedBytes;
|
||||
}
|
||||
while (messageCount != 0);
|
||||
|
||||
unsigned long byteCount;
|
||||
do
|
||||
{
|
||||
byteCount = ULONG_MAX;
|
||||
unsigned int 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);
|
||||
}
|
||||
|
||||
unsigned int BufferedTransformation::ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order, bool blocking)
|
||||
{
|
||||
FixedSizeSecBlock<byte, 2> buf;
|
||||
PutWord(false, order, buf, value);
|
||||
return ChannelPut(channel, buf, 2, blocking);
|
||||
}
|
||||
|
||||
unsigned int BufferedTransformation::ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order, bool blocking)
|
||||
{
|
||||
FixedSizeSecBlock<byte, 4> buf;
|
||||
PutWord(false, order, buf, value);
|
||||
return ChannelPut(channel, buf, 4, blocking);
|
||||
}
|
||||
|
||||
unsigned int BufferedTransformation::PutWord16(word16 value, ByteOrder order, bool blocking)
|
||||
{
|
||||
return ChannelPutWord16(NULL_CHANNEL, value, order, blocking);
|
||||
}
|
||||
|
||||
unsigned int BufferedTransformation::PutWord32(word32 value, ByteOrder order, bool blocking)
|
||||
{
|
||||
return ChannelPutWord32(NULL_CHANNEL, value, order, blocking);
|
||||
}
|
||||
|
||||
unsigned int BufferedTransformation::PeekWord16(word16 &value, ByteOrder order)
|
||||
{
|
||||
byte buf[2] = {0, 0};
|
||||
unsigned int len = Peek(buf, 2);
|
||||
|
||||
if (order)
|
||||
value = (buf[0] << 8) | buf[1];
|
||||
else
|
||||
value = (buf[1] << 8) | buf[0];
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
unsigned int BufferedTransformation::PeekWord32(word32 &value, ByteOrder order)
|
||||
{
|
||||
byte buf[4] = {0, 0, 0, 0};
|
||||
unsigned int 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;
|
||||
}
|
||||
|
||||
unsigned int BufferedTransformation::GetWord16(word16 &value, ByteOrder order)
|
||||
{
|
||||
return Skip(PeekWord16(value, order));
|
||||
}
|
||||
|
||||
unsigned int BufferedTransformation::GetWord32(word32 &value, ByteOrder order)
|
||||
{
|
||||
return 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));
|
||||
}
|
||||
|
||||
BufferedTransformation * PK_Encryptor::CreateEncryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment) const
|
||||
{
|
||||
struct EncryptionFilter : public Unflushable<FilterWithInputQueue>
|
||||
{
|
||||
// VC60 complains if this function is missing
|
||||
EncryptionFilter(const EncryptionFilter &x) : Unflushable<FilterWithInputQueue>(NULL), m_rng(x.m_rng), m_encryptor(x.m_encryptor) {}
|
||||
|
||||
EncryptionFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment)
|
||||
: Unflushable<FilterWithInputQueue>(attachment), m_rng(rng), m_encryptor(encryptor)
|
||||
{
|
||||
}
|
||||
|
||||
bool IsolatedMessageEnd(bool blocking)
|
||||
{
|
||||
switch (m_continueAt)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
unsigned int plaintextLength = m_inQueue.CurrentSize();
|
||||
m_ciphertextLength = m_encryptor.CiphertextLength(plaintextLength);
|
||||
|
||||
SecByteBlock plaintext(plaintextLength);
|
||||
m_inQueue.Get(plaintext, plaintextLength);
|
||||
m_ciphertext.resize(m_ciphertextLength);
|
||||
m_encryptor.Encrypt(m_rng, plaintext, plaintextLength, m_ciphertext);
|
||||
}
|
||||
|
||||
case 1:
|
||||
if (!Output(1, m_ciphertext, m_ciphertextLength, 0, blocking))
|
||||
return false;
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
RandomNumberGenerator &m_rng;
|
||||
const PK_Encryptor &m_encryptor;
|
||||
unsigned int m_ciphertextLength;
|
||||
SecByteBlock m_ciphertext;
|
||||
};
|
||||
|
||||
return new EncryptionFilter(rng, *this, attachment);
|
||||
}
|
||||
|
||||
BufferedTransformation * PK_Decryptor::CreateDecryptionFilter(BufferedTransformation *attachment) const
|
||||
{
|
||||
struct DecryptionFilter : public Unflushable<FilterWithInputQueue>
|
||||
{
|
||||
// VC60 complains if this function is missing
|
||||
DecryptionFilter(const DecryptionFilter &x) : Unflushable<FilterWithInputQueue>(NULL), m_decryptor(x.m_decryptor) {}
|
||||
|
||||
DecryptionFilter(const PK_Decryptor &decryptor, BufferedTransformation *attachment)
|
||||
: Unflushable<FilterWithInputQueue>(attachment), m_decryptor(decryptor)
|
||||
{
|
||||
}
|
||||
|
||||
bool IsolatedMessageEnd(bool blocking)
|
||||
{
|
||||
switch (m_continueAt)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
unsigned int ciphertextLength = m_inQueue.CurrentSize();
|
||||
unsigned int maxPlaintextLength = m_decryptor.MaxPlaintextLength(ciphertextLength);
|
||||
|
||||
SecByteBlock ciphertext(ciphertextLength);
|
||||
m_inQueue.Get(ciphertext, ciphertextLength);
|
||||
m_plaintext.resize(maxPlaintextLength);
|
||||
m_result = m_decryptor.Decrypt(ciphertext, ciphertextLength, m_plaintext);
|
||||
if (!m_result.isValidCoding)
|
||||
throw InvalidCiphertext(m_decryptor.AlgorithmName() + ": invalid ciphertext");
|
||||
}
|
||||
|
||||
case 1:
|
||||
if (!Output(1, m_plaintext, m_result.messageLength, 0, blocking))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const PK_Decryptor &m_decryptor;
|
||||
SecByteBlock m_plaintext;
|
||||
DecodingResult m_result;
|
||||
};
|
||||
|
||||
return new DecryptionFilter(*this, attachment);
|
||||
}
|
||||
|
||||
unsigned int PK_FixedLengthCryptoSystem::MaxPlaintextLength(unsigned int cipherTextLength) const
|
||||
{
|
||||
if (cipherTextLength == FixedCiphertextLength())
|
||||
return FixedMaxPlaintextLength();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int PK_FixedLengthCryptoSystem::CiphertextLength(unsigned int plainTextLength) const
|
||||
{
|
||||
if (plainTextLength <= FixedMaxPlaintextLength())
|
||||
return FixedCiphertextLength();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
DecodingResult PK_FixedLengthDecryptor::Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const
|
||||
{
|
||||
if (cipherTextLength != FixedCiphertextLength())
|
||||
return DecodingResult();
|
||||
|
||||
return FixedLengthDecrypt(cipherText, plainText);
|
||||
}
|
||||
|
||||
void PK_Signer::Sign(RandomNumberGenerator &rng, HashTransformation *messageAccumulator, byte *signature) const
|
||||
{
|
||||
std::auto_ptr<HashTransformation> m(messageAccumulator);
|
||||
SignAndRestart(rng, *m, signature);
|
||||
}
|
||||
|
||||
void PK_Signer::SignMessage(RandomNumberGenerator &rng, const byte *message, unsigned int messageLen, byte *signature) const
|
||||
{
|
||||
std::auto_ptr<HashTransformation> accumulator(NewSignatureAccumulator());
|
||||
accumulator->Update(message, messageLen);
|
||||
SignAndRestart(rng, *accumulator, signature);
|
||||
}
|
||||
|
||||
bool PK_Verifier::Verify(HashTransformation *messageAccumulator, const byte *signature) const
|
||||
{
|
||||
std::auto_ptr<HashTransformation> m(messageAccumulator);
|
||||
return VerifyAndRestart(*m, signature);
|
||||
}
|
||||
|
||||
bool PK_Verifier::VerifyMessage(const byte *message, unsigned int messageLen, const byte *sig) const
|
||||
{
|
||||
std::auto_ptr<HashTransformation> accumulator(NewVerificationAccumulator());
|
||||
accumulator->Update(message, messageLen);
|
||||
return VerifyAndRestart(*accumulator, sig);
|
||||
}
|
||||
|
||||
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
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,258 @@
|
|||
// 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, word16 inLen, byte *out, word16 outLen, int iterations)
|
||||
{
|
||||
unsigned int bufSize = (outLen-1+DefaultHashModule::DIGESTSIZE-((outLen-1)%DefaultHashModule::DIGESTSIZE));
|
||||
|
||||
// ASSERT: bufSize == (the smallest multiple of DIGESTSIZE that is >= outLen)
|
||||
|
||||
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, unsigned int passphraseLength, const byte *salt, unsigned int 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, unsigned int 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, unsigned int 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, unsigned int 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, unsigned int 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 (memcmp(check, check+BLOCKSIZE, BLOCKSIZE))
|
||||
{
|
||||
m_state = KEY_BAD;
|
||||
if (m_throwException)
|
||||
throw KeyBadErr();
|
||||
}
|
||||
else
|
||||
m_state = KEY_GOOD;
|
||||
}
|
||||
|
||||
// ********************************************************
|
||||
|
||||
static DefaultMAC * NewDefaultEncryptorMAC(const byte *passphrase, unsigned int passphraseLength)
|
||||
{
|
||||
unsigned int 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, unsigned int 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, unsigned int 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, unsigned int 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, unsigned int length)
|
||||
{
|
||||
m_filter->MessageEnd();
|
||||
if (m_throwException && !CheckLastMAC())
|
||||
throw MACBadErr();
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
#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, unsigned int passphraseLength, BufferedTransformation *attachment = NULL);
|
||||
|
||||
protected:
|
||||
void FirstPut(const byte *);
|
||||
void LastPut(const byte *inString, unsigned int 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, unsigned int 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, unsigned int 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, unsigned int passphraseLength, BufferedTransformation *attachment = NULL);
|
||||
|
||||
protected:
|
||||
void FirstPut(const byte *inString) {}
|
||||
void LastPut(const byte *inString, unsigned int 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, unsigned int 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, unsigned int length);
|
||||
|
||||
private:
|
||||
member_ptr<DefaultMAC> m_mac;
|
||||
HashVerifier *m_hashVerifier;
|
||||
bool m_throwException;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,464 @@
|
|||
// 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)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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 DES::Base::UncheckedSetKey(CipherDir dir, const byte *key, unsigned int length)
|
||||
{
|
||||
AssertValidKeyLength(length);
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
// 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::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;
|
||||
}
|
||||
|
||||
typedef BlockGetAndPut<word32, BigEndian> Block;
|
||||
|
||||
// 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);
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
FPERM(l,r);
|
||||
Block::Put(xorBlock, outBlock)(r)(l);
|
||||
}
|
||||
|
||||
void DES_EDE2::Base::UncheckedSetKey(CipherDir dir, const byte *key, unsigned int length)
|
||||
{
|
||||
AssertValidKeyLength(length);
|
||||
|
||||
m_des1.UncheckedSetKey(dir, key);
|
||||
m_des2.UncheckedSetKey(ReverseCipherDir(dir), key+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(CipherDir dir, const byte *key, unsigned int length)
|
||||
{
|
||||
AssertValidKeyLength(length);
|
||||
|
||||
m_des1.UncheckedSetKey(dir, key+(dir==ENCRYPTION?0:2*8));
|
||||
m_des2.UncheckedSetKey(ReverseCipherDir(dir), key+8);
|
||||
m_des3.UncheckedSetKey(dir, key+(dir==DECRYPTION?0:2*8));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void DES_XEX3::Base::UncheckedSetKey(CipherDir dir, const byte *key, unsigned int length)
|
||||
{
|
||||
AssertValidKeyLength(length);
|
||||
|
||||
memcpy(m_x1, key+(dir==ENCRYPTION?0:2*8), BLOCKSIZE);
|
||||
m_des.UncheckedSetKey(dir, key+8);
|
||||
memcpy(m_x3, key+(dir==DECRYPTION?0:2*8), 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
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
#ifndef CRYPTOPP_DES_H
|
||||
#define CRYPTOPP_DES_H
|
||||
|
||||
/** \file
|
||||
*/
|
||||
|
||||
#include "seckey.h"
|
||||
#include "secblock.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
struct DES_Info : public FixedBlockSize<8>, public FixedKeyLength<8>
|
||||
{
|
||||
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 Base : public BlockCipherBaseTemplate<DES_Info>
|
||||
{
|
||||
public:
|
||||
void UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length = 8);
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
|
||||
// exposed for faster Triple-DES
|
||||
void RawProcessBlock(word32 &l, word32 &r) const;
|
||||
|
||||
protected:
|
||||
static const word32 Spbox[8][64];
|
||||
|
||||
FixedSizeSecBlock<word32, 32> k;
|
||||
};
|
||||
|
||||
public:
|
||||
//! check DES key parity bits
|
||||
static bool CheckKeyParityBits(const byte *key);
|
||||
//! correct DES key parity bits
|
||||
static void CorrectKeyParityBits(byte *key);
|
||||
|
||||
typedef BlockCipherTemplate<ENCRYPTION, Base> Encryption;
|
||||
typedef BlockCipherTemplate<DECRYPTION, Base> Decryption;
|
||||
};
|
||||
|
||||
struct DES_EDE2_Info : public FixedBlockSize<8>, public FixedKeyLength<16>
|
||||
{
|
||||
static const char *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 Base : public BlockCipherBaseTemplate<DES_EDE2_Info>
|
||||
{
|
||||
public:
|
||||
void UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length);
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
|
||||
protected:
|
||||
DES::Encryption m_des1, m_des2;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef BlockCipherTemplate<ENCRYPTION, Base> Encryption;
|
||||
typedef BlockCipherTemplate<DECRYPTION, Base> Decryption;
|
||||
};
|
||||
|
||||
struct DES_EDE3_Info : public FixedBlockSize<8>, public FixedKeyLength<24>
|
||||
{
|
||||
static const char *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 Base : public BlockCipherBaseTemplate<DES_EDE3_Info>
|
||||
{
|
||||
public:
|
||||
void UncheckedSetKey(CipherDir dir, const byte *key, unsigned int length);
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
|
||||
protected:
|
||||
DES::Encryption m_des1, m_des2, m_des3;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef BlockCipherTemplate<ENCRYPTION, Base> Encryption;
|
||||
typedef BlockCipherTemplate<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 Base : public BlockCipherBaseTemplate<DES_XEX3_Info>
|
||||
{
|
||||
public:
|
||||
void UncheckedSetKey(CipherDir dir, const byte *key, unsigned int length);
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
|
||||
protected:
|
||||
FixedSizeSecBlock<byte, BLOCKSIZE> m_x1, m_x3;
|
||||
DES::Encryption m_des;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef BlockCipherTemplate<ENCRYPTION, Base> Encryption;
|
||||
typedef BlockCipherTemplate<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
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
0101010101010101 95F8A5E5DD31D900 8000000000000000
|
||||
0101010101010101 DD7F121CA5015619 4000000000000000
|
||||
0101010101010101 2E8653104F3834EA 2000000000000000
|
||||
0101010101010101 4BD388FF6CD81D4F 1000000000000000
|
||||
0101010101010101 20B9E767B2FB1456 0800000000000000
|
||||
0101010101010101 55579380D77138EF 0400000000000000
|
||||
0101010101010101 6CC5DEFAAF04512F 0200000000000000
|
||||
0101010101010101 0D9F279BA5D87260 0100000000000000
|
||||
0101010101010101 D9031B0271BD5A0A 0080000000000000
|
||||
0101010101010101 424250B37C3DD951 0040000000000000
|
||||
0101010101010101 B8061B7ECD9A21E5 0020000000000000
|
||||
0101010101010101 F15D0F286B65BD28 0010000000000000
|
||||
0101010101010101 ADD0CC8D6E5DEBA1 0008000000000000
|
||||
0101010101010101 E6D5F82752AD63D1 0004000000000000
|
||||
0101010101010101 ECBFE3BD3F591A5E 0002000000000000
|
||||
0101010101010101 F356834379D165CD 0001000000000000
|
||||
0101010101010101 2B9F982F20037FA9 0000800000000000
|
||||
0101010101010101 889DE068A16F0BE6 0000400000000000
|
||||
0101010101010101 E19E275D846A1298 0000200000000000
|
||||
0101010101010101 329A8ED523D71AEC 0000100000000000
|
||||
0101010101010101 E7FCE22557D23C97 0000080000000000
|
||||
0101010101010101 12A9F5817FF2D65D 0000040000000000
|
||||
0101010101010101 A484C3AD38DC9C19 0000020000000000
|
||||
0101010101010101 FBE00A8A1EF8AD72 0000010000000000
|
||||
0101010101010101 750D079407521363 0000008000000000
|
||||
0101010101010101 64FEED9C724C2FAF 0000004000000000
|
||||
0101010101010101 F02B263B328E2B60 0000002000000000
|
||||
0101010101010101 9D64555A9A10B852 0000001000000000
|
||||
0101010101010101 D106FF0BED5255D7 0000000800000000
|
||||
0101010101010101 E1652C6B138C64A5 0000000400000000
|
||||
0101010101010101 E428581186EC8F46 0000000200000000
|
||||
0101010101010101 AEB5F5EDE22D1A36 0000000100000000
|
||||
0101010101010101 E943D7568AEC0C5C 0000000080000000
|
||||
0101010101010101 DF98C8276F54B04B 0000000040000000
|
||||
0101010101010101 B160E4680F6C696F 0000000020000000
|
||||
0101010101010101 FA0752B07D9C4AB8 0000000010000000
|
||||
0101010101010101 CA3A2B036DBC8502 0000000008000000
|
||||
0101010101010101 5E0905517BB59BCF 0000000004000000
|
||||
0101010101010101 814EEB3B91D90726 0000000002000000
|
||||
0101010101010101 4D49DB1532919C9F 0000000001000000
|
||||
0101010101010101 25EB5FC3F8CF0621 0000000000800000
|
||||
0101010101010101 AB6A20C0620D1C6F 0000000000400000
|
||||
0101010101010101 79E90DBC98F92CCA 0000000000200000
|
||||
0101010101010101 866ECEDD8072BB0E 0000000000100000
|
||||
0101010101010101 8B54536F2F3E64A8 0000000000080000
|
||||
0101010101010101 EA51D3975595B86B 0000000000040000
|
||||
0101010101010101 CAFFC6AC4542DE31 0000000000020000
|
||||
0101010101010101 8DD45A2DDF90796C 0000000000010000
|
||||
0101010101010101 1029D55E880EC2D0 0000000000008000
|
||||
0101010101010101 5D86CB23639DBEA9 0000000000004000
|
||||
0101010101010101 1D1CA853AE7C0C5F 0000000000002000
|
||||
0101010101010101 CE332329248F3228 0000000000001000
|
||||
0101010101010101 8405D1ABE24FB942 0000000000000800
|
||||
0101010101010101 E643D78090CA4207 0000000000000400
|
||||
0101010101010101 48221B9937748A23 0000000000000200
|
||||
0101010101010101 DD7C0BBD61FAFD54 0000000000000100
|
||||
0101010101010101 2FBC291A570DB5C4 0000000000000080
|
||||
0101010101010101 E07C30D7E4E26E12 0000000000000040
|
||||
0101010101010101 0953E2258E8E90A1 0000000000000020
|
||||
0101010101010101 5B711BC4CEEBF2EE 0000000000000010
|
||||
0101010101010101 CC083F1E6D9E85F6 0000000000000008
|
||||
0101010101010101 D2FD8867D50D2DFE 0000000000000004
|
||||
0101010101010101 06E7EA22CE92708F 0000000000000002
|
||||
0101010101010101 166B40B44ABA4BD6 0000000000000001
|
||||
8001010101010101 0000000000000000 95A8D72813DAA94D
|
||||
4001010101010101 0000000000000000 0EEC1487DD8C26D5
|
||||
2001010101010101 0000000000000000 7AD16FFB79C45926
|
||||
1001010101010101 0000000000000000 D3746294CA6A6CF3
|
||||
0801010101010101 0000000000000000 809F5F873C1FD761
|
||||
0401010101010101 0000000000000000 C02FAFFEC989D1FC
|
||||
0201010101010101 0000000000000000 4615AA1D33E72F10
|
||||
0180010101010101 0000000000000000 2055123350C00858
|
||||
0140010101010101 0000000000000000 DF3B99D6577397C8
|
||||
0120010101010101 0000000000000000 31FE17369B5288C9
|
||||
0110010101010101 0000000000000000 DFDD3CC64DAE1642
|
||||
0108010101010101 0000000000000000 178C83CE2B399D94
|
||||
0104010101010101 0000000000000000 50F636324A9B7F80
|
||||
0102010101010101 0000000000000000 A8468EE3BC18F06D
|
||||
0101800101010101 0000000000000000 A2DC9E92FD3CDE92
|
||||
0101400101010101 0000000000000000 CAC09F797D031287
|
||||
0101200101010101 0000000000000000 90BA680B22AEB525
|
||||
0101100101010101 0000000000000000 CE7A24F350E280B6
|
||||
0101080101010101 0000000000000000 882BFF0AA01A0B87
|
||||
0101040101010101 0000000000000000 25610288924511C2
|
||||
0101020101010101 0000000000000000 C71516C29C75D170
|
||||
0101018001010101 0000000000000000 5199C29A52C9F059
|
||||
0101014001010101 0000000000000000 C22F0A294A71F29F
|
||||
0101012001010101 0000000000000000 EE371483714C02EA
|
||||
0101011001010101 0000000000000000 A81FBD448F9E522F
|
||||
0101010801010101 0000000000000000 4F644C92E192DFED
|
||||
0101010401010101 0000000000000000 1AFA9A66A6DF92AE
|
||||
0101010201010101 0000000000000000 B3C1CC715CB879D8
|
||||
0101010180010101 0000000000000000 19D032E64AB0BD8B
|
||||
0101010140010101 0000000000000000 3CFAA7A7DC8720DC
|
||||
0101010120010101 0000000000000000 B7265F7F447AC6F3
|
||||
0101010110010101 0000000000000000 9DB73B3C0D163F54
|
||||
0101010108010101 0000000000000000 8181B65BABF4A975
|
||||
0101010104010101 0000000000000000 93C9B64042EAA240
|
||||
0101010102010101 0000000000000000 5570530829705592
|
||||
0101010101800101 0000000000000000 8638809E878787A0
|
||||
0101010101400101 0000000000000000 41B9A79AF79AC208
|
||||
0101010101200101 0000000000000000 7A9BE42F2009A892
|
||||
0101010101100101 0000000000000000 29038D56BA6D2745
|
||||
0101010101080101 0000000000000000 5495C6ABF1E5DF51
|
||||
0101010101040101 0000000000000000 AE13DBD561488933
|
||||
0101010101020101 0000000000000000 024D1FFA8904E389
|
||||
0101010101018001 0000000000000000 D1399712F99BF02E
|
||||
0101010101014001 0000000000000000 14C1D7C1CFFEC79E
|
||||
0101010101012001 0000000000000000 1DE5279DAE3BED6F
|
||||
0101010101011001 0000000000000000 E941A33F85501303
|
||||
0101010101010801 0000000000000000 DA99DBBC9A03F379
|
||||
0101010101010401 0000000000000000 B7FC92F91D8E92E9
|
||||
0101010101010201 0000000000000000 AE8E5CAA3CA04E85
|
||||
0101010101010180 0000000000000000 9CC62DF43B6EED74
|
||||
0101010101010140 0000000000000000 D863DBB5C59A91A0
|
||||
0101010101010120 0000000000000000 A1AB2190545B91D7
|
||||
0101010101010110 0000000000000000 0875041E64C570F7
|
||||
0101010101010108 0000000000000000 5A594528BEBEF1CC
|
||||
0101010101010104 0000000000000000 FCDB3291DE21F0C0
|
||||
0101010101010102 0000000000000000 869EFD7F9F265A09
|
||||
1046913489980131 0000000000000000 88D55E54F54C97B4
|
||||
1007103489988020 0000000000000000 0C0CC00C83EA48FD
|
||||
10071034C8980120 0000000000000000 83BC8EF3A6570183
|
||||
1046103489988020 0000000000000000 DF725DCAD94EA2E9
|
||||
1086911519190101 0000000000000000 E652B53B550BE8B0
|
||||
1086911519580101 0000000000000000 AF527120C485CBB0
|
||||
5107B01519580101 0000000000000000 0F04CE393DB926D5
|
||||
1007B01519190101 0000000000000000 C9F00FFC74079067
|
||||
3107915498080101 0000000000000000 7CFD82A593252B4E
|
||||
3107919498080101 0000000000000000 CB49A2F9E91363E3
|
||||
10079115B9080140 0000000000000000 00B588BE70D23F56
|
||||
3107911598090140 0000000000000000 406A9A6AB43399AE
|
||||
1007D01589980101 0000000000000000 6CB773611DCA9ADA
|
||||
9107911589980101 0000000000000000 67FD21C17DBB5D70
|
||||
9107D01589190101 0000000000000000 9592CB4110430787
|
||||
1007D01598980120 0000000000000000 A6B7FF68A318DDD3
|
||||
1007940498190101 0000000000000000 4D102196C914CA16
|
||||
0107910491190401 0000000000000000 2DFA9F4573594965
|
||||
0107910491190101 0000000000000000 B46604816C0E0774
|
||||
0107940491190401 0000000000000000 6E7E6221A4F34E87
|
||||
19079210981A0101 0000000000000000 AA85E74643233199
|
||||
1007911998190801 0000000000000000 2E5A19DB4D1962D6
|
||||
10079119981A0801 0000000000000000 23A866A809D30894
|
||||
1007921098190101 0000000000000000 D812D961F017D320
|
||||
100791159819010B 0000000000000000 055605816E58608F
|
||||
1004801598190101 0000000000000000 ABD88E8B1B7716F1
|
||||
1004801598190102 0000000000000000 537AC95BE69DA1E1
|
||||
1004801598190108 0000000000000000 AED0F6AE3C25CDD8
|
||||
1002911598100104 0000000000000000 B3E35A5EE53E7B8D
|
||||
1002911598190104 0000000000000000 61C79C71921A2EF8
|
||||
1002911598100201 0000000000000000 E2F5728F0995013C
|
||||
1002911698100101 0000000000000000 1AEAC39A61F0A464
|
||||
7CA110454A1A6E57 01A1D6D039776742 690F5B0D9A26939B
|
||||
0131D9619DC1376E 5CD54CA83DEF57DA 7A389D10354BD271
|
||||
07A1133E4A0B2686 0248D43806F67172 868EBB51CAB4599A
|
||||
3849674C2602319E 51454B582DDF440A 7178876E01F19B2A
|
||||
04B915BA43FEB5B6 42FD443059577FA2 AF37FB421F8C4095
|
||||
0113B970FD34F2CE 059B5E0851CF143A 86A560F10EC6D85B
|
||||
0170F175468FB5E6 0756D8E0774761D2 0CD3DA020021DC09
|
||||
43297FAD38E373FE 762514B829BF486A EA676B2CB7DB2B7A
|
||||
07A7137045DA2A16 3BDD119049372802 DFD64A815CAF1A0F
|
||||
04689104C2FD3B2F 26955F6835AF609A 5C513C9C4886C088
|
||||
37D06BB516CB7546 164D5E404F275232 0A2AEEAE3FF4AB77
|
||||
1F08260D1AC2465E 6B056E18759F5CCA EF1BF03E5DFA575A
|
||||
584023641ABA6176 004BD6EF09176062 88BF0DB6D70DEE56
|
||||
025816164629B007 480D39006EE762F2 A1F9915541020B56
|
||||
49793EBC79B3258F 437540C8698F3CFA 6FBF1CAFCFFD0556
|
||||
4FB05E1515AB73A7 072D43A077075292 2F22E49BAB7CA1AC
|
||||
49E95D6D4CA229BF 02FE55778117F12A 5A6B612CC26CCE4A
|
||||
018310DC409B26D6 1D9D5C5018F728C2 5F4C038ED12B2E41
|
||||
1C587F1C13924FEF 305532286D6F295A 63FAC0D034D9F793
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
// This file is mostly generated by Phil Karn's gensp.c
|
||||
|
||||
#include "pch.h"
|
||||
#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 DES::Base::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
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// dh.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "dh.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
void DH_TestInstantiations()
|
||||
{
|
||||
DH dh1;
|
||||
DH dh2(NullRNG(), 10);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
#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> KeyAgreementAlgorithm;
|
||||
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 T2 &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 T2 &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(PrivateKeyLength());
|
||||
GeneratePrivateKey(rng, privateKey2);
|
||||
|
||||
SecByteBlock publicKey2(PublicKeyLength());
|
||||
Base::GeneratePublicKey(rng, privateKey2, publicKey2);
|
||||
|
||||
SecByteBlock agreedValue(AgreedValueLength()), agreedValue2(AgreedValueLength());
|
||||
Agree(agreedValue, privateKey, publicKey2);
|
||||
Agree(agreedValue2, privateKey2, publicKey);
|
||||
|
||||
if (agreedValue != agreedValue2)
|
||||
throw SelfTestFailure(AlgorithmName() + ": pairwise consistency test failed");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const
|
||||
{static KeyAgreementAlgorithm a; return a;}
|
||||
DL_GroupParameters<Element> & AccessAbstractGroupParameters()
|
||||
{return m_groupParameters;}
|
||||
|
||||
GroupParameters m_groupParameters;
|
||||
};
|
||||
|
||||
//! <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
|
||||
|
|
@ -0,0 +1 @@
|
|||
30818702818100DA9A18547FF03B385CC16508C173A7EF4EB61CB40EF8FEF3B31F145051676166BCDC3FE6B799FC394D08C26385F9413F896E09117E46209D6923602683CEA100924A6EE695281775C619DAA94EA8CB3691B4275B0183F1D39639EBC92995FE645D6C1BC28D409E585549BBD2C5DCDD6C208B04EADD8B7A6D997F72CBAD88390F020102
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// dh2.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "dh2.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
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
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
#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(const SimpleKeyAgreementDomain &domain)
|
||||
: d1(domain), d2(domain) {}
|
||||
DH2(const SimpleKeyAgreementDomain &staticDomain, const SimpleKeyAgreementDomain &ephemeralDomain)
|
||||
: d1(staticDomain), d2(ephemeralDomain) {}
|
||||
|
||||
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:
|
||||
const SimpleKeyAgreementDomain &d1, &d2;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1 @@
|
|||
308201080282010100EB60DBD494AAFBCD2EAC6A36DB8E7DD4A2A64512A5BBB15B9BFB581C7C1CAFB647D4612973C3770C2166D75EEA695F67EA8261557591DB78BCF5A886AA5294F3AEE4D25B57C8EE8C7FE8DBF70C132CD7FFCB6F89426F807F552C5DAE2FB1F329E340094E4B30D8EF6265AB4D350E9837B151C86AC524DE4E1FC04746C668BE318275E420D51AEDDFBDF887D435CDEEF6AC81293DB45287132F8236A43AD8F4D6642D7CA6732DA06A1DE008259008C9D74403B68ADAC788CF8AB5BEFFC310DCCCD32901D1F290E5B7A993D2CF6A652AF81B6DA0FD2E70678D1AE086150E41444522F20621195AD2A1F0975652B4AF7DE5261A9FD46B9EA8B443641F3BBA695B9B020103
|
||||
|
|
@ -0,0 +1,572 @@
|
|||
// diamond.cpp - modified by Wei Dai from:
|
||||
|
||||
/* diamond2.c - Encryption designed to exceed DES in security.
|
||||
This file and the Diamond2 and Diamond2 Lite Block Ciphers
|
||||
described herein are hereby dedicated to the Public Domain by the
|
||||
author and inventor, Michael Paul Johnson. Feel free to use these
|
||||
for any purpose that is legally and morally right. The names
|
||||
"Diamond2 Block Cipher" and "Diamond2 Lite Block Cipher" should only
|
||||
be used to describe the algorithms described in this file, to avoid
|
||||
confusion.
|
||||
|
||||
Disclaimers: the following comes with no warranty, expressed or
|
||||
implied. You, the user, must determine the suitability of this
|
||||
information to your own uses. You must also find out what legal
|
||||
requirements exist with respect to this data and programs using
|
||||
it, and comply with whatever valid requirements exist.
|
||||
*/
|
||||
|
||||
#include "pch.h"
|
||||
#include "diamond.h"
|
||||
#include "crc.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
class Diamond2SboxMaker
|
||||
{
|
||||
public:
|
||||
Diamond2SboxMaker(const byte *external_key, unsigned int key_size,
|
||||
unsigned int rounds, bool lite);
|
||||
|
||||
void MakeSbox(byte *sbox, CipherDir direction);
|
||||
|
||||
private:
|
||||
unsigned int keyrand(unsigned int max_value, const byte *prevSbox);
|
||||
void makeonebox(byte *s, unsigned int i, unsigned int j);
|
||||
|
||||
CRC32 crc;
|
||||
const byte *const key;
|
||||
const unsigned keysize;
|
||||
unsigned keyindex;
|
||||
const unsigned numrounds;
|
||||
const unsigned roundsize; // Number of bytes in one round of substitution boxes
|
||||
const unsigned blocksize;
|
||||
};
|
||||
|
||||
Diamond2SboxMaker::Diamond2SboxMaker(const byte *external_key, unsigned int key_size, unsigned int rounds,
|
||||
bool lite)
|
||||
: key(external_key),
|
||||
keysize(key_size),
|
||||
keyindex(0),
|
||||
numrounds(rounds),
|
||||
roundsize(lite ? 2048 : 4096),
|
||||
blocksize(lite ? 8 : 16)
|
||||
{
|
||||
assert((rounds * blocksize) <= 255);
|
||||
}
|
||||
|
||||
// Returns uniformly distributed pseudorandom value based on key[], sized keysize
|
||||
inline unsigned int Diamond2SboxMaker::keyrand(unsigned int max_value, const byte *prevSbox)
|
||||
{
|
||||
assert(max_value <= 255);
|
||||
|
||||
if (!max_value) return 0;
|
||||
|
||||
unsigned int mask, prandvalue, i;
|
||||
|
||||
// Create a mask to get the minimum number of
|
||||
// bits to cover the range 0 to max_value.
|
||||
for (i=max_value, mask=0; i > 0; i = i >> 1)
|
||||
mask = (mask << 1) | 1;
|
||||
|
||||
assert(i==0);
|
||||
do
|
||||
{
|
||||
if (prevSbox)
|
||||
crc.UpdateByte(prevSbox[key[keyindex++]]);
|
||||
else
|
||||
crc.UpdateByte(key[keyindex++]);
|
||||
|
||||
if (keyindex >= keysize)
|
||||
{
|
||||
keyindex = 0; /* Recycle thru the key */
|
||||
crc.UpdateByte(byte(keysize));
|
||||
crc.UpdateByte(byte(keysize >> 8));
|
||||
}
|
||||
prandvalue = crc.GetCrcByte(0) & mask;
|
||||
if ((++i>97) && (prandvalue > max_value)) /* Don't loop forever. */
|
||||
prandvalue -= max_value; /* Introduce negligible bias. */
|
||||
}
|
||||
while (prandvalue > max_value); /* Discard out of range values. */
|
||||
return prandvalue;
|
||||
}
|
||||
|
||||
void Diamond2SboxMaker::makeonebox(byte *s, unsigned int i, unsigned int j)
|
||||
{
|
||||
bool filled[256];
|
||||
byte *sbox = s + (roundsize*i) + (256*j);
|
||||
byte *prevSbox = (i||j) ? sbox-256 : 0;
|
||||
|
||||
unsigned m;
|
||||
for (m = 0; m < 256; m++) /* The filled array is used to make sure that */
|
||||
filled[m] = false; /* each byte of the array is filled only once. */
|
||||
for (int n = 255; n >= 0 ; n--) /* n counts the number of bytes left to fill */
|
||||
{
|
||||
// pos is the position among the UNFILLED
|
||||
// components of the s array that the number n should be placed.
|
||||
unsigned pos = keyrand(n, prevSbox);
|
||||
unsigned p=0;
|
||||
while (filled[p]) p++;
|
||||
for (m=0; m<pos; m++)
|
||||
{
|
||||
p++;
|
||||
while (filled[p]) p++;
|
||||
}
|
||||
assert(p<256);
|
||||
sbox[p] = n;
|
||||
filled[p] = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Diamond2SboxMaker::MakeSbox(byte *s, CipherDir direction)
|
||||
{
|
||||
unsigned int i, j, k;
|
||||
|
||||
for (i = 0; i < numrounds; i++)
|
||||
for (j = 0; j < blocksize; j++)
|
||||
makeonebox(s, i, j);
|
||||
|
||||
if (direction==DECRYPTION)
|
||||
{
|
||||
SecByteBlock si(numrounds * roundsize);
|
||||
for (i = 0; i < numrounds; i++)
|
||||
for (j = 0; j < blocksize; j++)
|
||||
for (k = 0; k < 256; k++)
|
||||
*(si + (roundsize * i) + (256 * j) + *(s + (roundsize * i) + (256 * j) + k)) = k;
|
||||
memcpy(s, si, numrounds * roundsize);
|
||||
}
|
||||
}
|
||||
|
||||
void Diamond2::Base::UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length, unsigned int rounds)
|
||||
{
|
||||
AssertValidKeyLength(length);
|
||||
|
||||
numrounds = rounds;
|
||||
s.New(numrounds * ROUNDSIZE);
|
||||
|
||||
Diamond2SboxMaker m(userKey, length, rounds, false);
|
||||
m.MakeSbox(s, direction);
|
||||
}
|
||||
|
||||
inline void Diamond2::Base::substitute(int round, byte *x, const byte *y) const
|
||||
{
|
||||
const byte *sbox = s + (ROUNDSIZE*round);
|
||||
x[0] = sbox[0*256+y[0]];
|
||||
x[1] = sbox[1*256+y[1]];
|
||||
x[2] = sbox[2*256+y[2]];
|
||||
x[3] = sbox[3*256+y[3]];
|
||||
x[4] = sbox[4*256+y[4]];
|
||||
x[5] = sbox[5*256+y[5]];
|
||||
x[6] = sbox[6*256+y[6]];
|
||||
x[7] = sbox[7*256+y[7]];
|
||||
x[8] = sbox[8*256+y[8]];
|
||||
x[9] = sbox[9*256+y[9]];
|
||||
x[10] = sbox[10*256+y[10]];
|
||||
x[11] = sbox[11*256+y[11]];
|
||||
x[12] = sbox[12*256+y[12]];
|
||||
x[13] = sbox[13*256+y[13]];
|
||||
x[14] = sbox[14*256+y[14]];
|
||||
x[15] = sbox[15*256+y[15]];
|
||||
}
|
||||
|
||||
#ifdef DIAMOND_USE_PERMTABLE
|
||||
|
||||
inline void Diamond2::Base::permute(byte *a)
|
||||
{
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
word32 temp0 = (a[0] | (word32(a[10])<<24)) & 0x80000001;
|
||||
#else
|
||||
word32 temp0 = ((word32(a[0])<<24) | a[10]) & 0x01000080;
|
||||
#endif
|
||||
temp0 |= permtable[0][a[1]] |
|
||||
permtable[1][a[2]] | permtable[2][a[3]] |
|
||||
permtable[3][a[4]] | permtable[4][a[5]] |
|
||||
permtable[5][a[6]] | permtable[6][a[7]] |
|
||||
permtable[7][a[8]] | permtable[8][a[9]];
|
||||
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
word32 temp1 = (a[4] | (word32(a[14])<<24)) & 0x80000001;
|
||||
#else
|
||||
word32 temp1 = ((word32(a[4])<<24) | a[14]) & 0x01000080;
|
||||
#endif
|
||||
temp1 |= permtable[0][a[5]] |
|
||||
permtable[1][a[6]] | permtable[2][a[7]] |
|
||||
permtable[3][a[8]] | permtable[4][a[9]] |
|
||||
permtable[5][a[10]] | permtable[6][a[11]] |
|
||||
permtable[7][a[12]] | permtable[8][a[13]];
|
||||
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
word32 temp2 = (a[8] | (word32(a[2])<<24)) & 0x80000001;
|
||||
#else
|
||||
word32 temp2 = ((word32(a[8])<<24) | a[2]) & 0x01000080;
|
||||
#endif
|
||||
temp2 |= permtable[0][a[9]] |
|
||||
permtable[1][a[10]] | permtable[2][a[11]] |
|
||||
permtable[3][a[12]] | permtable[4][a[13]] |
|
||||
permtable[5][a[14]] | permtable[6][a[15]] |
|
||||
permtable[7][a[0]] | permtable[8][a[1]];
|
||||
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
word32 temp3 = (a[12] | (word32(a[6])<<24)) & 0x80000001;
|
||||
#else
|
||||
word32 temp3 = ((word32(a[12])<<24) | a[6]) & 0x01000080;
|
||||
#endif
|
||||
((word32 *)a)[3] = temp3 | permtable[0][a[13]] |
|
||||
permtable[1][a[14]] | permtable[2][a[15]] |
|
||||
permtable[3][a[0]] | permtable[4][a[1]] |
|
||||
permtable[5][a[2]] | permtable[6][a[3]] |
|
||||
permtable[7][a[4]] | permtable[8][a[5]];
|
||||
|
||||
((word32 *)a)[0] = temp0;
|
||||
((word32 *)a)[1] = temp1;
|
||||
((word32 *)a)[2] = temp2;
|
||||
}
|
||||
|
||||
inline void Diamond2::Base::ipermute(byte *a)
|
||||
{
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
word32 temp0 = (a[9] | (word32(a[3])<<24)) & 0x01000080;
|
||||
#else
|
||||
word32 temp0 = ((word32(a[9])<<24) | a[3]) & 0x80000001;
|
||||
#endif
|
||||
temp0 |= ipermtable[0][a[2]] |
|
||||
ipermtable[1][a[1]] | ipermtable[2][a[0]] |
|
||||
ipermtable[3][a[15]] | ipermtable[4][a[14]] |
|
||||
ipermtable[5][a[13]] | ipermtable[6][a[12]] |
|
||||
ipermtable[7][a[11]] | ipermtable[8][a[10]];
|
||||
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
word32 temp1 = (a[13] | (word32(a[7])<<24)) & 0x01000080;
|
||||
#else
|
||||
word32 temp1 = ((word32(a[13])<<24) | a[7]) & 0x80000001;
|
||||
#endif
|
||||
temp1 |= ipermtable[0][a[6]] |
|
||||
ipermtable[1][a[5]] | ipermtable[2][a[4]] |
|
||||
ipermtable[3][a[3]] | ipermtable[4][a[2]] |
|
||||
ipermtable[5][a[1]] | ipermtable[6][a[0]] |
|
||||
ipermtable[7][a[15]] | ipermtable[8][a[14]];
|
||||
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
word32 temp2 = (a[1] | (word32(a[11])<<24)) & 0x01000080;
|
||||
#else
|
||||
word32 temp2 = ((word32(a[1])<<24) | a[11]) & 0x80000001;
|
||||
#endif
|
||||
temp2 |= ipermtable[0][a[10]] |
|
||||
ipermtable[1][a[9]] | ipermtable[2][a[8]] |
|
||||
ipermtable[3][a[7]] | ipermtable[4][a[6]] |
|
||||
ipermtable[5][a[5]] | ipermtable[6][a[4]] |
|
||||
ipermtable[7][a[3]] | ipermtable[8][a[2]];
|
||||
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
word32 temp3 = (a[5] | (word32(a[15])<<24)) & 0x01000080;
|
||||
#else
|
||||
word32 temp3 = ((word32(a[5])<<24) | a[15]) & 0x80000001;
|
||||
#endif
|
||||
((word32 *)a)[3] = temp3 | ipermtable[0][a[14]] |
|
||||
ipermtable[1][a[13]] | ipermtable[2][a[12]] |
|
||||
ipermtable[3][a[11]] | ipermtable[4][a[10]] |
|
||||
ipermtable[5][a[9]] | ipermtable[6][a[8]] |
|
||||
ipermtable[7][a[7]] | ipermtable[8][a[6]];
|
||||
|
||||
((word32 *)a)[0] = temp0;
|
||||
((word32 *)a)[1] = temp1;
|
||||
((word32 *)a)[2] = temp2;
|
||||
}
|
||||
|
||||
#else // DIAMOND_USE_PERMTABLE
|
||||
|
||||
inline void Diamond2::Base::permute(byte *x)
|
||||
{
|
||||
byte y[16];
|
||||
|
||||
y[0] = (x[0] & 1) | (x[1] & 2) | (x[2] & 4) |
|
||||
(x[3] & 8) | (x[4] & 16) | (x[5] & 32) |
|
||||
(x[6] & 64) | (x[7] & 128);
|
||||
y[1] = (x[1] & 1) | (x[2] & 2) | (x[3] & 4) |
|
||||
(x[4] & 8) | (x[5] & 16) | (x[6] & 32) |
|
||||
(x[7] & 64) | (x[8] & 128);
|
||||
y[2] = (x[2] & 1) | (x[3] & 2) | (x[4] & 4) |
|
||||
(x[5] & 8) | (x[6] & 16) | (x[7] & 32) |
|
||||
(x[8] & 64) | (x[9] & 128);
|
||||
y[3] = (x[3] & 1) | (x[4] & 2) | (x[5] & 4) |
|
||||
(x[6] & 8) | (x[7] & 16) | (x[8] & 32) |
|
||||
(x[9] & 64) | (x[10] & 128);
|
||||
y[4] = (x[4] & 1) | (x[5] & 2) | (x[6] & 4) |
|
||||
(x[7] & 8) | (x[8] & 16) | (x[9] & 32) |
|
||||
(x[10] & 64) | (x[11] & 128);
|
||||
y[5] = (x[5] & 1) | (x[6] & 2) | (x[7] & 4) |
|
||||
(x[8] & 8) | (x[9] & 16) | (x[10] & 32) |
|
||||
(x[11] & 64) | (x[12] & 128);
|
||||
y[6] = (x[6] & 1) | (x[7] & 2) | (x[8] & 4) |
|
||||
(x[9] & 8) | (x[10] & 16) | (x[11] & 32) |
|
||||
(x[12] & 64) | (x[13] & 128);
|
||||
y[7] = (x[7] & 1) | (x[8] & 2) | (x[9] & 4) |
|
||||
(x[10] & 8) | (x[11] & 16) | (x[12] & 32) |
|
||||
(x[13] & 64) | (x[14] & 128);
|
||||
y[8] = (x[8] & 1) | (x[9] & 2) | (x[10] & 4) |
|
||||
(x[11] & 8) | (x[12] & 16) | (x[13] & 32) |
|
||||
(x[14] & 64) | (x[15] & 128);
|
||||
y[9] = (x[9] & 1) | (x[10] & 2) | (x[11] & 4) |
|
||||
(x[12] & 8) | (x[13] & 16) | (x[14] & 32) |
|
||||
(x[15] & 64) | (x[0] & 128);
|
||||
y[10] = (x[10] & 1) | (x[11] & 2) | (x[12] & 4) |
|
||||
(x[13] & 8) | (x[14] & 16) | (x[15] & 32) |
|
||||
(x[0] & 64) | (x[1] & 128);
|
||||
y[11] = (x[11] & 1) | (x[12] & 2) | (x[13] & 4) |
|
||||
(x[14] & 8) | (x[15] & 16) | (x[0] & 32) |
|
||||
(x[1] & 64) | (x[2] & 128);
|
||||
y[12] = (x[12] & 1) | (x[13] & 2) | (x[14] & 4) |
|
||||
(x[15] & 8) | (x[0] & 16) | (x[1] & 32) |
|
||||
(x[2] & 64) | (x[3] & 128);
|
||||
y[13] = (x[13] & 1) | (x[14] & 2) | (x[15] & 4) |
|
||||
(x[0] & 8) | (x[1] & 16) | (x[2] & 32) |
|
||||
(x[3] & 64) | (x[4] & 128);
|
||||
y[14] = (x[14] & 1) | (x[15] & 2) | (x[0] & 4) |
|
||||
(x[1] & 8) | (x[2] & 16) | (x[3] & 32) |
|
||||
(x[4] & 64) | (x[5] & 128);
|
||||
y[15] = (x[15] & 1) | (x[0] & 2) | (x[1] & 4) |
|
||||
(x[2] & 8) | (x[3] & 16) | (x[4] & 32) |
|
||||
(x[5] & 64) | (x[6] & 128);
|
||||
|
||||
memcpy(x, y, 16);
|
||||
}
|
||||
|
||||
inline void Diamond2::Base::ipermute(byte *x)
|
||||
{
|
||||
byte y[16];
|
||||
|
||||
y[0] = (x[0] & 1) | (x[15] & 2) | (x[14] & 4) |
|
||||
(x[13] & 8) | (x[12] & 16) | (x[11] & 32) |
|
||||
(x[10] & 64) | (x[9] & 128);
|
||||
y[1] = (x[1] & 1) | (x[0] & 2) | (x[15] & 4) |
|
||||
(x[14] & 8) | (x[13] & 16) | (x[12] & 32) |
|
||||
(x[11] & 64) | (x[10] & 128);
|
||||
y[2] = (x[2] & 1) | (x[1] & 2) | (x[0] & 4) |
|
||||
(x[15] & 8) | (x[14] & 16) | (x[13] & 32) |
|
||||
(x[12] & 64) | (x[11] & 128);
|
||||
y[3] = (x[3] & 1) | (x[2] & 2) | (x[1] & 4) |
|
||||
(x[0] & 8) | (x[15] & 16) | (x[14] & 32) |
|
||||
(x[13] & 64) | (x[12] & 128);
|
||||
y[4] = (x[4] & 1) | (x[3] & 2) | (x[2] & 4) |
|
||||
(x[1] & 8) | (x[0] & 16) | (x[15] & 32) |
|
||||
(x[14] & 64) | (x[13] & 128);
|
||||
y[5] = (x[5] & 1) | (x[4] & 2) | (x[3] & 4) |
|
||||
(x[2] & 8) | (x[1] & 16) | (x[0] & 32) |
|
||||
(x[15] & 64) | (x[14] & 128);
|
||||
y[6] = (x[6] & 1) | (x[5] & 2) | (x[4] & 4) |
|
||||
(x[3] & 8) | (x[2] & 16) | (x[1] & 32) |
|
||||
(x[0] & 64) | (x[15] & 128);
|
||||
y[7] = (x[7] & 1) | (x[6] & 2) | (x[5] & 4) |
|
||||
(x[4] & 8) | (x[3] & 16) | (x[2] & 32) |
|
||||
(x[1] & 64) | (x[0] & 128);
|
||||
y[8] = (x[8] & 1) | (x[7] & 2) | (x[6] & 4) |
|
||||
(x[5] & 8) | (x[4] & 16) | (x[3] & 32) |
|
||||
(x[2] & 64) | (x[1] & 128);
|
||||
y[9] = (x[9] & 1) | (x[8] & 2) | (x[7] & 4) |
|
||||
(x[6] & 8) | (x[5] & 16) | (x[4] & 32) |
|
||||
(x[3] & 64) | (x[2] & 128);
|
||||
y[10] = (x[10] & 1) | (x[9] & 2) | (x[8] & 4) |
|
||||
(x[7] & 8) | (x[6] & 16) | (x[5] & 32) |
|
||||
(x[4] & 64) | (x[3] & 128);
|
||||
y[11] = (x[11] & 1) | (x[10] & 2) | (x[9] & 4) |
|
||||
(x[8] & 8) | (x[7] & 16) | (x[6] & 32) |
|
||||
(x[5] & 64) | (x[4] & 128);
|
||||
y[12] = (x[12] & 1) | (x[11] & 2) | (x[10] & 4) |
|
||||
(x[9] & 8) | (x[8] & 16) | (x[7] & 32) |
|
||||
(x[6] & 64) | (x[5] & 128);
|
||||
y[13] = (x[13] & 1) | (x[12] & 2) | (x[11] & 4) |
|
||||
(x[10] & 8) | (x[9] & 16) | (x[8] & 32) |
|
||||
(x[7] & 64) | (x[6] & 128);
|
||||
y[14] = (x[14] & 1) | (x[13] & 2) | (x[12] & 4) |
|
||||
(x[11] & 8) | (x[10] & 16) | (x[9] & 32) |
|
||||
(x[8] & 64) | (x[7] & 128);
|
||||
y[15] = (x[15] & 1) | (x[14] & 2) | (x[13] & 4) |
|
||||
(x[12] & 8) | (x[11] & 16) | (x[10] & 32) |
|
||||
(x[9] & 64) | (x[8] & 128);
|
||||
|
||||
memcpy(x, y, 16);
|
||||
}
|
||||
|
||||
#endif // DIAMOND_USE_PERMTABLE
|
||||
|
||||
void Diamond2::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
const byte *x = inBlock;
|
||||
byte y[16];
|
||||
|
||||
substitute(0, y, x);
|
||||
for (int round=1; round < numrounds; round++)
|
||||
{
|
||||
permute(y);
|
||||
substitute(round, y, y);
|
||||
}
|
||||
|
||||
if (xorBlock)
|
||||
xorbuf(outBlock, xorBlock, y, BLOCKSIZE);
|
||||
else
|
||||
memcpy(outBlock, y, BLOCKSIZE);
|
||||
}
|
||||
|
||||
void Diamond2::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
const byte *x = inBlock;
|
||||
byte y[16];
|
||||
|
||||
substitute(numrounds-1, y, x);
|
||||
for (int round=numrounds-2; round >= 0; round--)
|
||||
{
|
||||
ipermute(y);
|
||||
substitute(round, y, y);
|
||||
}
|
||||
|
||||
if (xorBlock)
|
||||
xorbuf(outBlock, xorBlock, y, BLOCKSIZE);
|
||||
else
|
||||
memcpy(outBlock, y, BLOCKSIZE);
|
||||
}
|
||||
|
||||
void Diamond2Lite::Base::UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length, unsigned int rounds)
|
||||
{
|
||||
AssertValidKeyLength(length);
|
||||
|
||||
numrounds = rounds;
|
||||
s.New(numrounds * ROUNDSIZE);
|
||||
|
||||
Diamond2SboxMaker m(userKey, length, rounds, true);
|
||||
m.MakeSbox(s, direction);
|
||||
}
|
||||
|
||||
inline void Diamond2Lite::Base::substitute(int round, byte *x, const byte *y) const
|
||||
{
|
||||
const byte *sbox = s + (ROUNDSIZE*round);
|
||||
x[0] = sbox[0*256+y[0]];
|
||||
x[1] = sbox[1*256+y[1]];
|
||||
x[2] = sbox[2*256+y[2]];
|
||||
x[3] = sbox[3*256+y[3]];
|
||||
x[4] = sbox[4*256+y[4]];
|
||||
x[5] = sbox[5*256+y[5]];
|
||||
x[6] = sbox[6*256+y[6]];
|
||||
x[7] = sbox[7*256+y[7]];
|
||||
}
|
||||
|
||||
#ifdef DIAMOND_USE_PERMTABLE
|
||||
|
||||
inline void Diamond2Lite::Base::permute(byte *a)
|
||||
{
|
||||
word32 temp = permtable[0][a[0]] | permtable[1][a[1]] |
|
||||
permtable[2][a[2]] | permtable[3][a[3]] |
|
||||
permtable[4][a[4]] | permtable[5][a[5]] |
|
||||
permtable[6][a[6]] | permtable[7][a[7]];
|
||||
|
||||
((word32 *)a)[1] = permtable[0][a[4]] | permtable[1][a[5]] |
|
||||
permtable[2][a[6]] | permtable[3][a[7]] |
|
||||
permtable[4][a[0]] | permtable[5][a[1]] |
|
||||
permtable[6][a[2]] | permtable[7][a[3]];
|
||||
|
||||
((word32 *)a)[0] = temp;
|
||||
}
|
||||
|
||||
inline void Diamond2Lite::Base::ipermute(byte *a)
|
||||
{
|
||||
word32 temp = ipermtable[0][a[0]] | ipermtable[1][a[1]] |
|
||||
ipermtable[2][a[2]] | ipermtable[3][a[3]] |
|
||||
ipermtable[4][a[4]] | ipermtable[5][a[5]] |
|
||||
ipermtable[6][a[6]] | ipermtable[7][a[7]];
|
||||
|
||||
((word32 *)a)[1] = ipermtable[0][a[4]] | ipermtable[1][a[5]] |
|
||||
ipermtable[2][a[6]] | ipermtable[3][a[7]] |
|
||||
ipermtable[4][a[0]] | ipermtable[5][a[1]] |
|
||||
ipermtable[6][a[2]] | ipermtable[7][a[3]];
|
||||
|
||||
((word32 *)a)[0] = temp;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline void Diamond2Lite::Base::permute(byte *a)
|
||||
{
|
||||
byte b[8];
|
||||
|
||||
b[0] = (a[0] & 1) + (a[1] & 2) + (a[2] & 4) + (a[3] & 8) + (a[4] & 0x10) +
|
||||
(a[5] & 0x20) + (a[6] & 0x40) + (a[7] & 0x80);
|
||||
b[1] = (a[1] & 1) + (a[2] & 2) + (a[3] & 4) + (a[4] & 8) + (a[5] & 0x10) +
|
||||
(a[6] & 0x20) + (a[7] & 0x40) + (a[0] & 0x80);
|
||||
b[2] = (a[2] & 1) + (a[3] & 2) + (a[4] & 4) + (a[5] & 8) + (a[6] & 0x10) +
|
||||
(a[7] & 0x20) + (a[0] & 0x40) + (a[1] & 0x80);
|
||||
b[3] = (a[3] & 1) + (a[4] & 2) + (a[5] & 4) + (a[6] & 8) + (a[7] & 0x10) +
|
||||
(a[0] & 0x20) + (a[1] & 0x40) + (a[2] & 0x80);
|
||||
b[4] = (a[4] & 1) + (a[5] & 2) + (a[6] & 4) + (a[7] & 8) + (a[0] & 0x10) +
|
||||
(a[1] & 0x20) + (a[2] & 0x40) + (a[3] & 0x80);
|
||||
b[5] = (a[5] & 1) + (a[6] & 2) + (a[7] & 4) + (a[0] & 8) + (a[1] & 0x10) +
|
||||
(a[2] & 0x20) + (a[3] & 0x40) + (a[4] & 0x80);
|
||||
b[6] = (a[6] & 1) + (a[7] & 2) + (a[0] & 4) + (a[1] & 8) + (a[2] & 0x10) +
|
||||
(a[3] & 0x20) + (a[4] & 0x40) + (a[5] & 0x80);
|
||||
b[7] = (a[7] & 1) + (a[0] & 2) + (a[1] & 4) + (a[2] & 8) + (a[3] & 0x10) +
|
||||
(a[4] & 0x20) + (a[5] & 0x40) + (a[6] & 0x80);
|
||||
|
||||
memcpy(a, b, 8);
|
||||
}
|
||||
|
||||
inline void Diamond2Lite::Base::ipermute(byte *b)
|
||||
{
|
||||
byte a[8];
|
||||
|
||||
a[0] = (b[0] & 1) + (b[7] & 2) + (b[6] & 4) + (b[5] & 8) + (b[4] & 0x10) +
|
||||
(b[3] & 0x20) + (b[2] & 0x40) + (b[1] & 0x80);
|
||||
a[1] = (b[1] & 1) + (b[0] & 2) + (b[7] & 4) + (b[6] & 8) + (b[5] & 0x10) +
|
||||
(b[4] & 0x20) + (b[3] & 0x40) + (b[2] & 0x80);
|
||||
a[2] = (b[2] & 1) + (b[1] & 2) + (b[0] & 4) + (b[7] & 8) + (b[6] & 0x10) +
|
||||
(b[5] & 0x20) + (b[4] & 0x40) + (b[3] & 0x80);
|
||||
a[3] = (b[3] & 1) + (b[2] & 2) + (b[1] & 4) + (b[0] & 8) + (b[7] & 0x10) +
|
||||
(b[6] & 0x20) + (b[5] & 0x40) + (b[4] & 0x80);
|
||||
a[4] = (b[4] & 1) + (b[3] & 2) + (b[2] & 4) + (b[1] & 8) + (b[0] & 0x10) +
|
||||
(b[7] & 0x20) + (b[6] & 0x40) + (b[5] & 0x80);
|
||||
a[5] = (b[5] & 1) + (b[4] & 2) + (b[3] & 4) + (b[2] & 8) + (b[1] & 0x10) +
|
||||
(b[0] & 0x20) + (b[7] & 0x40) + (b[6] & 0x80);
|
||||
a[6] = (b[6] & 1) + (b[5] & 2) + (b[4] & 4) + (b[3] & 8) + (b[2] & 0x10) +
|
||||
(b[1] & 0x20) + (b[0] & 0x40) + (b[7] & 0x80);
|
||||
a[7] = (b[7] & 1) + (b[6] & 2) + (b[5] & 4) + (b[4] & 8) + (b[3] & 0x10) +
|
||||
(b[2] & 0x20) + (b[1] & 0x40) + (b[0] & 0x80);
|
||||
|
||||
memcpy(b, a, 8);
|
||||
}
|
||||
|
||||
#endif // DIAMOND_USE_PERMTABLE
|
||||
|
||||
void Diamond2Lite::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
const byte *x = inBlock;
|
||||
byte y[8];
|
||||
|
||||
substitute(0, y, x);
|
||||
for (int round=1; round < numrounds; round++)
|
||||
{
|
||||
permute(y);
|
||||
substitute(round, y, y);
|
||||
}
|
||||
|
||||
if (xorBlock)
|
||||
xorbuf(outBlock, xorBlock, y, BLOCKSIZE);
|
||||
else
|
||||
memcpy(outBlock, y, BLOCKSIZE);
|
||||
}
|
||||
|
||||
void Diamond2Lite::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
const byte *x = inBlock;
|
||||
byte y[8];
|
||||
|
||||
substitute(numrounds-1, y, x);
|
||||
for (int round=numrounds-2; round >= 0; round--)
|
||||
{
|
||||
ipermute(y);
|
||||
substitute(round, y, y);
|
||||
}
|
||||
|
||||
if (xorBlock)
|
||||
xorbuf(outBlock, xorBlock, y, BLOCKSIZE);
|
||||
else
|
||||
memcpy(outBlock, y, BLOCKSIZE);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
08 1E 20 E834FDB933C502923D92BC9E14368E70D41C66CBDF36155033A66E07E6CC6D8D
|
||||
5A8D872D31EEDDE6 2E69544D7723CBA0
|
||||
10 0F 20 E834FDB933C502923D92BC9E14368E70D41C66CBDF36155033A66E07E6CC6D8D
|
||||
5A8D872D31EEDDE63FC46F6C36456D8E 39B60490AEEF791A29015D74494AAA89
|
||||
|
||||
08 0B 11 599B02FBD0D321A789EB97B388BF77C663
|
||||
56A25A87D40AB25A 3177400DE74099BB
|
||||
10 0E 11 599B02FBD0D321A789EB97B388BF77C663
|
||||
56A25A87D40AB25A1DD972A7D154F8A5 081420F230D5A85AB2B55453C43C7967
|
||||
|
||||
08 0A 08 3361066B2C297543
|
||||
787699FCB627774F 06AD8CDF623D31F7
|
||||
10 09 08 3361066B2C297543
|
||||
787699FCB627774FCF0F0D82462D6E7D CEB8B4F88C02DF34ADDAF431E7A7A07C
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
#ifndef CRYPTOPP_DIAMOND_H
|
||||
#define CRYPTOPP_DIAMOND_H
|
||||
|
||||
/** \file
|
||||
*/
|
||||
|
||||
#include "seckey.h"
|
||||
#include "secblock.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
struct Diamond2_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 1, 256>, public VariableRounds<10>
|
||||
{
|
||||
static const char *StaticAlgorithmName() {return "Diamond2";}
|
||||
};
|
||||
|
||||
/// <a href="http://www.weidai.com/scan-mirror/cs.html#Diamond2">Diamond2</a>
|
||||
class Diamond2 : public Diamond2_Info, public BlockCipherDocumentation
|
||||
{
|
||||
class Base : public BlockCipherBaseTemplate<Diamond2_Info>
|
||||
{
|
||||
public:
|
||||
void UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length, unsigned int rounds);
|
||||
|
||||
protected:
|
||||
enum {ROUNDSIZE=4096};
|
||||
inline void substitute(int round, byte *x, const byte *y) const;
|
||||
|
||||
int numrounds;
|
||||
SecByteBlock s; // Substitution boxes
|
||||
|
||||
static inline void permute(byte *);
|
||||
static inline void ipermute(byte *);
|
||||
#ifdef DIAMOND_USE_PERMTABLE
|
||||
static const word32 permtable[9][256];
|
||||
static const word32 ipermtable[9][256];
|
||||
#endif
|
||||
};
|
||||
|
||||
class Enc : public Base
|
||||
{
|
||||
public:
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
};
|
||||
|
||||
class Dec : public Base
|
||||
{
|
||||
public:
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef BlockCipherTemplate<ENCRYPTION, Enc> Encryption;
|
||||
typedef BlockCipherTemplate<DECRYPTION, Dec> Decryption;
|
||||
};
|
||||
|
||||
typedef Diamond2::Encryption Diamond2Encryption;
|
||||
typedef Diamond2::Decryption Diamond2Decryption;
|
||||
|
||||
struct Diamond2Lite_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 1, 256>, public VariableRounds<8>
|
||||
{
|
||||
static const char *StaticAlgorithmName() {return "Diamond2Lite";}
|
||||
};
|
||||
|
||||
/// <a href="http://www.weidai.com/scan-mirror/cs.html#Diamond2">Diamond2Lite</a>
|
||||
class Diamond2Lite : public Diamond2Lite_Info, public BlockCipherDocumentation
|
||||
{
|
||||
class Base : public BlockCipherBaseTemplate<Diamond2Lite_Info>
|
||||
{
|
||||
public:
|
||||
void UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length, unsigned int rounds);
|
||||
|
||||
protected:
|
||||
enum {ROUNDSIZE=2048};
|
||||
inline void substitute(int round, byte *x, const byte *y) const;
|
||||
int numrounds;
|
||||
SecByteBlock s; // Substitution boxes
|
||||
|
||||
static inline void permute(byte *);
|
||||
static inline void ipermute(byte *);
|
||||
#ifdef DIAMOND_USE_PERMTABLE
|
||||
static const word32 permtable[8][256];
|
||||
static const word32 ipermtable[8][256];
|
||||
#endif
|
||||
};
|
||||
|
||||
class Enc : public Base
|
||||
{
|
||||
public:
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
};
|
||||
|
||||
class Dec : public Base
|
||||
{
|
||||
public:
|
||||
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef BlockCipherTemplate<ENCRYPTION, Enc> Encryption;
|
||||
typedef BlockCipherTemplate<DECRYPTION, Dec> Decryption;
|
||||
};
|
||||
|
||||
typedef Diamond2Lite::Encryption Diamond2LiteEncryption;
|
||||
typedef Diamond2Lite::Decryption Diamond2LiteDecryption;
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1 @@
|
|||
308201A40201003082011706072A8648CE3804013082010A028181008B333697371663F8869E3EC80A414E46BBAFE41F6D40E754A01ADA60FE7D12ACD16DE311C4115293114F6B92A54195909276380F04BCD4ED5CD993ED7F516DF7A752B928E5035E0D3A1A979A1CDE8387734338793C02001D59B662D4FC8F2BF0EABB1F553F9F46F57E74BCABCBA4E458812DB601FCD04609D435317181236B9702818045999B4B9B8B31FC434F1F640520A7235DD7F20FB6A073AA500D6D307F3E895668B6F188E208A94988A7B5C952A0CAC8493B1C07825E6A76AE6CC9F6BFA8B6FBD3A95C947281AF069D0D4BCD0E6F41C3B9A19C3C9E01000EACDB316A7E4795F8755D8FAA9FCFA37ABF3A5E55E5D2722C4096DB00FE682304EA1A98B8C091B5CB02010204818302818045999B4B9B8B31FC434F1F640520A7235DD7F20FB6A073AA500D6D307F3E895668B6F188E208A94988A7B5C952A0CAC8493B1C07825E6A76AE6CC9F6BFA8B6FBD3A95C947281AF069D0D4BCD0E6F41C3B9A19C3C9E01000EACDB316A7E4795F8755D8FAA9FCFA37ABF3A5E2958F40032EF29CB145C7481380458812D62F09287
|
||||
|
|
@ -0,0 +1 @@
|
|||
308203280201003082021906072A8648CE3804013082020C0282010100A2D27D91489706E93358E6F57E7F85B986A972EFC2D5F2150B5981AE5C82AF3DCB99EB2B05EBDB4E3F7B7463536AD58AAE4E679E02B580E0A0952E88B3C5CEF73274C0458BD2CB0498E1431DF7EFC570F4D3A58686C498A3A0D404B1F68BDF1961A1160F4099EEC91CED5982B924610ECA12882F74B8CEDB49B5153E68B62ACE0ED93AD8019680CA333EF4B237AE43C1359C46281092A23DDAFFA915F639EDE93001D5D3C5CECF808B1FBC9D1FC941597137A811606DBCF643E73DF844532B540FD7A60566B5C859BC5B56C8CC5591D30E765E45CB33EFDF32322C29A843341AEA6E35348F5749E510783E8DAC70E7A646F6C8FEA25C7465DE8D58041F5CD8F30282010051693EC8A44B837499AC737ABF3FC2DCC354B977E16AF90A85ACC0D72E41579EE5CCF59582F5EDA71FBDBA31A9B56AC5572733CF015AC070504A974459E2E77B993A6022C5E965824C70A18EFBF7E2B87A69D2C343624C51D06A0258FB45EF8CB0D08B07A04CF7648E76ACC15C92308765094417BA5C676DA4DA8A9F345B1567076C9D6C00CB4065199F7A591BD721E09ACE23140849511EED7FD48AFB1CF6F49800EAE9E2E767C0458FDE4E8FE4A0ACB89BD408B036DE7B21F39EFC222995AA07EBD302B35AE42CDE2DAB64662AC8E9873B2F22E599F7EF99191614D4219A0D75371A9A47ABA4F2883C1F46D63873D3237B647F512E3A32EF46AC020FAE6C79020103048201040282010051693EC8A44B837499AC737ABF3FC2DCC354B977E16AF90A85ACC0D72E41579EE5CCF59582F5EDA71FBDBA31A9B56AC5572733CF015AC070504A974459E2E77B993A6022C5E965824C70A18EFBF7E2B87A69D2C343624C51D06A0258FB45EF8CB0D08B07A04CF7648E76ACC15C92308765094417BA5C676DA4DA8A9F345B1567076C9D6C00CB4065199F7A591BD721E09ACE23140849511EED7FD48AFB1CF6F49800EAE9E2E767C0458FDE4E8FE4A0ACB89BD408B036DE7B21F39EFC222995AA07EBD302B35AE42CDE2DAB64662AC8E9873B2F22E599F7EF99191614D4219A0D75371A943DF2A781AEF1E87084B0419C5988BF5EF581798F6CBFAD827CE75642
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
#ifndef CRYPTOPP_DMAC_H
|
||||
#define CRYPTOPP_DMAC_H
|
||||
|
||||
#include "cbcmac.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
template <class T>
|
||||
class DMAC_Base : public SameKeyLengthAs<T>, public MessageAuthenticationCode
|
||||
{
|
||||
public:
|
||||
static std::string StaticAlgorithmName() {return std::string("DMAC(") + T::StaticAlgorithmName() + ")";}
|
||||
|
||||
enum {DIGESTSIZE=T::BLOCKSIZE};
|
||||
|
||||
DMAC_Base() {}
|
||||
|
||||
void CheckedSetKey(void *, Empty empty, const byte *key, unsigned int length, const NameValuePairs ¶ms);
|
||||
void Update(const byte *input, unsigned int length);
|
||||
void TruncatedFinal(byte *mac, unsigned int size);
|
||||
unsigned int DigestSize() const {return DIGESTSIZE;}
|
||||
|
||||
private:
|
||||
byte *GenerateSubKeys(const byte *key, unsigned int keylength);
|
||||
|
||||
unsigned int 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 BlockTransformation class.
|
||||
*/
|
||||
template <class T>
|
||||
class DMAC : public MessageAuthenticationCodeTemplate<DMAC_Base<T> >
|
||||
{
|
||||
public:
|
||||
DMAC() {}
|
||||
DMAC(const byte *key, unsigned int length=DMAC_Base<T>::DEFAULT_KEYLENGTH)
|
||||
{SetKey(key, length);}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void DMAC_Base<T>::CheckedSetKey(void *, Empty empty, const byte *key, unsigned int length, const NameValuePairs ¶ms)
|
||||
{
|
||||
m_subkeylength = T::StaticGetValidKeyLength(T::BLOCKSIZE);
|
||||
m_subkeys.resize(2*STDMAX((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, unsigned int length)
|
||||
{
|
||||
m_mac1.Update(input, length);
|
||||
m_counter = (m_counter + length) % T::BLOCKSIZE;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void DMAC_Base<T>::TruncatedFinal(byte *mac, unsigned int 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);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
byte *DMAC_Base<T>::GenerateSubKeys(const byte *key, unsigned int 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
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
// dsa.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "dsa.h"
|
||||
#include "nbtheory.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
unsigned int DSAConvertSignatureFormat(byte *buffer, unsigned int bufferSize, DSASignatureFormat toFormat, const byte *signature, unsigned int 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 sink.TotalPutLength();
|
||||
}
|
||||
|
||||
bool DSA::GeneratePrimes(const byte *seedIn, unsigned int g, int &counter,
|
||||
Integer &p, unsigned int L, Integer &q, bool useInputCounterValue)
|
||||
{
|
||||
assert(g%8 == 0);
|
||||
|
||||
SHA sha;
|
||||
SecByteBlock seed(seedIn, g/8);
|
||||
SecByteBlock U(SHA::DIGESTSIZE);
|
||||
SecByteBlock temp(SHA::DIGESTSIZE);
|
||||
SecByteBlock W(((L-1)/160+1) * SHA::DIGESTSIZE);
|
||||
const int n = (L-1) / 160;
|
||||
const int b = (L-1) % 160;
|
||||
Integer X;
|
||||
|
||||
sha.CalculateDigest(U, seed, g/8);
|
||||
|
||||
for (int i=g/8-1, carry=true; i>=0 && carry; i--)
|
||||
carry=!++seed[i];
|
||||
|
||||
sha.CalculateDigest(temp, seed, g/8);
|
||||
xorbuf(U, temp, SHA::DIGESTSIZE);
|
||||
|
||||
U[0] |= 0x80;
|
||||
U[SHA::DIGESTSIZE-1] |= 1;
|
||||
q.Decode(U, SHA::DIGESTSIZE);
|
||||
|
||||
if (!IsPrime(q))
|
||||
return false;
|
||||
|
||||
int counterEnd = useInputCounterValue ? counter+1 : 4096;
|
||||
|
||||
for (int c = 0; c < counterEnd; c++)
|
||||
{
|
||||
for (int k=0; k<=n; k++)
|
||||
{
|
||||
for (int i=g/8-1, carry=true; i>=0 && carry; i--)
|
||||
carry=!++seed[i];
|
||||
if (!useInputCounterValue || c == counter)
|
||||
sha.CalculateDigest(W+(n-k)*SHA::DIGESTSIZE, seed, g/8);
|
||||
}
|
||||
if (!useInputCounterValue || c == counter)
|
||||
{
|
||||
W[SHA::DIGESTSIZE - 1 - b/8] |= 0x80;
|
||||
X.Decode(W + SHA::DIGESTSIZE - 1 - b/8, L/8);
|
||||
p = X-((X % (2*q))-1);
|
||||
|
||||
if (p.GetBit(L-1) && IsPrime(p))
|
||||
{
|
||||
counter = c;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#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() */
|
||||
unsigned int DSAConvertSignatureFormat(byte *buffer, unsigned int bufferSize, DSASignatureFormat toFormat,
|
||||
const byte *signature, unsigned int 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;
|
||||
|
||||
bool GenerateDSAPrimes(const byte *seed, unsigned int seedLength, int &counter, Integer &p, unsigned int primeLength, Integer &q)
|
||||
{return DSA::GeneratePrimes(seed, seedLength, counter, p, primeLength, q);}
|
||||
|
||||
#endif
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1 @@
|
|||
3082014A0201003082012B06072A8648CE3804013082011E02818100F468699A6F6EBCC0120D3B34C8E007F125EC7D81F763B8D0F33869AE3BD6B9F2ECCC7DF34DF84C0307449E9B85D30D57194BCCEB310F48141914DD13A077AAF9B624A6CBE666BBA1D7EBEA95B5BA6F54417FD5D4E4220C601E071D316A24EA814E8B0122DBF47EE8AEEFD319EBB01DD95683F10DBB4FEB023F8262A07EAEB7FD02150082AD4E034DA6EEACDFDAE68C36F2BAD614F9E53B02818071AAF73361A26081529F7D84078ADAFCA48E031DB54AD57FB1A833ADBD8672328AABAA0C756247998D7A5B10DACA359D231332CE8120B483A784FE07D46EEBFF0D7D374A10691F78653E6DC29E27CCB1B174923960DFE5B959B919B2C3816C19251832AFD8E35D810E598F82877ABF7D40A041565168BD7F0E21E3FE2A8D8C1C0416021426EBA66E846E755169F84A1DA981D86502405DDF
|
||||
|
|
@ -0,0 +1 @@
|
|||
308201B73082012B06072A8648CE3804013082011E02818100F468699A6F6EBCC0120D3B34C8E007F125EC7D81F763B8D0F33869AE3BD6B9F2ECCC7DF34DF84C0307449E9B85D30D57194BCCEB310F48141914DD13A077AAF9B624A6CBE666BBA1D7EBEA95B5BA6F54417FD5D4E4220C601E071D316A24EA814E8B0122DBF47EE8AEEFD319EBB01DD95683F10DBB4FEB023F8262A07EAEB7FD02150082AD4E034DA6EEACDFDAE68C36F2BAD614F9E53B02818071AAF73361A26081529F7D84078ADAFCA48E031DB54AD57FB1A833ADBD8672328AABAA0C756247998D7A5B10DACA359D231332CE8120B483A784FE07D46EEBFF0D7D374A10691F78653E6DC29E27CCB1B174923960DFE5B959B919B2C3816C19251832AFD8E35D810E598F82877ABF7D40A041565168BD7F0E21E3FE2A8D8C1C0381850002818100D30312B7179661DA4691EDE39A71CB961199CD792C50AED6EA7E1A24C53590B6BCD92F26509D3372B2849A17C99C0962FBE4A2606CA37E6DF10244805363450FFAA24A7C274DF0B5D24AE7F31A8319FD2AA6E98AC6E7E3364E7AEDE575A9993609B0DFA387084141EA0B5B2D59B6DE718C0DAB4F86BC59F0DBE8602AED933494
|
||||
|
|
@ -0,0 +1 @@
|
|||
3081C60201003081A806072A8648CE38040130819C0241008DF2A494492276AA3D25759BB06869CBEAC0D83AFB8D0CF7CBB8324F0D7882E5D0762FC5B7210EAFC2E9ADAC32AB7AAC49693DFBF83724C2EC0736EE31C80291021500C773218C737EC8EE993B4F2DED30F48EDACE915F0240626D027839EA0A13413163A55B4CB500299D5522956CEFCB3BFF10F399CE2C2E71CB9DE5FA24BABF58E5B79521925C9CC42E9F6F464B088CC572AF53E6D78802041602142070B3223DBA372FDE1C0FFC7B2E3B498B260614
|
||||
|
|
@ -0,0 +1,287 @@
|
|||
// ec2n.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#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())
|
||||
BERDecodeOctetString(seq, TheBitBucket());
|
||||
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, unsigned int encodedPointLen) const
|
||||
{
|
||||
StringStore store(encodedPoint, encodedPointLen);
|
||||
return DecodePoint(P, store, encodedPointLen);
|
||||
}
|
||||
|
||||
bool EC2N::DecodePoint(EC2N::Point &P, BufferedTransformation &bt, unsigned int 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
|
||||
{
|
||||
static const Point zero;
|
||||
return zero;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
*/
|
||||
|
||||
template class AbstractGroup<EC2N::Point>;
|
||||
template class DL_FixedBasePrecomputationImpl<EC2N::Point>;
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
#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 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;
|
||||
};
|
||||
|
||||
//! Elliptic Curve over GF(2^n)
|
||||
class 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, unsigned int len) const;
|
||||
bool DecodePoint(Point &P, const byte *encodedPoint, unsigned int 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;}
|
||||
|
||||
private:
|
||||
clonable_ptr<Field> m_field;
|
||||
FieldElement m_a, m_b;
|
||||
mutable Point m_R;
|
||||
};
|
||||
|
||||
template <class T> class EcPrecomputation;
|
||||
|
||||
//! .
|
||||
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
|
||||
|
|
@ -0,0 +1,639 @@
|
|||
#include "pch.h"
|
||||
#include "eccrypto.h"
|
||||
#include "ec2n.h"
|
||||
#include "ecp.h"
|
||||
#include "nbtheory.h"
|
||||
#include "oids.h"
|
||||
#include "hex.h"
|
||||
#include "argnames.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
Integer t=1;
|
||||
unsigned int n=q.BitCount(), m=r.BitCount();
|
||||
|
||||
for (unsigned int i=n; DiscreteLogWorkFactor(i)<m/2; i+=n)
|
||||
{
|
||||
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, ssA.MaxRetrievable()), EC2N::FieldElement(ssB, ssB.MaxRetrievable()));
|
||||
else
|
||||
return new EC2N(GF2NPP(t0, t1, t2, t3, t4), EC2N::FieldElement(ssA, ssA.MaxRetrievable()), EC2N::FieldElement(ssB, 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, ssP.MaxRetrievable()), ECP::FieldElement(ssA, ssA.MaxRetrievable()), ECP::FieldElement(ssB, 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;}
|
||||
};
|
||||
|
||||
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::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());
|
||||
m_groupPrecomputation.SetCurve(*ec);
|
||||
|
||||
StringSource ssG(param.g, true, new HexDecoder);
|
||||
Element G;
|
||||
bool result = GetCurve().DecodePoint(G, ssG, ssG.MaxRetrievable());
|
||||
SetSubgroupGenerator(G);
|
||||
assert(result);
|
||||
|
||||
StringSource ssN(param.n, true, new HexDecoder);
|
||||
m_n.Decode(ssN, 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;
|
||||
|
||||
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, 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(GetGroupPrecomputation(), Integer::One()) == g;
|
||||
}
|
||||
if (level >= 2)
|
||||
{
|
||||
const Integer &q = GetSubgroupOrder();
|
||||
pass = pass && IsIdentity(gpc ? gpc->Exponentiate(GetGroupPrecomputation(), q) : ExponentiateElement(g, q));
|
||||
}
|
||||
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>
|
||||
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>
|
||||
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>::BERDecodeKey2(BufferedTransformation &bt, bool parametersPresent, unsigned int size)
|
||||
{
|
||||
typename EC::Point P;
|
||||
if (!GetGroupParameters().GetCurve().DecodePoint(P, bt, size))
|
||||
BERDecodeError();
|
||||
SetPublicElement(P);
|
||||
}
|
||||
|
||||
template <class EC>
|
||||
void DL_PublicKey_EC<EC>::DEREncodeKey(BufferedTransformation &bt) const
|
||||
{
|
||||
GetGroupParameters().GetCurve().EncodePoint(bt, GetPublicElement(), GetGroupParameters().GetPointCompression());
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
||||
template <class EC>
|
||||
void DL_PrivateKey_EC<EC>::BERDecodeKey2(BufferedTransformation &bt, bool parametersPresent, unsigned int 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, 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);
|
||||
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 && GetGroupParameters().GetCurve().DecodePoint(Q, subjectPublicKey, subjectPublicKey.size())))
|
||||
BERDecodeError();
|
||||
}
|
||||
seq.MessageEnd();
|
||||
|
||||
SetPrivateExponent(x);
|
||||
}
|
||||
|
||||
template <class EC>
|
||||
void DL_PrivateKey_EC<EC>::DEREncodeKey(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
|
||||
GetPrivateExponent().DEREncodeAsOctetString(privateKey, GetGroupParameters().GetSubgroupOrder().ByteCount());
|
||||
privateKey.MessageEnd();
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
||||
template class DL_GroupParameters_EC<EC2N>;
|
||||
template class DL_GroupParameters_EC<ECP>;
|
||||
template class DL_PublicKey_EC<EC2N>;
|
||||
template class DL_PublicKey_EC<ECP>;
|
||||
template class DL_PrivateKey_EC<EC2N>;
|
||||
template class DL_PrivateKey_EC<ECP>;
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,253 @@
|
|||
#ifndef CRYPTOPP_ECCRYPTO_H
|
||||
#define CRYPTOPP_ECCRTPTO_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"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
template <class T> class EcPrecomputation;
|
||||
|
||||
//! 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())
|
||||
{
|
||||
m_groupPrecomputation.SetCurve(ec);
|
||||
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 m_gpc;}
|
||||
DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return 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;
|
||||
|
||||
// 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 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 m_groupPrecomputation.GetCurve();}
|
||||
|
||||
#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
|
||||
};
|
||||
|
||||
//! .
|
||||
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)
|
||||
{AccessGroupParameters() = params; SetPublicElement(Q);}
|
||||
void Initialize(const EC &ec, const Element &G, const Integer &n, const Element &Q)
|
||||
{AccessGroupParameters().Initialize(ec, G, n); SetPublicElement(Q);}
|
||||
|
||||
// X509PublicKey
|
||||
void BERDecodeKey2(BufferedTransformation &bt, bool parametersPresent, unsigned int size);
|
||||
void DEREncodeKey(BufferedTransformation &bt) const;
|
||||
};
|
||||
|
||||
//! .
|
||||
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)
|
||||
{AccessGroupParameters() = params; SetPrivateExponent(x);}
|
||||
void Initialize(const EC &ec, const Element &G, const Integer &n, const Integer &x)
|
||||
{AccessGroupParameters().Initialize(ec, G, n); SetPrivateExponent(x);}
|
||||
void Initialize(RandomNumberGenerator &rng, const DL_GroupParameters_EC<EC> ¶ms)
|
||||
{GenerateRandom(rng, params);}
|
||||
void Initialize(RandomNumberGenerator &rng, const EC &ec, const Element &G, const Integer &n)
|
||||
{GenerateRandom(rng, DL_GroupParameters_EC<EC>(ec, G, n));}
|
||||
|
||||
// PKCS8PrivateKey
|
||||
void BERDecodeKey2(BufferedTransformation &bt, bool parametersPresent, unsigned int size);
|
||||
void DEREncodeKey(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 = 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 = DL_GroupParameters_EC<EC>::DefaultCofactorOption>
|
||||
struct ECMQV
|
||||
{
|
||||
typedef MQV_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION> Domain;
|
||||
};
|
||||
|
||||
//! .
|
||||
template <class EC>
|
||||
struct DL_Keys_EC
|
||||
{
|
||||
typedef DL_PublicKey_EC<EC> PublicKey;
|
||||
typedef DL_PrivateKey_EC<EC> PrivateKey;
|
||||
};
|
||||
|
||||
template <class EC, class H = SHA>
|
||||
struct ECDSA;
|
||||
|
||||
//! .
|
||||
template <class EC>
|
||||
struct DL_Keys_ECDSA
|
||||
{
|
||||
typedef DL_PublicKey_EC<EC> PublicKey;
|
||||
typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<EC>, ECDSA<EC> > PrivateKey;
|
||||
};
|
||||
|
||||
//! .
|
||||
template <class EC>
|
||||
class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA<typename EC::Point>
|
||||
{
|
||||
public:
|
||||
static const char * StaticAlgorithmName() {return "ECDSA";}
|
||||
};
|
||||
|
||||
//! .
|
||||
template <class EC>
|
||||
class DL_Algorithm_ECNR : public DL_Algorithm_NR<typename EC::Point>
|
||||
{
|
||||
public:
|
||||
static const char * 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_SSA<DL_Keys_ECDSA<EC>, DL_Algorithm_ECDSA<EC>, H>
|
||||
{
|
||||
};
|
||||
|
||||
//! ECNR
|
||||
template <class EC, class H = SHA>
|
||||
struct ECNR : public DL_SSA<DL_Keys_EC<EC>, DL_Algorithm_ECNR<EC>, 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 StaticAlgorithmName() {return "ECIES";} // TODO: fix this after name is standardized
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,477 @@
|
|||
// ecp.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "ecp.h"
|
||||
#include "asn.h"
|
||||
#include "nbtheory.h"
|
||||
|
||||
#include "algebra.cpp"
|
||||
#include "eprecomp.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())
|
||||
BERDecodeOctetString(seq, TheBitBucket());
|
||||
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, unsigned int encodedPointLen) const
|
||||
{
|
||||
StringStore store(encodedPoint, encodedPointLen);
|
||||
return DecodePoint(P, store, encodedPointLen);
|
||||
}
|
||||
|
||||
bool ECP::DecodePoint(ECP::Point &P, BufferedTransformation &bt, unsigned int 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
|
||||
{
|
||||
static const Point zero;
|
||||
return zero;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
unsigned int 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 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<unsigned int> > baseIndices(expCount);
|
||||
std::vector<std::vector<bool> > negateBase(expCount);
|
||||
std::vector<std::vector<unsigned int> > 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(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, word> > 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 = 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);
|
||||
}
|
||||
|
||||
// ********************************************************
|
||||
|
||||
void EcPrecomputation<ECP>::SetCurve(const ECP &ec)
|
||||
{
|
||||
m_ec.reset(new ECP(ec, true));
|
||||
m_ecOriginal = ec;
|
||||
}
|
||||
|
||||
template class AbstractGroup<ECP::Point>;
|
||||
template class DL_FixedBasePrecomputationImpl<ECP::Point>;
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
#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 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;
|
||||
};
|
||||
|
||||
//! Elliptic Curve over GF(p), where p is prime
|
||||
class 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, unsigned int len) const;
|
||||
bool DecodePoint(Point &P, const byte *encodedPoint, unsigned int 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;}
|
||||
|
||||
private:
|
||||
clonable_ptr<Field> m_fieldPtr;
|
||||
FieldElement m_a, m_b;
|
||||
mutable Point m_R;
|
||||
};
|
||||
|
||||
template <class T> class EcPrecomputation;
|
||||
|
||||
//! .
|
||||
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);
|
||||
const ECP & GetCurve() const {return *m_ecOriginal;}
|
||||
|
||||
private:
|
||||
value_ptr<ECP> m_ec, m_ecOriginal;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// 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
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
#ifndef CRYPTOPP_ELGAMAL_H
|
||||
#define CRYPTOPP_ELGAMAL_H
|
||||
|
||||
#include "modexppc.h"
|
||||
#include "dsa.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
class ElGamalBase : public DL_KeyAgreementAlgorithm_DH<Integer, NoCofactorMultiplication>,
|
||||
public DL_KeyDerivationAlgorithm<Integer>,
|
||||
public DL_SymmetricEncryptionAlgorithm
|
||||
{
|
||||
public:
|
||||
void Derive(const DL_GroupParameters<Integer> ¶ms, byte *derivedKey, unsigned int derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey) const
|
||||
{
|
||||
agreedElement.Encode(derivedKey, derivedLength);
|
||||
}
|
||||
|
||||
unsigned int GetSymmetricKeyLength(unsigned int plainTextLength) const
|
||||
{
|
||||
return GetGroupParameters().GetModulus().ByteCount();
|
||||
}
|
||||
|
||||
unsigned int GetSymmetricCiphertextLength(unsigned int plainTextLength) const
|
||||
{
|
||||
unsigned int len = GetGroupParameters().GetModulus().ByteCount();
|
||||
if (plainTextLength <= GetMaxSymmetricPlaintextLength(len))
|
||||
return len;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int GetMaxSymmetricPlaintextLength(unsigned int 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, unsigned int plainTextLength, byte *cipherText) 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] = 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, unsigned int cipherTextLength, byte *plainText) 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:
|
||||
unsigned int FixedMaxPlaintextLength() const {return MaxPlaintextLength(FixedCiphertextLength());}
|
||||
unsigned int FixedCiphertextLength() const {return CiphertextLength(0);}
|
||||
|
||||
const DL_GroupParameters_GFP & GetGroupParameters() const {return GetKey().GetGroupParameters();}
|
||||
|
||||
DecodingResult FixedLengthDecrypt(const byte *cipherText, byte *plainText) const
|
||||
{return Decrypt(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";}
|
||||
|
||||
class EncryptorImpl : public ElGamalObjectImpl<DL_EncryptorBase<Integer, PK_FixedLengthEncryptor>, SchemeOptions, SchemeOptions::PublicKey>, public PublicKeyCopier<SchemeOptions>
|
||||
{
|
||||
public:
|
||||
void CopyKeyInto(SchemeOptions::PublicKey &key) const
|
||||
{key = GetKey();}
|
||||
};
|
||||
|
||||
class DecryptorImpl : public ElGamalObjectImpl<DL_DecryptorBase<Integer, PK_FixedLengthDecryptor>, SchemeOptions, SchemeOptions::PrivateKey>, public PrivateKeyCopier<SchemeOptions>
|
||||
{
|
||||
public:
|
||||
void CopyKeyInto(SchemeOptions::PublicKey &key) const
|
||||
{GetKey().MakePublicKey(key);}
|
||||
void CopyKeyInto(SchemeOptions::PrivateKey &key) const
|
||||
{key = GetKey();}
|
||||
};
|
||||
|
||||
typedef SchemeOptions::GroupParameters GroupParameters;
|
||||
//! implements PK_Encryptor interface
|
||||
typedef PK_FinalTemplate<EncryptorImpl> Encryptor;
|
||||
//! implements PK_Decryptor interface
|
||||
typedef PK_FinalTemplate<DecryptorImpl> Decryptor;
|
||||
};
|
||||
|
||||
typedef ElGamal::Encryptor ElGamalEncryptor;
|
||||
typedef ElGamal::Decryptor ElGamalDecryptor;
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1 @@
|
|||
3082018E028181008B333697371663F8869E3EC80A414E46BBAFE41F6D40E754A01ADA60FE7D12ACD16DE311C4115293114F6B92A54195909276380F04BCD4ED5CD993ED7F516DF7A752B928E5035E0D3A1A979A1CDE8387734338793C02001D59B662D4FC8F2BF0EABB1F553F9F46F57E74BCABCBA4E458812DB601FCD04609D435317181236B9702010202818038FBC56751763146BC107ECC59E9BAD3852EBC38799B41B40EF5745810BCF9DCC6D569B7E61063EA358B0DF2A194910029B72A9CFD11AD240681D3F976EDCB18D79C0530AB2944DC1E314C2B520BE23066C802754C19BF2EC15DE0439E2663383CEA5163DC857B6A5F91079F54FB47C9B33F23A9EB6B3FCBA8581524B3EC5C75028181008B333697371663F8869E3EC80A414E46BBAFE41F6D40E754A01ADA60FE7D12ACD16DE311C4115293114F6B92A54195909276380F04BCD4ED5CD993ED7F516DF7A752B928E5035E0D3A1A979A1CDE8387734338793C02001D59B662D4FC8F2BF0EABB1F553F9F46F57E74BC7F3EC6725F2FC0A6155ADCA43CEE7319E623824852
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
// eprecomp.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#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
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
#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_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
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1 @@
|
|||
3081E00281807040653BA4FCD5C66E3318B31E82654C5A62957F68D2EE6AE10BD6678D7A14EEF8EBF0C85F28FE22056C12B2A2DD4E9C897EB2FF06D57DB03B872C049ED2806DC3E4D86F2947D134065AC642F233F95FBCB55C533274FA91FFDC0CEB9E71B8795B71A977C7956001FC19E28DE18A80B20E4AE8F775B952CEEA0DEFEAE8E93D7F020120022B1EC74E9FC5EEA090E8DDF4BDB64861C7DC3F8EC7E64286EC2FE39DA55B4763C582DB48146521BDEF0146D5022B1E559EB15755298408E4E4C6F4791BF075C7A8C9B3C7F5B7FA3E8C322BA0A160C09A9DB6BBC4974BE0F877
|
||||
|
|
@ -0,0 +1 @@
|
|||
3082014D0281C100E2A6788AB3CC986AEC06C51690143D3677141645D0628165EE924B9AFB7E6EDD52D90145B2F6031522C7A6CEC05E358F42B7837DACEA589F868F8DCA1C0F5FD8E5EDB8BBBAFCFF6D64CFCFBE68F46FBA6EFF45BC9D0CBB4F7F6075F5FFC2049C2F304B51C417764E18D182926E02D4116CE5C5C010E3D0AA6872A49B0D1FF4B37D54689C31F5821D04E9D4DB34D7536EE7F88B8C481B0EC1F93193A0B70567E6FD76E9FAC4F67BB47DACD356D0C8015261E068DDF8C34C0CAFCF3FA775577FEB020120024100FAF0F292EE96D4F449024F86C0A104E0633C722586EC00AD33E0234629825D2081BA337597889CAC55DC6BEBDD8F13FE3AA2133D6371601A37D195DA7BC45EF3024100EBE16F88887A425AA08E271467CC2220DC44012AB24ED4FF3512A96E8CB600C8BBCB771459FF0EE63D4B6786952A83A7143A775073F0A1D69B6D0B5817755673
|
||||
|
|
@ -0,0 +1 @@
|
|||
308201B70282010028B1F9CDF87EF6D74F3AC2EA83C17CE376215FB2B3B4817145F1A137FB86B0F7BF0F9BA1BDCF7CC15DF1884DD1B150A983279B90F7A1E4392CB3C16390771DA5668E68621C3898DF66BD254F3787ECFB64B3435E707D5C237A6C09F407D8CD618CC3BBFBAB3DEBA38A0D1A88B2A4E09AE32FF2064EF1896348D5B83047EC2E079D85662EED4A66FBB9C159A617EE3C333BAED66989740F54C3CB336C0EF71130786E70648F2698F4F4192DA06C1578FDB065F8E320EFB63049E4BA664F215924B3E89F69131C5987F357C54593BE173A7AED2D37BE69F90CB574EF83AD49145EB15950FADE9E848DA83BC2CACBEDCAFC4A3B31BFFBBFC4DD03B8E47A218A51410201200256033F9C3F8BDDC021503A687BEC90438F38FF9C0E4C050DD95E46BACA370F478B843611A94BC37B5E838AABFD4ECCCE757BAC967DF8A7DD219B3A71A4DA64D54AB367622B7EB9B4282E898755F02036E91D2A12C81F41025603DB3DE2AE2B52889148C98D68F2B7606B0E5112E60E6A6FF5FD98E5D74143C000B43BEC77082F17C1EF4C82127010B12438D498AAFE8521E21EE6391627D464B54D1BE31F57FFF18C27EC38F08093EA65139A61A2C1
|
||||
|
|
@ -0,0 +1,210 @@
|
|||
// 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;
|
||||
const NameValuePairs &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());
|
||||
|
||||
UnalignedPutWord(BIG_ENDIAN_ORDER, seed, (word32)0);
|
||||
m_p.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("Seed", ConstByteArrayParameter(seed))));
|
||||
UnalignedPutWord(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
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
#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"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! .
|
||||
class ESIGNFunction : public TrapdoorFunction, public PublicKey, public ASN1CryptoMaterial
|
||||
{
|
||||
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_NonreversiblePaddingAlgorithm
|
||||
{
|
||||
public:
|
||||
static const char *StaticAlgorithmName() {return "EMSA5";}
|
||||
|
||||
unsigned int MaxUnpaddedLength(unsigned int paddedLength) const {return UINT_MAX;}
|
||||
|
||||
void Pad(RandomNumberGenerator &rng, const byte *raw, unsigned int inputLength, byte *padded, unsigned int paddedLength) const
|
||||
{
|
||||
unsigned int paddedByteLength = BitsToBytes(paddedLength);
|
||||
memset(padded, 0, paddedByteLength);
|
||||
T::GenerateAndMask(padded, paddedByteLength, raw, inputLength);
|
||||
if (paddedLength % 8 != 0)
|
||||
padded[0] = (byte)Crop(padded[0], paddedLength % 8);
|
||||
}
|
||||
};
|
||||
|
||||
//! EMSA5, for use with ESIGN
|
||||
struct P1363_EMSA5 : public SignatureStandard
|
||||
{
|
||||
template <class H> struct SignaturePaddingAlgorithm {typedef EMSA5Pad<P1363_MGF1<H> > type;};
|
||||
template <class H> struct DecoratedHashingAlgorithm {typedef H type;};
|
||||
};
|
||||
|
||||
template<> struct CryptoStandardTraits<P1363_EMSA5> : public P1363_EMSA5 {};
|
||||
|
||||
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_SSA<STANDARD, H, ESIGN_Keys>
|
||||
{
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
// files.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "files.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
using namespace std;
|
||||
|
||||
void Files_TestInstantiations()
|
||||
{
|
||||
FileStore f0;
|
||||
FileSource f1;
|
||||
FileSink f2;
|
||||
}
|
||||
|
||||
void FileStore::StoreInitialize(const NameValuePairs ¶meters)
|
||||
{
|
||||
const char *fileName;
|
||||
if (parameters.GetValue("InputFileName", fileName))
|
||||
{
|
||||
ios::openmode binary = parameters.GetValueWithDefault("InputBinaryMode", true) ? ios::binary : ios::openmode(0);
|
||||
m_file.open(fileName, ios::in | binary);
|
||||
if (!m_file)
|
||||
throw OpenErr(fileName);
|
||||
m_stream = &m_file;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_stream = NULL;
|
||||
parameters.GetValue("InputStreamPointer", m_stream);
|
||||
}
|
||||
m_waiting = false;
|
||||
}
|
||||
|
||||
unsigned long 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;
|
||||
}
|
||||
|
||||
unsigned int FileStore::Peek(byte &outByte) const
|
||||
{
|
||||
if (!m_stream)
|
||||
return 0;
|
||||
|
||||
int result = m_stream->peek();
|
||||
if (result == EOF) // GCC workaround: 2.95.2 doesn't have char_traits<char>::eof()
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
outByte = byte(result);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int FileStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
|
||||
{
|
||||
if (!m_stream)
|
||||
{
|
||||
transferBytes = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long size=transferBytes;
|
||||
transferBytes = 0;
|
||||
|
||||
if (m_waiting)
|
||||
goto output;
|
||||
|
||||
while (size && m_stream->good())
|
||||
{
|
||||
{
|
||||
unsigned int spaceSize = 1024;
|
||||
m_space = HelpCreatePutSpace(target, channel, 1, (unsigned int)STDMIN(size, (unsigned long)UINT_MAX), spaceSize);
|
||||
|
||||
m_stream->read((char *)m_space, STDMIN(size, (unsigned long)spaceSize));
|
||||
}
|
||||
m_len = m_stream->gcount();
|
||||
unsigned int 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;
|
||||
}
|
||||
|
||||
unsigned int FileStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
|
||||
{
|
||||
if (!m_stream)
|
||||
return 0;
|
||||
|
||||
// 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);
|
||||
unsigned long total = 0;
|
||||
try
|
||||
{
|
||||
assert(!m_waiting);
|
||||
unsigned long copyMax = end-begin;
|
||||
unsigned int 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;
|
||||
}
|
||||
|
||||
void FileSink::IsolatedInitialize(const NameValuePairs ¶meters)
|
||||
{
|
||||
const char *fileName;
|
||||
if (parameters.GetValue("OutputFileName", fileName))
|
||||
{
|
||||
ios::openmode binary = parameters.GetValueWithDefault("OutputBinaryMode", true) ? ios::binary : ios::openmode(0);
|
||||
m_file.open(fileName, ios::out | ios::trunc | binary);
|
||||
if (!m_file)
|
||||
throw OpenErr(fileName);
|
||||
m_stream = &m_file;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_stream = NULL;
|
||||
parameters.GetValue("OutputStreamPointer", m_stream);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
unsigned int FileSink::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
|
||||
{
|
||||
if (!m_stream)
|
||||
throw Err("FileSink: output stream not opened");
|
||||
|
||||
m_stream->write((const char *)inString, length);
|
||||
|
||||
if (messageEnd)
|
||||
m_stream->flush();
|
||||
|
||||
if (!m_stream->good())
|
||||
throw WriteErr();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
#ifndef CRYPTOPP_FILES_H
|
||||
#define CRYPTOPP_FILES_H
|
||||
|
||||
#include "cryptlib.h"
|
||||
#include "filters.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! .
|
||||
class FileStore : public Store, private FilterPutSpaceHelper
|
||||
{
|
||||
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("InputStreamPointer", &in));}
|
||||
FileStore(const char *filename)
|
||||
{StoreInitialize(MakeParameters("InputFileName", filename));}
|
||||
|
||||
std::istream* GetStream() {return m_stream;}
|
||||
|
||||
unsigned long MaxRetrievable() const;
|
||||
unsigned int Peek(byte &outByte) const;
|
||||
|
||||
unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
|
||||
unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
|
||||
|
||||
private:
|
||||
void StoreInitialize(const NameValuePairs ¶meters);
|
||||
|
||||
std::ifstream m_file;
|
||||
std::istream *m_stream;
|
||||
byte *m_space;
|
||||
unsigned int m_len;
|
||||
bool m_waiting;
|
||||
};
|
||||
|
||||
//! .
|
||||
class 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("InputStreamPointer", &in));}
|
||||
FileSource(const char *filename, bool pumpAll, BufferedTransformation *attachment = NULL, bool binary=true)
|
||||
: SourceTemplate<FileStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputFileName", filename)("InputBinaryMode", binary));}
|
||||
|
||||
std::istream* GetStream() {return m_store.GetStream();}
|
||||
};
|
||||
|
||||
//! .
|
||||
class FileSink : public Sink
|
||||
{
|
||||
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("OutputStreamPointer", &out));}
|
||||
FileSink(const char *filename, bool binary=true)
|
||||
{IsolatedInitialize(MakeParameters("OutputFileName", filename)("OutputBinaryMode", binary));}
|
||||
|
||||
std::ostream* GetStream() {return m_stream;}
|
||||
|
||||
void IsolatedInitialize(const NameValuePairs ¶meters);
|
||||
unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking);
|
||||
bool IsolatedFlush(bool hardFlush, bool blocking);
|
||||
|
||||
private:
|
||||
std::ofstream m_file;
|
||||
std::ostream *m_stream;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,898 @@
|
|||
// filters.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#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);
|
||||
NotifyAttachmentChange();
|
||||
}
|
||||
|
||||
void Filter::Insert(Filter *filter)
|
||||
{
|
||||
filter->m_attachment.reset(m_attachment.release());
|
||||
m_attachment.reset(filter);
|
||||
NotifyAttachmentChange();
|
||||
}
|
||||
|
||||
unsigned int Filter::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
|
||||
{
|
||||
return AttachedTransformation()->CopyRangeTo2(target, begin, end, channel, blocking);
|
||||
}
|
||||
|
||||
unsigned int Filter::TransferTo2(BufferedTransformation &target, unsigned long &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, const std::string &channel)
|
||||
{
|
||||
if (propagation)
|
||||
AttachedTransformation()->ChannelInitialize(channel, parameters, propagation-1);
|
||||
}
|
||||
|
||||
unsigned int Filter::Output(int outputSite, const byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel)
|
||||
{
|
||||
if (messageEnd)
|
||||
messageEnd--;
|
||||
unsigned int result = AttachedTransformation()->Put2(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;
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
|
||||
unsigned int MeterFilter::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
|
||||
{
|
||||
FILTER_BEGIN;
|
||||
m_currentMessageBytes += length;
|
||||
m_totalBytes += length;
|
||||
|
||||
if (messageEnd)
|
||||
{
|
||||
m_currentMessageBytes = 0;
|
||||
m_currentSeriesMessages++;
|
||||
m_totalMessages++;
|
||||
}
|
||||
|
||||
FILTER_OUTPUT(1, begin, length, messageEnd);
|
||||
FILTER_END;
|
||||
}
|
||||
|
||||
bool MeterFilter::IsolatedMessageSeriesEnd(bool blocking)
|
||||
{
|
||||
m_currentMessageBytes = 0;
|
||||
m_currentSeriesMessages = 0;
|
||||
m_totalMessageSeries++;
|
||||
return false;
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
|
||||
void FilterWithBufferedInput::BlockQueue::ResetQueue(unsigned int blockSize, unsigned int 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(unsigned int &numberOfBytes)
|
||||
{
|
||||
numberOfBytes = STDMIN(numberOfBytes, STDMIN((unsigned int)(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;
|
||||
}
|
||||
|
||||
unsigned int FilterWithBufferedInput::BlockQueue::GetAll(byte *outString)
|
||||
{
|
||||
unsigned int size = m_size;
|
||||
unsigned int 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, unsigned int length)
|
||||
{
|
||||
assert(m_size + length <= m_buffer.size());
|
||||
byte *end = (m_size < (unsigned int)(m_buffer.end()-m_begin)) ? m_begin + m_size : m_begin + m_size - m_buffer.size();
|
||||
unsigned int len = STDMIN(length, (unsigned int)(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(unsigned int firstSize, unsigned int blockSize, unsigned int 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;
|
||||
}
|
||||
|
||||
unsigned int FilterWithBufferedInput::PutMaybeModifiable(byte *inString, unsigned int length, int messageEnd, bool blocking, bool modifiable)
|
||||
{
|
||||
if (!blocking)
|
||||
throw BlockingInputOnly("FilterWithBufferedInput");
|
||||
|
||||
if (length != 0)
|
||||
{
|
||||
unsigned int newLength = m_queue.CurrentSize() + length;
|
||||
|
||||
if (!m_firstInputDone && newLength >= m_firstSize)
|
||||
{
|
||||
unsigned int 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)
|
||||
{
|
||||
unsigned int len = newLength - m_lastSize;
|
||||
byte *ptr = m_queue.GetContigousBlocks(len);
|
||||
NextPutModifiable(ptr, len);
|
||||
newLength -= len;
|
||||
}
|
||||
|
||||
if (newLength > m_lastSize)
|
||||
{
|
||||
unsigned int 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);
|
||||
unsigned int 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)
|
||||
{
|
||||
unsigned int 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
|
||||
{
|
||||
unsigned int len;
|
||||
while ((len = m_queue.CurrentSize()) > 0)
|
||||
NextPutModifiable(m_queue.GetContigousBlocks(len), len);
|
||||
}
|
||||
}
|
||||
|
||||
void FilterWithBufferedInput::NextPutMultiple(const byte *inString, unsigned int 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::ChannelInitialize(const std::string &channel, const NameValuePairs ¶meters, int propagation)
|
||||
{
|
||||
if (channel.empty())
|
||||
{
|
||||
m_target = parameters.GetValueWithDefault("RedirectionTargetPointer", (BufferedTransformation*)NULL);
|
||||
m_passSignal = parameters.GetValueWithDefault("PassSignal", true);
|
||||
}
|
||||
|
||||
if (m_target && m_passSignal)
|
||||
m_target->ChannelInitialize(channel, parameters, propagation);
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
|
||||
ProxyFilter::ProxyFilter(BufferedTransformation *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *attachment)
|
||||
: FilterWithBufferedInput(firstSize, 1, lastSize, attachment), m_filter(filter), m_proxy(NULL)
|
||||
{
|
||||
if (m_filter.get())
|
||||
m_filter->Attach(m_proxy = new OutputProxy(*this, false));
|
||||
}
|
||||
|
||||
void ProxyFilter::IsolatedFlush(bool completeFlush)
|
||||
{
|
||||
if (m_filter.get())
|
||||
{
|
||||
bool passSignal = m_proxy->GetPassSignal();
|
||||
m_proxy->SetPassSignal(false);
|
||||
m_filter->Flush(completeFlush, -1);
|
||||
m_proxy->SetPassSignal(passSignal);
|
||||
}
|
||||
}
|
||||
|
||||
void ProxyFilter::SetFilter(Filter *filter)
|
||||
{
|
||||
bool passSignal = m_proxy ? m_proxy->GetPassSignal() : false;
|
||||
m_filter.reset(filter);
|
||||
if (filter)
|
||||
{
|
||||
std::auto_ptr<OutputProxy> temp(m_proxy = new OutputProxy(*this, passSignal));
|
||||
m_filter->TransferAllTo(*m_proxy);
|
||||
m_filter->Attach(temp.release());
|
||||
}
|
||||
else
|
||||
m_proxy=NULL;
|
||||
}
|
||||
|
||||
void ProxyFilter::NextPutMultiple(const byte *s, unsigned int len)
|
||||
{
|
||||
if (m_filter.get())
|
||||
m_filter->Put(s, len);
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
|
||||
unsigned int ArraySink::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
|
||||
{
|
||||
memcpy(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total)));
|
||||
m_total += length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte * ArraySink::CreatePutSpace(unsigned int &size)
|
||||
{
|
||||
size = 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;
|
||||
}
|
||||
|
||||
unsigned int ArrayXorSink::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
|
||||
{
|
||||
xorbuf(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total)));
|
||||
m_total += length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
|
||||
unsigned int 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;
|
||||
}
|
||||
|
||||
StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding)
|
||||
: FilterWithBufferedInput(0, c.MandatoryBlockSize(), LastBlockSize(c, padding), attachment)
|
||||
, m_cipher(c)
|
||||
{
|
||||
assert(c.MinLastBlockSize() == 0 || c.MinLastBlockSize() > c.MandatoryBlockSize());
|
||||
|
||||
bool isBlockCipher = (c.MandatoryBlockSize() > 1 && c.MinLastBlockSize() == 0);
|
||||
|
||||
if (padding == DEFAULT_PADDING)
|
||||
{
|
||||
if (isBlockCipher)
|
||||
m_padding = PKCS_PADDING;
|
||||
else
|
||||
m_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 " + c.AlgorithmName());
|
||||
}
|
||||
|
||||
void StreamTransformationFilter::FirstPut(const byte *inString)
|
||||
{
|
||||
m_optimalBufferSize = m_cipher.OptimalBlockSize();
|
||||
m_optimalBufferSize = STDMAX(m_optimalBufferSize, RoundDownToMultipleOf(4096U, m_optimalBufferSize));
|
||||
}
|
||||
|
||||
void StreamTransformationFilter::NextPutMultiple(const byte *inString, unsigned int length)
|
||||
{
|
||||
if (!length)
|
||||
return;
|
||||
|
||||
unsigned int s = m_cipher.MandatoryBlockSize();
|
||||
|
||||
do
|
||||
{
|
||||
unsigned int len = m_optimalBufferSize;
|
||||
byte *space = HelpCreatePutSpace(*AttachedTransformation(), NULL_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, unsigned int length)
|
||||
{
|
||||
m_cipher.ProcessString(inString, length);
|
||||
AttachedTransformation()->PutModifiable(inString, length);
|
||||
}
|
||||
|
||||
void StreamTransformationFilter::LastPut(const byte *inString, unsigned int length)
|
||||
{
|
||||
byte *space = NULL;
|
||||
|
||||
switch (m_padding)
|
||||
{
|
||||
case NO_PADDING:
|
||||
case ZEROS_PADDING:
|
||||
if (length > 0)
|
||||
{
|
||||
unsigned int minLastBlockSize = m_cipher.MinLastBlockSize();
|
||||
bool isForwardTransformation = m_cipher.IsForwardTransformation();
|
||||
|
||||
if (isForwardTransformation && m_padding == ZEROS_PADDING && (minLastBlockSize == 0 || length < minLastBlockSize))
|
||||
{
|
||||
// do padding
|
||||
unsigned int blockSize = STDMAX(minLastBlockSize, m_cipher.MandatoryBlockSize());
|
||||
space = HelpCreatePutSpace(*AttachedTransformation(), NULL_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(), NULL_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(), NULL_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 = s-length;
|
||||
memset(space+length, pad, s-length);
|
||||
}
|
||||
else
|
||||
{
|
||||
space[length] = 1;
|
||||
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] != '\1')
|
||||
throw InvalidCiphertext("StreamTransformationFilter: invalid ones-and-zeros padding found");
|
||||
}
|
||||
AttachedTransformation()->Put(space, length);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
|
||||
void HashFilter::IsolatedInitialize(const NameValuePairs ¶meters)
|
||||
{
|
||||
m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false);
|
||||
m_hashModule.Restart();
|
||||
}
|
||||
|
||||
unsigned int HashFilter::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
|
||||
{
|
||||
FILTER_BEGIN;
|
||||
m_hashModule.Update(inString, length);
|
||||
if (m_putMessage)
|
||||
FILTER_OUTPUT(1, inString, length, 0);
|
||||
if (messageEnd)
|
||||
{
|
||||
{
|
||||
unsigned int size, digestSize = m_hashModule.DigestSize();
|
||||
m_space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, digestSize, digestSize, size = digestSize);
|
||||
m_hashModule.Final(m_space);
|
||||
}
|
||||
FILTER_OUTPUT(2, m_space, m_hashModule.DigestSize(), messageEnd);
|
||||
}
|
||||
FILTER_END_NO_MESSAGE_END;
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
|
||||
HashVerificationFilter::HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment, word32 flags)
|
||||
: FilterWithBufferedInput(attachment)
|
||||
, m_hashModule(hm)
|
||||
{
|
||||
IsolatedInitialize(MakeParameters(Name::HashVerificationFilterFlags(), flags));
|
||||
}
|
||||
|
||||
void HashVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize)
|
||||
{
|
||||
m_flags = parameters.GetValueWithDefault(Name::HashVerificationFilterFlags(), (word32)DEFAULT_FLAGS);
|
||||
m_hashModule.Restart();
|
||||
unsigned int size = m_hashModule.DigestSize();
|
||||
m_verified = false;
|
||||
firstSize = m_flags & HASH_AT_BEGIN ? size : 0;
|
||||
blockSize = 1;
|
||||
lastSize = m_flags & HASH_AT_BEGIN ? 0 : size;
|
||||
}
|
||||
|
||||
void HashVerificationFilter::FirstPut(const byte *inString)
|
||||
{
|
||||
if (m_flags & HASH_AT_BEGIN)
|
||||
{
|
||||
m_expectedHash.New(m_hashModule.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, unsigned int length)
|
||||
{
|
||||
m_hashModule.Update(inString, length);
|
||||
if (m_flags & PUT_MESSAGE)
|
||||
AttachedTransformation()->Put(inString, length);
|
||||
}
|
||||
|
||||
void HashVerificationFilter::LastPut(const byte *inString, unsigned int length)
|
||||
{
|
||||
if (m_flags & HASH_AT_BEGIN)
|
||||
{
|
||||
assert(length == 0);
|
||||
m_verified = m_hashModule.Verify(m_expectedHash);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_verified = (length==m_hashModule.DigestSize() && m_hashModule.Verify(inString));
|
||||
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();
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
|
||||
void SignerFilter::IsolatedInitialize(const NameValuePairs ¶meters)
|
||||
{
|
||||
m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false);
|
||||
m_messageAccumulator.reset(m_signer.NewSignatureAccumulator());
|
||||
}
|
||||
|
||||
unsigned int SignerFilter::Put2(const byte *inString, unsigned int 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());
|
||||
}
|
||||
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, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize)
|
||||
{
|
||||
m_flags = parameters.GetValueWithDefault(Name::SignatureVerificationFilterFlags(), (word32)DEFAULT_FLAGS);
|
||||
m_messageAccumulator.reset(m_verifier.NewVerificationAccumulator());
|
||||
unsigned int size = m_verifier.SignatureLength();
|
||||
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.SignatureUpfrontForVerification())
|
||||
m_verifier.InitializeVerificationAccumulator(*m_messageAccumulator, inString);
|
||||
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.SignatureUpfrontForVerification());
|
||||
}
|
||||
}
|
||||
|
||||
void SignatureVerificationFilter::NextPutMultiple(const byte *inString, unsigned int length)
|
||||
{
|
||||
m_messageAccumulator->Update(inString, length);
|
||||
if (m_flags & PUT_MESSAGE)
|
||||
AttachedTransformation()->Put(inString, length);
|
||||
}
|
||||
|
||||
void SignatureVerificationFilter::LastPut(const byte *inString, unsigned int length)
|
||||
{
|
||||
if (m_flags & SIGNATURE_AT_BEGIN)
|
||||
{
|
||||
assert(length == 0);
|
||||
m_verified = m_verifier.Verify(m_messageAccumulator.release(), m_signature);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_verified = (length==m_verifier.SignatureLength() && m_verifier.Verify(m_messageAccumulator.release(), inString));
|
||||
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();
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
|
||||
unsigned int Source::PumpAll2(bool blocking)
|
||||
{
|
||||
// TODO: switch length type
|
||||
unsigned long i = UINT_MAX;
|
||||
RETURN_IF_NONZERO(Pump2(i, blocking));
|
||||
unsigned int j = UINT_MAX;
|
||||
return PumpMessages2(j, blocking);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
unsigned int StringStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
|
||||
{
|
||||
unsigned long position = 0;
|
||||
unsigned int blockedBytes = CopyRangeTo2(target, position, transferBytes, channel, blocking);
|
||||
m_count += position;
|
||||
transferBytes = position;
|
||||
return blockedBytes;
|
||||
}
|
||||
|
||||
unsigned int StringStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
|
||||
{
|
||||
unsigned int i = (unsigned int)STDMIN((unsigned long)m_count+begin, (unsigned long)m_length);
|
||||
unsigned int len = (unsigned int)STDMIN((unsigned long)m_length-i, end-begin);
|
||||
unsigned int blockedBytes = target.ChannelPut2(channel, m_store+i, len, 0, blocking);
|
||||
if (!blockedBytes)
|
||||
begin += len;
|
||||
return blockedBytes;
|
||||
}
|
||||
|
||||
unsigned int RandomNumberStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
|
||||
{
|
||||
if (!blocking)
|
||||
throw NotImplemented("RandomNumberStore: nonblocking transfer is not implemented by this object");
|
||||
|
||||
unsigned long transferMax = transferBytes;
|
||||
for (transferBytes = 0; transferBytes<transferMax && m_count < m_length; ++transferBytes, ++m_count)
|
||||
target.ChannelPut(channel, m_rng.GenerateByte());
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int NullStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
|
||||
{
|
||||
static const byte nullBytes[128] = {0};
|
||||
while (begin < end)
|
||||
{
|
||||
unsigned int len = STDMIN(end-begin, 128UL);
|
||||
unsigned int blockedBytes = target.ChannelPut2(channel, nullBytes, len, 0, blocking);
|
||||
if (blockedBytes)
|
||||
return blockedBytes;
|
||||
begin += len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int NullStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
|
||||
{
|
||||
unsigned long begin = 0;
|
||||
unsigned int blockedBytes = NullStore::CopyRangeTo2(target, begin, transferBytes, channel, blocking);
|
||||
transferBytes = begin;
|
||||
m_size -= begin;
|
||||
return blockedBytes;
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,682 @@
|
|||
#ifndef CRYPTOPP_FILTERS_H
|
||||
#define CRYPTOPP_FILTERS_H
|
||||
|
||||
#include "simple.h"
|
||||
#include "secblock.h"
|
||||
#include "misc.h"
|
||||
#include "smartptr.h"
|
||||
#include "queue.h"
|
||||
#include "algparam.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
/// provides an implementation of BufferedTransformation's attachment interface
|
||||
class Filter : public BufferedTransformation, public NotCopyable
|
||||
{
|
||||
public:
|
||||
Filter(BufferedTransformation *attachment);
|
||||
|
||||
bool Attachable() {return true;}
|
||||
BufferedTransformation *AttachedTransformation();
|
||||
const BufferedTransformation *AttachedTransformation() const;
|
||||
void Detach(BufferedTransformation *newAttachment = NULL);
|
||||
|
||||
unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
|
||||
unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_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 void NotifyAttachmentChange() {}
|
||||
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, const std::string &channel=NULL_CHANNEL);
|
||||
|
||||
unsigned int Output(int outputSite, const byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel=NULL_CHANNEL);
|
||||
bool OutputMessageEnd(int outputSite, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL);
|
||||
bool OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL);
|
||||
bool OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL);
|
||||
|
||||
private:
|
||||
member_ptr<BufferedTransformation> m_attachment;
|
||||
|
||||
protected:
|
||||
unsigned int m_inputPosition;
|
||||
int m_continueAt;
|
||||
};
|
||||
|
||||
struct 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, unsigned int minSize, unsigned int desiredSize, unsigned int &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, unsigned int minSize)
|
||||
{return HelpCreatePutSpace(target, channel, minSize, minSize, minSize);}
|
||||
byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, unsigned int minSize, unsigned int bufferSize)
|
||||
{return HelpCreatePutSpace(target, channel, minSize, minSize, bufferSize);}
|
||||
SecByteBlock m_tempSpace;
|
||||
};
|
||||
|
||||
//! measure how many byte and messages pass through, also serves as valve
|
||||
class MeterFilter : public Bufferless<Filter>
|
||||
{
|
||||
public:
|
||||
MeterFilter(BufferedTransformation *attachment=NULL, bool transparent=true)
|
||||
: Bufferless<Filter>(attachment), m_transparent(transparent) {ResetMeter();}
|
||||
|
||||
void SetTransparent(bool transparent) {m_transparent = transparent;}
|
||||
void ResetMeter() {m_currentMessageBytes = m_totalBytes = m_currentSeriesMessages = m_totalMessages = m_totalMessageSeries = 0;}
|
||||
|
||||
unsigned long GetCurrentMessageBytes() const {return m_currentMessageBytes;}
|
||||
unsigned long GetTotalBytes() {return m_totalBytes;}
|
||||
unsigned int GetCurrentSeriesMessages() {return m_currentSeriesMessages;}
|
||||
unsigned int GetTotalMessages() {return m_totalMessages;}
|
||||
unsigned int GetTotalMessageSeries() {return m_totalMessageSeries;}
|
||||
|
||||
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
|
||||
bool IsolatedMessageSeriesEnd(bool blocking);
|
||||
|
||||
private:
|
||||
bool ShouldPropagateMessageEnd() const {return m_transparent;}
|
||||
bool ShouldPropagateMessageSeriesEnd() const {return m_transparent;}
|
||||
|
||||
bool m_transparent;
|
||||
unsigned long m_currentMessageBytes, m_totalBytes;
|
||||
unsigned int m_currentSeriesMessages, m_totalMessages, m_totalMessageSeries;
|
||||
};
|
||||
|
||||
//! .
|
||||
class TransparentFilter : public MeterFilter
|
||||
{
|
||||
public:
|
||||
TransparentFilter(BufferedTransformation *attachment=NULL) : MeterFilter(attachment, true) {}
|
||||
};
|
||||
|
||||
//! .
|
||||
class 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 FilterWithBufferedInput : public Filter
|
||||
{
|
||||
public:
|
||||
FilterWithBufferedInput(BufferedTransformation *attachment);
|
||||
//! firstSize and lastSize may be 0, blockSize must be at least 1
|
||||
FilterWithBufferedInput(unsigned int firstSize, unsigned int blockSize, unsigned int lastSize, BufferedTransformation *attachment);
|
||||
|
||||
void IsolatedInitialize(const NameValuePairs ¶meters);
|
||||
unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
|
||||
{
|
||||
return PutMaybeModifiable(const_cast<byte *>(inString), length, messageEnd, blocking, false);
|
||||
}
|
||||
unsigned int PutModifiable2(byte *inString, unsigned int 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, unsigned int &firstSize, unsigned int &blockSize, unsigned int &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, unsigned int length);
|
||||
// Same as NextPutMultiple(), but inString can be modified
|
||||
virtual void NextPutModifiable(byte *inString, unsigned int 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, unsigned int length) =0;
|
||||
virtual void FlushDerived() {}
|
||||
|
||||
private:
|
||||
unsigned int PutMaybeModifiable(byte *begin, unsigned int length, int messageEnd, bool blocking, bool modifiable);
|
||||
void NextPutMaybeModifiable(byte *inString, unsigned int 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, unsigned int length) {assert(false); return 0;}
|
||||
|
||||
class BlockQueue
|
||||
{
|
||||
public:
|
||||
void ResetQueue(unsigned int blockSize, unsigned int maxBlocks);
|
||||
byte *GetBlock();
|
||||
byte *GetContigousBlocks(unsigned int &numberOfBytes);
|
||||
unsigned int GetAll(byte *outString);
|
||||
void Put(const byte *inString, unsigned int length);
|
||||
unsigned int CurrentSize() const {return m_size;}
|
||||
unsigned int MaxSize() const {return m_buffer.size();}
|
||||
|
||||
private:
|
||||
SecByteBlock m_buffer;
|
||||
unsigned int m_blockSize, m_maxBlocks, m_size;
|
||||
byte *m_begin;
|
||||
};
|
||||
|
||||
unsigned int m_firstSize, m_blockSize, m_lastSize;
|
||||
bool m_firstInputDone;
|
||||
BlockQueue m_queue;
|
||||
};
|
||||
|
||||
//! .
|
||||
class FilterWithInputQueue : public Filter
|
||||
{
|
||||
public:
|
||||
FilterWithInputQueue(BufferedTransformation *attachment) : Filter(attachment) {}
|
||||
unsigned int Put2(const byte *inString, unsigned int 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;
|
||||
};
|
||||
|
||||
//! Filter Wrapper for StreamTransformation
|
||||
class StreamTransformationFilter : public FilterWithBufferedInput, private FilterPutSpaceHelper
|
||||
{
|
||||
public:
|
||||
enum BlockPaddingScheme {NO_PADDING, ZEROS_PADDING, PKCS_PADDING, ONE_AND_ZEROS_PADDING, DEFAULT_PADDING};
|
||||
/*! 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) */
|
||||
StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment = NULL, BlockPaddingScheme padding = DEFAULT_PADDING);
|
||||
|
||||
void FirstPut(const byte *inString);
|
||||
void NextPutMultiple(const byte *inString, unsigned int length);
|
||||
void NextPutModifiable(byte *inString, unsigned int length);
|
||||
void LastPut(const byte *inString, unsigned int length);
|
||||
// byte * CreatePutSpace(unsigned int &size);
|
||||
|
||||
protected:
|
||||
static unsigned int 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 HashFilter : public Bufferless<Filter>, private FilterPutSpaceHelper
|
||||
{
|
||||
public:
|
||||
HashFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, bool putMessage=false)
|
||||
: Bufferless<Filter>(attachment), m_hashModule(hm), m_putMessage(putMessage) {}
|
||||
|
||||
void IsolatedInitialize(const NameValuePairs ¶meters);
|
||||
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
|
||||
|
||||
byte * CreatePutSpace(unsigned int &size) {return m_hashModule.CreateUpdateSpace(size);}
|
||||
|
||||
private:
|
||||
HashTransformation &m_hashModule;
|
||||
bool m_putMessage;
|
||||
byte *m_space;
|
||||
};
|
||||
|
||||
//! Filter Wrapper for HashTransformation
|
||||
class HashVerificationFilter : public FilterWithBufferedInput
|
||||
{
|
||||
public:
|
||||
class HashVerificationFailed : public Exception
|
||||
{
|
||||
public:
|
||||
HashVerificationFailed()
|
||||
: Exception(DATA_INTEGRITY_CHECK_FAILED, "HashVerifier: message hash not valid") {}
|
||||
};
|
||||
|
||||
enum Flags {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);
|
||||
|
||||
bool GetLastResult() const {return m_verified;}
|
||||
|
||||
protected:
|
||||
void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize);
|
||||
void FirstPut(const byte *inString);
|
||||
void NextPutMultiple(const byte *inString, unsigned int length);
|
||||
void LastPut(const byte *inString, unsigned int length);
|
||||
|
||||
private:
|
||||
static inline unsigned int FirstSize(word32 flags, HashTransformation &hm) {return flags & HASH_AT_BEGIN ? hm.DigestSize() : 0;}
|
||||
static inline unsigned int LastSize(word32 flags, HashTransformation &hm) {return flags & HASH_AT_BEGIN ? 0 : hm.DigestSize();}
|
||||
|
||||
HashTransformation &m_hashModule;
|
||||
word32 m_flags;
|
||||
SecByteBlock m_expectedHash;
|
||||
bool m_verified;
|
||||
};
|
||||
|
||||
typedef HashVerificationFilter HashVerifier; // for backwards compatibility
|
||||
|
||||
//! Filter Wrapper for PK_Signer
|
||||
class SignerFilter : public Unflushable<Filter>
|
||||
{
|
||||
public:
|
||||
SignerFilter(RandomNumberGenerator &rng, const PK_Signer &signer, BufferedTransformation *attachment = NULL, bool putMessage=false)
|
||||
: Unflushable<Filter>(attachment), m_rng(rng), m_signer(signer), m_messageAccumulator(signer.NewSignatureAccumulator()), m_putMessage(putMessage) {}
|
||||
|
||||
void IsolatedInitialize(const NameValuePairs ¶meters);
|
||||
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
|
||||
|
||||
private:
|
||||
RandomNumberGenerator &m_rng;
|
||||
const PK_Signer &m_signer;
|
||||
member_ptr<HashTransformation> m_messageAccumulator;
|
||||
bool m_putMessage;
|
||||
SecByteBlock m_buf;
|
||||
};
|
||||
|
||||
//! Filter Wrapper for PK_Verifier
|
||||
class SignatureVerificationFilter : public FilterWithBufferedInput
|
||||
{
|
||||
public:
|
||||
class SignatureVerificationFailed : public Exception
|
||||
{
|
||||
public:
|
||||
SignatureVerificationFailed()
|
||||
: Exception(DATA_INTEGRITY_CHECK_FAILED, "VerifierFilter: digital signature not valid") {}
|
||||
};
|
||||
|
||||
enum Flags {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);
|
||||
|
||||
bool GetLastResult() const {return m_verified;}
|
||||
|
||||
protected:
|
||||
void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize);
|
||||
void FirstPut(const byte *inString);
|
||||
void NextPutMultiple(const byte *inString, unsigned int length);
|
||||
void LastPut(const byte *inString, unsigned int length);
|
||||
|
||||
private:
|
||||
const PK_Verifier &m_verifier;
|
||||
member_ptr<HashTransformation> 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 Redirector : public CustomSignalPropagation<Sink>
|
||||
{
|
||||
public:
|
||||
Redirector() : m_target(NULL), m_passSignal(true) {}
|
||||
Redirector(BufferedTransformation &target, bool passSignal=true) : m_target(&target), m_passSignal(passSignal) {}
|
||||
|
||||
void Redirect(BufferedTransformation &target) {m_target = ⌖}
|
||||
void StopRedirection() {m_target = NULL;}
|
||||
bool GetPassSignal() const {return m_passSignal;}
|
||||
void SetPassSignal(bool passSignal) {m_passSignal = passSignal;}
|
||||
|
||||
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
|
||||
{return m_target ? m_target->Put2(begin, length, m_passSignal ? messageEnd : 0, blocking) : 0;}
|
||||
void Initialize(const NameValuePairs ¶meters, int propagation)
|
||||
{ChannelInitialize(NULL_CHANNEL, parameters, propagation);}
|
||||
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
|
||||
{return m_target && m_passSignal ? m_target->Flush(hardFlush, propagation, blocking) : false;}
|
||||
bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
|
||||
{return m_target && m_passSignal ? m_target->MessageSeriesEnd(propagation, blocking) : false;}
|
||||
|
||||
void ChannelInitialize(const std::string &channel, const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1);
|
||||
unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
|
||||
{return m_target ? m_target->ChannelPut2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking) : 0;}
|
||||
unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking)
|
||||
{return m_target ? m_target->ChannelPutModifiable2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking) : 0;}
|
||||
bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
|
||||
{return m_target && m_passSignal ? m_target->ChannelFlush(channel, completeFlush, propagation, blocking) : false;}
|
||||
bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)
|
||||
{return m_target && m_passSignal ? m_target->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;}
|
||||
|
||||
private:
|
||||
BufferedTransformation *m_target;
|
||||
bool m_passSignal;
|
||||
};
|
||||
|
||||
// Used By ProxyFilter
|
||||
class 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;}
|
||||
|
||||
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
|
||||
{return m_owner.AttachedTransformation()->Put2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
|
||||
unsigned int PutModifiable2(byte *begin, unsigned int 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;}
|
||||
|
||||
unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
|
||||
{return m_owner.AttachedTransformation()->ChannelPut2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
|
||||
unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking)
|
||||
{return m_owner.AttachedTransformation()->ChannelPutModifiable2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
|
||||
void ChannelInitialize(const std::string &channel, const NameValuePairs ¶meters, int propagation=-1)
|
||||
{if (m_passSignal) m_owner.AttachedTransformation()->ChannelInitialize(channel, parameters, propagation);}
|
||||
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 ProxyFilter : public FilterWithBufferedInput
|
||||
{
|
||||
public:
|
||||
ProxyFilter(BufferedTransformation *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *attachment);
|
||||
|
||||
void IsolatedFlush(bool completeFlush);
|
||||
|
||||
void SetFilter(Filter *filter);
|
||||
void NextPutMultiple(const byte *s, unsigned int len);
|
||||
|
||||
protected:
|
||||
member_ptr<BufferedTransformation> m_filter;
|
||||
OutputProxy *m_proxy;
|
||||
};
|
||||
|
||||
//! simple proxy filter that doesn't modify the underlying filter's input or output
|
||||
class SimpleProxyFilter : public ProxyFilter
|
||||
{
|
||||
public:
|
||||
SimpleProxyFilter(BufferedTransformation *filter, BufferedTransformation *attachment)
|
||||
: ProxyFilter(filter, 0, 0, attachment) {}
|
||||
|
||||
void FirstPut(const byte *) {}
|
||||
void LastPut(const byte *, unsigned int) {m_filter->MessageEnd();}
|
||||
};
|
||||
|
||||
//! proxy for the filter created by PK_Encryptor::CreateEncryptionFilter
|
||||
/*! This class is here just to provide symmetry with VerifierFilter. */
|
||||
class 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 PK_DecryptorFilter : public SimpleProxyFilter
|
||||
{
|
||||
public:
|
||||
PK_DecryptorFilter(const PK_Decryptor &decryptor, BufferedTransformation *attachment = NULL)
|
||||
: SimpleProxyFilter(decryptor.CreateDecryptionFilter(), 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");}
|
||||
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
|
||||
{
|
||||
m_output->append((const char_type *)begin, (const char_type *)begin+length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
T *m_output;
|
||||
};
|
||||
|
||||
//! Append input to an std::string
|
||||
typedef StringSinkTemplate<std::string> StringSink;
|
||||
|
||||
//! Copy input to a memory buffer
|
||||
class ArraySink : public Bufferless<Sink>
|
||||
{
|
||||
public:
|
||||
ArraySink(const NameValuePairs ¶meters = g_nullNameValuePairs) {IsolatedInitialize(parameters);}
|
||||
ArraySink(byte *buf, unsigned int size) : m_buf(buf), m_size(size), m_total(0) {}
|
||||
|
||||
unsigned int AvailableSize() {return m_size - STDMIN(m_total, (unsigned long)m_size);}
|
||||
unsigned long TotalPutLength() {return m_total;}
|
||||
|
||||
void IsolatedInitialize(const NameValuePairs ¶meters);
|
||||
byte * CreatePutSpace(unsigned int &size);
|
||||
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
|
||||
|
||||
protected:
|
||||
byte *m_buf;
|
||||
unsigned int m_size;
|
||||
unsigned long m_total;
|
||||
};
|
||||
|
||||
//! Xor input to a memory buffer
|
||||
class ArrayXorSink : public ArraySink
|
||||
{
|
||||
public:
|
||||
ArrayXorSink(byte *buf, unsigned int size)
|
||||
: ArraySink(buf, size) {}
|
||||
|
||||
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
|
||||
byte * CreatePutSpace(unsigned int &size) {return BufferedTransformation::CreatePutSpace(size);}
|
||||
};
|
||||
|
||||
//! .
|
||||
class StringStore : public Store
|
||||
{
|
||||
public:
|
||||
StringStore(const char *string = NULL)
|
||||
{StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
|
||||
StringStore(const byte *string, unsigned int length)
|
||||
{StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
|
||||
template <class T> StringStore(const T &string)
|
||||
{StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
|
||||
|
||||
unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
|
||||
unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
|
||||
|
||||
private:
|
||||
void StoreInitialize(const NameValuePairs ¶meters);
|
||||
|
||||
const byte *m_store;
|
||||
unsigned int m_length, m_count;
|
||||
};
|
||||
|
||||
//! .
|
||||
class RandomNumberStore : public Store
|
||||
{
|
||||
public:
|
||||
RandomNumberStore(RandomNumberGenerator &rng, unsigned long length)
|
||||
: m_rng(rng), m_length(length), m_count(0) {}
|
||||
|
||||
bool AnyRetrievable() const {return MaxRetrievable() != 0;}
|
||||
unsigned long MaxRetrievable() const {return m_length-m_count;}
|
||||
|
||||
unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
|
||||
unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const
|
||||
{
|
||||
throw NotImplemented("RandomNumberStore: CopyRangeTo2() is not supported by this store");
|
||||
}
|
||||
|
||||
private:
|
||||
void StoreInitialize(const NameValuePairs ¶meters) {m_count = 0;}
|
||||
|
||||
RandomNumberGenerator &m_rng;
|
||||
const unsigned long m_length;
|
||||
unsigned long m_count;
|
||||
};
|
||||
|
||||
//! .
|
||||
class NullStore : public Store
|
||||
{
|
||||
public:
|
||||
NullStore(unsigned long size = ULONG_MAX) : m_size(size) {}
|
||||
void StoreInitialize(const NameValuePairs ¶meters) {}
|
||||
unsigned long MaxRetrievable() const {return m_size;}
|
||||
unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
|
||||
unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
|
||||
|
||||
private:
|
||||
unsigned long m_size;
|
||||
};
|
||||
|
||||
//! A Filter that pumps data into its attachment as input
|
||||
class Source : public InputRejecting<Filter>
|
||||
{
|
||||
public:
|
||||
Source(BufferedTransformation *attachment)
|
||||
: InputRejecting<Filter>(attachment) {}
|
||||
|
||||
unsigned long Pump(unsigned long pumpMax=ULONG_MAX)
|
||||
{Pump2(pumpMax); return pumpMax;}
|
||||
unsigned int PumpMessages(unsigned int count=UINT_MAX)
|
||||
{PumpMessages2(count); return count;}
|
||||
void PumpAll()
|
||||
{PumpAll2();}
|
||||
virtual unsigned int Pump2(unsigned long &byteCount, bool blocking=true) =0;
|
||||
virtual unsigned int PumpMessages2(unsigned int &messageCount, bool blocking=true) =0;
|
||||
virtual unsigned int 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) {}
|
||||
SourceTemplate<T>(BufferedTransformation *attachment, T store)
|
||||
: Source(attachment), m_store(store) {}
|
||||
void IsolatedInitialize(const NameValuePairs ¶meters)
|
||||
{m_store.IsolatedInitialize(parameters);}
|
||||
unsigned int Pump2(unsigned long &byteCount, bool blocking=true)
|
||||
{return m_store.TransferTo2(*AttachedTransformation(), byteCount, NULL_CHANNEL, blocking);}
|
||||
unsigned int PumpMessages2(unsigned int &messageCount, bool blocking=true)
|
||||
{return m_store.TransferMessagesTo2(*AttachedTransformation(), messageCount, NULL_CHANNEL, blocking);}
|
||||
unsigned int PumpAll2(bool blocking=true)
|
||||
{return m_store.TransferAllTo2(*AttachedTransformation(), NULL_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;
|
||||
};
|
||||
|
||||
//! .
|
||||
class StringSource : public SourceTemplate<StringStore>
|
||||
{
|
||||
public:
|
||||
StringSource(BufferedTransformation *attachment = NULL)
|
||||
: SourceTemplate<StringStore>(attachment) {}
|
||||
StringSource(const char *string, bool pumpAll, BufferedTransformation *attachment = NULL)
|
||||
: SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
|
||||
StringSource(const byte *string, unsigned int length, bool pumpAll, BufferedTransformation *attachment = NULL)
|
||||
: SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
|
||||
|
||||
#ifdef __MWERKS__ // CW60 workaround
|
||||
StringSource(const std::string &string, bool pumpAll, BufferedTransformation *attachment = NULL)
|
||||
#else
|
||||
template <class T> StringSource(const T &string, bool pumpAll, BufferedTransformation *attachment = NULL)
|
||||
#endif
|
||||
: SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
|
||||
};
|
||||
|
||||
//! .
|
||||
class RandomNumberSource : public SourceTemplate<RandomNumberStore>
|
||||
{
|
||||
public:
|
||||
RandomNumberSource(RandomNumberGenerator &rng, unsigned int length, bool pumpAll, BufferedTransformation *attachment = NULL)
|
||||
: SourceTemplate<RandomNumberStore>(attachment, RandomNumberStore(rng, length)) {if (pumpAll) PumpAll();}
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
// fips140.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#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 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
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef CRYPTOPP_FIPS140_H
|
||||
#define CRYPTOPP_FIPS140_H
|
||||
|
||||
/*! \file
|
||||
FIPS-140 related functions and classes.
|
||||
*/
|
||||
|
||||
#include "cryptlib.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! exception thrown when a crypto algorithm is used after a self test fails
|
||||
class 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
|
||||
bool 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
|
||||
void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleSha1Digest);
|
||||
|
||||
//! set the power-up self test status to POWER_UP_SELF_TEST_FAILED
|
||||
void SimulatePowerUpSelfTestFailure();
|
||||
|
||||
//! return the current power-up self test status
|
||||
PowerUpSelfTestStatus GetPowerUpSelfTestStatus();
|
||||
|
||||
// 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);
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,304 @@
|
|||
// fipstest.cpp - written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "fips140.h"
|
||||
#include "sha.h"
|
||||
#include "files.h"
|
||||
#include "hex.h"
|
||||
#include "rsa.h"
|
||||
#include "dsa.h"
|
||||
#include "mqueue.h"
|
||||
#include "channels.h"
|
||||
#include "osrng.h"
|
||||
#include "des.h"
|
||||
#include "eccrypto.h"
|
||||
#include "ec2n.h"
|
||||
#include "ecp.h"
|
||||
#include "modes.h"
|
||||
#include "aes.h"
|
||||
#include "skipjack.h"
|
||||
#include "trdlocal.h" // needs to be included last for cygwin
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
extern PowerUpSelfTestStatus g_powerUpSelfTestStatus;
|
||||
|
||||
void KnownAnswerTest(StreamTransformation &encryption, StreamTransformation &decryption, const char *plaintext, const char *ciphertext)
|
||||
{
|
||||
EqualityComparisonFilter comparison;
|
||||
|
||||
StringSource(plaintext, true, new HexDecoder(new StreamTransformationFilter(encryption, new ChannelSwitch(comparison, "0"), StreamTransformationFilter::NO_PADDING)));
|
||||
StringSource(ciphertext, true, new HexDecoder(new ChannelSwitch(comparison, "1")));
|
||||
|
||||
StringSource(ciphertext, true, new HexDecoder(new StreamTransformationFilter(decryption, new ChannelSwitch(comparison, "0"), StreamTransformationFilter::NO_PADDING)));
|
||||
StringSource(plaintext, true, new HexDecoder(new ChannelSwitch(comparison, "1")));
|
||||
|
||||
comparison.ChannelMessageSeriesEnd("0");
|
||||
comparison.ChannelMessageSeriesEnd("1");
|
||||
}
|
||||
|
||||
template <class CIPHER>
|
||||
void SymmetricEncryptionKnownAnswerTest(
|
||||
const char *key,
|
||||
const char *hexIV,
|
||||
const char *plaintext,
|
||||
const char *ecb,
|
||||
const char *cbc,
|
||||
const char *cfb,
|
||||
const char *ofb,
|
||||
const char *ctr,
|
||||
CIPHER *dummy = NULL)
|
||||
{
|
||||
std::string decodedKey;
|
||||
StringSource(key, true, new HexDecoder(new StringSink(decodedKey)));
|
||||
|
||||
typename CIPHER::Encryption encryption((const byte *)decodedKey.data(), decodedKey.size());
|
||||
typename CIPHER::Decryption decryption((const byte *)decodedKey.data(), decodedKey.size());
|
||||
|
||||
SecByteBlock iv(encryption.BlockSize());
|
||||
StringSource(hexIV, true, new HexDecoder(new ArraySink(iv, iv.size())));
|
||||
|
||||
if (ecb)
|
||||
KnownAnswerTest(ECB_Mode_ExternalCipher::Encryption(encryption).Ref(), ECB_Mode_ExternalCipher::Decryption(decryption).Ref(), plaintext, ecb);
|
||||
if (cbc)
|
||||
KnownAnswerTest(CBC_Mode_ExternalCipher::Encryption(encryption, iv).Ref(), CBC_Mode_ExternalCipher::Decryption(decryption, iv).Ref(), plaintext, cbc);
|
||||
if (cfb)
|
||||
KnownAnswerTest(CFB_Mode_ExternalCipher::Encryption(encryption, iv).Ref(), CFB_Mode_ExternalCipher::Decryption(encryption, iv).Ref(), plaintext, cfb);
|
||||
if (ofb)
|
||||
KnownAnswerTest(OFB_Mode_ExternalCipher::Encryption(encryption, iv).Ref(), OFB_Mode_ExternalCipher::Decryption(encryption, iv).Ref(), plaintext, ofb);
|
||||
if (ctr)
|
||||
KnownAnswerTest(CTR_Mode_ExternalCipher::Encryption(encryption, iv).Ref(), CTR_Mode_ExternalCipher::Decryption(encryption, iv).Ref(), plaintext, ctr);
|
||||
}
|
||||
|
||||
void KnownAnswerTest(HashTransformation &hash, const char *message, const char *digest)
|
||||
{
|
||||
EqualityComparisonFilter comparison;
|
||||
StringSource(message, true, new HashFilter(hash, new ChannelSwitch(comparison, "0")));
|
||||
StringSource(digest, true, new HexDecoder(new ChannelSwitch(comparison, "1")));
|
||||
|
||||
comparison.ChannelMessageSeriesEnd("0");
|
||||
comparison.ChannelMessageSeriesEnd("1");
|
||||
}
|
||||
|
||||
template <class HASH>
|
||||
void SecureHashKnownAnswerTest(const char *message, const char *digest)
|
||||
{
|
||||
HASH hash;
|
||||
KnownAnswerTest(hash, message, digest);
|
||||
}
|
||||
|
||||
template <class MAC>
|
||||
void MAC_KnownAnswerTest(const char *key, const char *message, const char *digest)
|
||||
{
|
||||
std::string decodedKey;
|
||||
StringSource(key, true, new HexDecoder(new StringSink(decodedKey)));
|
||||
|
||||
MAC mac((const byte *)decodedKey.data(), decodedKey.size());
|
||||
KnownAnswerTest(mac, message, digest);
|
||||
}
|
||||
|
||||
template <class SCHEME>
|
||||
void SignatureKnownAnswerTest(const char *key, const char *message, const char *signature, SCHEME *dummy = NULL)
|
||||
{
|
||||
typename SCHEME::Signer signer(StringSource(key, true, new HexDecoder).Ref());
|
||||
typename SCHEME::Verifier verifier(signer);
|
||||
|
||||
EqualityComparisonFilter comparison;
|
||||
|
||||
StringSource(message, true, new SignerFilter(NullRNG(), signer, new ChannelSwitch(comparison, "0")));
|
||||
StringSource(signature, true, new HexDecoder(new ChannelSwitch(comparison, "1")));
|
||||
|
||||
comparison.ChannelMessageSeriesEnd("0");
|
||||
comparison.ChannelMessageSeriesEnd("1");
|
||||
|
||||
VerifierFilter verifierFilter(verifier, NULL, VerifierFilter::SIGNATURE_AT_BEGIN | VerifierFilter::THROW_EXCEPTION);
|
||||
StringSource(signature, true, new HexDecoder(new Redirector(verifierFilter, false)));
|
||||
StringSource(message, true, new Redirector(verifierFilter));
|
||||
}
|
||||
|
||||
void EncryptionPairwiseConsistencyTest(const PK_Encryptor &encryptor, const PK_Decryptor &decryptor)
|
||||
{
|
||||
try
|
||||
{
|
||||
#ifdef OS_RNG_AVAILABLE
|
||||
AutoSeededX917RNG<DES_EDE3> rng;
|
||||
#else
|
||||
RandomNumberGenerator &rng = NullRNG();
|
||||
#endif
|
||||
const char *testMessage ="test message";
|
||||
|
||||
EqualityComparisonFilter comparison;
|
||||
comparison.ChannelPutMessageEnd("0", (const byte *)testMessage, strlen(testMessage));
|
||||
|
||||
StringSource(
|
||||
testMessage,
|
||||
true,
|
||||
new PK_EncryptorFilter(
|
||||
rng,
|
||||
encryptor,
|
||||
new PK_DecryptorFilter(decryptor, new ChannelSwitch(comparison, "1"))));
|
||||
|
||||
comparison.ChannelMessageSeriesEnd("0");
|
||||
comparison.ChannelMessageSeriesEnd("1");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
throw SelfTestFailure(encryptor.AlgorithmName() + ": pairwise consistency test failed");
|
||||
}
|
||||
}
|
||||
|
||||
void SignaturePairwiseConsistencyTest(const PK_Signer &signer, const PK_Verifier &verifier)
|
||||
{
|
||||
try
|
||||
{
|
||||
#ifdef OS_RNG_AVAILABLE
|
||||
AutoSeededX917RNG<DES_EDE3> rng;
|
||||
#else
|
||||
RandomNumberGenerator &rng = NullRNG();
|
||||
#endif
|
||||
|
||||
StringSource(
|
||||
"test message",
|
||||
true,
|
||||
new SignerFilter(
|
||||
rng,
|
||||
signer,
|
||||
new VerifierFilter(verifier, NULL, VerifierFilter::THROW_EXCEPTION),
|
||||
true));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
throw SelfTestFailure(signer.AlgorithmName() + ": pairwise consistency test failed");
|
||||
}
|
||||
}
|
||||
|
||||
template <class SCHEME>
|
||||
void SignaturePairwiseConsistencyTest(const char *key, SCHEME *dummy = NULL)
|
||||
{
|
||||
typename SCHEME::Signer signer(StringSource(key, true, new HexDecoder).Ref());
|
||||
typename SCHEME::Verifier verifier(signer);
|
||||
|
||||
SignaturePairwiseConsistencyTest(signer, verifier);
|
||||
}
|
||||
|
||||
void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleSha1Digest)
|
||||
{
|
||||
g_powerUpSelfTestStatus = POWER_UP_SELF_TEST_NOT_DONE;
|
||||
SetPowerUpSelfTestInProgressOnThisThread(true);
|
||||
|
||||
try
|
||||
{
|
||||
if (FIPS_140_2_ComplianceEnabled() || moduleFilename != NULL)
|
||||
{
|
||||
// integrity test
|
||||
SHA1 sha;
|
||||
HashVerifier verifier(sha);
|
||||
verifier.Put(expectedModuleSha1Digest, sha.DigestSize());
|
||||
FileStore(moduleFilename).TransferAllTo(verifier);
|
||||
if (!verifier.GetLastResult())
|
||||
{
|
||||
#ifdef CRYPTOPP_WIN32_AVAILABLE
|
||||
std::string actualDigest;
|
||||
FileSource(moduleFilename, true, new HashFilter(sha, new HexEncoder(new StringSink(actualDigest))));
|
||||
OutputDebugString(("Crypto++ EDC test failed. Actual digest is: " + actualDigest + "\n").c_str());
|
||||
#endif
|
||||
throw 0; // throw here so we break in the debugger, this will be caught right away
|
||||
}
|
||||
}
|
||||
|
||||
// algorithm tests
|
||||
|
||||
SymmetricEncryptionKnownAnswerTest<DES>(
|
||||
"0123456789abcdef", // key
|
||||
"1234567890abcdef", // IV
|
||||
"4e6f77206973207468652074696d6520666f7220616c6c20", // plaintext
|
||||
"3fa40e8a984d48156a271787ab8883f9893d51ec4b563b53", // ecb
|
||||
"E5C7CDDE872BF27C43E934008C389C0F683788499A7C05F6", // cbc
|
||||
"F3096249C7F46E51A69E839B1A92F78403467133898EA622", // cfb
|
||||
"f3096249c7f46e5135f24a242eeb3d3f3d6d5be3255af8c3", // ofb
|
||||
"F3096249C7F46E51163A8CA0FFC94C27FA2F80F480B86F75");// ctr
|
||||
|
||||
SymmetricEncryptionKnownAnswerTest<DES_EDE3>(
|
||||
"385D7189A5C3D485E1370AA5D408082B5CCCCB5E19F2D90E",
|
||||
"C141B5FCCD28DC8A",
|
||||
"6E1BD7C6120947A464A6AAB293A0F89A563D8D40D3461B68",
|
||||
"64EAAD4ACBB9CEAD6C7615E7C7E4792FE587D91F20C7D2F4",
|
||||
"6235A461AFD312973E3B4F7AA7D23E34E03371F8E8C376C9",
|
||||
"E26BA806A59B0330DE40CA38E77A3E494BE2B212F6DD624B",
|
||||
"E26BA806A59B03307DE2BCC25A08BA40A8BA335F5D604C62",
|
||||
"E26BA806A59B03303C62C2EFF32D3ACDD5D5F35EBCC53371");
|
||||
|
||||
SymmetricEncryptionKnownAnswerTest<SKIPJACK>(
|
||||
"1555E5531C3A169B2D65",
|
||||
"6EC9795701F49864",
|
||||
"00AFA48E9621E52E8CBDA312660184EDDB1F33D9DACDA8DA",
|
||||
"DBEC73562EFCAEB56204EB8AE9557EBF77473FBB52D17CD1",
|
||||
"0C7B0B74E21F99B8F2C8DF37879F6C044967F42A796DCA8B",
|
||||
"79FDDA9724E36CC2E023E9A5C717A8A8A7FDA465CADCBF63",
|
||||
"79FDDA9724E36CC26CACBD83C1ABC06EAF5B249BE5B1E040",
|
||||
"79FDDA9724E36CC211B0AEC607B95A96BCDA318440B82F49");
|
||||
|
||||
SymmetricEncryptionKnownAnswerTest<AES>(
|
||||
"2b7e151628aed2a6abf7158809cf4f3c",
|
||||
"000102030405060708090a0b0c0d0e0f",
|
||||
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710", // plaintext
|
||||
"3ad77bb40d7a3660a89ecaf32466ef97f5d3d58503b9699de785895a96fdbaaf43b1cd7f598ece23881b00e3ed0306887b0c785e27e8ad3f8223207104725dd4", // ecb
|
||||
"7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b273bed6b8e3c1743b7116e69e222295163ff1caa1681fac09120eca307586e1a7", // cbc
|
||||
"3b3fd92eb72dad20333449f8e83cfb4ac8a64537a0b3a93fcde3cdad9f1ce58b26751f67a3cbb140b1808cf187a4f4dfc04b05357c5d1c0eeac4c66f9ff7f2e6", // cfb
|
||||
"3b3fd92eb72dad20333449f8e83cfb4a7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e", // ofb
|
||||
NULL);
|
||||
|
||||
SymmetricEncryptionKnownAnswerTest<AES>(
|
||||
"2b7e151628aed2a6abf7158809cf4f3c",
|
||||
"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
|
||||
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
"874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee"); // ctr
|
||||
|
||||
|
||||
SecureHashKnownAnswerTest<SHA>(
|
||||
"abc",
|
||||
"A9993E364706816ABA3E25717850C26C9CD0D89D");
|
||||
|
||||
MAC_KnownAnswerTest<HMAC<SHA> >(
|
||||
"303132333435363738393a3b3c3d3e3f40414243",
|
||||
"Sample #2",
|
||||
"0922d3405faa3d194f82a45830737d5cc6c75d24");
|
||||
|
||||
SignatureKnownAnswerTest<RSASSA<PKCS1v15, SHA> >(
|
||||
"30820150020100300d06092a864886f70d01010105000482013a3082013602010002400a66791dc6988168de7ab77419bb7fb0"
|
||||
"c001c62710270075142942e19a8d8c51d053b3e3782a1de5dc5af4ebe99468170114a1dfe67cdc9a9af55d655620bbab0203010001"
|
||||
"02400123c5b61ba36edb1d3679904199a89ea80c09b9122e1400c09adcf7784676d01d23356a7d44d6bd8bd50e94bfc723fa"
|
||||
"87d8862b75177691c11d757692df8881022033d48445c859e52340de704bcdda065fbb4058d740bd1d67d29e9c146c11cf61"
|
||||
"0220335e8408866b0fd38dc7002d3f972c67389a65d5d8306566d5c4f2a5aa52628b0220045ec90071525325d3d46db79695e9af"
|
||||
"acc4523964360e02b119baa366316241022015eb327360c7b60d12e5e2d16bdcd97981d17fba6b70db13b20b436e24eada590220"
|
||||
"2ca6366d72781dfa24d34a9a24cbc2ae927a9958af426563ff63fb11658a461d",
|
||||
"Everyone gets Friday off.",
|
||||
"0610761F95FFD1B8F29DA34212947EC2AA0E358866A722F03CC3C41487ADC604A48FF54F5C6BEDB9FB7BD59F82D6E55D8F3174BA361B2214B2D74E8825E04E81");
|
||||
|
||||
SignaturePairwiseConsistencyTest<DSA>(
|
||||
"3082014A0201003082012B06072A8648CE3804013082011E02818100F468699A6F6EBCC0120D3B34C8E007F125EC7D81F763B8D0F33869AE3BD6B9F2ECCC7DF34DF84C0307449E9B85D30D57194BCCEB310F48141914DD13A077AAF9B624A6CBE666BBA1D7EBEA95B5BA6F54417FD5D4E4220C601E071D316A24EA814E8B0122DBF47EE8AEEFD319EBB01DD95683F10DBB4FEB023F8262A07EAEB7FD02150082AD4E034DA6EEACDFDAE68C36F2BAD614F9E53B02818071AAF73361A26081529F7D84078ADAFCA48E031DB54AD57FB1A833ADBD8672328AABAA0C756247998D7A5B10DACA359D231332CE8120B483A784FE07D46EEBFF0D7D374A10691F78653E6DC29E27CCB1B174923960DFE5B959B919B2C3816C19251832AFD8E35D810E598F82877ABF7D40A041565168BD7F0E21E3FE2A8D8C1C0416021426EBA66E846E755169F84A1DA981D86502405DDF");
|
||||
|
||||
SignaturePairwiseConsistencyTest<ECDSA<EC2N, SHA> >(
|
||||
"302D020100301006072A8648CE3D020106052B8104000404163014020101040F0070337065E1E196980A9D00E37211");
|
||||
|
||||
SignaturePairwiseConsistencyTest<ECDSA<ECP, SHA> >(
|
||||
"3039020100301306072A8648CE3D020106082A8648CE3D030101041F301D02010104182BB8A13C8B867010BD9471D9E81FDB01ABD0538C64D6249A");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
g_powerUpSelfTestStatus = POWER_UP_SELF_TEST_FAILED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
g_powerUpSelfTestStatus = POWER_UP_SELF_TEST_PASSED;
|
||||
|
||||
done:
|
||||
SetPowerUpSelfTestInProgressOnThisThread(false);
|
||||
return;
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#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 (Output(-1, NULL, 0, messageEnd, blocking)) \
|
||||
return 1; \
|
||||
FILTER_END_NO_MESSAGE_END
|
||||
|
||||
#define FILTER_OUTPUT2(site, statement, output, length, messageEnd) \
|
||||
{\
|
||||
case site: \
|
||||
statement; \
|
||||
if (Output(site, output, length, messageEnd, blocking)) \
|
||||
return STDMAX(1U, (unsigned int)length-m_inputPosition);\
|
||||
}
|
||||
|
||||
#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)
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// 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
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
#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
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
// 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);
|
||||
}
|
||||
|
||||
#ifdef FAST_ROTATE
|
||||
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
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
#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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue