Quadcap Embeddable Database

com/quadcap/crypto/RSAPrivateKey.java

Go to the documentation of this file.
00001 package com.quadcap.crypto; 00002 00003 /* Copyright 2002 - 2003 Quadcap Software. All rights reserved. 00004 * 00005 * This software is distributed under the Quadcap Free Software License. 00006 * This software may be used or modified for any purpose, personal or 00007 * commercial. Open Source redistributions are permitted. Commercial 00008 * redistribution of larger works derived from, or works which bundle 00009 * this software requires a "Commercial Redistribution License"; see 00010 * http://www.quadcap.com/purchase. 00011 * 00012 * Redistributions qualify as "Open Source" under one of the following terms: 00013 * 00014 * Redistributions are made at no charge beyond the reasonable cost of 00015 * materials and delivery. 00016 * 00017 * Redistributions are accompanied by a copy of the Source Code or by an 00018 * irrevocable offer to provide a copy of the Source Code for up to three 00019 * years at the cost of materials and delivery. Such redistributions 00020 * must allow further use, modification, and redistribution of the Source 00021 * Code under substantially the same terms as this license. 00022 * 00023 * Redistributions of source code must retain the copyright notices as they 00024 * appear in each source code file, these license terms, and the 00025 * disclaimer/limitation of liability set forth as paragraph 6 below. 00026 * 00027 * Redistributions in binary form must reproduce this Copyright Notice, 00028 * these license terms, and the disclaimer/limitation of liability set 00029 * forth as paragraph 6 below, in the documentation and/or other materials 00030 * provided with the distribution. 00031 * 00032 * The Software is provided on an "AS IS" basis. No warranty is 00033 * provided that the Software is free of defects, or fit for a 00034 * particular purpose. 00035 * 00036 * Limitation of Liability. Quadcap Software shall not be liable 00037 * for any damages suffered by the Licensee or any third party resulting 00038 * from use of the Software. 00039 */ 00040 00041 import java.util.Random; 00042 import java.math.BigInteger; 00043 import java.nio.ByteBuffer; 00044 00045 import com.quadcap.util.text.Text; 00046 00047 /** 00048 * RSA Private Key implementation 00049 * 00050 * @author Stan Bailes 00051 */ 00052 public class RSAPrivateKey extends RSAKey implements PrivateKey { 00053 private final BigInteger ZERO = BigInteger.ZERO; 00054 private final BigInteger ONE = BigInteger.ONE; 00055 private final BigInteger TWO = new BigInteger("2"); 00056 private final BigInteger THREE = new BigInteger("3"); 00057 00058 private BigInteger p; // first prime 00059 private BigInteger q; // second prime 00060 00061 private BigInteger d; // decryption exponent 00062 private BigInteger dP; // d % (p-1) 00063 private BigInteger dQ; // d % (q-1) 00064 private BigInteger qInv; // p.modInverse(q) 00065 00066 /** 00067 * Default constructor 00068 */ 00069 public RSAPrivateKey() {} 00070 00071 /** 00072 * Initialize from string representation 00073 */ 00074 public void init(String s) { 00075 String[] v = Text.extractN(s, "*:*:*:*:*:*:*:*"); 00076 this.p = new BigInteger(v[2]); 00077 this.q = new BigInteger(v[3]); 00078 super.init(v[4], Integer.parseInt(v[1]), p.multiply(q)); 00079 init(); 00080 } 00081 00082 /** 00083 * Return the string representation 00084 */ 00085 public String toString() { 00086 return "RSAPriv:" + size + ":" + p + ":" + q + ":" + 00087 dP + ":" + dQ + ":" + qInv + ":" + text; 00088 } 00089 00090 /** 00091 * Create a new keypair 00092 */ 00093 public void init(String text, int siz, Random random) { 00094 int s2 = (siz / 2); 00095 int offset = (int)(random.nextDouble() * 10) - 5; 00096 offset += (offset < 0) ? -5.0 : 5.0; 00097 00098 do { 00099 this.p = makePrime(s2 + offset, random); 00100 this.q = makePrime(s2 - offset, random); 00101 this.n = p.multiply(q); 00102 } while (n.bitLength() != siz); 00103 00104 super.init(text, siz, n); 00105 init(); 00106 } 00107 00108 /** 00109 * Decrypt a buffer (in chunks) 00110 */ 00111 public void f(ByteBuffer cipher, ByteBuffer plain) { 00112 engine(cipher, plain); 00113 } 00114 00115 /** 00116 * Return the public portion of the key 00117 */ 00118 public PublicKey getPublicKey() { 00119 RSAPublicKey pub = new RSAPublicKey(); 00120 pub.init(text, size, n); 00121 return pub; 00122 } 00123 00124 private final void init() { 00125 BigInteger p1 = p.subtract(BigInteger.ONE); 00126 BigInteger q1 = q.subtract(BigInteger.ONE); 00127 BigInteger m = p1.multiply(q1); // M = (p-1)*(q-1) 00128 00129 this.d = e.modInverse(m); 00130 00131 dP = d.remainder(p1); 00132 dQ = d.remainder(q1); 00133 qInv = p.modInverse(q); 00134 } 00135 00136 final private BigInteger makePrime(int size, Random random) { 00137 BigInteger bn = new BigInteger(size, 100, random); 00138 while (bn.subtract(ONE).remainder(THREE).equals(ZERO)) { 00139 bn = new BigInteger(size, 100, random); 00140 } 00141 return bn; 00142 } 00143 00144 final protected BigInteger engine(BigInteger c) { 00145 if (false) { 00146 return c.modPow(d, n); 00147 } else { 00148 BigInteger m1 = c.modPow(dP, p); 00149 BigInteger m2 = c.modPow(dQ, q); 00150 BigInteger h = ((m2.subtract(m1)).multiply(qInv)).remainder(q); 00151 if (h.compareTo(BigInteger.ZERO) < 0) { 00152 h = h.add(q); 00153 } 00154 return m1.add(h.multiply(p)); 00155 } 00156 } 00157 00158 }