001: package com.quadcap.crypto;
002:
003: /* Copyright 2002 - 2003 Quadcap Software. All rights reserved.
004: *
005: * This software is distributed under the Quadcap Free Software License.
006: * This software may be used or modified for any purpose, personal or
007: * commercial. Open Source redistributions are permitted. Commercial
008: * redistribution of larger works derived from, or works which bundle
009: * this software requires a "Commercial Redistribution License"; see
010: * http://www.quadcap.com/purchase.
011: *
012: * Redistributions qualify as "Open Source" under one of the following terms:
013: *
014: * Redistributions are made at no charge beyond the reasonable cost of
015: * materials and delivery.
016: *
017: * Redistributions are accompanied by a copy of the Source Code or by an
018: * irrevocable offer to provide a copy of the Source Code for up to three
019: * years at the cost of materials and delivery. Such redistributions
020: * must allow further use, modification, and redistribution of the Source
021: * Code under substantially the same terms as this license.
022: *
023: * Redistributions of source code must retain the copyright notices as they
024: * appear in each source code file, these license terms, and the
025: * disclaimer/limitation of liability set forth as paragraph 6 below.
026: *
027: * Redistributions in binary form must reproduce this Copyright Notice,
028: * these license terms, and the disclaimer/limitation of liability set
029: * forth as paragraph 6 below, in the documentation and/or other materials
030: * provided with the distribution.
031: *
032: * The Software is provided on an "AS IS" basis. No warranty is
033: * provided that the Software is free of defects, or fit for a
034: * particular purpose.
035: *
036: * Limitation of Liability. Quadcap Software shall not be liable
037: * for any damages suffered by the Licensee or any third party resulting
038: * from use of the Software.
039: */
040:
041: import java.util.Random;
042: import java.math.BigInteger;
043: import java.nio.ByteBuffer;
044:
045: import com.quadcap.util.text.Text;
046:
047: /**
048: * RSA Private Key implementation
049: *
050: * @author Stan Bailes
051: */
052: public class RSAPrivateKey extends RSAKey implements PrivateKey {
053: private final BigInteger ZERO = BigInteger.ZERO;
054: private final BigInteger ONE = BigInteger.ONE;
055: private final BigInteger TWO = new BigInteger("2");
056: private final BigInteger THREE = new BigInteger("3");
057:
058: private BigInteger p; // first prime
059: private BigInteger q; // second prime
060:
061: private BigInteger d; // decryption exponent
062: private BigInteger dP; // d % (p-1)
063: private BigInteger dQ; // d % (q-1)
064: private BigInteger qInv; // p.modInverse(q)
065:
066: /**
067: * Default constructor
068: */
069: public RSAPrivateKey() {
070: }
071:
072: /**
073: * Initialize from string representation
074: */
075: public void init(String s) {
076: String[] v = Text.extractN(s, "*:*:*:*:*:*:*:*");
077: this .p = new BigInteger(v[2]);
078: this .q = new BigInteger(v[3]);
079: super .init(v[4], Integer.parseInt(v[1]), p.multiply(q));
080: init();
081: }
082:
083: /**
084: * Return the string representation
085: */
086: public String toString() {
087: return "RSAPriv:" + size + ":" + p + ":" + q + ":" + dP + ":"
088: + dQ + ":" + qInv + ":" + text;
089: }
090:
091: /**
092: * Create a new keypair
093: */
094: public void init(String text, int siz, Random random) {
095: int s2 = (siz / 2);
096: int offset = (int) (random.nextDouble() * 10) - 5;
097: offset += (offset < 0) ? -5.0 : 5.0;
098:
099: do {
100: this .p = makePrime(s2 + offset, random);
101: this .q = makePrime(s2 - offset, random);
102: this .n = p.multiply(q);
103: } while (n.bitLength() != siz);
104:
105: super .init(text, siz, n);
106: init();
107: }
108:
109: /**
110: * Decrypt a buffer (in chunks)
111: */
112: public void f(ByteBuffer cipher, ByteBuffer plain) {
113: engine(cipher, plain);
114: }
115:
116: /**
117: * Return the public portion of the key
118: */
119: public PublicKey getPublicKey() {
120: RSAPublicKey pub = new RSAPublicKey();
121: pub.init(text, size, n);
122: return pub;
123: }
124:
125: private final void init() {
126: BigInteger p1 = p.subtract(BigInteger.ONE);
127: BigInteger q1 = q.subtract(BigInteger.ONE);
128: BigInteger m = p1.multiply(q1); // M = (p-1)*(q-1)
129:
130: this .d = e.modInverse(m);
131:
132: dP = d.remainder(p1);
133: dQ = d.remainder(q1);
134: qInv = p.modInverse(q);
135: }
136:
137: final private BigInteger makePrime(int size, Random random) {
138: BigInteger bn = new BigInteger(size, 100, random);
139: while (bn.subtract(ONE).remainder(THREE).equals(ZERO)) {
140: bn = new BigInteger(size, 100, random);
141: }
142: return bn;
143: }
144:
145: final protected BigInteger engine(BigInteger c) {
146: if (false) {
147: return c.modPow(d, n);
148: } else {
149: BigInteger m1 = c.modPow(dP, p);
150: BigInteger m2 = c.modPow(dQ, q);
151: BigInteger h = ((m2.subtract(m1)).multiply(qInv))
152: .remainder(q);
153: if (h.compareTo(BigInteger.ZERO) < 0) {
154: h = h.add(q);
155: }
156: return m1.add(h.multiply(p));
157: }
158: }
159:
160: }
|