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>