Browse Source

added libtomcrypt-0.77

Tom St Denis 22 years ago
parent
commit
5581d44fd4
24 changed files with 360 additions and 1140 deletions
  1. 5 7
      aes.c
  2. 17 196
      blowfish.c
  3. 24 0
      changes
  4. BIN
      crypt.pdf
  5. 30 17
      crypt.tex
  6. 19 24
      demos/test.c
  7. 11 13
      dh.c
  8. 10 0
      dh_sys.c
  9. 11 3
      ecc.c
  10. 13 3
      ecc_sys.c
  11. 7 9
      keyring.c
  12. 1 6
      makefile
  13. 3 3
      mpi-config.h
  14. 2 2
      mycrypt.h
  15. 0 1
      mycrypt_cfg.h
  16. 1 1
      mycrypt_cipher.h
  17. 46 0
      notes/tech0003.txt
  18. 105 815
      prime.c
  19. 3 3
      rsa.c
  20. 2 1
      sha256.c
  21. 2 1
      sha512.c
  22. 0 2
      tiger.c
  23. 5 17
      twofish.c
  24. 43 16
      xtea.c

+ 5 - 7
aes.c

@@ -220,11 +220,10 @@ void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
     b0[2] ^= skey->rijndael.eK[2]; b0[3] ^= skey->rijndael.eK[3];
     b0[2] ^= skey->rijndael.eK[2]; b0[3] ^= skey->rijndael.eK[3];
     kp = skey->rijndael.eK + 4;
     kp = skey->rijndael.eK + 4;
 
 
-    if(skey->rijndael.k_len > 6) {
+    if (skey->rijndael.k_len > 6) {
         f_nround(b1, b0, kp); f_nround(b0, b1, kp);
         f_nround(b1, b0, kp); f_nround(b0, b1, kp);
-    }
-
-    if(skey->rijndael.k_len > 4) {
+        f_nround(b1, b0, kp); f_nround(b0, b1, kp);
+    } else if (skey->rijndael.k_len > 4) {
         f_nround(b1, b0, kp); f_nround(b0, b1, kp);
         f_nround(b1, b0, kp); f_nround(b0, b1, kp);
     }
     }
 
 
@@ -294,9 +293,8 @@ void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
 
 
     if(skey->rijndael.k_len > 6) {
     if(skey->rijndael.k_len > 6) {
         i_nround(b1, b0, kp); i_nround(b0, b1, kp);
         i_nround(b1, b0, kp); i_nround(b0, b1, kp);
-    }
-
-    if(skey->rijndael.k_len > 4) {
+        i_nround(b1, b0, kp); i_nround(b0, b1, kp);
+    } else if(skey->rijndael.k_len > 4) {
         i_nround(b1, b0, kp); i_nround(b0, b1, kp);
         i_nround(b1, b0, kp); i_nround(b0, b1, kp);
     }
     }
 
 

+ 17 - 196
blowfish.c

@@ -281,14 +281,6 @@ static const unsigned long ORIG_S[4][256] = {
         0xB74E6132UL, 0xCE77E25BUL, 0x578FDFE3UL, 0x3AC372E6UL  }
         0xB74E6132UL, 0xCE77E25BUL, 0x578FDFE3UL, 0x3AC372E6UL  }
 };
 };
 
 
-static unsigned long F(unsigned long x, symmetric_key *key)
-{
-   return (((key->blowfish.S[0][(x>>24)&255] +
-            key->blowfish.S[1][(x>>16)&255]) ^
-            key->blowfish.S[2][(x>>8)&255]) +
-            key->blowfish.S[3][(x>>0)&255]);
-}
-
 int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,
 int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,
                    symmetric_key *skey)
                    symmetric_key *skey)
 {
 {
@@ -352,6 +344,8 @@ int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,
    return CRYPT_OK;
    return CRYPT_OK;
 }
 }
 
 
+#define F(x) ((((key->blowfish.S[0][((x)>>24)&255] + key->blowfish.S[1][((x)>>16)&255]) ^ key->blowfish.S[2][((x)>>8)&255]) + key->blowfish.S[3][((x)>>0)&255]))
+
 #ifdef CLEAN_STACK
 #ifdef CLEAN_STACK
 static void _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
 static void _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
 #else
 #else
