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

📄 crypt.tex

📁 NIST推荐的素域上的椭圆曲线
💻 TEX
📖 第 1 页 / 共 5 页
字号:
      printf("Error registering Rijndael\n");      return -1;   }   /* use Rijndael */   /* remove it */   if ((errno = unregister_cipher(&rijndael_desc)) != CRYPT_OK) {      printf("Error removing Rijndael: %s\n", error_to_string(errno));      return -1;   }   return 0;}\end{verbatim}\end{small}This snippet is a small program that registers only Rijndael only.  Note you must register ciphers beforeusing the PK code since all of the PK code (RSA, DH and ECC) rely heavily on the descriptor tables.\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}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}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}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}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}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):\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:\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.  Allfour of the functions return {\bf CRYPT\_OK} on success.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.  When you are done working with either mode you should wipe the memory (using ``zeromem()'') to help prevent the key from leaking.  For example:\newpage\begin{small}\begin{verbatim}#include <mycrypt.h>int main(void){   unsigned char key[16], IV[16], buffer[512];   symmetric_CTR ctr;   int x, errno;   /* 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 ((errno = ctr_start(find_cipher("twofish"), IV, key, 16, 0, &ctr)) != CRYPT_OK) {      printf("ctr_start error: %s\n", error_to_string(errno));      return -1;   }   /* somehow fill buffer than encrypt it */   if ((errno = ctr_encrypt(buffer, buffer, sizeof(buffer), &ctr)) != CRYPT_OK) {      printf("ctr_encrypt error: %s\n", error_to_string(errno));      return -1;   }   /* make use of ciphertext... */   /* clear up and return */   zeromem(key, sizeof(key));   zeromem(&ctr, sizeof(ctr));   return 0;}\end{verbatim}\end{small}\chapter{One-Way Cryptographic Hash Functions}\section{Core Functions}Like the ciphers there are hash core functions and a universal data type to hold the hash state called ``hash\_state''.  To initialize hash XXX (where XXX is the name) call:\index{Hash Functions}\begin{verbatim}void XXX_init(hash_state *md);\end{verbatim}This simply sets up the hash to the default state governed by the specifications of the hash.  To add data to the message being hashed call:\begin{verbatim}void XXX_process(hash_state *md, const unsigned char *in, unsigned long len);\end{verbatim}Essentially all hash messages are virtually infinitely\footnote{Most hashes are limited to $2^{64}$ bits or 2,305,843,009,213,693,952 bytes.} long message which are buffered.  The data can be passed in any sized chunks as long as the order of the bytes are the same the message digest(hash output) will be the same.  For example, this means that:\begin{verbatim}md5_process(&md, "hello ", 6);md5_process(&md, "world", 5);\end{verbatim}Will produce the same message digest as the single call:\index{Message Digest}\begin{verbatim}md5_process(&md, "hello world", 11);\end{verbatim}To finally get the message digest (the hash) call:\begin{verbatim}void XXX_done(hash_state *md,               unsigned char *out);\end{verbatim}This function will finish up the hash and store the result in the ``out'' array.  You must ensure that ``out'' is longenough for the hash in question.  Often hashes are used to get keys for symmetric ciphers so the ``XXX\_done()'' functionswill wipe the ``md'' variable before returning automatically.To test a hash function call:\begin{verbatim}int XXX_test(void);\end{verbatim}This will return {\bf CRYPTO\_OK} if the hash matches the test vectors, otherwise it returns an error code.  Anexample snippet that hashes a message with md5 is given below.\begin{small}\begin{verbatim}#include <mycrypt.h>int main(void){    hash_state md;    unsigned char *in = "hello world", out[16];    /* setup the hash */    md5_init(&md);    /* add the message */    md5_process(&md, in, strlen(in));    /* get the hash */    md5_done(&md, out);    return 0;}\end{verbatim}\end{small}\section{Hash Descriptors}\index{Hash Descriptors}Like the set of ciphers the set of hashes have descriptors too.  They are stored in an array called ``hash\_descriptor'' andare defined by:\begin{verbatim}struct _hash_descriptor {    char *name;    unsigned long hashsize;    /* digest output size in bytes  */    unsigned long blocksize;   /* the block size the hash uses */    void (*init)   (hash_state *);    void (*process)(hash_state *, const unsigned char *, unsigned long);    void (*done)   (hash_state *, unsigned char *);    int  (*test)   (void);};\end{verbatim}Similarly ``name'' is the name of the hash function in ASCII (all lowercase).  ``hashsize'' is the size of the digest outputin bytes.  The remaining fields are pointers to the functions that do the respective tasks.  There is a function tosearch the array as well called ``int find\_hash(char *name)''.  It returns -1 if the hash is not found, otherwise theposition in the descriptor table of the hash.You can use the table to indirectly call a hash function that is chosen at runtime.  For example:\begin{small}\begin{verbatim}#include <mycrypt.h>int main(void){   unsigned char buffer[100], hash[MAXBLOCKSIZE];   int idx, x;   hash_state md;   /* register hashes .... */   if (register_hash(&md5_desc) == -1) {      printf("Error registering MD5.\n");      return -1;   }   /* register other hashes ... */   /* prompt for name and strip newline */   printf("Enter hash name: \n");   fgets(buffer, sizeof(buffer), stdin);   buffer[strlen(buffer) - 1] = 0;   /* get hash index */   idx = find_hash(buffer);   if (idx == -1) {      printf("Invalid hash name!\n");      return -1;   }

⌨️ 快捷键说明

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