added Base64.java, fixed package names
[org.ibex.crypto.git] / src / org / ibex / crypto / RSA.java
1 package org.ibex.crypto;
2 import java.math.BigInteger;
3
4 public class RSA {
5     private final BigInteger pq;
6     private final BigInteger e;
7     private final boolean reverse;
8     
9     public RSA(BigInteger pq, BigInteger e, boolean reverse) {
10         this.pq = pq;
11         this.e = e;
12         this.reverse = reverse;
13     }
14     
15     public int getInputBlockSize() { return (pq.bitLength()+7) / 8 - (reverse ? 0 : 1); }
16     public int getOutputBlockSize() { return (pq.bitLength()+7) / 8 - (reverse ? 1 : 0); }
17     
18     public byte[] process(byte[] in) {
19         // output block is the same size as the modulus (rounded up)
20         int outSize = getOutputBlockSize();
21         BigInteger t = new BigInteger(1,in);
22         BigInteger c = t.modPow(e,pq);
23         byte[] cbytes = c.toByteArray();
24         if(cbytes.length > outSize || (reverse && cbytes[0] == 0)) {
25             if(cbytes[0] != 0) throw new RuntimeException("should never happen");
26             byte[] buf = new byte[outSize];
27             System.arraycopy(cbytes,1,buf,0,outSize);
28             return buf;
29         } else if(!reverse && cbytes.length < outSize) {
30             // output needs to be exactly outSize in length
31             byte[] buf = new byte[outSize];
32             System.arraycopy(cbytes,0,buf,outSize-cbytes.length,cbytes.length);
33             return buf;
34         } else {
35             return cbytes;
36         }
37     }
38
39     public static class PublicKey {
40         public final BigInteger modulus;
41         public final BigInteger exponent;
42         
43         public PublicKey(Object o) {
44             Vector seq = (Vector) o;
45             modulus = (BigInteger) seq.elementAt(0);
46             exponent = (BigInteger) seq.elementAt(1);
47         }
48     }
49
50 }