merge copyright headers with brians code
[org.ibex.crypto.git] / src / org / ibex / crypto / RSA.java
1 // Copyright 2000-2005 the Contributors, as shown in the revision logs.
2 // Licensed under the Apache Public Source License 2.0 ("the License").
3 // You may not use this file except in compliance with the License.
4
5 /*
6  * org.ibex.RSA - By Brian Alliet
7  * Copyright (C) 2004 Brian Alliet
8  */
9  
10 package org.ibex.crypto;
11 import java.math.BigInteger;
12 import java.util.*;
13
14 public class RSA {
15     private final BigInteger pq;
16     private final BigInteger e;
17     private final boolean reverse;
18     
19     public RSA(BigInteger pq, BigInteger e, boolean reverse) {
20         this.pq = pq;
21         this.e = e;
22         this.reverse = reverse;
23     }
24     
25     public int getInputBlockSize() { return (pq.bitLength()+7) / 8 - (reverse ? 0 : 1); }
26     public int getOutputBlockSize() { return (pq.bitLength()+7) / 8 - (reverse ? 1 : 0); }
27     
28     // FEATURE: Check that in.length is within the expected range
29     public byte[] process(byte[] in) {
30         // output block is the same size as the modulus (rounded up)
31         int outSize = getOutputBlockSize();
32         BigInteger t = new BigInteger(1,in);
33         BigInteger c = t.modPow(e,pq);
34         byte[] cbytes = c.toByteArray();
35         if(cbytes.length > outSize + 1) throw new RuntimeException("should never happen");
36         if(reverse ? cbytes[0] == 0 : cbytes.length > outSize) {
37             if(cbytes[0] != 0) throw new RuntimeException("should never happen");
38             byte[] buf = new byte[cbytes.length-1];
39             System.arraycopy(cbytes,1,buf,0,buf.length);
40             return buf;
41         } else if(!reverse && cbytes.length < outSize) {
42             // output needs to be exactly outSize in length
43             byte[] buf = new byte[outSize];
44             System.arraycopy(cbytes,0,buf,outSize-cbytes.length,cbytes.length);
45             return buf;
46         } else {
47             return cbytes;
48         }
49     }
50
51     public static class PublicKey {
52         public final BigInteger modulus;
53         public final BigInteger exponent;
54         
55         public PublicKey(Object o) {
56             Vector seq = (Vector) o;
57             modulus = (BigInteger) seq.elementAt(0);
58             exponent = (BigInteger) seq.elementAt(1);
59         }
60     }
61     
62     public static class PrivateKey {
63         public final int version;
64         public final BigInteger modulus;
65         public final BigInteger publicExponent;
66         public final BigInteger privateExponent;
67         public final BigInteger prime1;
68         public final BigInteger prime2;
69         public final BigInteger exponent1;
70         public final BigInteger exponent2;
71         public final BigInteger coefficient;
72         
73         public PrivateKey(Object o) throws DER.Exception {
74             Vector seq = (Vector) o;
75             version = ((Number)seq.elementAt(0)).intValue();
76             if(version != 0) throw new DER.Exception("Only private key version 0 is supported");
77             modulus = (BigInteger) seq.elementAt(1);
78             publicExponent = (BigInteger) seq.elementAt(2);
79             privateExponent = (BigInteger) seq.elementAt(3);
80             prime1 = (BigInteger) seq.elementAt(4);
81             prime2 = (BigInteger) seq.elementAt(5);
82             exponent1 = (BigInteger) seq.elementAt(6);
83             exponent2 = (BigInteger) seq.elementAt(7);
84             coefficient = (BigInteger) seq.elementAt(8);
85         }
86     }
87 }