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