[BACK]Return to ntlrsa.cpp CVS log [TXT][DIR] Up to [local] / OpenXM / src / ox_ntl / crypt / rsa

Annotation of OpenXM/src/ox_ntl/crypt/rsa/ntlrsa.cpp, Revision 1.2

1.2     ! iwane       1: /* $OpenXM: OpenXM/src/ox_ntl/crypt/rsa/ntlrsa.cpp,v 1.1 2004/05/16 15:04:54 iwane Exp $ */
1.1       iwane       2: /*-- References: RFC 3447 PKCS #1: RSA Encryption Version 2.1 --*/
                      3:
                      4: #include <stdio.h>
                      5: #include <string.h>
                      6:
                      7: #include <NTL/ZZ.h>
                      8:
                      9: #include "ntlrsa.h"
                     10:
                     11: //////////////////////////////////////////////////////////////////////////////
                     12: // static variable
                     13: //////////////////////////////////////////////////////////////////////////////
                     14: const ZZ NtlRsa::dummy = to_ZZ(-1);
                     15:
                     16: //////////////////////////////////////////////////////////////////////////////
                     17: // Operator
                     18: //////////////////////////////////////////////////////////////////////////////
                     19: ostream &
                     20: operator << (ostream &o, const NtlRsa &rsa)
                     21: {
                     22:        return (o << "[public[" << rsa.getPublicKey() << ",mod=" << rsa.getMod() << ",k=" << rsa.getModLen() << "],private[" << rsa.getPrivateKey() << "]");
                     23: }
                     24:
                     25:
                     26:
                     27: //////////////////////////////////////////////////////////////////////////////
                     28: // Constructor/Destructor
                     29: //////////////////////////////////////////////////////////////////////////////
                     30: NtlRsa::NtlRsa(void) // sample for test
                     31: {
                     32:        setKeys(to_ZZ(1231 * 4567), to_ZZ(65537), to_ZZ(3988493));
                     33: }
                     34:
                     35: NtlRsa::NtlRsa(int seed, int bit)
                     36: {
                     37:        keygen(seed, bit);
                     38: }
                     39:
                     40: NtlRsa::NtlRsa(ZZ &mod, ZZ &publicKey, ZZ &privateKey) {
                     41:        setKeys(mod, publicKey, privateKey);
                     42: }
                     43:
                     44: NtlRsa::NtlRsa(ZZ &mod, ZZ &publicKey) {
                     45:        setKeys(mod, publicKey);
                     46: }
                     47:
                     48:
                     49: void
                     50: NtlRsa::keygen(const char *seed_str, int bit)
                     51: {
                     52:        int seed = 0;
                     53:        const char *p = seed_str;
                     54:
                     55:        for (; *p != '\0'; p++) {
                     56:                seed = seed << 5 + *p;
                     57:        }
                     58:
                     59:        keygen(seed, bit);
                     60: }
                     61:
                     62: void
                     63: NtlRsa::keygen(int seed, int bit)
                     64: {
                     65:        // at least 512 bit
                     66:        keygen(seed, bit, mod, publicKey, privateKey);
                     67:        k = getBlockSize(mod);
                     68: }
                     69:
                     70: void
                     71: NtlRsa::keygen(int seed, int bit, ZZ &n, ZZ &e, ZZ &d)
                     72: {
                     73:        ZZ gcd, phi;
                     74:        ZZ p, q;
                     75:
                     76:        e = to_ZZ(65537); // or 3, 11 ...
                     77:
                     78:        SetSeed(to_ZZ(seed));
                     79:
                     80:        do {
                     81:                /* select two prime number */
                     82:                p = RandomPrime_ZZ(bit / 2);
                     83:                q = RandomPrime_ZZ(bit / 2);
                     84:
                     85:                mul(phi, p - 1, q - 1);
                     86:
                     87:                GCD(gcd, e, phi);
                     88:        } while (gcd != 1);
                     89:
                     90:        InvMod(d, e, phi);
                     91:        mul(n, p, q);
                     92: }
                     93:
                     94:
                     95: /****************************************************************************
                     96:  *
                     97:  * PARAM : n : positive number.
                     98:  * RETURN: octet size of n
                     99:  *
                    100:  * NOTE: NumBits()
                    101:  *   n : -3 -2 -1  0  1  2  3  4  5  6  7  8  9 ... 1022 1023 1024 1025
                    102:  *  bit:  2  2  1  0  1  2  2  3  3  3  3  4  4 ...   10   10   11   11
                    103:  ****************************************************************************/
                    104: inline int
                    105: NtlRsa::getBlockSize(const ZZ& n)
                    106: {
                    107:        return ((int)((NumBits(n) + 7) / 8));
                    108: }
                    109:
                    110:
                    111: /****************************************************************************
                    112:  *
                    113:  * PARAM : O : vec
                    114:  *       : I : null-terminate string.
                    115:  *       : I : k : lenth of modulus in octets > NtlRsa::PS_MIN + 3
                    116:  *       :   :   : k is computed by RSAPublicKey-modulus
                    117:  *       : I : f : if (f) public_key else private_key
                    118:  * RETURN: size of encrypted data
                    119:  ****************************************************************************/
                    120: int
                    121: NtlRsa::encrypt(unsigned char *eb, const unsigned char *msg, int size, int k, const ZZ &c, const ZZ &mod, int padding) const
                    122: {
                    123:        int i;
                    124:        int s;      /* length of data */
                    125:        int ps;     /* length of padding string */
                    126:        const int DATA_MAX = k - NtlRsa::PS_MIN - 3;
                    127:        ZZ x, y, ebz;
                    128:        unsigned char uch;
                    129:
                    130:        // k == ps + s + 3;
                    131:        if (size > DATA_MAX) {
                    132:                s = DATA_MAX;
                    133:                ps = NtlRsa::PS_MIN;
                    134:        } else {
                    135:                s = size;
                    136:                ps = DATA_MAX - size + NtlRsa::PS_MIN;
                    137:        }
                    138:
                    139:        //--------------------------------------------------
                    140:        // Encryption-block formatting
                    141:        //--------------------------------------------------
                    142:        eb[k - 1] = 0x00;
                    143:        eb[k - 2] = padding;
                    144:
                    145:        switch (padding) {
                    146:        case NtlRsa::PADDING_PUBLIC:
                    147:                for (i = 0; i < ps; i++) {
                    148:                        // 0 < random number < 255
                    149:                        eb[k - i - 3] = (unsigned char)(random() % (NtlRsa::OCTET_SIZE - 1) + 1);
                    150:                }
                    151:                break;
                    152:        case NtlRsa::PADDING_PRIVATE:
                    153:                for (i = 0; i < ps; i++) {
                    154:                        eb[k - i - 3] = 0xff;
                    155:                }
                    156:                break;
                    157:        case NtlRsa::PADDING_PRIVATE0: //
                    158:                for (i = 0; i < ps; i++) {
                    159:                        eb[k - i - 3] = 0x00;
                    160:                }
                    161:                break;
                    162:        default:
                    163:                return (-1);
                    164:        }
                    165:
                    166:        eb[k - ps - 3] = 0x00;
                    167:        for (i = 0; i < s; i++) {
                    168:                eb[k - ps - 4 - i] = *msg++;
                    169:        }
                    170:
                    171:        //--------------------------------------------------
                    172:        // Octet-string-to-integer conversion
                    173:        //--------------------------------------------------
                    174:        ZZFromBytes(x, eb, k);
                    175:
                    176:        //--------------------------------------------------
                    177:        // RSA computation
                    178:        //--------------------------------------------------
                    179:        PowerMod(y, x, c, mod);
                    180:
                    181:        //--------------------------------------------------
1.2     ! iwane     182:        // Integer-to-octet-string conversion
1.1       iwane     183:        //--------------------------------------------------
                    184:        memset(eb, 0, sizeof(k));
                    185:        BytesFromZZ(eb, y, k);
                    186:
                    187:        // reverse
                    188:        for (i = 0; i < k / 2; i++) {
                    189:                uch = eb[i];
                    190:                eb[i] = eb[k - i - 1];
                    191:                eb[k - i - 1] = uch;
                    192:        }
                    193:
                    194:        return (s);
                    195: }
                    196:
                    197:
                    198: int
                    199: NtlRsa::encryptByPublicKey(unsigned char *eb, const char *msg) const
                    200: {
                    201:        return (encryptByPublicKey(eb, (const unsigned char *)msg, strlen(msg) + 1));
                    202: }
                    203:
                    204:
                    205: int
                    206: NtlRsa::encryptByPublicKey(unsigned char *eb, const unsigned char *msg, int len) const
                    207: {
                    208:        return (encrypt(eb, msg, len, k, publicKey, mod, PADDING_PUBLIC));
                    209: }
                    210:
                    211: int
                    212: NtlRsa::encryptByPrivateKey(unsigned char *eb, const char *msg) const
                    213: {
                    214:        return (encryptByPrivateKey(eb, (unsigned char *)msg, strlen(msg) + 1));
                    215: }
                    216:
                    217: int
                    218: NtlRsa::encryptByPrivateKey(unsigned char *eb, const unsigned char *msg, int len) const
                    219: {
                    220:        return (encrypt(eb, msg, len, k, privateKey, mod, PADDING_PRIVATE));
                    221: }
                    222:
                    223:
                    224:
                    225:
                    226: int
                    227: NtlRsa::decryptByPrivateKey(unsigned char *buf, const unsigned char *eb) const
                    228: {
                    229:        return (decrypt(buf, eb, k, privateKey, mod, PADDING_PRIVATE));
                    230: }
                    231:
                    232: int
                    233: NtlRsa::decryptByPublicKey(unsigned char *buf, const unsigned char *eb) const
                    234: {
                    235:        return (decrypt(buf, eb, k, publicKey, mod, PADDING_PUBLIC));
                    236: }
                    237:
                    238:
                    239: /***
                    240:  *
                    241:  * PARAM  : O : d : data :: buffer size >= k.
                    242:  * RETURN : data size
                    243:  */
                    244: int
                    245: NtlRsa::decrypt(unsigned char *d, const unsigned char *eb, int k, const ZZ &exp, const ZZ &mod, int padding) const
                    246: {
                    247:        ZZ x, y;
                    248:        int i, n;
                    249:        int bt;
                    250:        unsigned char uch;
                    251:
                    252:        //--------------------------------------------------
                    253:        // Octet-string-to-integer
                    254:        //--------------------------------------------------
                    255:
                    256:        // reverse
                    257:        for (i = 0; i < k; i++) {
                    258:                d[k - i - 1] = eb[i];
                    259:        }
                    260:
                    261:        ZZFromBytes(y, d, k);
                    262:
                    263:        // error check.
                    264:        if (y >= mod || sign(y) < 0) {
                    265:                cerr << "error1: " << sign(y) << endl;
                    266:                return (-1);
                    267:        }
                    268:
                    269:        //--------------------------------------------------
                    270:        // RSA computation
                    271:        //--------------------------------------------------
                    272:        PowerMod(x, y, exp, mod);
                    273:
                    274:        //--------------------------------------------------
                    275:        // Integer-to-octet-string
                    276:        //--------------------------------------------------
                    277:        BytesFromZZ(d, x, k);
                    278:
                    279:        //--------------------------------------------------
                    280:        // Encryption-block parsing
                    281:        // EB = D || 00 || PS || BT || 00 <== attention
                    282:        //--------------------------------------------------
                    283:        if (d[k - 1] != 0x00) {
                    284:                return (-2);
                    285:        }
                    286:
                    287:
                    288:        if (padding == PADDING_PUBLIC) { // public key
                    289:                bt = d[k - 2];
                    290:                if (bt != 0x00 && bt != 0x01)
                    291:                        return (-3);
                    292:
                    293:                if (bt == 0x00) {
                    294:                        for (i = 0; i < k - 3; i++) {
                    295:                                if (d[k - 3 - i] != 0x00) {
                    296:                                        i--;
                    297:                                        break;
                    298:                                }
                    299:                        }
                    300:                } else {
                    301:                        for (i = 0; i < k - 3; i++) {
                    302:                                if (d[k - 3 - i] != 0xff)
                    303:                                        break;
                    304:                        }
                    305:                }
                    306:
                    307:        } else { // private key
                    308:                if (d[k - 2] != 0x02)
                    309:                        return (-4);
                    310:
                    311:                for (i = 0; i < k - 3; i++) {
                    312:                        if (d[k - 3 - i] == 0x00)
                    313:                                break;
                    314:                }
                    315:        }
                    316:
                    317:        if (d[k - 3 - i] != 0x00) {
                    318:                return (-5);
                    319:        }
                    320:        if (i < NtlRsa::PS_MIN) // too short
                    321:                return (-6);
                    322:
                    323:        if (i == k - 3)             // parse error.
                    324:                return (-7);
                    325:
                    326:
                    327:        // reverse
                    328:        n = k - 3 - i;
                    329:        for (i = 0; i < n / 2; i++) {
                    330:                uch = d[i];
                    331:                d[i] = d[n - i - 1];
                    332:                d[n - i - 1] = uch;
                    333:        }
                    334:
                    335:        return (n);     // data size.
                    336: }
                    337:
                    338:

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>