@@ -359,6 +353,7 @@ void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
 #endif
 #endif
 {
 {
    unsigned long L, R;
    unsigned long L, R;
+   int r;
 
 
    _ARGCHK(pt != NULL);
    _ARGCHK(pt != NULL);
    _ARGCHK(ct != NULL);
    _ARGCHK(ct != NULL);
@@ -369,22 +364,12 @@ void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
    LOAD32H(R, &pt[4]);
    LOAD32H(R, &pt[4]);
 
 
    /* do 16 rounds */
    /* do 16 rounds */
-   L ^= key->blowfish.K[0];  R ^= F(L, key);
-   R ^= key->blowfish.K[1];  L ^= F(R, key);
-   L ^= key->blowfish.K[2];  R ^= F(L, key);
-   R ^= key->blowfish.K[3];  L ^= F(R, key);
-   L ^= key->blowfish.K[4];  R ^= F(L, key);
-   R ^= key->blowfish.K[5];  L ^= F(R, key);
-   L ^= key->blowfish.K[6];  R ^= F(L, key);
-   R ^= key->blowfish.K[7];  L ^= F(R, key);
-   L ^= key->blowfish.K[8];  R ^= F(L, key);
-   R ^= key->blowfish.K[9];  L ^= F(R, key);
-   L ^= key->blowfish.K[10]; R ^= F(L, key);
-   R ^= key->blowfish.K[11]; L ^= F(R, key);
-   L ^= key->blowfish.K[12]; R ^= F(L, key);
-   R ^= key->blowfish.K[13]; L ^= F(R, key);
-   L ^= key->blowfish.K[14]; R ^= F(L, key);
-   R ^= key->blowfish.K[15]; L ^= F(R, key);
+   for (r = 0; r < 16; ) {
+      L ^= key->blowfish.K[r++];  R ^= F(L);
+      R ^= key->blowfish.K[r++];  L ^= F(R);
+      L ^= key->blowfish.K[r++];  R ^= F(L);
+      R ^= key->blowfish.K[r++];  L ^= F(R);
+   }
 
 
    /* last keying */
    /* last keying */
    R ^= key->blowfish.K[17];
    R ^= key->blowfish.K[17];
@@ -410,7 +395,8 @@ void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
 #endif
 #endif
 {
 {
    unsigned long L, R;
    unsigned long L, R;
-
+   int r;
+   
    _ARGCHK(pt != NULL);
    _ARGCHK(pt != NULL);
    _ARGCHK(ct != NULL);
    _ARGCHK(ct != NULL);
    _ARGCHK(key != NULL);
    _ARGCHK(key != NULL);
@@ -424,22 +410,12 @@ void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
    L ^= key->blowfish.K[16];
    L ^= key->blowfish.K[16];
 
 
    /* do 16 rounds */
    /* do 16 rounds */
-   L ^= F(R, key); R ^= key->blowfish.K[15];
-   R ^= F(L, key); L ^= key->blowfish.K[14];
-   L ^= F(R, key); R ^= key->blowfish.K[13];
-   R ^= F(L, key); L ^= key->blowfish.K[12];
-   L ^= F(R, key); R ^= key->blowfish.K[11];
-   R ^= F(L, key); L ^= key->blowfish.K[10];
-   L ^= F(R, key); R ^= key->blowfish.K[9];
-   R ^= F(L, key); L ^= key->blowfish.K[8];
-   L ^= F(R, key); R ^= key->blowfish.K[7];
-   R ^= F(L, key); L ^= key->blowfish.K[6];
-   L ^= F(R, key); R ^= key->blowfish.K[5];
-   R ^= F(L, key); L ^= key->blowfish.K[4];
-   L ^= F(R, key); R ^= key->blowfish.K[3];
-   R ^= F(L, key); L ^= key->blowfish.K[2];
-   L ^= F(R, key); R ^= key->blowfish.K[1];
-   R ^= F(L, key); L ^= key->blowfish.K[0];
+   for (r = 15; r > 0; ) {
+      L ^= F(R); R ^= key->blowfish.K[r--];
+      R ^= F(L); L ^= key->blowfish.K[r--];
+      L ^= F(R); R ^= key->blowfish.K[r--];
+      R ^= F(L); L ^= key->blowfish.K[r--];
+   }
 
 
    /* store */
    /* store */
    STORE32H(L, &pt[0]);
    STORE32H(L, &pt[0]);
@@ -476,161 +452,6 @@ int blowfish_test(void)
            { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
            { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
            { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
            { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
            { 0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2}
            { 0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2}
-       },
-       {
-           { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
-           { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
-           { 0x24, 0x66, 0xDD, 0x87, 0x8B, 0x96, 0x3C, 0x9D}
-       },
-       {
-           { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
-           { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
-           { 0x61, 0xF9, 0xC3, 0x80, 0x22, 0x81, 0xB0, 0x96}
-       },
-       {
-           { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
-           { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
-           { 0x7D, 0x0C, 0xC6, 0x30, 0xAF, 0xDA, 0x1E, 0xC7}
-       },
-       {
-           { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-           { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-           { 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78}
-       },
-       {
-           { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10},
-           { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
-           { 0x0A, 0xCE, 0xAB, 0x0F, 0xC6, 0xA0, 0xA2, 0x8D}
-       },
-       {
-           { 0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57},
-           { 0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42},
-           { 0x59, 0xC6, 0x82, 0x45, 0xEB, 0x05, 0x28, 0x2B}
-       },
-       {
-           { 0x01, 0x31, 0xD9, 0x61, 0x9D, 0xC1, 0x37, 0x6E},
-           { 0x5C, 0xD5, 0x4C, 0xA8, 0x3D, 0xEF, 0x57, 0xDA},
-           { 0xB1, 0xB8, 0xCC, 0x0B, 0x25, 0x0F, 0x09, 0xA0}
-       },
-       {
-           { 0x07, 0xA1, 0x13, 0x3E, 0x4A, 0x0B, 0x26, 0x86},
-           { 0x02, 0x48, 0xD4, 0x38, 0x06, 0xF6, 0x71, 0x72},
-           { 0x17, 0x30, 0xE5, 0x77, 0x8B, 0xEA, 0x1D, 0xA4}
-       },
-       {
-           { 0x38, 0x49, 0x67, 0x4C, 0x26, 0x02, 0x31, 0x9E},
-           { 0x51, 0x45, 0x4B, 0x58, 0x2D, 0xDF, 0x44, 0x0A},
-           { 0xA2, 0x5E, 0x78, 0x56, 0xCF, 0x26, 0x51, 0xEB}
-       },
-       {
-           { 0x04, 0xB9, 0x15, 0xBA, 0x43, 0xFE, 0xB5, 0xB6},
-           { 0x42, 0xFD, 0x44, 0x30, 0x59, 0x57, 0x7F, 0xA2},
-           { 0x35, 0x38, 0x82, 0xB1, 0x09, 0xCE, 0x8F, 0x1A}
-       },
-       {
-           { 0x01, 0x13, 0xB9, 0x70, 0xFD, 0x34, 0xF2, 0xCE},
-           { 0x05, 0x9B, 0x5E, 0x08, 0x51, 0xCF, 0x14, 0x3A},
-           { 0x48, 0xF4, 0xD0, 0x88, 0x4C, 0x37, 0x99, 0x18}
-       },
-       {
-           { 0x01, 0x70, 0xF1, 0x75, 0x46, 0x8F, 0xB5, 0xE6},
-           { 0x07, 0x56, 0xD8, 0xE0, 0x77, 0x47, 0x61, 0xD2},
-           { 0x43, 0x21, 0x93, 0xB7, 0x89, 0x51, 0xFC, 0x98}
-       },
-       {
-           { 0x43, 0x29, 0x7F, 0xAD, 0x38, 0xE3, 0x73, 0xFE},
-           { 0x76, 0x25, 0x14, 0xB8, 0x29, 0xBF, 0x48, 0x6A},
-           { 0x13, 0xF0, 0x41, 0x54, 0xD6, 0x9D, 0x1A, 0xE5}
-       },
-       {
-           { 0x07, 0xA7, 0x13, 0x70, 0x45, 0xDA, 0x2A, 0x16},
-           { 0x3B, 0xDD, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02},
-           { 0x2E, 0xED, 0xDA, 0x93, 0xFF, 0xD3, 0x9C, 0x79}
-       },
-       {
-           { 0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F},
-           { 0x26, 0x95, 0x5F, 0x68, 0x35, 0xAF, 0x60, 0x9A},
-           { 0xD8, 0x87, 0xE0, 0x39, 0x3C, 0x2D, 0xA6, 0xE3}
-       },
-       {
-           { 0x37, 0xD0, 0x6B, 0xB5, 0x16, 0xCB, 0x75, 0x46},
-           { 0x16, 0x4D, 0x5E, 0x40, 0x4F, 0x27, 0x52, 0x32},
-           { 0x5F, 0x99, 0xD0, 0x4F, 0x5B, 0x16, 0x39, 0x69}
-       },
-       {
-           { 0x1F, 0x08, 0x26, 0x0D, 0x1A, 0xC2, 0x46, 0x5E},
-           { 0x6B, 0x05, 0x6E, 0x18, 0x75, 0x9F, 0x5C, 0xCA},
-           { 0x4A, 0x05, 0x7A, 0x3B, 0x24, 0xD3, 0x97, 0x7B}
-       },
-       {
-           { 0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76},
-           { 0x00, 0x4B, 0xD6, 0xEF, 0x09, 0x17, 0x60, 0x62},
-           { 0x45, 0x20, 0x31, 0xC1, 0xE4, 0xFA, 0xDA, 0x8E}
-       },
-       {
-           { 0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xB0, 0x07},
-           { 0x48, 0x0D, 0x39, 0x00, 0x6E, 0xE7, 0x62, 0xF2},
-           { 0x75, 0x55, 0xAE, 0x39, 0xF5, 0x9B, 0x87, 0xBD}
-       },
-       {
-           { 0x49, 0x79, 0x3E, 0xBC, 0x79, 0xB3, 0x25, 0x8F},
-           { 0x43, 0x75, 0x40, 0xC8, 0x69, 0x8F, 0x3C, 0xFA},
-           { 0x53, 0xC5, 0x5F, 0x9C, 0xB4, 0x9F, 0xC0, 0x19}
-       },
-       {
-           { 0x4F, 0xB0, 0x5E, 0x15, 0x15, 0xAB, 0x73, 0xA7},
-           { 0x07, 0x2D, 0x43, 0xA0, 0x77, 0x07, 0x52, 0x92},
-           { 0x7A, 0x8E, 0x7B, 0xFA, 0x93, 0x7E, 0x89, 0xA3}
-       },
-       {
-           { 0x49, 0xE9, 0x5D, 0x6D, 0x4C, 0xA2, 0x29, 0xBF},
-           { 0x02, 0xFE, 0x55, 0x77, 0x81, 0x17, 0xF1, 0x2A},
-           { 0xCF, 0x9C, 0x5D, 0x7A, 0x49, 0x86, 0xAD, 0xB5}
-       },
-       {
-           { 0x01, 0x83, 0x10, 0xDC, 0x40, 0x9B, 0x26, 0xD6},
-           { 0x1D, 0x9D, 0x5C, 0x50, 0x18, 0xF7, 0x28, 0xC2},
-           { 0xD1, 0xAB, 0xB2, 0x90, 0x65, 0x8B, 0xC7, 0x78}
-       },
-       {
-           { 0x1C, 0x58, 0x7F, 0x1C, 0x13, 0x92, 0x4F, 0xEF},
-           { 0x30, 0x55, 0x32, 0x28, 0x6D, 0x6F, 0x29, 0x5A},
-           { 0x55, 0xCB, 0x37, 0x74, 0xD1, 0x3E, 0xF2, 0x01}
-       },
-       {
-           { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
-           { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
-           { 0xFA, 0x34, 0xEC, 0x48, 0x47, 0xB2, 0x68, 0xB2}
-       },
-       {
-           { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E},
-           { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
-           { 0xA7, 0x90, 0x79, 0x51, 0x08, 0xEA, 0x3C, 0xAE}
-       },
-       {
-           { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE},
-           { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
-           { 0xC3, 0x9E, 0x07, 0x2D, 0x9F, 0xAC, 0x63, 0x1D}
-       },
-       {
-           { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-           { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
-           { 0x01, 0x49, 0x33, 0xE0, 0xCD, 0xAF, 0xF6, 0xE4}
-       },
-       {
-           { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
-           { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-           { 0xF2, 0x1E, 0x9A, 0x77, 0xB7, 0x1C, 0x49, 0xBC}
-       },
-       {
-           { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
-           { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-           { 0x24, 0x59, 0x46, 0x88, 0x57, 0x54, 0x36, 0x9A}
-       },
-       {
-           { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10},
-           { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
-           { 0x6B, 0x5C, 0x5A, 0x9C, 0x5D, 0x9E, 0x0A, 0x5A}
        }
        }
    };
    };
    unsigned char buf[2][8];
    unsigned char buf[2][8];

+ 24 - 0
changes

@@ -1,3 +1,27 @@
+Nov 26th, 2002
+v0.77  -- Updated the XTEA code to use pre-computed keys.  With optimizations for speed it achieves 222Mbit/sec
+          compared to the 121Mbit/sec before.  It is 288 bytes bigger than before.
+       -- Cleaned up some of the ciphers and hashes (coding style, cosmetic changes)
+       -- Optimized AES slightly for 256-bit keys [only one if statement now, still two for 192-bit keys]
+       -- Removed most test cases from Blowfish, left three of them there.  Makes it smaller and faster to test.
+       -- Changed the primality routines around.  I now use 8 rounds of Rabin-Miller, I use 256 primes in the sieve
+          step and the "rand_prime" function uses a modified sieve that avoids alot of un-needed bignum work.
+       -- Fixed a bug in the ECC/DH signatures where the keys "setting" value was not checked for validity.  This means
+          that a invalid value could have caused segfaults, etc...
+       -- **NOTE** Changed the way the ECC/DH export/import functions work.  They are source but not binary compatible
+          with v0.76.  Essentially insteading of exporting the setting index like before I export the key size.  Now
+          if you ever re-configure which key settings are supported the lib will still be able to make use of your 
+          keys.
+       -- Optimized Blowfish by inlining the round function, unrolling it for four rounds then using a for loop for the 
+          rest.  It achieves a rate of 425Mbit/sec with the new code compared to 314Mbit/sec before.  The new blowfish 
+          object file is 7,813 bytes compared to 8,663 before and is 850 bytes smaller.  So the code is both smaller and 
+          faster!
+       -- Optimized Twofish as well by inlining the round function.  Gets ~400Mbit/sec compared to 280Mbit/sec before
+          and the code is only 78 bytes larger than the previous copy.
+       -- Removed SMALL_PRIME_TAB build option.  I use the smaller table always.
+       -- Fixed some mistakes concerning prime generation in the manual.
+       -- [Note: sizes/speeds are for GCC 3.2 on an x86 Athlon XP @ 1.53Ghz]
+
 Nov 25th, 2002
 Nov 25th, 2002
 v0.76  -- Updated makefiles a bit more, use "-Os" instead of "-O2" to optimize for size.  Got the lib
 v0.76  -- Updated makefiles a bit more, use "-Os" instead of "-O2" to optimize for size.  Got the lib
           downto 265KB using GCC 3.2 on my x86 box.
           downto 265KB using GCC 3.2 on my x86 box.

BIN
crypt.pdf


+ 30 - 17
crypt.tex

@@ -44,7 +44,7 @@
 \def\gap{\vspace{0.5ex}}
 \def\gap{\vspace{0.5ex}}
 \makeindex
 \makeindex
 \begin{document}
 \begin{document}
-\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.76}
+\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.77}
 \author{Tom St Denis \\
 \author{Tom St Denis \\
 Algonquin College \\
 Algonquin College \\
 \\
 \\
@@ -1453,10 +1453,10 @@ Note that if the key fails to ``rsa\_import()'' you do not have to free the memo
 
 
 \section{Remarks}
 \section{Remarks}
 It is important that you match your RSA key size with the function you are performing.  The internal padding for both
 It is important that you match your RSA key size with the function you are performing.  The internal padding for both
-signatures and encryption triple the size of the plaintext you send to rsa\_exptmod().  This means to encrypt or sign
-a message of N bytes with rsa\_exptmod() you must have a modulus of 1+3N bytes.  Note that this doesn't affect the length
-of the plaintext you pass into functions like rsa\_encrypt().  This restriction applies only to data that is passed through
-RSA directly.
+signatures and encryption triple the size of the plaintext.  This means to encrypt or sign
+a message of N bytes you must have a modulus of 1+3N bytes.  Note that this doesn't affect the length of the plaintext 
+you pass into functions like rsa\_encrypt().  This restriction applies only to data that is passed through the
+internal RSA routines directly directly.
 
 
 The following table gives the size requirements for various hashes.
 The following table gives the size requirements for various hashes.
 \begin{center}
 \begin{center}
@@ -1517,19 +1517,16 @@ make a Diffie-Hellman private key pair:
 int dh_make_key(prng_state *prng, int wprng, 
 int dh_make_key(prng_state *prng, int wprng, 
                 int keysize, dh_key *key);
                 int keysize, dh_key *key);
 \end{verbatim}
 \end{verbatim}
-The ``keysize'' is the size of the modulus you want in bytes.  Currently support sizes are 64 to 512 bytes which correspond 
-to key sizes of 512 to 4096 bits. The smaller the key the faster it is to use however it will be less secure.  When 
+The ``keysize'' is the size of the modulus you want in bytes.  Currently support sizes are 96 to 512 bytes which correspond 
+to key sizes of 768 to 4096 bits. The smaller the key the faster it is to use however it will be less secure.  When 
 specifying a size not explicitly supported by the library it will round {\em up} to the next key size.  If the size is 
 specifying a size not explicitly supported by the library it will round {\em up} to the next key size.  If the size is 
-above 512 it will return an error.  So if you pass ``keysize == 32'' it will use a 512 bit key but if you pass 
+above 512 it will return an error.  So if you pass ``keysize == 32'' it will use a 768 bit key but if you pass 
 ``keysize == 20000'' it will return an error.  The primes and generators used are built-into the library and were designed 
 ``keysize == 20000'' it will return an error.  The primes and generators used are built-into the library and were designed 
 to meet very specific goals.  The primes are strong primes which means that if $p$ is the prime then
 to meet very specific goals.  The primes are strong primes which means that if $p$ is the prime then
 $p-1$ is equal to $2r$ where $r$ is a large prime.  The bases are chosen to generate a group of order $r$ to prevent
 $p-1$ is equal to $2r$ where $r$ is a large prime.  The bases are chosen to generate a group of order $r$ to prevent
 leaking a bit of the key.  This means the bases generate a very large prime order group which is good to make cryptanalysis
 leaking a bit of the key.  This means the bases generate a very large prime order group which is good to make cryptanalysis
 hard.
 hard.
 
 
-As for Diffie-Hellman key sizes its recommended that you use at least a 768-bit key.  Since a 512-bit key has never been broken (its much
-harder than 512-bit RSA to attack) a 512-bit key setting is supported.  You can use it if you want I just suggest you don't.
-
 The next two routines are for exporting/importing Diffie-Hellman keys in a binary format.  This is useful for transport
 The next two routines are for exporting/importing Diffie-Hellman keys in a binary format.  This is useful for transport
 over communication mediums.  
 over communication mediums.  
 
 
@@ -1875,6 +1872,15 @@ int ecc_verify_hash(const unsigned char *sig, const unsigned char *hash,
                           ecc_key *key);
                           ecc_key *key);
 \end{verbatim}
 \end{verbatim}
 
 
+\section{ECC Keysizes}
+With ECC if you try and sign a hash that is bigger than your ECC key you can run into problems.  The math will still work
+and in effect the signature will still work.  With ECC keys the strength of the signature is limited by the size of
+the hash or the size of they key, whichever is smaller.  For example, if you sign with SHA256 and a ECC-160 key in effect
+you have 160-bits of security (e.g. as if you signed with SHA-1).  
+
+The library will not warn you if you make this mistake so it is important to check yourself before using the 
+signatures.
+
 \chapter{Public Keyrings}
 \chapter{Public Keyrings}
 \section{Introduction}
 \section{Introduction}
 In order to simplify the usage of the public key algorithms a set of keyring routines have been developed.  They let the 
 In order to simplify the usage of the public key algorithms a set of keyring routines have been developed.  They let the 
@@ -2209,14 +2215,21 @@ length of the binary string.
 \subsection{Primality Testing}
 \subsection{Primality Testing}
 \index{Primality Testing}
 \index{Primality Testing}
 The library includes primality testing and random prime functions as well.  The primality tester will perform the test in
 The library includes primality testing and random prime functions as well.  The primality tester will perform the test in
-two phases.  First it will perform trial division by the first few primes.  Second it will perform sixteen rounds of the 
+two phases.  First it will perform trial division by the first few primes.  Second it will perform eight rounds of the 
 Rabin-Miller primality testing algorithm.  If the candidate passes both phases it is declared prime otherwise it is declared
 Rabin-Miller primality testing algorithm.  If the candidate passes both phases it is declared prime otherwise it is declared
 composite.  No prime number will fail the two phases but composites can.  Each round of the Rabin-Miller algorithm reduces
 composite.  No prime number will fail the two phases but composites can.  Each round of the Rabin-Miller algorithm reduces
 the probability of a pseudo-prime by $1 \over 4$ therefore after sixteen rounds the probability is no more than 
 the probability of a pseudo-prime by $1 \over 4$ therefore after sixteen rounds the probability is no more than 
-$\left ( { 1 \over 4 } \right )^{16} = 2^{-32}$.  Even if a composite did make it through it would most likely cause the 
-the algorithm trying to use it to fail.  For instance, in RSA two primes $p$ and $q$ are required.  The order of the 
-multiplicative sub-group (modulo $pq$) is given as $\phi(pq)$ or $(p - 1)(q - 1)$.  The decryption exponent $d$ is found
-as $de \equiv 1\mbox{ }(\mbox{mod } \phi(pq))$.  If either $p$ or $q$ is composite the value of $d$ will be incorrect and the user
+$\left ( { 1 \over 4 } \right )^{8} = 2^{-16}$.  In practice the probability of error is in fact much lower than that.
+
+When making random primes the trial division step is in fact an optimized implementation of ``Implementation of Fast RSA Key Generation on Smart Cards''\footnote{Chenghuai Lu, Andre L. M. dos Santos and Francisco R. Pimentel}.
+In essence a table of machine-word sized residues are kept of a candidate modulo a set of primes.  When the candiate
+is rejected and ultimately incremented to test the next number the residues are updated without using multi-word precision
+math operations.  As a result the routine can scan ahead to the next number required for testing with very little work
+involved.
+
+In the event that a composite did make it through it would most likely cause the the algorithm trying to use it to fail.  For 
+instance, in RSA two primes $p$ and $q$ are required.  The order of the multiplicative sub-group (modulo $pq$) is given 
+as $\phi(pq)$ or $(p - 1)(q - 1)$.  The decryption exponent $d$ is found as $de \equiv 1\mbox{ }(\mbox{mod } \phi(pq))$.  If either $p$ or $q$ is composite the value of $d$ will be incorrect and the user
 will not be able to sign or decrypt messages at all.  Suppose $p$ was prime and $q$ was composite this is just a variation of 
 will not be able to sign or decrypt messages at all.  Suppose $p$ was prime and $q$ was composite this is just a variation of 
 the multi-prime RSA.  Suppose $q = rs$ for two primes $r$ and $s$ then $\phi(pq) = (p - 1)(r - 1)(s - 1)$ which clearly is 
 the multi-prime RSA.  Suppose $q = rs$ for two primes $r$ and $s$ then $\phi(pq) = (p - 1)(r - 1)(s - 1)$ which clearly is 
 not equal to $(p - 1)(rs - 1)$.
 not equal to $(p - 1)(rs - 1)$.
@@ -2233,7 +2246,7 @@ a random prime call:
 \begin{verbatim}
 \begin{verbatim}
 int rand_prime(mp_int *N, unsigned long len, prng_state *prng, int wprng);
 int rand_prime(mp_int *N, unsigned long len, prng_state *prng, int wprng);
 \end{verbatim}
 \end{verbatim}
-Where ``len'' is the size of the prime in bytes ($2 \le len \le 1024$).  You can set ``len'' to the negative size you want
+Where ``len'' is the size of the prime in bytes ($2 \le len \le 256$).  You can set ``len'' to the negative size you want
 to get a prime of the form $p \equiv 3\mbox{ }(\mbox{mod } 4)$.  So if you want a 1024-bit prime of this sort pass 
 to get a prime of the form $p \equiv 3\mbox{ }(\mbox{mod } 4)$.  So if you want a 1024-bit prime of this sort pass 
 ``len = -128'' to the function.  Upon success it will return {\bf CRYPT\_OK} and ``N'' will contain an integer which
 ``len = -128'' to the function.  Upon success it will return {\bf CRYPT\_OK} and ``N'' will contain an integer which
 is very likely prime.
 is very likely prime.

+ 19 - 24
demos/test.c

@@ -691,12 +691,6 @@ void dh_tests(void)
    dh_free(&userb);
    dh_free(&userb);
 
 
 /* time stuff */
 /* time stuff */
-   t1 = XCLOCK();
-   dh_make_key(&prng, find_prng("yarrow"), 64, &usera);
-   t1 = XCLOCK() - t1;
-   printf("Make dh-512 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC));
-   dh_free(&usera);
-
    t1 = XCLOCK();
    t1 = XCLOCK();
    dh_make_key(&prng, find_prng("yarrow"), 96, &usera);
    dh_make_key(&prng, find_prng("yarrow"), 96, &usera);
    t1 = XCLOCK() - t1;
    t1 = XCLOCK() - t1;
@@ -1166,25 +1160,25 @@ void register_all_algs(void)
 #ifdef RIJNDAEL
 #ifdef RIJNDAEL
    register_cipher(&rijndael_desc);
    register_cipher(&rijndael_desc);
 #endif
 #endif
+#ifdef TWOFISH
+   register_cipher(&twofish_desc);
+#endif
 #ifdef SAFER
 #ifdef SAFER
    register_cipher(&safer_k64_desc);
    register_cipher(&safer_k64_desc);
    register_cipher(&safer_sk64_desc);
    register_cipher(&safer_sk64_desc);
    register_cipher(&safer_k128_desc);
    register_cipher(&safer_k128_desc);
    register_cipher(&safer_sk128_desc);
    register_cipher(&safer_sk128_desc);
 #endif
 #endif
-#ifdef TWOFISH
-   register_cipher(&twofish_desc);
-#endif
 #ifdef RC2
 #ifdef RC2
    register_cipher(&rc2_desc);
    register_cipher(&rc2_desc);
 #endif
 #endif
-#ifdef CAST5
-   register_cipher(&cast5_desc);
-#endif
 #ifdef DES
 #ifdef DES
    register_cipher(&des_desc);
    register_cipher(&des_desc);
    register_cipher(&des3_desc);
    register_cipher(&des3_desc);
 #endif
 #endif
+#ifdef CAST5
+   register_cipher(&cast5_desc);
+#endif
 
 
    register_cipher(&null_desc);
    register_cipher(&null_desc);
 
 
@@ -1240,9 +1234,16 @@ void kr_test_makekeys(pk_key **kr)
       exit(-1);
       exit(-1);
    }
    }
 
 
+   /* make a DH key */
+   printf("KR: Making DH key...\n");
+   if ((errno = kr_make_key(*kr, &prng, find_prng("yarrow"), DH_KEY, 128, "dhkey", "[email protected]", "dhkey one")) != CRYPT_OK) {
+      printf("Make key error: %s\n", error_to_string(errno));
+      exit(-1);
+   }
+
    /* make a ECC key */
    /* make a ECC key */
    printf("KR: Making ECC key...\n");
    printf("KR: Making ECC key...\n");
-   if ((errno = kr_make_key(*kr, &prng, find_prng("yarrow"), ECC_KEY, 24, "ecckey", "[email protected]", "ecckey one")) != CRYPT_OK) {
+   if ((errno = kr_make_key(*kr, &prng, find_prng("yarrow"), ECC_KEY, 20, "ecckey", "[email protected]", "ecckey one")) != CRYPT_OK) {
       printf("Make key error: %s\n", error_to_string(errno));
       printf("Make key error: %s\n", error_to_string(errno));
       exit(-1);
       exit(-1);
    }
    }
@@ -1254,12 +1255,6 @@ void kr_test_makekeys(pk_key **kr)
       exit(-1);
       exit(-1);
    }
    }
 
 
-   /* make a DH key */
-   printf("KR: Making DH key...\n");
-   if ((errno = kr_make_key(*kr, &prng, find_prng("yarrow"), DH_KEY, 128, "dhkey", "[email protected]", "dhkey one")) != CRYPT_OK) {
-      printf("Make key error: %s\n", error_to_string(errno));
-      exit(-1);
-   }
 }
 }
 
 
 void kr_test(void)
 void kr_test(void)
@@ -1362,7 +1357,7 @@ void kr_test(void)
 #endif
 #endif
 
 
 /* test the packet encryption/sign stuff */
 /* test the packet encryption/sign stuff */
-   for (i = 0; i < 16; i++) buf[i] = i;
+   for (i = 0; i < 32; i++) buf[i] = i;
    kr_test_makekeys(&kr);
    kr_test_makekeys(&kr);
    _kr = kr;
    _kr = kr;
    for (i = 0; i < 3; i++) {
    for (i = 0; i < 3; i++) {
@@ -1384,18 +1379,18 @@ void kr_test(void)
        printf("kr_encrypt_key passed, ");
        printf("kr_encrypt_key passed, ");
 
 
        len = sizeof(buf2);
        len = sizeof(buf2);
-       if ((errno = kr_sign_hash(kr, _kr->ID, buf, 16, buf2, &len, &prng, find_prng("yarrow"))) != CRYPT_OK) {
+       if ((errno = kr_sign_hash(kr, _kr->ID, buf, 32, buf2, &len, &prng, find_prng("yarrow"))) != CRYPT_OK) {
           printf("kr_sign_hash failed, %i, %lu\n", i, len);
           printf("kr_sign_hash failed, %i, %lu\n", i, len);
           exit(-1);
           exit(-1);
        }
        }
        printf("kr_sign_hash: ");
        printf("kr_sign_hash: ");
-       if ((errno = kr_verify_hash(kr, buf2, buf, 16, &stat)) != CRYPT_OK) {
+       if ((errno = kr_verify_hash(kr, buf2, buf, 32, &stat)) != CRYPT_OK) {
           printf("kr_sign_hash failed, %i, %lu\n", i, len);
           printf("kr_sign_hash failed, %i, %lu\n", i, len);
           exit(-1);
           exit(-1);
        }
        }
        printf("%s, ", stat?"passed":"failed");
        printf("%s, ", stat?"passed":"failed");
        buf[15] ^= 1;
        buf[15] ^= 1;
-       if ((errno = kr_verify_hash(kr, buf2, buf, 16, &stat)) != CRYPT_OK) {
+       if ((errno = kr_verify_hash(kr, buf2, buf, 32, &stat)) != CRYPT_OK) {
           printf("kr_sign_hash failed, %i, %lu\n", i, len);
           printf("kr_sign_hash failed, %i, %lu\n", i, len);
           exit(-1);
           exit(-1);
        }
        }
@@ -1534,7 +1529,7 @@ int main(void)
 #endif
 #endif
 
 
  register_all_algs();
  register_all_algs();
-
+ 
  if ((errno = yarrow_start(&prng)) != CRYPT_OK) {
  if ((errno = yarrow_start(&prng)) != CRYPT_OK) {
     printf("yarrow_start: %s\n", error_to_string(errno));
     printf("yarrow_start: %s\n", error_to_string(errno));
  }
  }

+ 11 - 13
dh.c

@@ -2,20 +2,11 @@
 
 
 #ifdef MDH
 #ifdef MDH
 
 
+/* This holds the key settings.  ***MUST*** be organized by size from smallest to largest. */
 static const struct {
 static const struct {
     int size;
     int size;
     char *name, *base, *prime;
     char *name, *base, *prime;
 } sets[] = {
 } sets[] = {
-#ifdef DH512
-{ 
-    64,
-   "DH-512",
-   "3",
-   "1793360119486011337223707056216512835002732007217684422667328794587337075124"
-   "5439587792371960615073855669274087805055507977323024886880985062002853331424"
-   "203"
-},
-#endif
 #ifdef DH768
 #ifdef DH768
 {
 {
    96,
    96,
@@ -360,7 +351,7 @@ int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key)
 
 
    /* header */
    /* header */
    buf2[y++] = type;
    buf2[y++] = type;
-   buf2[y++] = key->idx;
+   buf2[y++] = sets[key->idx].size / 8;
 
 
    /* export y */
    /* export y */
    OUTPUT_BIGNUM(&key->y, buf2, y, z);
    OUTPUT_BIGNUM(&key->y, buf2, y, z);
@@ -392,7 +383,7 @@ int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key)
 
 
 int dh_import(const unsigned char *in, dh_key *key)
 int dh_import(const unsigned char *in, dh_key *key)
 {
 {
-   long x, y;
+   long x, y, s;
    int errno;
    int errno;
 
 
    _ARGCHK(in != NULL);
    _ARGCHK(in != NULL);
@@ -410,7 +401,14 @@ int dh_import(const unsigned char *in, dh_key *key)
 
 
    y = PACKET_SIZE;
    y = PACKET_SIZE;
    key->type = in[y++];
    key->type = in[y++];
-   key->idx  = in[y++];
+   s  = (long)in[y++] * 8;
+   
+   for (x = 0; (s > sets[x].size) && (sets[x].size); x++);
+   if (sets[x].size == 0) {
+      errno = CRYPT_INVALID_KEYSIZE;
+      goto error;
+   }
+   key->idx = x;
 
 
    /* type check both values */
    /* type check both values */
    if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE))  {
    if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE))  {

+ 10 - 0
dh_sys.c

@@ -246,6 +246,11 @@ int dh_sign(const unsigned char *in,  unsigned long inlen,
    if (key->type != PK_PRIVATE) {
    if (key->type != PK_PRIVATE) {
       return CRYPT_PK_NOT_PRIVATE;
       return CRYPT_PK_NOT_PRIVATE;
    }
    }
+   
+   /* is the IDX valid ?  */
+   if (!is_valid_idx(key->idx)) {
+      return CRYPT_PK_INVALID_TYPE;
+   }
 
 
    if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
    if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
       return errno;
       return errno;
@@ -618,6 +623,11 @@ int dh_sign_hash(const unsigned char *in,  unsigned long inlen,
       return errno;
       return errno;
    }
    }
 
 
+   /* is the IDX valid ?  */
+   if (!is_valid_idx(key->idx)) {
+      return CRYPT_PK_INVALID_TYPE;
+   }
+
    /* hash the message */
    /* hash the message */
    md[0] = 0;
    md[0] = 0;
    memcpy(md+1, in, MIN(sizeof(md) - 1, inlen));
    memcpy(md+1, in, MIN(sizeof(md) - 1, inlen));

+ 11 - 3
ecc.c

@@ -8,6 +8,7 @@
 
 
 #ifdef MECC
 #ifdef MECC
 
 
+/* This holds the key settings.  ***MUST*** be organized by size from smallest to largest. */
 static const struct {
 static const struct {
    int size;
    int size;
    char *name, *prime, *B, *order, *Gx, *Gy;
    char *name, *prime, *B, *order, *Gx, *Gy;
@@ -668,7 +669,7 @@ int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key
    /* output type and magic byte */
    /* output type and magic byte */
    y = PACKET_SIZE;
    y = PACKET_SIZE;
    buf2[y++] = type;
    buf2[y++] = type;
-   buf2[y++] = key->idx;
+   buf2[y++] = sets[key->idx].size;
 
 
    /* output x coordinate */
    /* output x coordinate */
    OUTPUT_BIGNUM(&(key->pubkey.x), buf2, y, z);
    OUTPUT_BIGNUM(&(key->pubkey.x), buf2, y, z);
@@ -702,7 +703,7 @@ int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key
 
 
 int ecc_import(const unsigned char *in, ecc_key *key)
 int ecc_import(const unsigned char *in, ecc_key *key)
 {
 {
-   unsigned long x, y;
+   unsigned long x, y, s;
    int res, errno;
    int res, errno;
 
 
    _ARGCHK(in != NULL);
    _ARGCHK(in != NULL);
@@ -720,7 +721,14 @@ int ecc_import(const unsigned char *in, ecc_key *key)
 
 
    y = PACKET_SIZE;
    y = PACKET_SIZE;
    key->type = in[y++];
    key->type = in[y++];
-   key->idx  = in[y++];
+   s = in[y++];
+   
+   for (x = 0; (s > (unsigned long)sets[x].size) && (sets[x].size); x++);
+   if (sets[x].size == 0) { 
+      res = CRYPT_INVALID_KEYSIZE;
+      goto error2;
+   }
+   key->idx = x;
 
 
    /* type check both values */
    /* type check both values */
    if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE))  {
    if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE))  {

+ 13 - 3
ecc_sys.c

@@ -274,7 +274,12 @@ int ecc_sign(const unsigned char *in,  unsigned long inlen,
    if (key->type != PK_PRIVATE) {
    if (key->type != PK_PRIVATE) {
       return CRYPT_PK_NOT_PRIVATE;
       return CRYPT_PK_NOT_PRIVATE;
    }
    }
-
+   
+   /* is the IDX valid ?  */
+   if (!is_valid_idx(key->idx)) {
+      return CRYPT_PK_INVALID_TYPE;
+   }
+      
    if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
    if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
       return errno;
       return errno;
    }
    }
@@ -675,7 +680,12 @@ int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
    if (key->type != PK_PRIVATE) {
    if (key->type != PK_PRIVATE) {
       return CRYPT_PK_NOT_PRIVATE;
       return CRYPT_PK_NOT_PRIVATE;
    }
    }
-
+   
+   /* is the IDX valid ?  */
+   if (!is_valid_idx(key->idx)) {
+      return CRYPT_PK_INVALID_TYPE;
+   }
+   
    if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
    if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
       return errno;
       return errno;
    }
    }
@@ -701,7 +711,7 @@ int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
       return CRYPT_MEM;
       return CRYPT_MEM;
    }
    }
    if (mp_read_radix(&p, (unsigned char *)sets[key->idx].order, 10) != MP_OKAY)            { goto error; }
    if (mp_read_radix(&p, (unsigned char *)sets[key->idx].order, 10) != MP_OKAY)            { goto error; }
-   if (mp_read_raw(&b, md, 1+MIN(sizeof(md)-1,inlen)) != MP_OKAY)         { goto error; }
+   if (mp_read_raw(&b, md, 1+MIN(sizeof(md)-1,inlen)) != MP_OKAY)                          { goto error; }
 
 
    /* find b = (m - x)/k */
    /* find b = (m - x)/k */
    if (mp_invmod(&pubkey.k, &p, &pubkey.k) != MP_OKAY)                    { goto error; } /* k = 1/k */
    if (mp_invmod(&pubkey.k, &p, &pubkey.k) != MP_OKAY)                    { goto error; } /* k = 1/k */

+ 7 - 9
keyring.c

@@ -71,17 +71,15 @@ static const unsigned long crc_table[256] = {
 static unsigned long crc32 (unsigned long crc, const unsigned char *buf, unsigned long len)
 static unsigned long crc32 (unsigned long crc, const unsigned char *buf, unsigned long len)
 {
 {
   crc = crc ^ 0xffffffffL;
   crc = crc ^ 0xffffffffL;
-  while (len >= 8)
-    {
+  while (len >= 8) {
       DO8 (buf);
       DO8 (buf);
       len -= 8;
       len -= 8;
-    }
-  if (len)
-    do
-      {
-	DO1 (buf);
-      }
-    while (--len);
+  }
+  if (len) {
+    do {
+	   DO1 (buf);
+    } while (--len);
+  }    
   return crc ^ 0xffffffffUL;
   return crc ^ 0xffffffffUL;
 }
 }
 
 

+ 1 - 6
makefile

@@ -9,7 +9,7 @@
 # a build. This is easy to remedy though, for those that have problems.
 # a build. This is easy to remedy though, for those that have problems.
 
 
 # The version
 # The version
-VERSION=0.76
+VERSION=0.77
 
 
 #Compiler and Linker Names
 #Compiler and Linker Names
 CC=gcc
 CC=gcc
@@ -155,11 +155,6 @@ CFLAGS += -DKR
 # include large integer math routines? (required by the PK code)
 # include large integer math routines? (required by the PK code)
 CFLAGS += -DMPI
 CFLAGS += -DMPI
 
 
-# Use a small prime table?  It greatly reduces the size of prime.c at a little impact
-# in speed.
-#
-CFLAGS += -DSMALL_PRIME_TAB
-
 # include HMAC support
 # include HMAC support
 CFLAGS += -DHMAC
 CFLAGS += -DHMAC
 
 

+ 3 - 3
mpi-config.h

@@ -14,7 +14,7 @@
  */
  */
 
 
 #ifndef MP_IOFUNC
 #ifndef MP_IOFUNC
-#define MP_IOFUNC     1  /* include mp_print() ?                */
+#define MP_IOFUNC     0  /* include mp_print() ?                */
 #endif
 #endif
 
 
 #ifndef MP_MODARITH
 #ifndef MP_MODARITH
@@ -55,11 +55,11 @@
 #endif
 #endif
 
 
 #ifndef MP_DEFPREC
 #ifndef MP_DEFPREC
-#define MP_DEFPREC    8  /* default precision, in digits        */
+#define MP_DEFPREC    64  /* default precision, in digits        */
 #endif
 #endif
 
 
 #ifndef MP_MACRO
 #ifndef MP_MACRO
-#define MP_MACRO      1  /* use macros for frequent calls?      */
+#define MP_MACRO      0  /* use macros for frequent calls?      */
 #endif
 #endif
 
 
 #ifndef MP_SQUARE
 #ifndef MP_SQUARE

+ 2 - 2
mycrypt.h

@@ -13,8 +13,8 @@ extern "C" {
 #endif
 #endif
 
 
 /* version */
 /* version */
-#define CRYPT   0x0076
-#define SCRYPT  "0.76"
+#define CRYPT   0x0077
+#define SCRYPT  "0.77"
 
 
 /* max size of either a cipher/hash block or symmetric key [largest of the two] */
 /* max size of either a cipher/hash block or symmetric key [largest of the two] */
 #define MAXBLOCKSIZE           128
 #define MAXBLOCKSIZE           128

+ 0 - 1
mycrypt_cfg.h

@@ -79,7 +79,6 @@ extern clock_t XCLOCK(void);
 /* Diffie-Hellman key settings you can omit ones you don't want to save space */
 /* Diffie-Hellman key settings you can omit ones you don't want to save space */
 #ifdef MDH
 #ifdef MDH
 
 
-#define DH512
 #define DH768
 #define DH768
 #define DH1024
 #define DH1024
 #define DH1280
 #define DH1280

+ 1 - 1
mycrypt_cipher.h

@@ -44,7 +44,7 @@ struct rijndael_key {
 
 
 #ifdef XTEA
 #ifdef XTEA
 struct xtea_key {
 struct xtea_key {
-   unsigned long K[4];
+   unsigned long A[32], B[32];
 };
 };
 #endif
 #endif
 
 

+ 46 - 0
notes/tech0003.txt

@@ -0,0 +1,46 @@
+Tech Note 0003
+Minimizing Memory Usage
+Tom St Denis
+
+Introduction
+------------
+
+For the most part the library can get by with around 20KB of stack and about 32KB of heap even if you use the
+public key functions.  If all you plan on using are the hashes and ciphers than only about 1KB of stack is required
+and no heap.
+
+To save space all of the symmetric key scheduled keys are stored in a union called "symmetric_key".  This means the 
+size of a symmetric_key is the size of the largest scheduled key.  By removing the ciphers you don't use from
+the build you can minimize the size of this structure.  For instance, by removing both Twofish and Blowfish the
+size reduces to 528 bytes from the 4,256 bytes it would have been (on a 32-bit platform).  Or if you remove
+Blowfish and use Twofish with TWOFISH_SMALL defined its still 528 bytes.  Even at its largest the structure is only 
+4KB which is normally not a problem for any platform.  
+
+
+Cipher Name | Size of scheduled key (bytes) |
+------------+-------------------------------|
+Blowfish    | 4,168                         |
+RC5         | 204                           |
+RC6         | 176                           |
+SAFER+      | 532                           |
+Serpent     | 528                           |
+Rijndael    | 516                           |
+XTEA        | 256                           |
+Twofish     | 4,256                         |
+Twofish [*] | 193                           |
+SAFER [#]   | 217                           |
+RC2         | 256                           |
+DES         | 256                           |
+3DES        | 768                           |
+CAST5       | 132                           |
+------------+-------------------------------/
+Memory used per cipher on a 32-bit platform.
+
+[*] For Twofish with TWOFISH_SMALL defined
+[#] For all 64-bit SAFER ciphers.
+
+Following this chart its ideal that in extremely low memory platforms that all of the ciphers are disabled and CAST5 is
+left.  CAST5 is a fairly fast cipher on all platforms which makes it ideally suited.  It should be noted that the
+SAFER and SAFER+ keys are formed of arrays of unsigned char.  So in effect on platforms where "unsigned long" is 
+8 bytes SAFER would have the smallest key (CAST5 would come out to 264 bytes).  In this case I would recommend 
+SAFER-SK128.

+ 105 - 815
prime.c

@@ -2,7 +2,8 @@
 
 
 #ifdef MPI
 #ifdef MPI
 
 
-#ifdef SMALL_PRIME_TAB
+#define UPPER_LIMIT    (sizeof(prime_tab) / sizeof(prime_tab[0]))
+
 static const mp_digit prime_tab[] = {
 static const mp_digit prime_tab[] = {
     0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
     0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
     0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
     0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
@@ -11,18 +12,8 @@ static const mp_digit prime_tab[] = {
     0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
     0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
     0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
     0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
     0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
     0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
-    0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137 };
-#else
-static const mp_digit prime_tab[] = {
-    0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
-    0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, 
-    0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, 
-    0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, 0x0083, 
-    0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, 
-    0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, 
-    0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, 
-    0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, 
-
+    0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
+    
     0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, 
     0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, 
     0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, 
     0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, 
     0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, 
     0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, 
@@ -39,7 +30,8 @@ static const mp_digit prime_tab[] = {
     0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
     0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
     0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, 
     0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, 
     0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, 
     0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, 
-    0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, 
+    0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
+    
     0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, 
     0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, 
     0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, 
     0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, 
     0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, 
     0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, 
@@ -47,796 +39,8 @@ static const mp_digit prime_tab[] = {
     0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, 
     0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, 
     0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, 
     0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, 
     0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, 
     0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, 
-    0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653, 
-    0x0655, 0x065B, 0x0665, 0x0679, 0x067F, 0x0683, 0x0685, 0x069D, 
-    0x06A1, 0x06A3, 0x06AD, 0x06B9, 0x06BB, 0x06C5, 0x06CD, 0x06D3, 
-    0x06D9, 0x06DF, 0x06F1, 0x06F7, 0x06FB, 0x06FD, 0x0709, 0x0713, 
-    0x071F, 0x0727, 0x0737, 0x0745, 0x074B, 0x074F, 0x0751, 0x0755, 
-    0x0757, 0x0761, 0x076D, 0x0773, 0x0779, 0x078B, 0x078D, 0x079D, 
-    0x079F, 0x07B5, 0x07BB, 0x07C3, 0x07C9, 0x07CD, 0x07CF, 0x07D3,
-    0x07DB, 0x07E1, 0x07EB, 0x07ED, 0x07F7, 0x0805, 0x080F, 0x0815, 
-    0x0821, 0x0823, 0x0827, 0x0829, 0x0833, 0x083F, 0x0841, 0x0851, 
-    0x0853, 0x0859, 0x085D, 0x085F, 0x0869, 0x0871, 0x0883, 0x089B, 
-    0x089F, 0x08A5, 0x08AD, 0x08BD, 0x08BF, 0x08C3, 0x08CB, 0x08DB, 
-    0x08DD, 0x08E1, 0x08E9, 0x08EF, 0x08F5, 0x08F9, 0x0905, 0x0907, 
-    0x091D, 0x0923, 0x0925, 0x092B, 0x092F, 0x0935, 0x0943, 0x0949, 
-    0x094D, 0x094F, 0x0955, 0x0959, 0x095F, 0x096B, 0x0971, 0x0977, 
-    0x0985, 0x0989, 0x098F, 0x099B, 0x09A3, 0x09A9, 0x09AD, 0x09C7, 
-    0x09D9, 0x09E3, 0x09EB, 0x09EF, 0x09F5, 0x09F7, 0x09FD, 0x0A13, 
-    0x0A1F, 0x0A21, 0x0A31, 0x0A39, 0x0A3D, 0x0A49, 0x0A57, 0x0A61, 
-    0x0A63, 0x0A67, 0x0A6F, 0x0A75, 0x0A7B, 0x0A7F, 0x0A81, 0x0A85, 
-    0x0A8B, 0x0A93, 0x0A97, 0x0A99, 0x0A9F, 0x0AA9, 0x0AAB, 0x0AB5, 
-    0x0ABD, 0x0AC1, 0x0ACF, 0x0AD9, 0x0AE5, 0x0AE7, 0x0AED, 0x0AF1, 
-    0x0AF3, 0x0B03, 0x0B11, 0x0B15, 0x0B1B, 0x0B23, 0x0B29, 0x0B2D, 
-    0x0B3F, 0x0B47, 0x0B51, 0x0B57, 0x0B5D, 0x0B65, 0x0B6F, 0x0B7B,
-    0x0B89, 0x0B8D, 0x0B93, 0x0B99, 0x0B9B, 0x0BB7, 0x0BB9, 0x0BC3, 
-    0x0BCB, 0x0BCF, 0x0BDD, 0x0BE1, 0x0BE9, 0x0BF5, 0x0BFB, 0x0C07, 
-    0x0C0B, 0x0C11, 0x0C25, 0x0C2F, 0x0C31, 0x0C41, 0x0C5B, 0x0C5F, 
-    0x0C61, 0x0C6D, 0x0C73, 0x0C77, 0x0C83, 0x0C89, 0x0C91, 0x0C95, 
-    0x0C9D, 0x0CB3, 0x0CB5, 0x0CB9, 0x0CBB, 0x0CC7, 0x0CE3, 0x0CE5, 
-    0x0CEB, 0x0CF1, 0x0CF7, 0x0CFB, 0x0D01, 0x0D03, 0x0D0F, 0x0D13, 
-    0x0D1F, 0x0D21, 0x0D2B, 0x0D2D, 0x0D3D, 0x0D3F, 0x0D4F, 0x0D55, 
-    0x0D69, 0x0D79, 0x0D81, 0x0D85, 0x0D87, 0x0D8B, 0x0D8D, 0x0DA3, 
-    0x0DAB, 0x0DB7, 0x0DBD, 0x0DC7, 0x0DC9, 0x0DCD, 0x0DD3, 0x0DD5, 
-    0x0DDB, 0x0DE5, 0x0DE7, 0x0DF3, 0x0DFD, 0x0DFF, 0x0E09, 0x0E17, 
-    0x0E1D, 0x0E21, 0x0E27, 0x0E2F, 0x0E35, 0x0E3B, 0x0E4B, 0x0E57, 
-    0x0E59, 0x0E5D, 0x0E6B, 0x0E71, 0x0E75, 0x0E7D, 0x0E87, 0x0E8F, 
-    0x0E95, 0x0E9B, 0x0EB1, 0x0EB7, 0x0EB9, 0x0EC3, 0x0ED1, 0x0ED5, 
-    0x0EDB, 0x0EED, 0x0EEF, 0x0EF9, 0x0F07, 0x0F0B, 0x0F0D, 0x0F17, 
-    0x0F25, 0x0F29, 0x0F31, 0x0F43, 0x0F47, 0x0F4D, 0x0F4F, 0x0F53, 
-    0x0F59, 0x0F5B, 0x0F67, 0x0F6B, 0x0F7F, 0x0F95, 0x0FA1, 0x0FA3, 
-    0x0FA7, 0x0FAD, 0x0FB3, 0x0FB5, 0x0FBB, 0x0FD1, 0x0FD3, 0x0FD9, 
-    0x0FE9, 0x0FEF, 0x0FFB, 0x0FFD, 0x1003, 0x100F, 0x101F, 0x1021, 
-    0x1025, 0x102B, 0x1039, 0x103D, 0x103F, 0x1051, 0x1069, 0x1073, 
-    0x1079, 0x107B, 0x1085, 0x1087, 0x1091, 0x1093, 0x109D, 0x10A3, 
-    0x10A5, 0x10AF, 0x10B1, 0x10BB, 0x10C1, 0x10C9, 0x10E7, 0x10F1, 
-    0x10F3, 0x10FD, 0x1105, 0x110B, 0x1115, 0x1127, 0x112D, 0x1139, 
-    0x1145, 0x1147, 0x1159, 0x115F, 0x1163, 0x1169, 0x116F, 0x1181,
-    0x1183, 0x118D, 0x119B, 0x11A1, 0x11A5, 0x11A7, 0x11AB, 0x11C3, 
-    0x11C5, 0x11D1, 0x11D7, 0x11E7, 0x11EF, 0x11F5, 0x11FB, 0x120D, 
-    0x121D, 0x121F, 0x1223, 0x1229, 0x122B, 0x1231, 0x1237, 0x1241, 
-    0x1247, 0x1253, 0x125F, 0x1271, 0x1273, 0x1279, 0x127D, 0x128F, 
-    0x1297, 0x12AF, 0x12B3, 0x12B5, 0x12B9, 0x12BF, 0x12C1, 0x12CD, 
-    0x12D1, 0x12DF, 0x12FD, 0x1307, 0x130D, 0x1319, 0x1327, 0x132D, 
-    0x1337, 0x1343, 0x1345, 0x1349, 0x134F, 0x1357, 0x135D, 0x1367, 
-    0x1369, 0x136D, 0x137B, 0x1381, 0x1387, 0x138B, 0x1391, 0x1393, 
-    0x139D, 0x139F, 0x13AF, 0x13BB, 0x13C3, 0x13D5, 0x13D9, 0x13DF, 
-    0x13EB, 0x13ED, 0x13F3, 0x13F9, 0x13FF, 0x141B, 0x1421, 0x142F, 
-    0x1433, 0x143B, 0x1445, 0x144D, 0x1459, 0x146B, 0x146F, 0x1471, 
-    0x1475, 0x148D, 0x1499, 0x149F, 0x14A1, 0x14B1, 0x14B7, 0x14BD, 
-    0x14CB, 0x14D5, 0x14E3, 0x14E7, 0x1505, 0x150B, 0x1511, 0x1517, 
-    0x151F, 0x1525, 0x1529, 0x152B, 0x1537, 0x153D, 0x1541, 0x1543, 
-    0x1549, 0x155F, 0x1565, 0x1567, 0x156B, 0x157D, 0x157F, 0x1583, 
-    0x158F, 0x1591, 0x1597, 0x159B, 0x15B5, 0x15BB, 0x15C1, 0x15C5, 
-    0x15CD, 0x15D7, 0x15F7, 0x1607, 0x1609, 0x160F, 0x1613, 0x1615,
-    0x1619, 0x161B, 0x1625, 0x1633, 0x1639, 0x163D, 0x1645, 0x164F, 
-    0x1655, 0x1669, 0x166D, 0x166F, 0x1675, 0x1693, 0x1697, 0x169F, 
-    0x16A9, 0x16AF, 0x16B5, 0x16BD, 0x16C3, 0x16CF, 0x16D3, 0x16D9, 
-    0x16DB, 0x16E1, 0x16E5, 0x16EB, 0x16ED, 0x16F7, 0x16F9, 0x1709, 
-    0x170F, 0x1723, 0x1727, 0x1733, 0x1741, 0x175D, 0x1763, 0x1777, 
-    0x177B, 0x178D, 0x1795, 0x179B, 0x179F, 0x17A5, 0x17B3, 0x17B9, 
-    0x17BF, 0x17C9, 0x17CB, 0x17D5, 0x17E1, 0x17E9, 0x17F3, 0x17F5, 
-    0x17FF, 0x1807, 0x1813, 0x181D, 0x1835, 0x1837, 0x183B, 0x1843, 
-    0x1849, 0x184D, 0x1855, 0x1867, 0x1871, 0x1877, 0x187D, 0x187F, 
-    0x1885, 0x188F, 0x189B, 0x189D, 0x18A7, 0x18AD, 0x18B3, 0x18B9, 
-    0x18C1, 0x18C7, 0x18D1, 0x18D7, 0x18D9, 0x18DF, 0x18E5, 0x18EB, 
-    0x18F5, 0x18FD, 0x1915, 0x191B, 0x1931, 0x1933, 0x1945, 0x1949, 
-    0x1951, 0x195B, 0x1979, 0x1981, 0x1993, 0x1997, 0x1999, 0x19A3, 
-    0x19A9, 0x19AB, 0x19B1, 0x19B5, 0x19C7, 0x19CF, 0x19DB, 0x19ED, 
-    0x19FD, 0x1A03, 0x1A05, 0x1A11, 0x1A17, 0x1A21, 0x1A23, 0x1A2D,
-    0x1A2F, 0x1A35, 0x1A3F, 0x1A4D, 0x1A51, 0x1A69, 0x1A6B, 0x1A7B, 
-    0x1A7D, 0x1A87, 0x1A89, 0x1A93, 0x1AA7, 0x1AAB, 0x1AAD, 0x1AB1, 
-    0x1AB9, 0x1AC9, 0x1ACF, 0x1AD5, 0x1AD7, 0x1AE3, 0x1AF3, 0x1AFB, 
-    0x1AFF, 0x1B05, 0x1B23, 0x1B25, 0x1B2F, 0x1B31, 0x1B37, 0x1B3B, 
-    0x1B41, 0x1B47, 0x1B4F, 0x1B55, 0x1B59, 0x1B65, 0x1B6B, 0x1B73, 
-    0x1B7F, 0x1B83, 0x1B91, 0x1B9D, 0x1BA7, 0x1BBF, 0x1BC5, 0x1BD1, 
-    0x1BD7, 0x1BD9, 0x1BEF, 0x1BF7, 0x1C09, 0x1C13, 0x1C19, 0x1C27, 
-    0x1C2B, 0x1C2D, 0x1C33, 0x1C3D, 0x1C45, 0x1C4B, 0x1C4F, 0x1C55, 
-    0x1C73, 0x1C81, 0x1C8B, 0x1C8D, 0x1C99, 0x1CA3, 0x1CA5, 0x1CB5, 
-    0x1CB7, 0x1CC9, 0x1CE1, 0x1CF3, 0x1CF9, 0x1D09, 0x1D1B, 0x1D21, 
-    0x1D23, 0x1D35, 0x1D39, 0x1D3F, 0x1D41, 0x1D4B, 0x1D53, 0x1D5D, 
-    0x1D63, 0x1D69, 0x1D71, 0x1D75, 0x1D7B, 0x1D7D, 0x1D87, 0x1D89, 
-    0x1D95, 0x1D99, 0x1D9F, 0x1DA5, 0x1DA7, 0x1DB3, 0x1DB7, 0x1DC5, 
-    0x1DD7, 0x1DDB, 0x1DE1, 0x1DF5, 0x1DF9, 0x1E01, 0x1E07, 0x1E0B, 
-    0x1E13, 0x1E17, 0x1E25, 0x1E2B, 0x1E2F, 0x1E3D, 0x1E49, 0x1E4D, 
-    0x1E4F, 0x1E6D, 0x1E71, 0x1E89, 0x1E8F, 0x1E95, 0x1EA1, 0x1EAD, 
-    0x1EBB, 0x1EC1, 0x1EC5, 0x1EC7, 0x1ECB, 0x1EDD, 0x1EE3, 0x1EEF, 
-    0x1EF7, 0x1EFD, 0x1F01, 0x1F0D, 0x1F0F, 0x1F1B, 0x1F39, 0x1F49, 
-    0x1F4B, 0x1F51, 0x1F67, 0x1F75, 0x1F7B, 0x1F85, 0x1F91, 0x1F97, 
-    0x1F99, 0x1F9D, 0x1FA5, 0x1FAF, 0x1FB5, 0x1FBB, 0x1FD3, 0x1FE1, 
-    0x1FE7, 0x1FEB, 0x1FF3, 0x1FFF, 0x2011, 0x201B, 0x201D, 0x2027, 
-    0x2029, 0x202D, 0x2033, 0x2047, 0x204D, 0x2051, 0x205F, 0x2063, 
-    0x2065, 0x2069, 0x2077, 0x207D, 0x2089, 0x20A1, 0x20AB, 0x20B1,
-    0x20B9, 0x20C3, 0x20C5, 0x20E3, 0x20E7, 0x20ED, 0x20EF, 0x20FB, 
-    0x20FF, 0x210D, 0x2113, 0x2135, 0x2141, 0x2149, 0x214F, 0x2159, 
-    0x215B, 0x215F, 0x2173, 0x217D, 0x2185, 0x2195, 0x2197, 0x21A1, 
-    0x21AF, 0x21B3, 0x21B5, 0x21C1, 0x21C7, 0x21D7, 0x21DD, 0x21E5, 
-    0x21E9, 0x21F1, 0x21F5, 0x21FB, 0x2203, 0x2209, 0x220F, 0x221B, 
-    0x2221, 0x2225, 0x222B, 0x2231, 0x2239, 0x224B, 0x224F, 0x2263, 
-    0x2267, 0x2273, 0x2275, 0x227F, 0x2285, 0x2287, 0x2291, 0x229D, 
-    0x229F, 0x22A3, 0x22B7, 0x22BD, 0x22DB, 0x22E1, 0x22E5, 0x22ED, 
-    0x22F7, 0x2303, 0x2309, 0x230B, 0x2327, 0x2329, 0x232F, 0x2333, 
-    0x2335, 0x2345, 0x2351, 0x2353, 0x2359, 0x2363, 0x236B, 0x2383, 
-    0x238F, 0x2395, 0x23A7, 0x23AD, 0x23B1, 0x23BF, 0x23C5, 0x23C9, 
-    0x23D5, 0x23DD, 0x23E3, 0x23EF, 0x23F3, 0x23F9, 0x2405, 0x240B, 
-    0x2417, 0x2419, 0x2429, 0x243D, 0x2441, 0x2443, 0x244D, 0x245F, 
-    0x2467, 0x246B, 0x2479, 0x247D, 0x247F, 0x2485, 0x249B, 0x24A1, 
-    0x24AF, 0x24B5, 0x24BB, 0x24C5, 0x24CB, 0x24CD, 0x24D7, 0x24D9, 
-    0x24DD, 0x24DF, 0x24F5, 0x24F7, 0x24FB, 0x2501, 0x2507, 0x2513, 
-    0x2519, 0x2527, 0x2531, 0x253D, 0x2543, 0x254B, 0x254F, 0x2573,
-    0x2581, 0x258D, 0x2593, 0x2597, 0x259D, 0x259F, 0x25AB, 0x25B1, 
-    0x25BD, 0x25CD, 0x25CF, 0x25D9, 0x25E1, 0x25F7, 0x25F9, 0x2605, 
-    0x260B, 0x260F, 0x2615, 0x2627, 0x2629, 0x2635, 0x263B, 0x263F, 
-    0x264B, 0x2653, 0x2659, 0x2665, 0x2669, 0x266F, 0x267B, 0x2681, 
-    0x2683, 0x268F, 0x269B, 0x269F, 0x26AD, 0x26B3, 0x26C3, 0x26C9, 
-    0x26CB, 0x26D5, 0x26DD, 0x26EF, 0x26F5, 0x2717, 0x2719, 0x2735, 
-    0x2737, 0x274D, 0x2753, 0x2755, 0x275F, 0x276B, 0x276D, 0x2773, 
-    0x2777, 0x277F, 0x2795, 0x279B, 0x279D, 0x27A7, 0x27AF, 0x27B3, 
-    0x27B9, 0x27C1, 0x27C5, 0x27D1, 0x27E3, 0x27EF, 0x2803, 0x2807, 
-    0x280D, 0x2813, 0x281B, 0x281F, 0x2821, 0x2831, 0x283D, 0x283F, 
-    0x2849, 0x2851, 0x285B, 0x285D, 0x2861, 0x2867, 0x2875, 0x2881, 
-    0x2897, 0x289F, 0x28BB, 0x28BD, 0x28C1, 0x28D5, 0x28D9, 0x28DB, 
-    0x28DF, 0x28ED, 0x28F7, 0x2903, 0x2905, 0x2911, 0x2921, 0x2923, 
-    0x293F, 0x2947, 0x295D, 0x2965, 0x2969, 0x296F, 0x2975, 0x2983, 
-    0x2987, 0x298F, 0x299B, 0x29A1, 0x29A7, 0x29AB, 0x29BF, 0x29C3,
-    0x29D5, 0x29D7, 0x29E3, 0x29E9, 0x29ED, 0x29F3, 0x2A01, 0x2A13, 
-    0x2A1D, 0x2A25, 0x2A2F, 0x2A4F, 0x2A55, 0x2A5F, 0x2A65, 0x2A6B, 
-    0x2A6D, 0x2A73, 0x2A83, 0x2A89, 0x2A8B, 0x2A97, 0x2A9D, 0x2AB9, 
-    0x2ABB, 0x2AC5, 0x2ACD, 0x2ADD, 0x2AE3, 0x2AEB, 0x2AF1, 0x2AFB, 
-    0x2B13, 0x2B27, 0x2B31, 0x2B33, 0x2B3D, 0x2B3F, 0x2B4B, 0x2B4F, 
-    0x2B55, 0x2B69, 0x2B6D, 0x2B6F, 0x2B7B, 0x2B8D, 0x2B97, 0x2B99, 
-    0x2BA3, 0x2BA5, 0x2BA9, 0x2BBD, 0x2BCD, 0x2BE7, 0x2BEB, 0x2BF3, 
-    0x2BF9, 0x2BFD, 0x2C09, 0x2C0F, 0x2C17, 0x2C23, 0x2C2F, 0x2C35, 
-    0x2C39, 0x2C41, 0x2C57, 0x2C59, 0x2C69, 0x2C77, 0x2C81, 0x2C87, 
-    0x2C93, 0x2C9F, 0x2CAD, 0x2CB3, 0x2CB7, 0x2CCB, 0x2CCF, 0x2CDB, 
-    0x2CE1, 0x2CE3, 0x2CE9, 0x2CEF, 0x2CFF, 0x2D07, 0x2D1D, 0x2D1F, 
-    0x2D3B, 0x2D43, 0x2D49, 0x2D4D, 0x2D61, 0x2D65, 0x2D71, 0x2D89, 
-    0x2D9D, 0x2DA1, 0x2DA9, 0x2DB3, 0x2DB5, 0x2DC5, 0x2DC7, 0x2DD3, 
-    0x2DDF, 0x2E01, 0x2E03, 0x2E07, 0x2E0D, 0x2E19, 0x2E1F, 0x2E25, 
-    0x2E2D, 0x2E33, 0x2E37, 0x2E39, 0x2E3F, 0x2E57, 0x2E5B, 0x2E6F, 
-    0x2E79, 0x2E7F, 0x2E85, 0x2E93, 0x2E97, 0x2E9D, 0x2EA3, 0x2EA5, 
-    0x2EB1, 0x2EB7, 0x2EC1, 0x2EC3, 0x2ECD, 0x2ED3, 0x2EE7, 0x2EEB, 
-    0x2F05, 0x2F09, 0x2F0B, 0x2F11, 0x2F27, 0x2F29, 0x2F41, 0x2F45, 
-    0x2F4B, 0x2F4D, 0x2F51, 0x2F57, 0x2F6F, 0x2F75, 0x2F7D, 0x2F81, 
-    0x2F83, 0x2FA5, 0x2FAB, 0x2FB3, 0x2FC3, 0x2FCF, 0x2FD1, 0x2FDB, 
-    0x2FDD, 0x2FE7, 0x2FED, 0x2FF5, 0x2FF9, 0x3001, 0x300D, 0x3023, 
-    0x3029, 0x3037, 0x303B, 0x3055, 0x3059, 0x305B, 0x3067, 0x3071, 
-    0x3079, 0x307D, 0x3085, 0x3091, 0x3095, 0x30A3, 0x30A9, 0x30B9, 
-    0x30BF, 0x30C7, 0x30CB, 0x30D1, 0x30D7, 0x30DF, 0x30E5, 0x30EF, 
-    0x30FB, 0x30FD, 0x3103, 0x3109, 0x3119, 0x3121, 0x3127, 0x312D, 
-    0x3139, 0x3143, 0x3145, 0x314B, 0x315D, 0x3161, 0x3167, 0x316D, 
-    0x3173, 0x317F, 0x3191, 0x3199, 0x319F, 0x31A9, 0x31B1, 0x31C3, 
-    0x31C7, 0x31D5, 0x31DB, 0x31ED, 0x31F7, 0x31FF, 0x3209, 0x3215, 
-    0x3217, 0x321D, 0x3229, 0x3235, 0x3259, 0x325D, 0x3263, 0x326B, 
-    0x326F, 0x3275, 0x3277, 0x327B, 0x328D, 0x3299, 0x329F, 0x32A7, 
-    0x32AD, 0x32B3, 0x32B7, 0x32C9, 0x32CB, 0x32CF, 0x32D1, 0x32E9, 
-    0x32ED, 0x32F3, 0x32F9, 0x3307, 0x3325, 0x332B, 0x332F, 0x3335, 
-    0x3341, 0x3347, 0x335B, 0x335F, 0x3367, 0x336B, 0x3373, 0x3379, 
-    0x337F, 0x3383, 0x33A1, 0x33A3, 0x33AD, 0x33B9, 0x33C1, 0x33CB, 
-    0x33D3, 0x33EB, 0x33F1, 0x33FD, 0x3401, 0x340F, 0x3413, 0x3419, 
-    0x341B, 0x3437, 0x3445, 0x3455, 0x3457, 0x3463, 0x3469, 0x346D, 
-    0x3481, 0x348B, 0x3491, 0x3497, 0x349D, 0x34A5, 0x34AF, 0x34BB, 
-    0x34C9, 0x34D3, 0x34E1, 0x34F1, 0x34FF, 0x3509, 0x3517, 0x351D, 
-    0x352D, 0x3533, 0x353B, 0x3541, 0x3551, 0x3565, 0x356F, 0x3571, 
-    0x3577, 0x357B, 0x357D, 0x3581, 0x358D, 0x358F, 0x3599, 0x359B,
-    0x35A1, 0x35B7, 0x35BD, 0x35BF, 0x35C3, 0x35D5, 0x35DD, 0x35E7, 
-    0x35EF, 0x3605, 0x3607, 0x3611, 0x3623, 0x3631, 0x3635, 0x3637, 
-    0x363B, 0x364D, 0x364F, 0x3653, 0x3659, 0x3661, 0x366B, 0x366D, 
-    0x368B, 0x368F, 0x36AD, 0x36AF, 0x36B9, 0x36BB, 0x36CD, 0x36D1, 
-    0x36E3, 0x36E9, 0x36F7, 0x3701, 0x3703, 0x3707, 0x371B, 0x373F, 
-    0x3745, 0x3749, 0x374F, 0x375D, 0x3761, 0x3775, 0x377F, 0x378D, 
-    0x37A3, 0x37A9, 0x37AB, 0x37C9, 0x37D5, 0x37DF, 0x37F1, 0x37F3, 
-    0x37F7, 0x3805, 0x380B, 0x3821, 0x3833, 0x3835, 0x3841, 0x3847, 
-    0x384B, 0x3853, 0x3857, 0x385F, 0x3865, 0x386F, 0x3871, 0x387D, 
-    0x388F, 0x3899, 0x38A7, 0x38B7, 0x38C5, 0x38C9, 0x38CF, 0x38D5, 
-    0x38D7, 0x38DD, 0x38E1, 0x38E3, 0x38FF, 0x3901, 0x391D, 0x3923, 
-    0x3925, 0x3929, 0x392F, 0x393D, 0x3941, 0x394D, 0x395B, 0x396B, 
-    0x3979, 0x397D, 0x3983, 0x398B, 0x3991, 0x3995, 0x399B, 0x39A1, 
-    0x39A7, 0x39AF, 0x39B3, 0x39BB, 0x39BF, 0x39CD, 0x39DD, 0x39E5, 
-    0x39EB, 0x39EF, 0x39FB, 0x3A03, 0x3A13, 0x3A15, 0x3A1F, 0x3A27,
-    0x3A2B, 0x3A31, 0x3A4B, 0x3A51, 0x3A5B, 0x3A63, 0x3A67, 0x3A6D, 
-    0x3A79, 0x3A87, 0x3AA5, 0x3AA9, 0x3AB7, 0x3ACD, 0x3AD5, 0x3AE1, 
-    0x3AE5, 0x3AEB, 0x3AF3, 0x3AFD, 0x3B03, 0x3B11, 0x3B1B, 0x3B21, 
-    0x3B23, 0x3B2D, 0x3B39, 0x3B45, 0x3B53, 0x3B59, 0x3B5F, 0x3B71, 
-    0x3B7B, 0x3B81, 0x3B89, 0x3B9B, 0x3B9F, 0x3BA5, 0x3BA7, 0x3BAD, 
-    0x3BB7, 0x3BB9, 0x3BC3, 0x3BCB, 0x3BD1, 0x3BD7, 0x3BE1, 0x3BE3, 
-    0x3BF5, 0x3BFF, 0x3C01, 0x3C0D, 0x3C11, 0x3C17, 0x3C1F, 0x3C29, 
-    0x3C35, 0x3C43, 0x3C4F, 0x3C53, 0x3C5B, 0x3C65, 0x3C6B, 0x3C71, 
-    0x3C85, 0x3C89, 0x3C97, 0x3CA7, 0x3CB5, 0x3CBF, 0x3CC7, 0x3CD1, 
-    0x3CDD, 0x3CDF, 0x3CF1, 0x3CF7, 0x3D03, 0x3D0D, 0x3D19, 0x3D1B, 
-    0x3D1F, 0x3D21, 0x3D2D, 0x3D33, 0x3D37, 0x3D3F, 0x3D43, 0x3D6F, 
-    0x3D73, 0x3D75, 0x3D79, 0x3D7B, 0x3D85, 0x3D91, 0x3D97, 0x3D9D, 
-    0x3DAB, 0x3DAF, 0x3DB5, 0x3DBB, 0x3DC1, 0x3DC9, 0x3DCF, 0x3DF3, 
-    0x3E05, 0x3E09, 0x3E0F, 0x3E11, 0x3E1D, 0x3E23, 0x3E29, 0x3E2F, 
-    0x3E33, 0x3E41, 0x3E57, 0x3E63, 0x3E65, 0x3E77, 0x3E81, 0x3E87, 
-    0x3EA1, 0x3EB9, 0x3EBD, 0x3EBF, 0x3EC3, 0x3EC5, 0x3EC9, 0x3ED7, 
-    0x3EDB, 0x3EE1, 0x3EE7, 0x3EEF, 0x3EFF, 0x3F0B, 0x3F0D, 0x3F37, 
-    0x3F3B, 0x3F3D, 0x3F41, 0x3F59, 0x3F5F, 0x3F65, 0x3F67, 0x3F79, 
-    0x3F7D, 0x3F8B, 0x3F91, 0x3FAD, 0x3FBF, 0x3FCD, 0x3FD3, 0x3FDD, 
-    0x3FE9, 0x3FEB, 0x3FF1, 0x3FFD, 0x401B, 0x4021, 0x4025, 0x402B, 
-    0x4031, 0x403F, 0x4043, 0x4045, 0x405D, 0x4061, 0x4067, 0x406D, 
-    0x4087, 0x4091, 0x40A3, 0x40A9, 0x40B1, 0x40B7, 0x40BD, 0x40DB, 
-    0x40DF, 0x40EB, 0x40F7, 0x40F9, 0x4109, 0x410B, 0x4111, 0x4115, 
-    0x4121, 0x4133, 0x4135, 0x413B, 0x413F, 0x4159, 0x4165, 0x416B, 
-    0x4177, 0x417B, 0x4193, 0x41AB, 0x41B7, 0x41BD, 0x41BF, 0x41CB, 
-    0x41E7, 0x41EF, 0x41F3, 0x41F9, 0x4205, 0x4207, 0x4219, 0x421F, 
-    0x4223, 0x4229, 0x422F, 0x4243, 0x4253, 0x4255, 0x425B, 0x4261, 
-    0x4273, 0x427D, 0x4283, 0x4285, 0x4289, 0x4291, 0x4297, 0x429D, 
-    0x42B5, 0x42C5, 0x42CB, 0x42D3, 0x42DD, 0x42E3, 0x42F1, 0x4307, 
-    0x430F, 0x431F, 0x4325, 0x4327, 0x4333, 0x4337, 0x4339, 0x434F, 
-    0x4357, 0x4369, 0x438B, 0x438D, 0x4393, 0x43A5, 0x43A9, 0x43AF, 
-    0x43B5, 0x43BD, 0x43C7, 0x43CF, 0x43E1, 0x43E7, 0x43EB, 0x43ED, 
-    0x43F1, 0x43F9, 0x4409, 0x440B, 0x4417, 0x4423, 0x4429, 0x443B, 
-    0x443F, 0x4445, 0x444B, 0x4451, 0x4453, 0x4459, 0x4465, 0x446F, 
-    0x4483, 0x448F, 0x44A1, 0x44A5, 0x44AB, 0x44AD, 0x44BD, 0x44BF, 
-    0x44C9, 0x44D7, 0x44DB, 0x44F9, 0x44FB, 0x4505, 0x4511, 0x4513, 
-    0x452B, 0x4531, 0x4541, 0x4549, 0x4553, 0x4555, 0x4561, 0x4577, 
-    0x457D, 0x457F, 0x458F, 0x45A3, 0x45AD, 0x45AF, 0x45BB, 0x45C7, 
-    0x45D9, 0x45E3, 0x45EF, 0x45F5, 0x45F7, 0x4601, 0x4603, 0x4609, 
-    0x4613, 0x4625, 0x4627, 0x4633, 0x4639, 0x463D, 0x4643, 0x4645, 
-    0x465D, 0x4679, 0x467B, 0x467F, 0x4681, 0x468B, 0x468D, 0x469D, 
-    0x46A9, 0x46B1, 0x46C7, 0x46C9, 0x46CF, 0x46D3, 0x46D5, 0x46DF, 
-    0x46E5, 0x46F9, 0x4705, 0x470F, 0x4717, 0x4723, 0x4729, 0x472F, 
-    0x4735, 0x4739, 0x474B, 0x474D, 0x4751, 0x475D, 0x476F, 0x4771, 
-    0x477D, 0x4783, 0x4787, 0x4789, 0x4799, 0x47A5, 0x47B1, 0x47BF, 
-    0x47C3, 0x47CB, 0x47DD, 0x47E1, 0x47ED, 0x47FB, 0x4801, 0x4807, 
-    0x480B, 0x4813, 0x4819, 0x481D, 0x4831, 0x483D, 0x4847, 0x4855, 
-    0x4859, 0x485B, 0x486B, 0x486D, 0x4879, 0x4897, 0x489B, 0x48A1, 
-    0x48B9, 0x48CD, 0x48E5, 0x48EF, 0x48F7, 0x4903, 0x490D, 0x4919, 
-    0x491F, 0x492B, 0x4937, 0x493D, 0x4945, 0x4955, 0x4963, 0x4969, 
-    0x496D, 0x4973, 0x4997, 0x49AB, 0x49B5, 0x49D3, 0x49DF, 0x49E1, 
-    0x49E5, 0x49E7, 0x4A03, 0x4A0F, 0x4A1D, 0x4A23, 0x4A39, 0x4A41, 
-    0x4A45, 0x4A57, 0x4A5D, 0x4A6B, 0x4A7D, 0x4A81, 0x4A87, 0x4A89, 
-    0x4A8F, 0x4AB1, 0x4AC3, 0x4AC5, 0x4AD5, 0x4ADB, 0x4AED, 0x4AEF, 
-    0x4B07, 0x4B0B, 0x4B0D, 0x4B13, 0x4B1F, 0x4B25, 0x4B31, 0x4B3B,
-    0x4B43, 0x4B49, 0x4B59, 0x4B65, 0x4B6D, 0x4B77, 0x4B85, 0x4BAD, 
-    0x4BB3, 0x4BB5, 0x4BBB, 0x4BBF, 0x4BCB, 0x4BD9, 0x4BDD, 0x4BDF, 
-    0x4BE3, 0x4BE5, 0x4BE9, 0x4BF1, 0x4BF7, 0x4C01, 0x4C07, 0x4C0D, 
-    0x4C0F, 0x4C15, 0x4C1B, 0x4C21, 0x4C2D, 0x4C33, 0x4C4B, 0x4C55, 
-    0x4C57, 0x4C61, 0x4C67, 0x4C73, 0x4C79, 0x4C7F, 0x4C8D, 0x4C93, 
-    0x4C99, 0x4CCD, 0x4CE1, 0x4CE7, 0x4CF1, 0x4CF3, 0x4CFD, 0x4D05, 
-    0x4D0F, 0x4D1B, 0x4D27, 0x4D29, 0x4D2F, 0x4D33, 0x4D41, 0x4D51, 
-    0x4D59, 0x4D65, 0x4D6B, 0x4D81, 0x4D83, 0x4D8D, 0x4D95, 0x4D9B, 
-    0x4DB1, 0x4DB3, 0x4DC9, 0x4DCF, 0x4DD7, 0x4DE1, 0x4DED, 0x4DF9, 
-    0x4DFB, 0x4E05, 0x4E0B, 0x4E17, 0x4E19, 0x4E1D, 0x4E2B, 0x4E35, 
-    0x4E37, 0x4E3D, 0x4E4F, 0x4E53, 0x4E5F, 0x4E67, 0x4E79, 0x4E85, 
-    0x4E8B, 0x4E91, 0x4E95, 0x4E9B, 0x4EA1, 0x4EAF, 0x4EB3, 0x4EB5, 
-    0x4EC1, 0x4ECD, 0x4ED1, 0x4ED7, 0x4EE9, 0x4EFB, 0x4F07, 0x4F09, 
-    0x4F19, 0x4F25, 0x4F2D, 0x4F3F, 0x4F49, 0x4F63, 0x4F67, 0x4F6D, 
-    0x4F75, 0x4F7B, 0x4F81, 0x4F85, 0x4F87, 0x4F91, 0x4FA5, 0x4FA9, 
-    0x4FAF, 0x4FB7, 0x4FBB, 0x4FCF, 0x4FD9, 0x4FDB, 0x4FFD, 0x4FFF, 
-    0x5003, 0x501B, 0x501D, 0x5029, 0x5035, 0x503F, 0x5045, 0x5047, 
-    0x5053, 0x5071, 0x5077, 0x5083, 0x5093, 0x509F, 0x50A1, 0x50B7, 
-    0x50C9, 0x50D5, 0x50E3, 0x50ED, 0x50EF, 0x50FB, 0x5107, 0x510B, 
-    0x510D, 0x5111, 0x5117, 0x5123, 0x5125, 0x5135, 0x5147, 0x5149, 
-    0x5171, 0x5179, 0x5189, 0x518F, 0x5197, 0x51A1, 0x51A3, 0x51A7, 
-    0x51B9, 0x51C1, 0x51CB, 0x51D3, 0x51DF, 0x51E3, 0x51F5, 0x51F7, 
-    0x5209, 0x5213, 0x5215, 0x5219, 0x521B, 0x521F, 0x5227, 0x5243, 
-    0x5245, 0x524B, 0x5261, 0x526D, 0x5273, 0x5281, 0x5293, 0x5297, 
-    0x529D, 0x52A5, 0x52AB, 0x52B1, 0x52BB, 0x52C3, 0x52C7, 0x52C9, 
-    0x52DB, 0x52E5, 0x52EB, 0x52FF, 0x5315, 0x531D, 0x5323, 0x5341, 
-    0x5345, 0x5347, 0x534B, 0x535D, 0x5363, 0x5381, 0x5383, 0x5387, 
-    0x538F, 0x5395, 0x5399, 0x539F, 0x53AB, 0x53B9, 0x53DB, 0x53E9, 
-    0x53EF, 0x53F3, 0x53F5, 0x53FB, 0x53FF, 0x540D, 0x5411, 0x5413, 
-    0x5419, 0x5435, 0x5437, 0x543B, 0x5441, 0x5449, 0x5453, 0x5455, 
-    0x545F, 0x5461, 0x546B, 0x546D, 0x5471, 0x548F, 0x5491, 0x549D, 
-    0x54A9, 0x54B3, 0x54C5, 0x54D1, 0x54DF, 0x54E9, 0x54EB, 0x54F7, 
-    0x54FD, 0x5507, 0x550D, 0x551B, 0x5527, 0x552B, 0x5539, 0x553D, 
-    0x554F, 0x5551, 0x555B, 0x5563, 0x5567, 0x556F, 0x5579, 0x5585, 
-    0x5597, 0x55A9, 0x55B1, 0x55B7, 0x55C9, 0x55D9, 0x55E7, 0x55ED, 
-    0x55F3, 0x55FD, 0x560B, 0x560F, 0x5615, 0x5617, 0x5623, 0x562F, 
-    0x5633, 0x5639, 0x563F, 0x564B, 0x564D, 0x565D, 0x565F, 0x566B, 
-    0x5671, 0x5675, 0x5683, 0x5689, 0x568D, 0x568F, 0x569B, 0x56AD, 
-    0x56B1, 0x56D5, 0x56E7, 0x56F3, 0x56FF, 0x5701, 0x5705, 0x5707, 
-    0x570B, 0x5713, 0x571F, 0x5723, 0x5747, 0x574D, 0x575F, 0x5761, 
-    0x576D, 0x5777, 0x577D, 0x5789, 0x57A1, 0x57A9, 0x57AF, 0x57B5, 
-    0x57C5, 0x57D1, 0x57D3, 0x57E5, 0x57EF, 0x5803, 0x580D, 0x580F, 
-    0x5815, 0x5827, 0x582B, 0x582D, 0x5855, 0x585B, 0x585D, 0x586D, 
-    0x586F, 0x5873, 0x587B, 0x588D, 0x5897, 0x58A3, 0x58A9, 0x58AB, 
-    0x58B5, 0x58BD, 0x58C1, 0x58C7, 0x58D3, 0x58D5, 0x58DF, 0x58F1, 
-    0x58F9, 0x58FF, 0x5903, 0x5917, 0x591B, 0x5921, 0x5945, 0x594B, 
-    0x594D, 0x5957, 0x595D, 0x5975, 0x597B, 0x5989, 0x5999, 0x599F, 
-    0x59B1, 0x59B3, 0x59BD, 0x59D1, 0x59DB, 0x59E3, 0x59E9, 0x59ED, 
-    0x59F3, 0x59F5, 0x59FF, 0x5A01, 0x5A0D, 0x5A11, 0x5A13, 0x5A17, 
-    0x5A1F, 0x5A29, 0x5A2F, 0x5A3B, 0x5A4D, 0x5A5B, 0x5A67, 0x5A77, 
-    0x5A7F, 0x5A85, 0x5A95, 0x5A9D, 0x5AA1, 0x5AA3, 0x5AA9, 0x5ABB, 
-    0x5AD3, 0x5AE5, 0x5AEF, 0x5AFB, 0x5AFD, 0x5B01, 0x5B0F, 0x5B19, 
-    0x5B1F, 0x5B25, 0x5B2B, 0x5B3D, 0x5B49, 0x5B4B, 0x5B67, 0x5B79, 
-    0x5B87, 0x5B97, 0x5BA3, 0x5BB1, 0x5BC9, 0x5BD5, 0x5BEB, 0x5BF1, 
-    0x5BF3, 0x5BFD, 0x5C05, 0x5C09, 0x5C0B, 0x5C0F, 0x5C1D, 0x5C29,
-    0x5C2F, 0x5C33, 0x5C39, 0x5C47, 0x5C4B, 0x5C4D, 0x5C51, 0x5C6F, 
-    0x5C75, 0x5C77, 0x5C7D, 0x5C87, 0x5C89, 0x5CA7, 0x5CBD, 0x5CBF, 
-    0x5CC3, 0x5CC9, 0x5CD1, 0x5CD7, 0x5CDD, 0x5CED, 0x5CF9, 0x5D05, 
-    0x5D0B, 0x5D13, 0x5D17, 0x5D19, 0x5D31, 0x5D3D, 0x5D41, 0x5D47, 
-    0x5D4F, 0x5D55, 0x5D5B, 0x5D65, 0x5D67, 0x5D6D, 0x5D79, 0x5D95, 
-    0x5DA3, 0x5DA9, 0x5DAD, 0x5DB9, 0x5DC1, 0x5DC7, 0x5DD3, 0x5DD7, 
-    0x5DDD, 0x5DEB, 0x5DF1, 0x5DFD, 0x5E07, 0x5E0D, 0x5E13, 0x5E1B, 
-    0x5E21, 0x5E27, 0x5E2B, 0x5E2D, 0x5E31, 0x5E39, 0x5E45, 0x5E49, 
-    0x5E57, 0x5E69, 0x5E73, 0x5E75, 0x5E85, 0x5E8B, 0x5E9F, 0x5EA5, 
-    0x5EAF, 0x5EB7, 0x5EBB, 0x5ED9, 0x5EFD, 0x5F09, 0x5F11, 0x5F27, 
-    0x5F33, 0x5F35, 0x5F3B, 0x5F47, 0x5F57, 0x5F5D, 0x5F63, 0x5F65, 
-    0x5F77, 0x5F7B, 0x5F95, 0x5F99, 0x5FA1, 0x5FB3, 0x5FBD, 0x5FC5, 
-    0x5FCF, 0x5FD5, 0x5FE3, 0x5FE7, 0x5FFB, 0x6011, 0x6023, 0x602F, 
-    0x6037, 0x6053, 0x605F, 0x6065, 0x606B, 0x6073, 0x6079, 0x6085, 
-    0x609D, 0x60AD, 0x60BB, 0x60BF, 0x60CD, 0x60D9, 0x60DF, 0x60E9, 
-    0x60F5, 0x6109, 0x610F, 0x6113, 0x611B, 0x612D, 0x6139, 0x614B, 
-    0x6155, 0x6157, 0x615B, 0x616F, 0x6179, 0x6187, 0x618B, 0x6191, 
-    0x6193, 0x619D, 0x61B5, 0x61C7, 0x61C9, 0x61CD, 0x61E1, 0x61F1, 
-    0x61FF, 0x6209, 0x6217, 0x621D, 0x6221, 0x6227, 0x623B, 0x6241, 
-    0x624B, 0x6251, 0x6253, 0x625F, 0x6265, 0x6283, 0x628D, 0x6295, 
-    0x629B, 0x629F, 0x62A5, 0x62AD, 0x62D5, 0x62D7, 0x62DB, 0x62DD, 
-    0x62E9, 0x62FB, 0x62FF, 0x6305, 0x630D, 0x6317, 0x631D, 0x632F, 
-    0x6341, 0x6343, 0x634F, 0x635F, 0x6367, 0x636D, 0x6371, 0x6377, 
-    0x637D, 0x637F, 0x63B3, 0x63C1, 0x63C5, 0x63D9, 0x63E9, 0x63EB, 
-    0x63EF, 0x63F5, 0x6401, 0x6403, 0x6409, 0x6415, 0x6421, 0x6427, 
-    0x642B, 0x6439, 0x6443, 0x6449, 0x644F, 0x645D, 0x6467, 0x6475, 
-    0x6485, 0x648D, 0x6493, 0x649F, 0x64A3, 0x64AB, 0x64C1, 0x64C7, 
-    0x64C9, 0x64DB, 0x64F1, 0x64F7, 0x64F9, 0x650B, 0x6511, 0x6521, 
-    0x652F, 0x6539, 0x653F, 0x654B, 0x654D, 0x6553, 0x6557, 0x655F, 
-    0x6571, 0x657D, 0x658D, 0x658F, 0x6593, 0x65A1, 0x65A5, 0x65AD, 
-    0x65B9, 0x65C5, 0x65E3, 0x65F3, 0x65FB, 0x65FF, 0x6601, 0x6607, 
-    0x661D, 0x6629, 0x6631, 0x663B, 0x6641, 0x6647, 0x664D, 0x665B, 
-    0x6661, 0x6673, 0x667D, 0x6689, 0x668B, 0x6695, 0x6697, 0x669B, 
-    0x66B5, 0x66B9, 0x66C5, 0x66CD, 0x66D1, 0x66E3, 0x66EB, 0x66F5, 
-    0x6703, 0x6713, 0x6719, 0x671F, 0x6727, 0x6731, 0x6737, 0x673F, 
-    0x6745, 0x6751, 0x675B, 0x676F, 0x6779, 0x6781, 0x6785, 0x6791, 
-    0x67AB, 0x67BD, 0x67C1, 0x67CD, 0x67DF, 0x67E5, 0x6803, 0x6809, 
-    0x6811, 0x6817, 0x682D, 0x6839, 0x683B, 0x683F, 0x6845, 0x684B, 
-    0x684D, 0x6857, 0x6859, 0x685D, 0x6863, 0x6869, 0x686B, 0x6871, 
-    0x6887, 0x6899, 0x689F, 0x68B1, 0x68BD, 0x68C5, 0x68D1, 0x68D7, 
-    0x68E1, 0x68ED, 0x68EF, 0x68FF, 0x6901, 0x690B, 0x690D, 0x6917, 
-    0x6929, 0x692F, 0x6943, 0x6947, 0x6949, 0x694F, 0x6965, 0x696B, 
-    0x6971, 0x6983, 0x6989, 0x6997, 0x69A3, 0x69B3, 0x69B5, 0x69BB, 
-    0x69C1, 0x69C5, 0x69D3, 0x69DF, 0x69E3, 0x69E5, 0x69F7, 0x6A07, 
-    0x6A2B, 0x6A37, 0x6A3D, 0x6A4B, 0x6A67, 0x6A69, 0x6A75, 0x6A7B, 
-    0x6A87, 0x6A8D, 0x6A91, 0x6A93, 0x6AA3, 0x6AC1, 0x6AC9, 0x6AE1, 
-    0x6AE7, 0x6B05, 0x6B0F, 0x6B11, 0x6B23, 0x6B27, 0x6B2D, 0x6B39, 
-    0x6B41, 0x6B57, 0x6B59, 0x6B5F, 0x6B75, 0x6B87, 0x6B89, 0x6B93, 
-    0x6B95, 0x6B9F, 0x6BBD, 0x6BBF, 0x6BDB, 0x6BE1, 0x6BEF, 0x6BFF, 
-    0x6C05, 0x6C19, 0x6C29, 0x6C2B, 0x6C31, 0x6C35, 0x6C55, 0x6C59, 
-    0x6C5B, 0x6C5F, 0x6C65, 0x6C67, 0x6C73, 0x6C77, 0x6C7D, 0x6C83, 
-    0x6C8F, 0x6C91, 0x6C97, 0x6C9B, 0x6CA1, 0x6CA9, 0x6CAF, 0x6CB3, 
-    0x6CC7, 0x6CCB, 0x6CEB, 0x6CF5, 0x6CFD, 0x6D0D, 0x6D0F, 0x6D25, 
-    0x6D27, 0x6D2B, 0x6D31, 0x6D39, 0x6D3F, 0x6D4F, 0x6D5D, 0x6D61, 
-    0x6D73, 0x6D7B, 0x6D7F, 0x6D93, 0x6D99, 0x6DA5, 0x6DB1, 0x6DB7, 
-    0x6DC1, 0x6DC3, 0x6DCD, 0x6DCF, 0x6DDB, 0x6DF7, 0x6E03, 0x6E15, 
-    0x6E17, 0x6E29, 0x6E33, 0x6E3B, 0x6E45, 0x6E75, 0x6E77, 0x6E7B, 
-    0x6E81, 0x6E89, 0x6E93, 0x6E95, 0x6E9F, 0x6EBD, 0x6EBF, 0x6EE3, 
-    0x6EE9, 0x6EF3, 0x6EF9, 0x6EFB, 0x6F0D, 0x6F11, 0x6F17, 0x6F1F, 
-    0x6F2F, 0x6F3D, 0x6F4D, 0x6F53, 0x6F61, 0x6F65, 0x6F79, 0x6F7D, 
-    0x6F83, 0x6F85, 0x6F8F, 0x6F9B, 0x6F9D, 0x6FA3, 0x6FAF, 0x6FB5, 
-    0x6FBB, 0x6FBF, 0x6FCB, 0x6FCD, 0x6FD3, 0x6FD7, 0x6FE3, 0x6FE9, 
-    0x6FF1, 0x6FF5, 0x6FF7, 0x6FFD, 0x700F, 0x7019, 0x701F, 0x7027, 
-    0x7033, 0x7039, 0x704F, 0x7051, 0x7057, 0x7063, 0x7075, 0x7079, 
-    0x7087, 0x708D, 0x7091, 0x70A5, 0x70AB, 0x70BB, 0x70C3, 0x70C7, 
-    0x70CF, 0x70E5, 0x70ED, 0x70F9, 0x70FF, 0x7105, 0x7115, 0x7121, 
-    0x7133, 0x7151, 0x7159, 0x715D, 0x715F, 0x7163, 0x7169, 0x7183, 
-    0x7187, 0x7195, 0x71AD, 0x71C3, 0x71C9, 0x71CB, 0x71D1, 0x71DB, 
-    0x71E1, 0x71EF, 0x71F5, 0x71FB, 0x7207, 0x7211, 0x7217, 0x7219, 
-    0x7225, 0x722F, 0x723B, 0x7243, 0x7255, 0x7267, 0x7271, 0x7277, 
-    0x727F, 0x728F, 0x7295, 0x729B, 0x72A3, 0x72B3, 0x72C7, 0x72CB, 
-    0x72CD, 0x72D7, 0x72D9, 0x72E3, 0x72EF, 0x72F5, 0x72FD, 0x7303, 
-    0x730D, 0x7321, 0x732B, 0x733D, 0x7357, 0x735B, 0x7361, 0x737F, 
-    0x7381, 0x7385, 0x738D, 0x7393, 0x739F, 0x73AB, 0x73BD, 0x73C1, 
-    0x73C9, 0x73DF, 0x73E5, 0x73E7, 0x73F3, 0x7415, 0x741B, 0x742D, 
-    0x7439, 0x743F, 0x7441, 0x745D, 0x746B, 0x747B, 0x7489, 0x748D, 
-    0x749B, 0x74A7, 0x74AB, 0x74B1, 0x74B7, 0x74B9, 0x74DD, 0x74E1, 
-    0x74E7, 0x74FB, 0x7507, 0x751F, 0x7525, 0x753B, 0x753D, 0x754D, 
-    0x755F, 0x756B, 0x7577, 0x7589, 0x758B, 0x7591, 0x7597, 0x759D, 
-    0x75A1, 0x75A7, 0x75B5, 0x75B9, 0x75BB, 0x75D1, 0x75D9, 0x75E5, 
-    0x75EB, 0x75F5, 0x75FB, 0x7603, 0x760F, 0x7621, 0x762D, 0x7633, 
-    0x763D, 0x763F, 0x7655, 0x7663, 0x7669, 0x766F, 0x7673, 0x7685, 
-    0x768B, 0x769F, 0x76B5, 0x76B7, 0x76C3, 0x76DB, 0x76DF, 0x76F1, 
-    0x7703, 0x7705, 0x771B, 0x771D, 0x7721, 0x772D, 0x7735, 0x7741, 
-    0x774B, 0x7759, 0x775D, 0x775F, 0x7771, 0x7781, 0x77A7, 0x77AD, 
-    0x77B3, 0x77B9, 0x77C5, 0x77CF, 0x77D5, 0x77E1, 0x77E9, 0x77EF, 
-    0x77F3, 0x77F9, 0x7807, 0x7825, 0x782B, 0x7835, 0x783D, 0x7853, 
-    0x7859, 0x7861, 0x786D, 0x7877, 0x7879, 0x7883, 0x7885, 0x788B, 
-    0x7895, 0x7897, 0x78A1, 0x78AD, 0x78BF, 0x78D3, 0x78D9, 0x78DD, 
-    0x78E5, 0x78FB, 0x7901, 0x7907, 0x7925, 0x792B, 0x7939, 0x793F, 
-    0x794B, 0x7957, 0x795D, 0x7967, 0x7969, 0x7973, 0x7991, 0x7993, 
-    0x79A3, 0x79AB, 0x79AF, 0x79B1, 0x79B7, 0x79C9, 0x79CD, 0x79CF, 
-    0x79D5, 0x79D9, 0x79F3, 0x79F7, 0x79FF, 0x7A05, 0x7A0F, 0x7A11, 
-    0x7A15, 0x7A1B, 0x7A23, 0x7A27, 0x7A2D, 0x7A4B, 0x7A57, 0x7A59, 
-    0x7A5F, 0x7A65, 0x7A69, 0x7A7D, 0x7A93, 0x7A9B, 0x7A9F, 0x7AA1, 
-    0x7AA5, 0x7AED, 0x7AF5, 0x7AF9, 0x7B01, 0x7B17, 0x7B19, 0x7B1D, 
-    0x7B2B, 0x7B35, 0x7B37, 0x7B3B, 0x7B4F, 0x7B55, 0x7B5F, 0x7B71, 
-    0x7B77, 0x7B8B, 0x7B9B, 0x7BA1, 0x7BA9, 0x7BAF, 0x7BB3, 0x7BC7, 
-    0x7BD3, 0x7BE9, 0x7BEB, 0x7BEF, 0x7BF1, 0x7BFD, 0x7C07, 0x7C19, 
-    0x7C1B, 0x7C31, 0x7C37, 0x7C49, 0x7C67, 0x7C69, 0x7C73, 0x7C81, 
-    0x7C8B, 0x7C93, 0x7CA3, 0x7CD5, 0x7CDB, 0x7CE5, 0x7CED, 0x7CF7, 
-    0x7D03, 0x7D09, 0x7D1B, 0x7D1D, 0x7D33, 0x7D39, 0x7D3B, 0x7D3F, 
-    0x7D45, 0x7D4D, 0x7D53, 0x7D59, 0x7D63, 0x7D75, 0x7D77, 0x7D8D, 
-    0x7D8F, 0x7D9F, 0x7DAD, 0x7DB7, 0x7DBD, 0x7DBF, 0x7DCB, 0x7DD5, 
-    0x7DE9, 0x7DED, 0x7DFB, 0x7E01, 0x7E05, 0x7E29, 0x7E2B, 0x7E2F, 
-    0x7E35, 0x7E41, 0x7E43, 0x7E47, 0x7E55, 0x7E61, 0x7E67, 0x7E6B, 
-    0x7E71, 0x7E73, 0x7E79, 0x7E7D, 0x7E91, 0x7E9B, 0x7E9D, 0x7EA7, 
-    0x7EAD, 0x7EB9, 0x7EBB, 0x7ED3, 0x7EDF, 0x7EEB, 0x7EF1, 0x7EF7, 
-    0x7EFB, 0x7F13, 0x7F15, 0x7F19, 0x7F31, 0x7F33, 0x7F39, 0x7F3D, 
-    0x7F43, 0x7F4B, 0x7F5B, 0x7F61, 0x7F63, 0x7F6D, 0x7F79, 0x7F87, 
-    0x7F8D, 0x7FAF, 0x7FB5, 0x7FC3, 0x7FC9, 0x7FCD, 0x7FCF, 0x7FED, 
-    0x8003, 0x800B, 0x800F, 0x8015, 0x801D, 0x8021, 0x8023, 0x803F, 
-    0x8041, 0x8047, 0x804B, 0x8065, 0x8077, 0x808D, 0x808F, 0x8095, 
-    0x80A5, 0x80AB, 0x80AD, 0x80BD, 0x80C9, 0x80CB, 0x80D7, 0x80DB, 
-    0x80E1, 0x80E7, 0x80F5, 0x80FF, 0x8105, 0x810D, 0x8119, 0x811D, 
-    0x812F, 0x8131, 0x813B, 0x8143, 0x8153, 0x8159, 0x815F, 0x817D, 
-    0x817F, 0x8189, 0x819B, 0x819D, 0x81A7, 0x81AF, 0x81B3, 0x81BB, 
-    0x81C7, 0x81DF, 0x8207, 0x8209, 0x8215, 0x821F, 0x8225, 0x8231, 
-    0x8233, 0x823F, 0x8243, 0x8245, 0x8249, 0x824F, 0x8261, 0x826F, 
-    0x827B, 0x8281, 0x8285, 0x8293, 0x82B1, 0x82B5, 0x82BD, 0x82C7, 
-    0x82CF, 0x82D5, 0x82DF, 0x82F1, 0x82F9, 0x82FD, 0x830B, 0x831B, 
-    0x8321, 0x8329, 0x832D, 0x8333, 0x8335, 0x833F, 0x8341, 0x834D, 
-    0x8351, 0x8353, 0x8357, 0x835D, 0x8365, 0x8369, 0x836F, 0x838F, 
-    0x83A7, 0x83B1, 0x83B9, 0x83CB, 0x83D5, 0x83D7, 0x83DD, 0x83E7, 
-    0x83E9, 0x83ED, 0x83FF, 0x8405, 0x8411, 0x8413, 0x8423, 0x8425, 
-    0x843B, 0x8441, 0x8447, 0x844F, 0x8461, 0x8465, 0x8477, 0x8483, 
-    0x848B, 0x8491, 0x8495, 0x84A9, 0x84AF, 0x84CD, 0x84E3, 0x84EF, 
-    0x84F1, 0x84F7, 0x8509, 0x850D, 0x854B, 0x854F, 0x8551, 0x855D, 
-    0x8563, 0x856D, 0x856F, 0x857B, 0x8587, 0x85A3, 0x85A5, 0x85A9, 
-    0x85B7, 0x85CD, 0x85D3, 0x85D5, 0x85DB, 0x85E1, 0x85EB, 0x85F9, 
-    0x85FD, 0x85FF, 0x8609, 0x860F, 0x8617, 0x8621, 0x862F, 0x8639, 
-    0x863F, 0x8641, 0x864D, 0x8663, 0x8675, 0x867D, 0x8687, 0x8699, 
-    0x86A5, 0x86A7, 0x86B3, 0x86B7, 0x86C3, 0x86C5, 0x86CF, 0x86D1, 
-    0x86D7, 0x86E9, 0x86EF, 0x86F5, 0x8717, 0x871D, 0x871F, 0x872B, 
-    0x872F, 0x8735, 0x8747, 0x8759, 0x875B, 0x876B, 0x8771, 0x8777, 
-    0x877F, 0x8785, 0x878F, 0x87A1, 0x87A9, 0x87B3, 0x87BB, 0x87C5, 
-    0x87C7, 0x87CB, 0x87DD, 0x87F7, 0x8803, 0x8819, 0x881B, 0x881F, 
-    0x8821, 0x8837, 0x883D, 0x8843, 0x8851, 0x8861, 0x8867, 0x887B, 
-    0x8885, 0x8891, 0x8893, 0x88A5, 0x88CF, 0x88D3, 0x88EB, 0x88ED, 
-    0x88F3, 0x88FD, 0x8909, 0x890B, 0x8911, 0x891B, 0x8923, 0x8927, 
-    0x892D, 0x8939, 0x8945, 0x894D, 0x8951, 0x8957, 0x8963, 0x8981, 
-    0x8995, 0x899B, 0x89B3, 0x89B9, 0x89C3, 0x89CF, 0x89D1, 0x89DB, 
-    0x89EF, 0x89F5, 0x89FB, 0x89FF, 0x8A0B, 0x8A19, 0x8A23, 0x8A35, 
-    0x8A41, 0x8A49, 0x8A4F, 0x8A5B, 0x8A5F, 0x8A6D, 0x8A77, 0x8A79, 
-    0x8A85, 0x8AA3, 0x8AB3, 0x8AB5, 0x8AC1, 0x8AC7, 0x8ACB, 0x8ACD, 
-    0x8AD1, 0x8AD7, 0x8AF1, 0x8AF5, 0x8B07, 0x8B09, 0x8B0D, 0x8B13, 
-    0x8B21, 0x8B57, 0x8B5D, 0x8B91, 0x8B93, 0x8BA3, 0x8BA9, 0x8BAF, 
-    0x8BBB, 0x8BD5, 0x8BD9, 0x8BDB, 0x8BE1, 0x8BF7, 0x8BFD, 0x8BFF, 
-    0x8C0B, 0x8C17, 0x8C1D, 0x8C27, 0x8C39, 0x8C3B, 0x8C47, 0x8C53, 
-    0x8C5D, 0x8C6F, 0x8C7B, 0x8C81, 0x8C89, 0x8C8F, 0x8C99, 0x8C9F, 
-    0x8CA7, 0x8CAB, 0x8CAD, 0x8CB1, 0x8CC5, 0x8CDD, 0x8CE3, 0x8CE9, 
-    0x8CF3, 0x8D01, 0x8D0B, 0x8D0D, 0x8D23, 0x8D29, 0x8D37, 0x8D41, 
-    0x8D5B, 0x8D5F, 0x8D71, 0x8D79, 0x8D85, 0x8D91, 0x8D9B, 0x8DA7, 
-    0x8DAD, 0x8DB5, 0x8DC5, 0x8DCB, 0x8DD3, 0x8DD9, 0x8DDF, 0x8DF5, 
-    0x8DF7, 0x8E01, 0x8E15, 0x8E1F, 0x8E25, 0x8E51, 0x8E63, 0x8E69, 
-    0x8E73, 0x8E75, 0x8E79, 0x8E7F, 0x8E8D, 0x8E91, 0x8EAB, 0x8EAF, 
-    0x8EB1, 0x8EBD, 0x8EC7, 0x8ECF, 0x8ED3, 0x8EDB, 0x8EE7, 0x8EEB, 
-    0x8EF7, 0x8EFF, 0x8F15, 0x8F1D, 0x8F23, 0x8F2D, 0x8F3F, 0x8F45, 
-    0x8F4B, 0x8F53, 0x8F59, 0x8F65, 0x8F69, 0x8F71, 0x8F83, 0x8F8D, 
-    0x8F99, 0x8F9F, 0x8FAB, 0x8FAD, 0x8FB3, 0x8FB7, 0x8FB9, 0x8FC9, 
-    0x8FD5, 0x8FE1, 0x8FEF, 0x8FF9, 0x9007, 0x900D, 0x9017, 0x9023, 
-    0x9025, 0x9031, 0x9037, 0x903B, 0x9041, 0x9043, 0x904F, 0x9053, 
-    0x906D, 0x9073, 0x9085, 0x908B, 0x9095, 0x909B, 0x909D, 0x90AF, 
-    0x90B9, 0x90C1, 0x90C5, 0x90DF, 0x90E9, 0x90FD, 0x9103, 0x9113, 
-    0x9127, 0x9133, 0x913D, 0x9145, 0x914F, 0x9151, 0x9161, 0x9167, 
-    0x917B, 0x9185, 0x9199, 0x919D, 0x91BB, 0x91BD, 0x91C1, 0x91C9, 
-    0x91D9, 0x91DB, 0x91ED, 0x91F1, 0x91F3, 0x91F9, 0x9203, 0x9215, 
-    0x9221, 0x922F, 0x9241, 0x9247, 0x9257, 0x926B, 0x9271, 0x9275, 
-    0x927D, 0x9283, 0x9287, 0x928D, 0x9299, 0x92A1, 0x92AB, 0x92AD, 
-    0x92B9, 0x92BF, 0x92C3, 0x92C5, 0x92CB, 0x92D5, 0x92D7, 0x92E7, 
-    0x92F3, 0x9301, 0x930B, 0x9311, 0x9319, 0x931F, 0x933B, 0x933D, 
-    0x9343, 0x9355, 0x9373, 0x9395, 0x9397, 0x93A7, 0x93B3, 0x93B5, 
-    0x93C7, 0x93D7, 0x93DD, 0x93E5, 0x93EF, 0x93F7, 0x9401, 0x9409, 
-    0x9413, 0x943F, 0x9445, 0x944B, 0x944F, 0x9463, 0x9467, 0x9469, 
-    0x946D, 0x947B, 0x9497, 0x949F, 0x94A5, 0x94B5, 0x94C3, 0x94E1, 
-    0x94E7, 0x9505, 0x9509, 0x9517, 0x9521, 0x9527, 0x952D, 0x9535, 
-    0x9539, 0x954B, 0x9557, 0x955D, 0x955F, 0x9575, 0x9581, 0x9589, 
-    0x958F, 0x959B, 0x959F, 0x95AD, 0x95B1, 0x95B7, 0x95B9, 0x95BD, 
-    0x95CF, 0x95E3, 0x95E9, 0x95F9, 0x961F, 0x962F, 0x9631, 0x9635, 
-    0x963B, 0x963D, 0x9665, 0x968F, 0x969D, 0x96A1, 0x96A7, 0x96A9, 
-    0x96C1, 0x96CB, 0x96D1, 0x96D3, 0x96E5, 0x96EF, 0x96FB, 0x96FD, 
-    0x970D, 0x970F, 0x9715, 0x9725, 0x972B, 0x9733, 0x9737, 0x9739, 
-    0x9743, 0x9749, 0x9751, 0x975B, 0x975D, 0x976F, 0x977F, 0x9787, 
-    0x9793, 0x97A5, 0x97B1, 0x97B7, 0x97C3, 0x97CD, 0x97D3, 0x97D9, 
-    0x97EB, 0x97F7, 0x9805, 0x9809, 0x980B, 0x9815, 0x9829, 0x982F, 
-    0x983B, 0x9841, 0x9851, 0x986B, 0x986F, 0x9881, 0x9883, 0x9887, 
-    0x98A7, 0x98B1, 0x98B9, 0x98BF, 0x98C3, 0x98C9, 0x98CF, 0x98DD, 
-    0x98E3, 0x98F5, 0x98F9, 0x98FB, 0x990D, 0x9917, 0x991F, 0x9929, 
-    0x9931, 0x993B, 0x993D, 0x9941, 0x9947, 0x9949, 0x9953, 0x997D, 
-    0x9985, 0x9991, 0x9995, 0x999B, 0x99AD, 0x99AF, 0x99BF, 0x99C7, 
-    0x99CB, 0x99CD, 0x99D7, 0x99E5, 0x99F1, 0x99FB, 0x9A0F, 0x9A13, 
-    0x9A1B, 0x9A25, 0x9A4B, 0x9A4F, 0x9A55, 0x9A57, 0x9A61, 0x9A75, 
-    0x9A7F, 0x9A8B, 0x9A91, 0x9A9D, 0x9AB7, 0x9AC3, 0x9AC7, 0x9ACF, 
-    0x9AEB, 0x9AF3, 0x9AF7, 0x9AFF, 0x9B17, 0x9B1D, 0x9B27, 0x9B2F, 
-    0x9B35, 0x9B45, 0x9B51, 0x9B59, 0x9B63, 0x9B6F, 0x9B77, 0x9B8D, 
-    0x9B93, 0x9B95, 0x9B9F, 0x9BA1, 0x9BA7, 0x9BB1, 0x9BB7, 0x9BBD, 
-    0x9BC5, 0x9BCB, 0x9BCF, 0x9BDD, 0x9BF9, 0x9C01, 0x9C11, 0x9C23, 
-    0x9C2B, 0x9C2F, 0x9C35, 0x9C49, 0x9C4D, 0x9C5F, 0x9C65, 0x9C67, 
-    0x9C7F, 0x9C97, 0x9C9D, 0x9CA3, 0x9CAF, 0x9CBB, 0x9CBF, 0x9CC1, 
-    0x9CD7, 0x9CD9, 0x9CE3, 0x9CE9, 0x9CF1, 0x9CFD, 0x9D01, 0x9D15, 
-    0x9D27, 0x9D2D, 0x9D31, 0x9D3D, 0x9D55, 0x9D5B, 0x9D61, 0x9D97, 
-    0x9D9F, 0x9DA5, 0x9DA9, 0x9DC3, 0x9DE7, 0x9DEB, 0x9DED, 0x9DF1, 
-    0x9E0B, 0x9E17, 0x9E23, 0x9E27, 0x9E2D, 0x9E33, 0x9E3B, 0x9E47, 
-    0x9E51, 0x9E53, 0x9E5F, 0x9E6F, 0x9E81, 0x9E87, 0x9E8F, 0x9E95, 
-    0x9EA1, 0x9EB3, 0x9EBD, 0x9EBF, 0x9EF5, 0x9EF9, 0x9EFB, 0x9F05, 
-    0x9F23, 0x9F2F, 0x9F37, 0x9F3B, 0x9F43, 0x9F53, 0x9F61, 0x9F6D, 
-    0x9F73, 0x9F77, 0x9F7D, 0x9F89, 0x9F8F, 0x9F91, 0x9F95, 0x9FA3, 
-    0x9FAF, 0x9FB3, 0x9FC1, 0x9FC7, 0x9FDF, 0x9FE5, 0x9FEB, 0x9FF5, 
-    0xA001, 0xA00D, 0xA021, 0xA033, 0xA039, 0xA03F, 0xA04F, 0xA057, 
-    0xA05B, 0xA061, 0xA075, 0xA079, 0xA099, 0xA09D, 0xA0AB, 0xA0B5, 
-    0xA0B7, 0xA0BD, 0xA0C9, 0xA0D9, 0xA0DB, 0xA0DF, 0xA0E5, 0xA0F1, 
-    0xA0F3, 0xA0FD, 0xA105, 0xA10B, 0xA10F, 0xA111, 0xA11B, 0xA129, 
-    0xA12F, 0xA135, 0xA141, 0xA153, 0xA175, 0xA17D, 0xA187, 0xA18D, 
-    0xA1A5, 0xA1AB, 0xA1AD, 0xA1B7, 0xA1C3, 0xA1C5, 0xA1E3, 0xA1ED, 
-    0xA1FB, 0xA207, 0xA213, 0xA223, 0xA229, 0xA22F, 0xA231, 0xA243, 
-    0xA247, 0xA24D, 0xA26B, 0xA279, 0xA27D, 0xA283, 0xA289, 0xA28B, 
-    0xA291, 0xA295, 0xA29B, 0xA2A9, 0xA2AF, 0xA2B3, 0xA2BB, 0xA2C5, 
-    0xA2D1, 0xA2D7, 0xA2F7, 0xA301, 0xA309, 0xA31F, 0xA321, 0xA32B, 
-    0xA331, 0xA349, 0xA351, 0xA355, 0xA373, 0xA379, 0xA37B, 0xA387, 
-    0xA397, 0xA39F, 0xA3A5, 0xA3A9, 0xA3AF, 0xA3B7, 0xA3C7, 0xA3D5, 
-    0xA3DB, 0xA3E1, 0xA3E5, 0xA3E7, 0xA3F1, 0xA3FD, 0xA3FF, 0xA40F, 
-    0xA41D, 0xA421, 0xA423, 0xA427, 0xA43B, 0xA44D, 0xA457, 0xA459, 
-    0xA463, 0xA469, 0xA475, 0xA493, 0xA49B, 0xA4AD, 0xA4B9, 0xA4C3, 
-    0xA4C5, 0xA4CB, 0xA4D1, 0xA4D5, 0xA4E1, 0xA4ED, 0xA4EF, 0xA4F3, 
-    0xA4FF, 0xA511, 0xA529, 0xA52B, 0xA535, 0xA53B, 0xA543, 0xA553, 
-    0xA55B, 0xA561, 0xA56D, 0xA577, 0xA585, 0xA58B, 0xA597, 0xA59D, 
-    0xA5A3, 0xA5A7, 0xA5A9, 0xA5C1, 0xA5C5, 0xA5CB, 0xA5D3, 0xA5D9, 
-    0xA5DD, 0xA5DF, 0xA5E3, 0xA5E9, 0xA5F7, 0xA5FB, 0xA603, 0xA60D, 
-    0xA625, 0xA63D, 0xA649, 0xA64B, 0xA651, 0xA65D, 0xA673, 0xA691, 
-    0xA693, 0xA699, 0xA6AB, 0xA6B5, 0xA6BB, 0xA6C1, 0xA6C9, 0xA6CD, 
-    0xA6CF, 0xA6D5, 0xA6DF, 0xA6E7, 0xA6F1, 0xA6F7, 0xA6FF, 0xA70F, 
-    0xA715, 0xA723, 0xA729, 0xA72D, 0xA745, 0xA74D, 0xA757, 0xA759, 
-    0xA765, 0xA76B, 0xA76F, 0xA793, 0xA795, 0xA7AB, 0xA7B1, 0xA7B9, 
-    0xA7BF, 0xA7C9, 0xA7D1, 0xA7D7, 0xA7E3, 0xA7ED, 0xA7FB, 0xA805, 
-    0xA80B, 0xA81D, 0xA829, 0xA82B, 0xA837, 0xA83B, 0xA855, 0xA85F, 
-    0xA86D, 0xA87D, 0xA88F, 0xA897, 0xA8A9, 0xA8B5, 0xA8C1, 0xA8C7, 
-    0xA8D7, 0xA8E5, 0xA8FD, 0xA907, 0xA913, 0xA91B, 0xA931, 0xA937, 
-    0xA939, 0xA943, 0xA97F, 0xA985, 0xA987, 0xA98B, 0xA993, 0xA9A3, 
-    0xA9B1, 0xA9BB, 0xA9C1, 0xA9D9, 0xA9DF, 0xA9EB, 0xA9FD, 0xAA15, 
-    0xAA17, 0xAA35, 0xAA39, 0xAA3B, 0xAA47, 0xAA4D, 0xAA57, 0xAA59, 
-    0xAA5D, 0xAA6B, 0xAA71, 0xAA81, 0xAA83, 0xAA8D, 0xAA95, 0xAAAB, 
-    0xAABF, 0xAAC5, 0xAAC9, 0xAAE9, 0xAAEF, 0xAB01, 0xAB05, 0xAB07, 
-    0xAB0B, 0xAB0D, 0xAB11, 0xAB19, 0xAB4D, 0xAB5B, 0xAB71, 0xAB73, 
-    0xAB89, 0xAB9D, 0xABA7, 0xABAF, 0xABB9, 0xABBB, 0xABC1, 0xABC5, 
-    0xABD3, 0xABD7, 0xABDD, 0xABF1, 0xABF5, 0xABFB, 0xABFD, 0xAC09, 
-    0xAC15, 0xAC1B, 0xAC27, 0xAC37, 0xAC39, 0xAC45, 0xAC4F, 0xAC57, 
-    0xAC5B, 0xAC61, 0xAC63, 0xAC7F, 0xAC8B, 0xAC93, 0xAC9D, 0xACA9, 
-    0xACAB, 0xACAF, 0xACBD, 0xACD9, 0xACE1, 0xACE7, 0xACEB, 0xACED, 
-    0xACF1, 0xACF7, 0xACF9, 0xAD05, 0xAD3F, 0xAD45, 0xAD53, 0xAD5D, 
-    0xAD5F, 0xAD65, 0xAD81, 0xADA1, 0xADA5, 0xADC3, 0xADCB, 0xADD1, 
-    0xADD5, 0xADDB, 0xADE7, 0xADF3, 0xADF5, 0xADF9, 0xADFF, 0xAE05, 
-    0xAE13, 0xAE23, 0xAE2B, 0xAE49, 0xAE4D, 0xAE4F, 0xAE59, 0xAE61, 
-    0xAE67, 0xAE6B, 0xAE71, 0xAE8B, 0xAE8F, 0xAE9B, 0xAE9D, 0xAEA7, 
-    0xAEB9, 0xAEC5, 0xAED1, 0xAEE3, 0xAEE5, 0xAEE9, 0xAEF5, 0xAEFD, 
-    0xAF09, 0xAF13, 0xAF27, 0xAF2B, 0xAF33, 0xAF43, 0xAF4F, 0xAF57, 
-    0xAF5D, 0xAF6D, 0xAF75, 0xAF7F, 0xAF8B, 0xAF99, 0xAF9F, 0xAFA3, 
-    0xAFAB, 0xAFB7, 0xAFBB, 0xAFCF, 0xAFD5, 0xAFFD, 0xB005, 0xB015, 
-    0xB01B, 0xB03F, 0xB041, 0xB047, 0xB04B, 0xB051, 0xB053, 0xB069, 
-    0xB07B, 0xB07D, 0xB087, 0xB08D, 0xB0B1, 0xB0BF, 0xB0CB, 0xB0CF, 
-    0xB0E1, 0xB0E9, 0xB0ED, 0xB0FB, 0xB105, 0xB107, 0xB111, 0xB119, 
-    0xB11D, 0xB11F, 0xB131, 0xB141, 0xB14D, 0xB15B, 0xB165, 0xB173, 
-    0xB179, 0xB17F, 0xB1A9, 0xB1B3, 0xB1B9, 0xB1BF, 0xB1D3, 0xB1DD, 
-    0xB1E5, 0xB1F1, 0xB1F5, 0xB201, 0xB213, 0xB215, 0xB21F, 0xB22D, 
-    0xB23F, 0xB249, 0xB25B, 0xB263, 0xB269, 0xB26D, 0xB27B, 0xB281, 
-    0xB28B, 0xB2A9, 0xB2B7, 0xB2BD, 0xB2C3, 0xB2C7, 0xB2D3, 0xB2F9, 
-    0xB2FD, 0xB2FF, 0xB303, 0xB309, 0xB311, 0xB31D, 0xB327, 0xB32D, 
-    0xB33F, 0xB345, 0xB377, 0xB37D, 0xB381, 0xB387, 0xB393, 0xB39B, 
-    0xB3A5, 0xB3C5, 0xB3CB, 0xB3E1, 0xB3E3, 0xB3ED, 0xB3F9, 0xB40B, 
-    0xB40D, 0xB413, 0xB417, 0xB435, 0xB43D, 0xB443, 0xB449, 0xB45B, 
-    0xB465, 0xB467, 0xB46B, 0xB477, 0xB48B, 0xB495, 0xB49D, 0xB4B5, 
-    0xB4BF, 0xB4C1, 0xB4C7, 0xB4DD, 0xB4E3, 0xB4E5, 0xB4F7, 0xB501, 
-    0xB50D, 0xB50F, 0xB52D, 0xB53F, 0xB54B, 0xB567, 0xB569, 0xB56F, 
-    0xB573, 0xB579, 0xB587, 0xB58D, 0xB599, 0xB5A3, 0xB5AB, 0xB5AF, 
-    0xB5BB, 0xB5D5, 0xB5DF, 0xB5E7, 0xB5ED, 0xB5FD, 0xB5FF, 0xB609, 
-    0xB61B, 0xB629, 0xB62F, 0xB633, 0xB639, 0xB647, 0xB657, 0xB659, 
-    0xB65F, 0xB663, 0xB66F, 0xB683, 0xB687, 0xB69B, 0xB69F, 0xB6A5, 
-    0xB6B1, 0xB6B3, 0xB6D7, 0xB6DB, 0xB6E1, 0xB6E3, 0xB6ED, 0xB6EF, 
-    0xB705, 0xB70D, 0xB713, 0xB71D, 0xB729, 0xB735, 0xB747, 0xB755, 
-    0xB76D, 0xB791, 0xB795, 0xB7A9, 0xB7C1, 0xB7CB, 0xB7D1, 0xB7D3, 
-    0xB7EF, 0xB7F5, 0xB807, 0xB80F, 0xB813, 0xB819, 0xB821, 0xB827, 
-    0xB82B, 0xB82D, 0xB839, 0xB855, 0xB867, 0xB875, 0xB885, 0xB893, 
-    0xB8A5, 0xB8AF, 0xB8B7, 0xB8BD, 0xB8C1, 0xB8C7, 0xB8CD, 0xB8D5, 
-    0xB8EB, 0xB8F7, 0xB8F9, 0xB903, 0xB915, 0xB91B, 0xB91D, 0xB92F, 
-    0xB939, 0xB93B, 0xB947, 0xB951, 0xB963, 0xB983, 0xB989, 0xB98D, 
-    0xB993, 0xB999, 0xB9A1, 0xB9A7, 0xB9AD, 0xB9B7, 0xB9CB, 0xB9D1, 
-    0xB9DD, 0xB9E7, 0xB9EF, 0xB9F9, 0xBA07, 0xBA0D, 0xBA17, 0xBA25, 
-    0xBA29, 0xBA2B, 0xBA41, 0xBA53, 0xBA55, 0xBA5F, 0xBA61, 0xBA65, 
-    0xBA79, 0xBA7D, 0xBA7F, 0xBAA1, 0xBAA3, 0xBAAF, 0xBAB5, 0xBABF, 
-    0xBAC1, 0xBACB, 0xBADD, 0xBAE3, 0xBAF1, 0xBAFD, 0xBB09, 0xBB1F, 
-    0xBB27, 0xBB2D, 0xBB3D, 0xBB43, 0xBB4B, 0xBB4F, 0xBB5B, 0xBB61, 
-    0xBB69, 0xBB6D, 0xBB91, 0xBB97, 0xBB9D, 0xBBB1, 0xBBC9, 0xBBCF, 
-    0xBBDB, 0xBBED, 0xBBF7, 0xBBF9, 0xBC03, 0xBC1D, 0xBC23, 0xBC33, 
-    0xBC3B, 0xBC41, 0xBC45, 0xBC5D, 0xBC6F, 0xBC77, 0xBC83, 0xBC8F, 
-    0xBC99, 0xBCAB, 0xBCB7, 0xBCB9, 0xBCD1, 0xBCD5, 0xBCE1, 0xBCF3, 
-    0xBCFF, 0xBD0D, 0xBD17, 0xBD19, 0xBD1D, 0xBD35, 0xBD41, 0xBD4F, 
-    0xBD59, 0xBD5F, 0xBD61, 0xBD67, 0xBD6B, 0xBD71, 0xBD8B, 0xBD8F, 
-    0xBD95, 0xBD9B, 0xBD9D, 0xBDB3, 0xBDBB, 0xBDCD, 0xBDD1, 0xBDE3, 
-    0xBDEB, 0xBDEF, 0xBE07, 0xBE09, 0xBE15, 0xBE21, 0xBE25, 0xBE27, 
-    0xBE5B, 0xBE5D, 0xBE6F, 0xBE75, 0xBE79, 0xBE7F, 0xBE8B, 0xBE8D, 
-    0xBE93, 0xBE9F, 0xBEA9, 0xBEB1, 0xBEB5, 0xBEB7, 0xBECF, 0xBED9, 
-    0xBEDB, 0xBEE5, 0xBEE7, 0xBEF3, 0xBEF9, 0xBF0B, 0xBF33, 0xBF39, 
-    0xBF4D, 0xBF5D, 0xBF5F, 0xBF6B, 0xBF71, 0xBF7B, 0xBF87, 0xBF89, 
-    0xBF8D, 0xBF93, 0xBFA1, 0xBFAD, 0xBFB9, 0xBFCF, 0xBFD5, 0xBFDD, 
-    0xBFE1, 0xBFE3, 0xBFF3, 0xC005, 0xC011, 0xC013, 0xC019, 0xC029, 
-    0xC02F, 0xC031, 0xC037, 0xC03B, 0xC047, 0xC065, 0xC06D, 0xC07D, 
-    0xC07F, 0xC091, 0xC09B, 0xC0B3, 0xC0B5, 0xC0BB, 0xC0D3, 0xC0D7, 
-    0xC0D9, 0xC0EF, 0xC0F1, 0xC101, 0xC103, 0xC109, 0xC115, 0xC119, 
-    0xC12B, 0xC133, 0xC137, 0xC145, 0xC149, 0xC15B, 0xC173, 0xC179, 
-    0xC17B, 0xC181, 0xC18B, 0xC18D, 0xC197, 0xC1BD, 0xC1C3, 0xC1CD, 
-    0xC1DB, 0xC1E1, 0xC1E7, 0xC1FF, 0xC203, 0xC205, 0xC211, 0xC221, 
-    0xC22F, 0xC23F, 0xC24B, 0xC24D, 0xC253, 0xC25D, 0xC277, 0xC27B, 
-    0xC27D, 0xC289, 0xC28F, 0xC293, 0xC29F, 0xC2A7, 0xC2B3, 0xC2BD, 
-    0xC2CF, 0xC2D5, 0xC2E3, 0xC2FF, 0xC301, 0xC307, 0xC311, 0xC313, 
-    0xC317, 0xC325, 0xC347, 0xC349, 0xC34F, 0xC365, 0xC367, 0xC371, 
-    0xC37F, 0xC383, 0xC385, 0xC395, 0xC39D, 0xC3A7, 0xC3AD, 0xC3B5, 
-    0xC3BF, 0xC3C7, 0xC3CB, 0xC3D1, 0xC3D3, 0xC3E3, 0xC3E9, 0xC3EF, 
-    0xC401, 0xC41F, 0xC42D, 0xC433, 0xC437, 0xC455, 0xC457, 0xC461, 
-    0xC46F, 0xC473, 0xC487, 0xC491, 0xC499, 0xC49D, 0xC4A5, 0xC4B7, 
-    0xC4BB, 0xC4C9, 0xC4CF, 0xC4D3, 0xC4EB, 0xC4F1, 0xC4F7, 0xC509, 
-    0xC51B, 0xC51D, 0xC541, 0xC547, 0xC551, 0xC55F, 0xC56B, 0xC56F, 
-    0xC575, 0xC577, 0xC595, 0xC59B, 0xC59F, 0xC5A1, 0xC5A7, 0xC5C3, 
-    0xC5D7, 0xC5DB, 0xC5EF, 0xC5FB, 0xC613, 0xC623, 0xC635, 0xC641, 
-    0xC64F, 0xC655, 0xC659, 0xC665, 0xC685, 0xC691, 0xC697, 0xC6A1, 
-    0xC6A9, 0xC6B3, 0xC6B9, 0xC6CB, 0xC6CD, 0xC6DD, 0xC6EB, 0xC6F1, 
-    0xC707, 0xC70D, 0xC719, 0xC71B, 0xC72D, 0xC731, 0xC739, 0xC757, 
-    0xC763, 0xC767, 0xC773, 0xC775, 0xC77F, 0xC7A5, 0xC7BB, 0xC7BD, 
-    0xC7C1, 0xC7CF, 0xC7D5, 0xC7E1, 0xC7F9, 0xC7FD, 0xC7FF, 0xC803, 
-    0xC811, 0xC81D, 0xC827, 0xC829, 0xC839, 0xC83F, 0xC853, 0xC857, 
-    0xC86B, 0xC881, 0xC88D, 0xC88F, 0xC893, 0xC895, 0xC8A1, 0xC8B7, 
-    0xC8CF, 0xC8D5, 0xC8DB, 0xC8DD, 0xC8E3, 0xC8E7, 0xC8ED, 0xC8EF, 
-    0xC8F9, 0xC905, 0xC911, 0xC917, 0xC919, 0xC91F, 0xC92F, 0xC937, 
-    0xC93D, 0xC941, 0xC953, 0xC95F, 0xC96B, 0xC979, 0xC97D, 0xC989, 
-    0xC98F, 0xC997, 0xC99D, 0xC9AF, 0xC9B5, 0xC9BF, 0xC9CB, 0xC9D9, 
-    0xC9DF, 0xC9E3, 0xC9EB, 0xCA01, 0xCA07, 0xCA09, 0xCA25, 0xCA37, 
-    0xCA39, 0xCA4B, 0xCA55, 0xCA5B, 0xCA69, 0xCA73, 0xCA75, 0xCA7F, 
-    0xCA8D, 0xCA93, 0xCA9D, 0xCA9F, 0xCAB5, 0xCABB, 0xCAC3, 0xCAC9, 
-    0xCAD9, 0xCAE5, 0xCAED, 0xCB03, 0xCB05, 0xCB09, 0xCB17, 0xCB29, 
-    0xCB35, 0xCB3B, 0xCB53, 0xCB59, 0xCB63, 0xCB65, 0xCB71, 0xCB87, 
-    0xCB99, 0xCB9F, 0xCBB3, 0xCBB9, 0xCBC3, 0xCBD1, 0xCBD5, 0xCBD7, 
-    0xCBDD, 0xCBE9, 0xCBFF, 0xCC0D, 0xCC19, 0xCC1D, 0xCC23, 0xCC2B, 
-    0xCC41, 0xCC43, 0xCC4D, 0xCC59, 0xCC61, 0xCC89, 0xCC8B, 0xCC91, 
-    0xCC9B, 0xCCA3, 0xCCA7, 0xCCD1, 0xCCE5, 0xCCE9, 0xCD09, 0xCD15, 
-    0xCD1F, 0xCD25, 0xCD31, 0xCD3D, 0xCD3F, 0xCD49, 0xCD51, 0xCD57, 
-    0xCD5B, 0xCD63, 0xCD67, 0xCD81, 0xCD93, 0xCD97, 0xCD9F, 0xCDBB, 
-    0xCDC1, 0xCDD3, 0xCDD9, 0xCDE5, 0xCDE7, 0xCDF1, 0xCDF7, 0xCDFD, 
-    0xCE0B, 0xCE15, 0xCE21, 0xCE2F, 0xCE47, 0xCE4D, 0xCE51, 0xCE65, 
-    0xCE7B, 0xCE7D, 0xCE8F, 0xCE93, 0xCE99, 0xCEA5, 0xCEA7, 0xCEB7, 
-    0xCEC9, 0xCED7, 0xCEDD, 0xCEE3, 0xCEE7, 0xCEED, 0xCEF5, 0xCF07, 
-    0xCF0B, 0xCF19, 0xCF37, 0xCF3B, 0xCF4D, 0xCF55, 0xCF5F, 0xCF61, 
-    0xCF65, 0xCF6D, 0xCF79, 0xCF7D, 0xCF89, 0xCF9B, 0xCF9D, 0xCFA9, 
-    0xCFB3, 0xCFB5, 0xCFC5, 0xCFCD, 0xCFD1, 0xCFEF, 0xCFF1, 0xCFF7, 
-    0xD013, 0xD015, 0xD01F, 0xD021, 0xD033, 0xD03D, 0xD04B, 0xD04F, 
-    0xD069, 0xD06F, 0xD081, 0xD085, 0xD099, 0xD09F, 0xD0A3, 0xD0AB, 
-    0xD0BD, 0xD0C1, 0xD0CD, 0xD0E7, 0xD0FF, 0xD103, 0xD117, 0xD12D, 
-    0xD12F, 0xD141, 0xD157, 0xD159, 0xD15D, 0xD169, 0xD16B, 0xD171, 
-    0xD177, 0xD17D, 0xD181, 0xD187, 0xD195, 0xD199, 0xD1B1, 0xD1BD, 
-    0xD1C3, 0xD1D5, 0xD1D7, 0xD1E3, 0xD1FF, 0xD20D, 0xD211, 0xD217, 
-    0xD21F, 0xD235, 0xD23B, 0xD247, 0xD259, 0xD261, 0xD265, 0xD279, 
-    0xD27F, 0xD283, 0xD289, 0xD28B, 0xD29D, 0xD2A3, 0xD2A7, 0xD2B3, 
-    0xD2BF, 0xD2C7, 0xD2E3, 0xD2E9, 0xD2F1, 0xD2FB, 0xD2FD, 0xD315, 
-    0xD321, 0xD32B, 0xD343, 0xD34B, 0xD355, 0xD369, 0xD375, 0xD37B, 
-    0xD387, 0xD393, 0xD397, 0xD3A5, 0xD3B1, 0xD3C9, 0xD3EB, 0xD3FD, 
-    0xD405, 0xD40F, 0xD415, 0xD427, 0xD42F, 0xD433, 0xD43B, 0xD44B, 
-    0xD459, 0xD45F, 0xD463, 0xD469, 0xD481, 0xD483, 0xD489, 0xD48D, 
-    0xD493, 0xD495, 0xD4A5, 0xD4AB, 0xD4B1, 0xD4C5, 0xD4DD, 0xD4E1, 
-    0xD4E3, 0xD4E7, 0xD4F5, 0xD4F9, 0xD50B, 0xD50D, 0xD513, 0xD51F, 
-    0xD523, 0xD531, 0xD535, 0xD537, 0xD549, 0xD559, 0xD55F, 0xD565, 
-    0xD567, 0xD577, 0xD58B, 0xD591, 0xD597, 0xD5B5, 0xD5B9, 0xD5C1, 
-    0xD5C7, 0xD5DF, 0xD5EF, 0xD5F5, 0xD5FB, 0xD603, 0xD60F, 0xD62D, 
-    0xD631, 0xD643, 0xD655, 0xD65D, 0xD661, 0xD67B, 0xD685, 0xD687, 
-    0xD69D, 0xD6A5, 0xD6AF, 0xD6BD, 0xD6C3, 0xD6C7, 0xD6D9, 0xD6E1, 
-    0xD6ED, 0xD709, 0xD70B, 0xD711, 0xD715, 0xD721, 0xD727, 0xD73F, 
-    0xD745, 0xD74D, 0xD757, 0xD76B, 0xD77B, 0xD783, 0xD7A1, 0xD7A7, 
-    0xD7AD, 0xD7B1, 0xD7B3, 0xD7BD, 0xD7CB, 0xD7D1, 0xD7DB, 0xD7FB, 
-    0xD811, 0xD823, 0xD825, 0xD829, 0xD82B, 0xD82F, 0xD837, 0xD84D, 
-    0xD855, 0xD867, 0xD873, 0xD88F, 0xD891, 0xD8A1, 0xD8AD, 0xD8BF, 
-    0xD8CD, 0xD8D7, 0xD8E9, 0xD8F5, 0xD8FB, 0xD91B, 0xD925, 0xD933, 
-    0xD939, 0xD943, 0xD945, 0xD94F, 0xD951, 0xD957, 0xD96D, 0xD96F, 
-    0xD973, 0xD979, 0xD981, 0xD98B, 0xD991, 0xD99F, 0xD9A5, 0xD9A9, 
-    0xD9B5, 0xD9D3, 0xD9EB, 0xD9F1, 0xD9F7, 0xD9FF, 0xDA05, 0xDA09, 
-    0xDA0B, 0xDA0F, 0xDA15, 0xDA1D, 0xDA23, 0xDA29, 0xDA3F, 0xDA51, 
-    0xDA59, 0xDA5D, 0xDA5F, 0xDA71, 0xDA77, 0xDA7B, 0xDA7D, 0xDA8D, 
-    0xDA9F, 0xDAB3, 0xDABD, 0xDAC3, 0xDAC9, 0xDAE7, 0xDAE9, 0xDAF5, 
-    0xDB11, 0xDB17, 0xDB1D, 0xDB23, 0xDB25, 0xDB31, 0xDB3B, 0xDB43, 
-    0xDB55, 0xDB67, 0xDB6B, 0xDB73, 0xDB85, 0xDB8F, 0xDB91, 0xDBAD, 
-    0xDBAF, 0xDBB9, 0xDBC7, 0xDBCB, 0xDBCD, 0xDBEB, 0xDBF7, 0xDC0D, 
-    0xDC27, 0xDC31, 0xDC39, 0xDC3F, 0xDC49, 0xDC51, 0xDC61, 0xDC6F, 
-    0xDC75, 0xDC7B, 0xDC85, 0xDC93, 0xDC99, 0xDC9D, 0xDC9F, 0xDCA9, 
-    0xDCB5, 0xDCB7, 0xDCBD, 0xDCC7, 0xDCCF, 0xDCD3, 0xDCD5, 0xDCDF, 
-    0xDCF9, 0xDD0F, 0xDD15, 0xDD17, 0xDD23, 0xDD35, 0xDD39, 0xDD53, 
-    0xDD57, 0xDD5F, 0xDD69, 0xDD6F, 0xDD7D, 0xDD87, 0xDD89, 0xDD9B, 
-    0xDDA1, 0xDDAB, 0xDDBF, 0xDDC5, 0xDDCB, 0xDDCF, 0xDDE7, 0xDDE9, 
-    0xDDED, 0xDDF5, 0xDDFB, 0xDE0B, 0xDE19, 0xDE29, 0xDE3B, 0xDE3D, 
-    0xDE41, 0xDE4D, 0xDE4F, 0xDE59, 0xDE5B, 0xDE61, 0xDE6D, 0xDE77, 
-    0xDE7D, 0xDE83, 0xDE97, 0xDE9D, 0xDEA1, 0xDEA7, 0xDECD, 0xDED1, 
-    0xDED7, 0xDEE3, 0xDEF1, 0xDEF5, 0xDF01, 0xDF09, 0xDF13, 0xDF1F, 
-    0xDF2B, 0xDF33, 0xDF37, 0xDF3D, 0xDF4B, 0xDF55, 0xDF5B, 0xDF67, 
-    0xDF69, 0xDF73, 0xDF85, 0xDF87, 0xDF99, 0xDFA3, 0xDFAB, 0xDFB5, 
-    0xDFB7, 0xDFC3, 0xDFC7, 0xDFD5, 0xDFF1, 0xDFF3, 0xE003, 0xE005, 
-    0xE017, 0xE01D, 0xE027, 0xE02D, 0xE035, 0xE045, 0xE053, 0xE071, 
-    0xE07B, 0xE08F, 0xE095, 0xE09F, 0xE0B7, 0xE0B9, 0xE0D5, 0xE0D7, 
-    0xE0E3, 0xE0F3, 0xE0F9, 0xE101, 0xE125, 0xE129, 0xE131, 0xE135, 
-    0xE143, 0xE14F, 0xE159, 0xE161, 0xE16D, 0xE171, 0xE177, 0xE17F, 
-    0xE183, 0xE189, 0xE197, 0xE1AD, 0xE1B5, 0xE1BB, 0xE1BF, 0xE1C1, 
-    0xE1CB, 0xE1D1, 0xE1E5, 0xE1EF, 0xE1F7, 0xE1FD, 0xE203, 0xE219, 
-    0xE22B, 0xE22D, 0xE23D, 0xE243, 0xE257, 0xE25B, 0xE275, 0xE279, 
-    0xE287, 0xE29D, 0xE2AB, 0xE2AF, 0xE2BB, 0xE2C1, 0xE2C9, 0xE2CD, 
-    0xE2D3, 0xE2D9, 0xE2F3, 0xE2FD, 0xE2FF, 0xE311, 0xE323, 0xE327, 
-    0xE329, 0xE339, 0xE33B, 0xE34D, 0xE351, 0xE357, 0xE35F, 0xE363, 
-    0xE369, 0xE375, 0xE377, 0xE37D, 0xE383, 0xE39F, 0xE3C5, 0xE3C9, 
-    0xE3D1, 0xE3E1, 0xE3FB, 0xE3FF, 0xE401, 0xE40B, 0xE417, 0xE419, 
-    0xE423, 0xE42B, 0xE431, 0xE43B, 0xE447, 0xE449, 0xE453, 0xE455, 
-    0xE46D, 0xE471, 0xE48F, 0xE4A9, 0xE4AF, 0xE4B5, 0xE4C7, 0xE4CD, 
-    0xE4D3, 0xE4E9, 0xE4EB, 0xE4F5, 0xE507, 0xE521, 0xE525, 0xE537, 
-    0xE53F, 0xE545, 0xE54B, 0xE557, 0xE567, 0xE56D, 0xE575, 0xE585, 
-    0xE58B, 0xE593, 0xE5A3, 0xE5A5, 0xE5CF, 0xE609, 0xE611, 0xE615, 
-    0xE61B, 0xE61D, 0xE621, 0xE629, 0xE639, 0xE63F, 0xE653, 0xE657, 
-    0xE663, 0xE66F, 0xE675, 0xE681, 0xE683, 0xE68D, 0xE68F, 0xE695, 
-    0xE6AB, 0xE6AD, 0xE6B7, 0xE6BD, 0xE6C5, 0xE6CB, 0xE6D5, 0xE6E3, 
-    0xE6E9, 0xE6EF, 0xE6F3, 0xE705, 0xE70D, 0xE717, 0xE71F, 0xE72F, 
-    0xE73D, 0xE747, 0xE749, 0xE753, 0xE755, 0xE761, 0xE767, 0xE76B, 
-    0xE77F, 0xE789, 0xE791, 0xE7C5, 0xE7CD, 0xE7D7, 0xE7DD, 0xE7DF, 
-    0xE7E9, 0xE7F1, 0xE7FB, 0xE801, 0xE807, 0xE80F, 0xE819, 0xE81B, 
-    0xE831, 0xE833, 0xE837, 0xE83D, 0xE84B, 0xE84F, 0xE851, 0xE869, 
-    0xE875, 0xE879, 0xE893, 0xE8A5, 0xE8A9, 0xE8AF, 0xE8BD, 0xE8DB, 
-    0xE8E1, 0xE8E5, 0xE8EB, 0xE8ED, 0xE903, 0xE90B, 0xE90F, 0xE915, 
-    0xE917, 0xE92D, 0xE933, 0xE93B, 0xE94B, 0xE951, 0xE95F, 0xE963, 
-    0xE969, 0xE97B, 0xE983, 0xE98F, 0xE995, 0xE9A1, 0xE9B9, 0xE9D7, 
-    0xE9E7, 0xE9EF, 0xEA11, 0xEA19, 0xEA2F, 0xEA35, 0xEA43, 0xEA4D, 
-    0xEA5F, 0xEA6D, 0xEA71, 0xEA7D, 0xEA85, 0xEA89, 0xEAAD, 0xEAB3, 
-    0xEAB9, 0xEABB, 0xEAC5, 0xEAC7, 0xEACB, 0xEADF, 0xEAE5, 0xEAEB, 
-    0xEAF5, 0xEB01, 0xEB07, 0xEB09, 0xEB31, 0xEB39, 0xEB3F, 0xEB5B, 
-    0xEB61, 0xEB63, 0xEB6F, 0xEB81, 0xEB85, 0xEB9D, 0xEBAB, 0xEBB1, 
-    0xEBB7, 0xEBC1, 0xEBD5, 0xEBDF, 0xEBED, 0xEBFD, 0xEC0B, 0xEC1B, 
-    0xEC21, 0xEC29, 0xEC4D, 0xEC51, 0xEC5D, 0xEC69, 0xEC6F, 0xEC7B, 
-    0xECAD, 0xECB9, 0xECBF, 0xECC3, 0xECC9, 0xECCF, 0xECD7, 0xECDD, 
-    0xECE7, 0xECE9, 0xECF3, 0xECF5, 0xED07, 0xED11, 0xED1F, 0xED2F, 
-    0xED37, 0xED3D, 0xED41, 0xED55, 0xED59, 0xED5B, 0xED65, 0xED6B, 
-    0xED79, 0xED8B, 0xED95, 0xEDBB, 0xEDC5, 0xEDD7, 0xEDD9, 0xEDE3, 
-    0xEDE5, 0xEDF1, 0xEDF5, 0xEDF7, 0xEDFB, 0xEE09, 0xEE0F, 0xEE19, 
-    0xEE21, 0xEE49, 0xEE4F, 0xEE63, 0xEE67, 0xEE73, 0xEE7B, 0xEE81, 
-    0xEEA3, 0xEEAB, 0xEEC1, 0xEEC9, 0xEED5, 0xEEDF, 0xEEE1, 0xEEF1, 
-    0xEF1B, 0xEF27, 0xEF2F, 0xEF45, 0xEF4D, 0xEF63, 0xEF6B, 0xEF71, 
-    0xEF93, 0xEF95, 0xEF9B, 0xEF9F, 0xEFAD, 0xEFB3, 0xEFC3, 0xEFC5, 
-    0xEFDB, 0xEFE1, 0xEFE9, 0xF001, 0xF017, 0xF01D, 0xF01F, 0xF02B, 
-    0xF02F, 0xF035, 0xF043, 0xF047, 0xF04F, 0xF067, 0xF06B, 0xF071, 
-    0xF077, 0xF079, 0xF08F, 0xF0A3, 0xF0A9, 0xF0AD, 0xF0BB, 0xF0BF, 
-    0xF0C5, 0xF0CB, 0xF0D3, 0xF0D9, 0xF0E3, 0xF0E9, 0xF0F1, 0xF0F7, 
-    0xF107, 0xF115, 0xF11B, 0xF121, 0xF137, 0xF13D, 0xF155, 0xF175, 
-    0xF17B, 0xF18D, 0xF193, 0xF1A5, 0xF1AF, 0xF1B7, 0xF1D5, 0xF1E7, 
-    0xF1ED, 0xF1FD, 0xF209, 0xF20F, 0xF21B, 0xF21D, 0xF223, 0xF227, 
-    0xF233, 0xF23B, 0xF241, 0xF257, 0xF25F, 0xF265, 0xF269, 0xF277, 
-    0xF281, 0xF293, 0xF2A7, 0xF2B1, 0xF2B3, 0xF2B9, 0xF2BD, 0xF2BF, 
-    0xF2DB, 0xF2ED, 0xF2EF, 0xF2F9, 0xF2FF, 0xF305, 0xF30B, 0xF319, 
-    0xF341, 0xF359, 0xF35B, 0xF35F, 0xF367, 0xF373, 0xF377, 0xF38B, 
-    0xF38F, 0xF3AF, 0xF3C1, 0xF3D1, 0xF3D7, 0xF3FB, 0xF403, 0xF409, 
-    0xF40D, 0xF413, 0xF421, 0xF425, 0xF42B, 0xF445, 0xF44B, 0xF455, 
-    0xF463, 0xF475, 0xF47F, 0xF485, 0xF48B, 0xF499, 0xF4A3, 0xF4A9, 
-    0xF4AF, 0xF4BD, 0xF4C3, 0xF4DB, 0xF4DF, 0xF4ED, 0xF503, 0xF50B, 
-    0xF517, 0xF521, 0xF529, 0xF535, 0xF547, 0xF551, 0xF563, 0xF56B, 
-    0xF583, 0xF58D, 0xF595, 0xF599, 0xF5B1, 0xF5B7, 0xF5C9, 0xF5CF, 
-    0xF5D1, 0xF5DB, 0xF5F9, 0xF5FB, 0xF605, 0xF607, 0xF60B, 0xF60D, 
-    0xF635, 0xF637, 0xF653, 0xF65B, 0xF661, 0xF667, 0xF679, 0xF67F, 
-    0xF689, 0xF697, 0xF69B, 0xF6AD, 0xF6CB, 0xF6DD, 0xF6DF, 0xF6EB, 
-    0xF709, 0xF70F, 0xF72D, 0xF731, 0xF743, 0xF74F, 0xF751, 0xF755, 
-    0xF763, 0xF769, 0xF773, 0xF779, 0xF781, 0xF787, 0xF791, 0xF79D, 
-    0xF79F, 0xF7A5, 0xF7B1, 0xF7BB, 0xF7BD, 0xF7CF, 0xF7D3, 0xF7E7, 
-    0xF7EB, 0xF7F1, 0xF7FF, 0xF805, 0xF80B, 0xF821, 0xF827, 0xF82D, 
-    0xF835, 0xF847, 0xF859, 0xF863, 0xF865, 0xF86F, 0xF871, 0xF877, 
-    0xF87B, 0xF881, 0xF88D, 0xF89F, 0xF8A1, 0xF8AB, 0xF8B3, 0xF8B7, 
-    0xF8C9, 0xF8CB, 0xF8D1, 0xF8D7, 0xF8DD, 0xF8E7, 0xF8EF, 0xF8F9, 
-    0xF8FF, 0xF911, 0xF91D, 0xF925, 0xF931, 0xF937, 0xF93B, 0xF941, 
-    0xF94F, 0xF95F, 0xF961, 0xF96D, 0xF971, 0xF977, 0xF99D, 0xF9A3, 
-    0xF9A9, 0xF9B9, 0xF9CD, 0xF9E9, 0xF9FD, 0xFA07, 0xFA0D, 0xFA13, 
-    0xFA21, 0xFA25, 0xFA3F, 0xFA43, 0xFA51, 0xFA5B, 0xFA6D, 0xFA7B, 
-    0xFA97, 0xFA99, 0xFA9D, 0xFAAB, 0xFABB, 0xFABD, 0xFAD9, 0xFADF, 
-    0xFAE7, 0xFAED, 0xFB0F, 0xFB17, 0xFB1B, 0xFB2D, 0xFB2F, 0xFB3F, 
-    0xFB47, 0xFB4D, 0xFB75, 0xFB7D, 0xFB8F, 0xFB93, 0xFBB1, 0xFBB7, 
-    0xFBC3, 0xFBC5, 0xFBE3, 0xFBE9, 0xFBF3, 0xFC01, 0xFC29, 0xFC37, 
-    0xFC41, 0xFC43, 0xFC4F, 0xFC59, 0xFC61, 0xFC65, 0xFC6D, 0xFC73,
-    0xFC79, 0xFC95, 0xFC97, 0xFC9B, 0xFCA7, 0xFCB5, 0xFCC5, 0xFCCD, 
-    0xFCEB, 0xFCFB, 0xFD0D, 0xFD0F, 0xFD19, 0xFD2B, 0xFD31, 0xFD51, 
-    0xFD55, 0xFD67, 0xFD6D, 0xFD6F, 0xFD7B, 0xFD85, 0xFD97, 0xFD99, 
-    0xFD9F, 0xFDA9, 0xFDB7, 0xFDC9, 0xFDE5, 0xFDEB, 0xFDF3, 0xFE03, 
-    0xFE05, 0xFE09, 0xFE1D, 0xFE27, 0xFE2F, 0xFE41, 0xFE4B, 0xFE4D, 
-    0xFE57, 0xFE5F, 0xFE63, 0xFE69, 0xFE75, 0xFE7B, 0xFE8F, 0xFE93, 
-    0xFE95, 0xFE9B, 0xFE9F, 0xFEB3, 0xFEBD, 0xFED7, 0xFEE9, 0xFEF3, 
-    0xFEF5, 0xFF07, 0xFF0D, 0xFF1D, 0xFF2B, 0xFF2F, 0xFF49, 0xFF4D, 
-    0xFF5B, 0xFF65, 0xFF71, 0xFF7F, 0xFF85, 0xFF8B, 0xFF8F, 0xFF9D, 
-    0xFFA7, 0xFFA9, 0xFFC7, 0xFFD9, 0xFFEF, 0xFFF1 };
-#endif
+    0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 };    
 
 
-#define UPPER_LIMIT    (sizeof(prime_tab) / sizeof(prime_tab[0]))
 
 
 /* figures out if a number is prime (MR test) */
 /* figures out if a number is prime (MR test) */
 #ifdef CLEAN_STACK
 #ifdef CLEAN_STACK
@@ -885,16 +89,16 @@ int is_prime(mp_int *N, int *result)
     /* r = N - 1 */
     /* r = N - 1 */
     if (mp_copy(&n1, &r) != MP_OKAY)    { goto error; }
     if (mp_copy(&n1, &r) != MP_OKAY)    { goto error; }
 
 
-    /* find s such that N = (2^s)r */
+    /* find s such that N-1 = (2^s)r */
     s = 0;
     s = 0;
-    while (mp_iseven(&r) && mp_cmp_d(&r, 0)) {
+    while (mp_iseven(&r)) {
         ++s;
         ++s;
         if (mp_div_2(&r, &r) != MP_OKAY) {
         if (mp_div_2(&r, &r) != MP_OKAY) {
            goto error;
            goto error;
         }
         }
     }
     }
 
 
-    for (x = 0; x < 16; x++) {
+    for (x = 0; x < 8; x++) {
         /* choose a */
         /* choose a */
         mp_set(&a, prime_tab[x]);
         mp_set(&a, prime_tab[x]);
 
 
@@ -937,10 +141,101 @@ int is_prime(mp_int *N, int *result)
 }
 }
 #endif
 #endif
 
 
+static int next_prime(mp_int *N, mp_digit step)
+{
+    long x, s, j, total_dist;
+    int res;
+    mp_int n1, a, y, r;
+    mp_digit dist, residues[UPPER_LIMIT];
+    
+    _ARGCHK(N != NULL);
+
+    /* first find the residues */
+	for (x = 0; x < (long)UPPER_LIMIT; x++) {
+        if (mp_mod_d(N, prime_tab[x], &residues[x]) != MP_OKAY) {
+           return CRYPT_MEM;
+        }
+    }
+
+    /* init variables */
+    if (mp_init_multi(&r, &n1, &a, &y, NULL) != MP_OKAY) {
+       return CRYPT_MEM;
+    }
+    
+    total_dist = 0;
+loop:
+    /* while one of the residues is zero keep looping */
+    dist = step;
+    for (x = 0; (dist < 65000) && (x < (long)UPPER_LIMIT); x++) {
+        j = (long)residues[x] + (long)dist + total_dist;
+        if (j % (long)prime_tab[x] == 0) {
+           dist += step; x = -1;
+        }
+    }
+
+    /* recalc the total distance from where we started */
+    total_dist += dist;
+    
+    /* add to N */
+    if (mp_add_d(N, dist, N) != MP_OKAY) { goto error; }
+    
+    /* n1 = N - 1 */
+    if (mp_sub_d(N, 1, &n1) != MP_OKAY)  { goto error; }
+
+    /* r = N - 1 */
+    if (mp_copy(&n1, &r) != MP_OKAY)     { goto error; }
+
+    /* find s such that N-1 = (2^s)r */
+    s = 0;
+    while (mp_iseven(&r)) {
+        ++s;
+        if (mp_div_2(&r, &r) != MP_OKAY) {
+           goto error;
+        }
+    }
+
+    for (x = 0; x < 8; x++) {
+        /* choose a */
+        mp_set(&a, prime_tab[x]);
+
+        /* compute y = a^r mod n */
+        if (mp_exptmod(&a, &r, N, &y) != MP_OKAY)             { goto error; }
+
+        /* (y != 1) AND (y != N-1) */
+        if ((mp_cmp_d(&y, 1) != 0) && (mp_cmp(&y, &n1) != 0)) {
+            /* while j <= s-1 and y != n-1 */
+            for (j = 1; (j <= (s-1)) && (mp_cmp(&y, &n1) != 0); j++) {
+                /* y = y^2 mod N */
+                if (mp_sqrmod(&y, N, &y) != MP_OKAY)          { goto error; }
+
+                /* if y == 1 return false */
+                if (mp_cmp_d(&y, 1) == 0)                     { goto loop; }
+            }
+
+            /* if y != n-1 return false */
+            if (mp_cmp(&y, &n1) != 0)                         { goto loop; }
+        }
+    }
+
+    res = CRYPT_OK;
+    goto done;
+error:
+    res = CRYPT_MEM;
+done:
+    mp_clear_multi(&a, &y, &n1, &r, NULL);
+
+#ifdef CLEAN_STACK
+    zeromem(residues, sizeof(residues));
+#endif    
+    return res;
+}
+
+
+
 int rand_prime(mp_int *N, long len, prng_state *prng, int wprng)
 int rand_prime(mp_int *N, long len, prng_state *prng, int wprng)
 {
 {
    unsigned char buf[260];
    unsigned char buf[260];
-   int errno, step, ormask, res;
+   int errno, step, ormask;
 
 
    _ARGCHK(N != NULL);
    _ARGCHK(N != NULL);
 
 
@@ -986,14 +281,9 @@ int rand_prime(mp_int *N, long len, prng_state *prng, int wprng)
    }
    }
 
 
    /* add the step size to it while N is not prime */
    /* add the step size to it while N is not prime */
-   do {
-      if (mp_add_d(N, (mp_digit)step, N) != MP_OKAY) {
-         return CRYPT_MEM; 
-      }
-      if ((errno = is_prime(N, &res)) != CRYPT_OK) {
-         return errno;
-      }
-   } while (res == 0);
+   if ((errno = next_prime(N, step)) != CRYPT_OK) {
+      return errno;
+   }
 
 
 #ifdef CLEAN_STACK   
 #ifdef CLEAN_STACK   
    zeromem(buf, sizeof(buf));
    zeromem(buf, sizeof(buf));

+ 3 - 3
rsa.c

@@ -33,14 +33,14 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
        if (rand_prime(&p, size/2, prng, wprng) != CRYPT_OK) { res = CRYPT_ERROR; goto done; }
        if (rand_prime(&p, size/2, prng, wprng) != CRYPT_OK) { res = CRYPT_ERROR; goto done; }
        if (mp_sub_d(&p, 1, &tmp1) != MP_OKAY)              { goto error; }  /* tmp1 = p-1 */
        if (mp_sub_d(&p, 1, &tmp1) != MP_OKAY)              { goto error; }  /* tmp1 = p-1 */
        if (mp_gcd(&tmp1, &tmp3, &tmp2) != MP_OKAY)         { goto error; }  /* tmp2 = gcd(p-1, e) */
        if (mp_gcd(&tmp1, &tmp3, &tmp2) != MP_OKAY)         { goto error; }  /* tmp2 = gcd(p-1, e) */
-   } while (mp_cmp_d(&tmp2, 1) != 0);
+   } while (mp_cmp_d(&tmp2, 1) != 0);                                       /* while e divides p-1 */
        
        
    /* make prime "q" */
    /* make prime "q" */
    do {
    do {
        if (rand_prime(&q, size/2, prng, wprng) != CRYPT_OK) { res = CRYPT_ERROR; goto done; }
        if (rand_prime(&q, size/2, prng, wprng) != CRYPT_OK) { res = CRYPT_ERROR; goto done; }
        if (mp_sub_d(&q, 1, &tmp1) != MP_OKAY)              { goto error; } /* tmp1 = q-1 */
        if (mp_sub_d(&q, 1, &tmp1) != MP_OKAY)              { goto error; } /* tmp1 = q-1 */
        if (mp_gcd(&tmp1, &tmp3, &tmp2) != MP_OKAY)         { goto error; } /* tmp2 = gcd(q-1, e) */
        if (mp_gcd(&tmp1, &tmp3, &tmp2) != MP_OKAY)         { goto error; } /* tmp2 = gcd(q-1, e) */
-   } while (mp_cmp_d(&tmp2, 1) != 0);
+   } while (mp_cmp_d(&tmp2, 1) != 0);                                      /* while e divides q-1 */
 
 
    /* tmp1 = lcm(p-1, q-1) */
    /* tmp1 = lcm(p-1, q-1) */
    if (mp_sub_d(&p, 1, &tmp2) != MP_OKAY)                  { goto error; } /* tmp2 = p-1 */
    if (mp_sub_d(&p, 1, &tmp2) != MP_OKAY)                  { goto error; } /* tmp2 = p-1 */
@@ -191,7 +191,7 @@ int rsa_pad(const unsigned char *in,  unsigned long inlen,
                   unsigned char *out, unsigned long *outlen, 
                   unsigned char *out, unsigned long *outlen, 
                   int wprng, prng_state *prng)
                   int wprng, prng_state *prng)
 {
 {
-   unsigned char buf[2048];
+   unsigned char buf[1536];
    unsigned long x;
    unsigned long x;
    int errno;
    int errno;
 
 

+ 2 - 1
sha256.c

@@ -63,8 +63,9 @@ static void sha256_compress(hash_state * md)
     }
     }
 
 
     /* fill W[16..63] */
     /* fill W[16..63] */
-    for (i = 16; i < 64; i++)
+    for (i = 16; i < 64; i++) {
         W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
         W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
+    }        
 
 
     /* Compress */
     /* Compress */
     for (i = 0; i < 64; i++) {
     for (i = 0; i < 64; i++) {

+ 2 - 1
sha512.c

@@ -90,8 +90,9 @@ static void sha512_compress(hash_state * md)
     }
     }
 
 
     /* fill W[16..79] */
     /* fill W[16..79] */
-    for (i = 16; i < 80; i++)
+    for (i = 16; i < 80; i++) {
         W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
         W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
+    }        
 
 
     /* Compress */
     /* Compress */
     for (i = 0; i < 80; i++) {
     for (i = 0; i < 80; i++) {

+ 0 - 2
tiger.c

@@ -19,8 +19,6 @@ const struct _hash_descriptor tiger_desc =
 #define t3 (table+256*2)
 #define t3 (table+256*2)
 #define t4 (table+256*3)
 #define t4 (table+256*3)
 
 
-#define save_abc  aa = a; bb = b; cc = c;
-
 static const ulong64 table[4*256] = {
 static const ulong64 table[4*256] = {
     CONST64(0x02AAB17CF7E90C5E) /*    0 */, CONST64(0xAC424B03E243A8EC) /*    1 */,
     CONST64(0x02AAB17CF7E90C5E) /*    0 */, CONST64(0xAC424B03E243A8EC) /*    1 */,
     CONST64(0x72CD5BE30DD5FCD3) /*    2 */, CONST64(0x6D019B93F6F97F3A) /*    3 */,
     CONST64(0x72CD5BE30DD5FCD3) /*    2 */, CONST64(0x6D019B93F6F97F3A) /*    3 */,

+ 5 - 17
twofish.c

@@ -354,14 +354,7 @@ static void h_func(const unsigned char *in, unsigned char *out, unsigned char *M
 
 
 #ifndef TWOFISH_SMALL
 #ifndef TWOFISH_SMALL
 
 
-static unsigned long g_func(unsigned long x, symmetric_key *key)
-{
-   return
-       key->twofish.S[0][(x>>0)&255] ^
-       key->twofish.S[1][(x>>8)&255] ^
-       key->twofish.S[2][(x>>16)&255] ^
-       key->twofish.S[3][(x>>24)&255];
-}
+#define g_func(x,dum)  (key->twofish.S[0][((x)>>0)&255] ^ key->twofish.S[1][((x)>>8)&255] ^ key->twofish.S[2][((x)>>16)&255] ^ key->twofish.S[3][((x)>>24)&255])
 
 
 #else
 #else
 
 
@@ -538,7 +531,7 @@ void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
     c ^= key->twofish.K[2];
     c ^= key->twofish.K[2];
     d ^= key->twofish.K[3];
     d ^= key->twofish.K[3];
 
 
-    for (r = 0; r < 16; r += 2) {
+    for (r = 0; r < 16; ++r) {
         t1 = g_func(a, key);
         t1 = g_func(a, key);
         t2 = g_func(ROL(b, 8), key);
         t2 = g_func(ROL(b, 8), key);
         t2 += (t1 += t2);
         t2 += (t1 += t2);
@@ -546,14 +539,7 @@ void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
         t2 += key->twofish.K[r+r+9];
         t2 += key->twofish.K[r+r+9];
         c  ^= t1; c = ROR(c, 1);
         c  ^= t1; c = ROR(c, 1);
         d  = ROL(d, 1) ^ t2;
         d  = ROL(d, 1) ^ t2;
-
-        t1 = g_func(c, key);
-        t2 = g_func(ROL(d, 8), key);
-        t2 += (t1 += t2);
-        t1 += key->twofish.K[r+r+10];
-        t2 += key->twofish.K[r+r+11];
-        a ^= t1; a = ROR(a, 1);
-        b  = ROL(b, 1) ^ t2;
+        ta = a; a = c; c = ta; tb = b; b = d; d = tb;
     }
     }
 
 
     /* output with "undo last swap" */
     /* output with "undo last swap" */
@@ -598,6 +584,8 @@ void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
     c = ta ^ key->twofish.K[4];
     c = ta ^ key->twofish.K[4];
     d = tb ^ key->twofish.K[5];
     d = tb ^ key->twofish.K[5];
 
 
+    /* loop is kept partially unrolled because it is slower [at least on an Athlon]
+     * then the tight version.  */
     for (r = 14; r >= 0; r -= 2) {
     for (r = 14; r >= 0; r -= 2) {
         t1 = g_func(c, key);
         t1 = g_func(c, key);
         t2 = g_func(ROL(d, 8), key);
         t2 = g_func(ROL(d, 8), key);

+ 43 - 16
xtea.c

@@ -16,6 +16,8 @@ const struct _cipher_descriptor xtea_desc =
 
 
 int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
 int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
 {
 {
+   unsigned long x, sum, K[4];
+   
    _ARGCHK(key != NULL);
    _ARGCHK(key != NULL);
    _ARGCHK(skey != NULL);
    _ARGCHK(skey != NULL);
 
 
@@ -29,16 +31,27 @@ int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_k
    }
    }
 
 
    /* load key */
    /* load key */
-   LOAD32L(skey->xtea.K[0], key+0);
-   LOAD32L(skey->xtea.K[1], key+4);
-   LOAD32L(skey->xtea.K[2], key+8);
-   LOAD32L(skey->xtea.K[3], key+12);
+   LOAD32L(K[0], key+0);
+   LOAD32L(K[1], key+4);
+   LOAD32L(K[2], key+8);
+   LOAD32L(K[3], key+12);
+   
+   for (x = sum = 0; x < 32; x++) {
+       skey->xtea.A[x] = (sum + K[sum&3]) & 0xFFFFFFFFUL;
+       sum = (sum + 0x9E3779B9UL) & 0xFFFFFFFFUL;
+       skey->xtea.B[x] = (sum + K[(sum>>11)&3]) & 0xFFFFFFFFUL;
+   }
+   
+#ifdef CLEAN_STACK
+   zeromem(&K, sizeof(K));
+#endif   
+   
    return CRYPT_OK;
    return CRYPT_OK;
 }
 }
 
 
 void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
 void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
 {
 {
-   unsigned long y, z, sum;
+   unsigned long y, z;
    int r;
    int r;
 
 
    _ARGCHK(pt != NULL);
    _ARGCHK(pt != NULL);
@@ -47,11 +60,18 @@ void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
 
 
    LOAD32L(y, &pt[0]);
    LOAD32L(y, &pt[0]);
    LOAD32L(z, &pt[4]);
    LOAD32L(z, &pt[4]);
-   sum = 0;
-   for (r = 0; r < 32; r++) {
-       y = (y + ((((z<<4)^(z>>5)) + z) ^ (sum + key->xtea.K[sum&3]))) & 0xFFFFFFFFUL;
-       sum = (sum + 0x9E3779B9UL) & 0xFFFFFFFFUL;
-       z = (z + ((((y<<4)^(y>>5)) + y) ^ (sum + key->xtea.K[(sum>>11)&3]))) & 0xFFFFFFFFUL;
+   for (r = 0; r < 32; r += 4) {
+       y = (y + ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r])) & 0xFFFFFFFFUL;
+       z = (z + ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r])) & 0xFFFFFFFFUL;
+
+       y = (y + ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r+1])) & 0xFFFFFFFFUL;
+       z = (z + ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r+1])) & 0xFFFFFFFFUL;
+
+       y = (y + ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r+2])) & 0xFFFFFFFFUL;
+       z = (z + ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r+2])) & 0xFFFFFFFFUL;
+
+       y = (y + ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r+3])) & 0xFFFFFFFFUL;
+       z = (z + ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r+3])) & 0xFFFFFFFFUL;
    }
    }
    STORE32L(y, &ct[0]);
    STORE32L(y, &ct[0]);
    STORE32L(z, &ct[4]);
    STORE32L(z, &ct[4]);
@@ -59,7 +79,7 @@ void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
 
 
 void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
 void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
 {
 {
-   unsigned long y, z, sum;
+   unsigned long y, z;
    int r;
    int r;
 
 
    _ARGCHK(pt != NULL);
    _ARGCHK(pt != NULL);
@@ -68,11 +88,18 @@ void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key
 
 
    LOAD32L(y, &ct[0]);
    LOAD32L(y, &ct[0]);
    LOAD32L(z, &ct[4]);
    LOAD32L(z, &ct[4]);
-   sum = (32UL*0x9E3779B9UL)&0xFFFFFFFFUL;
-   for (r = 0; r < 32; r++) {
-       z = (z - ((((y<<4)^(y>>5)) + y) ^ (sum + key->xtea.K[(sum>>11)&3]))) & 0xFFFFFFFFUL;
-       sum = (sum - 0x9E3779B9UL) & 0xFFFFFFFFUL;
-       y = (y - ((((z<<4)^(z>>5)) + z) ^ (sum + key->xtea.K[sum&3]))) & 0xFFFFFFFFUL;
+   for (r = 31; r >= 0; r -= 4) {
+       z = (z - ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r])) & 0xFFFFFFFFUL;
+       y = (y - ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r])) & 0xFFFFFFFFUL;
+
+       z = (z - ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r-1])) & 0xFFFFFFFFUL;
+       y = (y - ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r-1])) & 0xFFFFFFFFUL;
+
+       z = (z - ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r-2])) & 0xFFFFFFFFUL;
+       y = (y - ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r-2])) & 0xFFFFFFFFUL;
+
+       z = (z - ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r-3])) & 0xFFFFFFFFUL;
+       y = (y - ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r-3])) & 0xFFFFFFFFUL;
    }
    }
    STORE32L(y, &pt[0]);
    STORE32L(y, &pt[0]);
    STORE32L(z, &pt[4]);
    STORE32L(z, &pt[4]);