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>