[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.1

1.1     ! iwane       1: /* $OpenXM$ */
        !             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:        //--------------------------------------------------
        !           182:        // Inteer-to-octet-string conversion
        !           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>