~brian-thomason/+junk/bouncycastle

« back to all changes in this revision

Viewing changes to jdk1.0/java/security/SecureRandom.java

  • Committer: Brian Thomason
  • Date: 2011-12-20 17:20:32 UTC
  • Revision ID: brian.thomason@canonical.com-20111220172032-rdtm13jgdxtksacr
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package java.security;
 
2
 
 
3
import org.bouncycastle.crypto.digests.SHA1Digest;
 
4
 
 
5
/**
 
6
 * An implementation of SecureRandom specifically for the
 
7
 * light-weight API, JDK 1.0, and the J2ME. Random generation is 
 
8
 * based on the traditional SHA1 with counter. Calling setSeed
 
9
 * will always increase the entropy of the hash.
 
10
 */
 
11
public class SecureRandom
 
12
    extends java.util.Random
 
13
{
 
14
    private static  SecureRandom rand = new SecureRandom();
 
15
 
 
16
    private byte[] seed;
 
17
 
 
18
    private long        counter = 1;
 
19
    private SHA1Digest  digest = new SHA1Digest();
 
20
    private byte[]      state = new byte[digest.getDigestSize()];
 
21
 
 
22
    // public constructors
 
23
    public SecureRandom()
 
24
    {
 
25
        super(0);
 
26
        setSeed(System.currentTimeMillis());
 
27
    }
 
28
 
 
29
    public SecureRandom(
 
30
        byte[] inSeed)
 
31
    {
 
32
        super(0);
 
33
        setSeed(inSeed);
 
34
    }
 
35
 
 
36
    // protected constructors
 
37
    // protected SecureRandom(SecureRandomSpi srs, Provider provider);
 
38
 
 
39
    // public class methods
 
40
    public static SecureRandom getInstance(String algorithm)
 
41
    {
 
42
        return new SecureRandom();
 
43
    }
 
44
 
 
45
    public static SecureRandom getInstance(String algorithm, String provider)
 
46
    {
 
47
        return new SecureRandom();
 
48
    }
 
49
 
 
50
    public static byte[] getSeed(
 
51
        int numBytes)
 
52
    {
 
53
        byte[] rv = new byte[numBytes];
 
54
 
 
55
        rand.setSeed(System.currentTimeMillis());
 
56
        rand.nextBytes(rv);
 
57
 
 
58
        return rv;
 
59
    }
 
60
 
 
61
    // public instance methods
 
62
    public byte[] generateSeed(
 
63
        int numBytes)
 
64
    {
 
65
        byte[] rv = new byte[numBytes];
 
66
    
 
67
        nextBytes(rv);    
 
68
 
 
69
        return rv;
 
70
    }
 
71
 
 
72
    // public final Provider getProvider();
 
73
    public void setSeed(
 
74
        byte[] inSeed)
 
75
    {
 
76
        digest.update(inSeed, 0, inSeed.length);
 
77
    }
 
78
        
 
79
    // public methods overriding random
 
80
    public void nextBytes(
 
81
        byte[] bytes)
 
82
    {
 
83
        int     stateOff = 0;
 
84
 
 
85
        digest.doFinal(state, 0);
 
86
 
 
87
        for (int i = 0; i != bytes.length; i++)
 
88
        {
 
89
            if (stateOff == state.length)
 
90
            {
 
91
                byte[]  b = longToBytes(counter++);
 
92
 
 
93
                digest.update(b, 0, b.length);
 
94
                digest.update(state, 0, state.length);
 
95
                digest.doFinal(state, 0);
 
96
                stateOff = 0;
 
97
            }
 
98
            bytes[i] = state[stateOff++];
 
99
        }
 
100
 
 
101
        byte[]  b = longToBytes(counter++);
 
102
 
 
103
        digest.update(b, 0, b.length);
 
104
        digest.update(state, 0, state.length);
 
105
    }
 
106
 
 
107
    public void setSeed(
 
108
        long rSeed)
 
109
    {
 
110
        if (rSeed != 0)
 
111
        {
 
112
            setSeed(longToBytes(rSeed));
 
113
        }
 
114
    }
 
115
 
 
116
    private byte[]  intBytes = new byte[4];
 
117
 
 
118
    public int nextInt()
 
119
    {
 
120
        nextBytes(intBytes);
 
121
 
 
122
        int result = 0;
 
123
 
 
124
        for (int i = 0; i < 4; i++)
 
125
        {
 
126
            result = (result << 8) + (intBytes[i] & 0xff);
 
127
        }
 
128
 
 
129
        return result;
 
130
    }
 
131
 
 
132
    protected final int next(
 
133
        int numBits)
 
134
    {
 
135
        int     size = (numBits + 7) / 8;
 
136
        byte[]  bytes = new byte[size];
 
137
 
 
138
        nextBytes(bytes);
 
139
 
 
140
        int result = 0;
 
141
 
 
142
        for (int i = 0; i < size; i++)
 
143
        {
 
144
            result = (result << 8) + (bytes[i] & 0xff);
 
145
        }
 
146
 
 
147
        return result & ((1 << numBits) - 1);
 
148
    }
 
149
 
 
150
    private byte[]  longBytes = new byte[8];
 
151
 
 
152
    private byte[] longToBytes(
 
153
        long    val)
 
154
    {
 
155
        for (int i = 0; i != 8; i++)
 
156
        {
 
157
            longBytes[i] = (byte)val;
 
158
            val >>>= 8;
 
159
        }
 
160
 
 
161
        return longBytes;
 
162
    }
 
163
}
 
164