⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crypt.tex

📁 最新版本的加密解密算法库
💻 TEX
📖 第 1 页 / 共 5 页
字号:
fact used for the purposes of encryption.  My suggestion is just to use random 8/24 byte keys instead of trying to make a 8/24byte string from the real 7/21 byte key.\itemNote that ``Twofish'' has additional configuration options that take place at build time.  These options are found inthe file ``mycrypt\_cfg.h''.  The first option is ``TWOFISH\_SMALL'' which when defined will force the Twofish codeto not pre-compute the Twofish ``$g(X)$'' function as a set of four $8 \times 32$ s-boxes.  This means that a scheduledkey will require less ram but the resulting cipher will be slower.  The second option is ``TWOFISH\_TABLES'' which whendefined will force the Twofish code to use pre-computed tables for the two s-boxes $q_0, q_1$ as well as the multiplicationby the polynomials 5B and EF used in the MDS multiplication.  As a result the code is faster and slightly larger.  Thespeed increase is useful when ``TWOFISH\_SMALL'' is defined since the s-boxes and MDS multiply form the heart of theTwofish round function.\index{Twofish build options}\begin{small}\begin{center}\begin{tabular}{|l|l|l|}\hline TWOFISH\_SMALL & TWOFISH\_TABLES & Speed and Memory (per key) \\\hline undefined & undefined & Very fast, 4.2KB of ram. \\\hline undefined & defined & As above, faster keysetup, larger code (1KB more). \\\hline defined & undefined & Very slow, 0.2KB of ram. \\\hline defined & defined & Somewhat faster, 0.2KB of ram, larger code. \\\hline\end{tabular}\end{center}\end{small}\end{enumerate}\end{small}To work with the cipher\_descriptor array there is a function:\index{find\_cipher()}\begin{verbatim}int find_cipher(char *name)\end{verbatim}Which will search for a given name in the array.  It returns negative one if the cipher is not found, otherwise it returnsthe location in the array where the cipher was found.  For example, to indirectly setup Blowfish you can also use:\begin{small}\begin{verbatim}#include <mycrypt.h>int main(void){   unsigned char key[8];   symmetric_key skey;   int err;   /* you must register a cipher before you use it */   if (register_cipher(&blowfish_desc)) == -1) {      printf("Unable to register Blowfish cipher.");      return -1;   }   /* generic call to function (assuming the key in key[] was already setup) */   if ((err = cipher_descriptor[find_cipher("blowfish")].setup(key, 8, 0, &skey)) != CRYPT_OK) {      printf("Error setting up Blowfish: %s\n", error_to_string(err));      return -1;   }   /* ... use cipher ... */}\end{verbatim}\end{small}A good safety would be to check the return value of ``find\_cipher()'' before accessing the desired function.  In orderto use a cipher with the descriptor table you must register it first using:\index{register\_cipher()}\begin{verbatim}int register_cipher(const struct _cipher_descriptor *cipher);\end{verbatim}Which accepts a pointer to a descriptor and returns the index into the global descriptor table.  If an error occurs suchas there is no more room (it can have 32 ciphers at most) it will return {\bf{-1}}.  If you try to add the same cipher morethan once it will just return the index of the first copy.  To remove a cipher call:\index{unregister\_cipher()}\begin{verbatim}int unregister_cipher(const struct _cipher_descriptor *cipher);\end{verbatim}Which returns {\bf CRYPT\_OK} if it removes it otherwise it returns {\bf CRYPT\_ERROR}.  Consider:\begin{small}\begin{verbatim}#include <mycrypt.h>int main(void){   int err;      /* register the cipher */   if (register_cipher(&rijndael_desc) == -1) {      printf("Error registering Rijndael\n");      return -1;   }   /* use Rijndael */   /* remove it */   if ((err = unregister_cipher(&rijndael_desc)) != CRYPT_OK) {      printf("Error removing Rijndael: %s\n", error_to_string(err));      return -1;   }   return 0;}\end{verbatim}\end{small}This snippet is a small program that registers only Rijndael only.  \section{Symmetric Modes of Operations}\subsection{Background}A typical symmetric block cipher can be used in chaining modes to effectively encrypt messages larger than the blocksize of the cipher.  Given a key $k$, a plaintext $P$ and a cipher $E$ we shall denote the encryption of the block$P$ under the key $k$ as $E_k(P)$.  In some modes there exists an initial vector denoted as $C_{-1}$.\subsubsection{ECB Mode}\index{ECB mode}ECB or Electronic Codebook Mode is the simplest method to use.  It is given as:\begin{equation}C_i = E_k(P_i)\end{equation}This mode is very weak since it allows people to swap blocks and perform replay attacks if the same key is used morethan once.\subsubsection{CBC Mode}\index{CBC mode}CBC or Cipher Block Chaining mode is a simple mode designed to prevent trivial forms of replay and swap attacks on ciphers.It is given as:\begin{equation}C_i = E_k(P_i \oplus C_{i - 1})\end{equation}It is important that the initial vector be unique and preferably random for each message encrypted under the same key.\subsubsection{CTR Mode}\index{CTR mode}CTR or Counter Mode is a mode which only uses the encryption function of the cipher.  Given a initial vector which istreated as a large binary counter the CTR mode is given as:\begin{eqnarray}C_{-1} = C_{-1} + 1\mbox{ }(\mbox{mod }2^W) \nonumber \\C_i = P_i \oplus E_k(C_{-1})\end{eqnarray}Where $W$ is the size of a block in bits (e.g. 64 for Blowfish).  As long as the initial vector is random for each messageencrypted under the same key replay and swap attacks are infeasible.  CTR mode may look simple but it is as secureas the block cipher is under a chosen plaintext attack (provided the initial vector is unique).\subsubsection{CFB Mode}\index{CFB mode}CFB or Ciphertext Feedback Mode is a mode akin to CBC.  It is given as:\begin{eqnarray}C_i = P_i \oplus C_{-1} \nonumber \\C_{-1} = E_k(C_i)\end{eqnarray}Note that in this library the output feedback width is equal to the size of the block cipher.  That is this mode is usedto encrypt whole blocks at a time.  However, the library will buffer data allowing the user to encrypt or decrypt partialblocks without a delay.  When this mode is first setup it will initially encrypt the initial vector as required.\subsubsection{OFB Mode}\index{OFB mode}OFB or Output Feedback Mode is a mode akin to CBC as well.  It is given as:\begin{eqnarray}C_{-1} = E_k(C_{-1}) \nonumber \\C_i = P_i \oplus C_{-1}\end{eqnarray}Like the CFB mode the output width in CFB mode is the same as the width of the block cipher.  OFB mode will alsobuffer the output which will allow you to encrypt or decrypt partial blocks without delay.\subsection{Choice of Mode}My personal preference is for the CTR mode since it has several key benefits:\begin{enumerate}   \item No short cycles which is possible in the OFB and CFB modes.   \item Provably as secure as the block cipher being used under a chosen plaintext attack.   \item Technically does not require the decryption routine of the cipher.   \item Allows random access to the plaintext.   \item Allows the encryption of block sizes that are not equal to the size of the block cipher.\end{enumerate}The CTR, CFB and OFB routines provided allow you to encrypt block sizes that differ from the ciphers block size.  They accomplish this by buffering the data required to complete a block.  This allows you to encrypt or decrypt any size block of memory with either of the three modes.The ECB and CBC modes process blocks of the same size as the cipher at a time.  Therefore they are less flexible than theother modes.\subsection{Implementation}\index{CBC Mode} \index{CTR Mode}\index{OFB Mode} \index{CFB Mode}The library provides simple support routines for handling CBC, CTR, CFB, OFB and ECB encoded messages.  Assuming the mode you want is XXX there is a structure called ``symmetric\_XXX'' that will contain the information required touse that mode.  They have identical setup routines (except ECB mode for obvious reasons):\index{ecb\_start()} \index{cfb\_start()} \index{cbc\_start()} \index{ofb\_start()} \index{ctr\_start()}\begin{verbatim}int XXX_start(int cipher, const unsigned char *IV,               const unsigned char *key, int keylen,               int num_rounds, symmetric_XXX *XXX);int ecb_start(int cipher, const unsigned char *key, int keylen,               int num_rounds, symmetric_ECB *ecb);\end{verbatim}In each case ``cipher'' is the index into the cipher\_descriptor array of the cipher you want to use.  The ``IV'' value is the initialization vector to be used with the cipher.  You must fill the IV yourself and it is assumed they are the same length as the block size\footnote{In otherwords the size of a block of plaintext for the cipher, e.g. 8 for DES, 16 for AES, etc.} of the cipher you choose.  It is important that the IV  be random for each unique message you want to encrypt.  The parameters ``key'', ``keylen'' and ``num\_rounds'' are the same as in the XXX\_setup() function call.  The final parameter is a pointer to the structure you want to hold the information for the mode of operation.Both routines return {\bf CRYPT\_OK} if the cipher initialized correctly, otherwise they return an error code.  To actually encrypt or decrypt the following routines are provided:\index{ecb\_encrypt()} \index{ecb\_decrypt()} \index{cfb\_encrypt()} \index{cfb\_decrypt()} \index{cbc\_encrypt()} \index{cbc\_decrypt()} \index{ofb\_encrypt()} \index{ofb\_decrypt()} \index{ctr\_encrypt()} \index{ctr\_decrypt()}\begin{verbatim}int XXX_encrypt(const unsigned char *pt, unsigned char *ct,                 symmetric_XXX *XXX);int XXX_decrypt(const unsigned char *ct, unsigned char *pt,                symmetric_XXX *XXX);int YYY_encrypt(const unsigned char *pt, unsigned char *ct,                 unsigned long len, symmetric_YYY *YYY);int YYY_decrypt(const unsigned char *ct, unsigned char *pt,                 unsigned long len, symmetric_YYY *YYY);\end{verbatim}Where ``XXX'' is one of (ecb, cbc) and ``YYY'' is one of (ctr, ofb, cfb).  In the CTR, OFB and CFB cases ``len'' is thesize of the buffer (as number of chars) to encrypt or decrypt.  The CTR, OFB and CFB modes are order sensitive but notchunk sensitive.  That is you can encrypt ``ABCDEF'' in three calls like ``AB'', ``CD'', ``EF'' or two like ``ABCDE'' and ``F''and end up with the same ciphertext.  However, encrypting ``ABC'' and ``DABC'' will result in different ciphertexts.  Allfive of the modes will return {\bf CRYPT\_OK} on success from the encrypt or decrypt functions.To decrypt in either mode you simply perform the setup like before (recall you have to fetch the IV value you used)and use the decrypt routine on all of the blocks.To change or read the IV of a previously initialized chaining mode use the following two functions.\index{cbc\_setiv()} \index{cbc\_getiv()} \index{ofb\_setiv()} \index{ofb\_getiv()} \index{cfb\_setiv()} \index{cfb\_getiv()}\index{ctr\_setiv()} \index{ctr\_getiv()}\begin{verbatim}int XXX_getiv(unsigned char *IV, unsigned long *len, symmetric_XXX *XXX);int XXX_setiv(const unsigned char *IV, unsigned long len, symmetric_XXX *XXX);\end{verbatim}The XXX\_getiv function will read the IV out of the chaining mode and store it into ``IV'' along with the length of the IV stored in ``len''.  The XXX\_setiv will initialize the chaining mode state as if the original IV were the new IV specified.  The lengthof the IV passed in must be the size of the ciphers block size.The XXX\_setiv functions are handy if you wish to change the IV without re--keying the cipher.  \newpage\begin{small}\begin{verbatim}#include <mycrypt.h>int main(void){   unsigned char key[16], IV[16], buffer[512];   symmetric_CTR ctr;   int x, err;   /* register twofish first */   if (register_cipher(&twofish_desc) == -1) {      printf("Error registering cipher.\n");      return -1;   }   /* somehow fill out key and IV */   /* start up CTR mode */   if ((err = ctr_start(find_cipher("twofish"), /* index of desired cipher */                                            IV, /* the initial vector */                                           key, /* the secret key */                                            16, /* length of secret key (16 bytes, 128 bits) */                                             0, /* 0 == default # of rounds */                                         &ctr)  /* where to store initialized CTR state */      ) != CRYPT_OK) {      printf("ctr_start error: %s\n", error_to_string(err));      return -1;   }   /* somehow fill buffer than encrypt it */   if ((err = ctr_encrypt(        buffer, /* plaintext */                                  buffer, /* ciphertext */                          sizeof(buffer), /* length of data to encrypt */                                   &ctr)  /* previously initialized CTR state */      ) != CRYPT_OK) {      printf("ctr_encrypt error: %s\n", error_to_string(err));      return -1;   }   /* make use of ciphertext... */   /* now we want to decrypt so let's use ctr_setiv */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -