OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [java/] [security/] [sig/] [dss/] [DSSSignature.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* DSSSignature.java --
2
   Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
3
 
4
This file is a part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or (at
9
your option) any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; if not, write to the Free Software
18
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19
USA
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version.  */
37
 
38
 
39
package gnu.java.security.sig.dss;
40
 
41
import gnu.java.security.Registry;
42
import gnu.java.security.hash.IMessageDigest;
43
import gnu.java.security.hash.Sha160;
44
import gnu.java.security.prng.IRandom;
45
import gnu.java.security.sig.BaseSignature;
46
import gnu.java.security.sig.ISignature;
47
 
48
import java.math.BigInteger;
49
import java.security.PrivateKey;
50
import java.security.PublicKey;
51
import java.security.interfaces.DSAPrivateKey;
52
import java.security.interfaces.DSAPublicKey;
53
import java.util.HashMap;
54
import java.util.Map;
55
import java.util.Random;
56
 
57
/**
58
 * The DSS (Digital Signature Standard) algorithm makes use of the following
59
 * parameters:
60
 * <ol>
61
 * <li>p: A prime modulus, where
62
 * <code>2<sup>L-1</sup> &lt; p &lt; 2<sup>L</sup> </code> for <code>512 &lt;= L
63
 * &lt;= 1024</code> and <code>L</code> a multiple of <code>64</code>.</li>
64
 * <li>q: A prime divisor of <code>p - 1</code>, where <code>2<sup>159</sup>
65
 *    &lt; q &lt; 2<sup>160</sup></code>.</li>
66
 * <li>g: Where <code>g = h<sup>(p-1)</sup>/q mod p</code>, where
67
 * <code>h</code> is any integer with <code>1 &lt; h &lt; p - 1</code> such
68
 * that <code>h<sup> (p-1)</sup>/q mod p > 1</code> (<code>g</code> has order
69
 * <code>q mod p</code>).</li>
70
 * <li>x: A randomly or pseudorandomly generated integer with <code>0 &lt; x
71
 *    &lt; q</code>.</li>
72
 * <li>y: <code>y = g<sup>x</sup> mod p</code>.</li>
73
 * <li>k: A randomly or pseudorandomly generated integer with <code>0 &lt; k
74
 *    &lt; q</code>.</li>
75
 * </ol>
76
 * <p>
77
 * The integers <code>p</code>, <code>q</code>, and <code>g</code> can be
78
 * public and can be common to a group of users. A user's private and public
79
 * keys are <code>x</code> and <code>y</code>, respectively. They are
80
 * normally fixed for a period of time. Parameters <code>x</code> and
81
 * <code>k</code> are used for signature generation only, and must be kept
82
 * secret. Parameter <code>k</code> must be regenerated for each signature.
83
 * <p>
84
 * The signature of a message <code>M</code> is the pair of numbers
85
 * <code>r</code> and <code>s</code> computed according to the equations below:
86
 * <ul>
87
 * <li><code>r = (g<sup>k</sup> mod p) mod q</code> and</li>
88
 * <li><code>s = (k<sup>-1</sup>(SHA(M) + xr)) mod q</code>.</li>
89
 * </ul>
90
 * <p>
91
 * In the above, <code>k<sup>-1</sup></code> is the multiplicative inverse of
92
 * <code>k</code>, <code>mod q</code>; i.e., <code>(k<sup>-1</sup> k) mod q =
93
 * 1</code> and <code>0 &lt; k-1 &lt; q</code>. The value of <code>SHA(M)</code>
94
 * is a 160-bit string output by the Secure Hash Algorithm specified in FIPS
95
 * 180. For use in computing <code>s</code>, this string must be converted to
96
 * an integer.
97
 * <p>
98
 * As an option, one may wish to check if <code>r == 0</code> or <code>s == 0
99
 * </code>.
100
 * If either <code>r == 0</code> or <code>s == 0</code>, a new value of
101
 * <code>k</code> should be generated and the signature should be recalculated
102
 * (it is extremely unlikely that <code>r == 0</code> or <code>s == 0</code> if
103
 * signatures are generated properly).
104
 * <p>
105
 * The signature is transmitted along with the message to the verifier.
106
 * <p>
107
 * References:
108
 * <ol>
109
 * <li><a href="http://www.itl.nist.gov/fipspubs/fip186.htm">Digital Signature
110
 * Standard (DSS)</a>, Federal Information Processing Standards Publication
111
 * 186. National Institute of Standards and Technology.</li>
112
 * </ol>
113
 */
114
public class DSSSignature
115
    extends BaseSignature
116
{
117
  /** Trivial 0-arguments constructor. */
118
  public DSSSignature()
119
  {
120
    super(Registry.DSS_SIG, new Sha160());
121
  }
122
 
123
  /** Private constructor for cloning purposes. */
124
  private DSSSignature(DSSSignature that)
125
  {
126
    this();
127
 
128
    this.publicKey = that.publicKey;
129
    this.privateKey = that.privateKey;
130
    this.md = (IMessageDigest) that.md.clone();
131
  }
132
 
133
  public static final BigInteger[] sign(final DSAPrivateKey k, final byte[] h)
134
  {
135
    final DSSSignature sig = new DSSSignature();
136
    final Map attributes = new HashMap();
137
    attributes.put(ISignature.SIGNER_KEY, k);
138
    sig.setupSign(attributes);
139
    return sig.computeRS(h);
140
  }
141
 
142
  public static final BigInteger[] sign(final DSAPrivateKey k, final byte[] h,
143
                                        Random rnd)
144
  {
145
    final DSSSignature sig = new DSSSignature();
146
    final Map attributes = new HashMap();
147
    attributes.put(ISignature.SIGNER_KEY, k);
148
    if (rnd != null)
149
      attributes.put(ISignature.SOURCE_OF_RANDOMNESS, rnd);
150
 
151
    sig.setupSign(attributes);
152
    return sig.computeRS(h);
153
  }
154
 
155
  public static final BigInteger[] sign(final DSAPrivateKey k, final byte[] h,
156
                                        IRandom irnd)
157
  {
158
    final DSSSignature sig = new DSSSignature();
159
    final Map attributes = new HashMap();
160
    attributes.put(ISignature.SIGNER_KEY, k);
161
    if (irnd != null)
162
      attributes.put(ISignature.SOURCE_OF_RANDOMNESS, irnd);
163
 
164
    sig.setupSign(attributes);
165
    return sig.computeRS(h);
166
  }
167
 
168
  public static final boolean verify(final DSAPublicKey k, final byte[] h,
169
                                     final BigInteger[] rs)
170
  {
171
    final DSSSignature sig = new DSSSignature();
172
    final Map attributes = new HashMap();
173
    attributes.put(ISignature.VERIFIER_KEY, k);
174
    sig.setupVerify(attributes);
175
    return sig.checkRS(rs, h);
176
  }
177
 
178
  public Object clone()
179
  {
180
    return new DSSSignature(this);
181
  }
182
 
183
  protected void setupForVerification(PublicKey k)
184
      throws IllegalArgumentException
185
  {
186
    if (! (k instanceof DSAPublicKey))
187
      throw new IllegalArgumentException();
188
 
189
    this.publicKey = k;
190
  }
191
 
192
  protected void setupForSigning(PrivateKey k) throws IllegalArgumentException
193
  {
194
    if (! (k instanceof DSAPrivateKey))
195
      throw new IllegalArgumentException();
196
 
197
    this.privateKey = k;
198
  }
199
 
200
  protected Object generateSignature() throws IllegalStateException
201
  {
202
    final BigInteger[] rs = computeRS(md.digest());
203
    return encodeSignature(rs[0], rs[1]);
204
  }
205
 
206
  protected boolean verifySignature(Object sig) throws IllegalStateException
207
  {
208
    final BigInteger[] rs = decodeSignature(sig);
209
    return checkRS(rs, md.digest());
210
  }
211
 
212
  /**
213
   * Returns the output of a signature generation phase.
214
   *
215
   * @return an object encapsulating the DSS signature pair <code>r</code> and
216
   *         <code>s</code>.
217
   */
218
  private Object encodeSignature(BigInteger r, BigInteger s)
219
  {
220
    return new BigInteger[] { r, s };
221
  }
222
 
223
  /**
224
   * Returns the output of a previously generated signature object as a pair of
225
   * {@link java.math.BigInteger}.
226
   *
227
   * @return the DSS signature pair <code>r</code> and <code>s</code>.
228
   */
229
  private BigInteger[] decodeSignature(Object signature)
230
  {
231
    return (BigInteger[]) signature;
232
  }
233
 
234
  private BigInteger[] computeRS(final byte[] digestBytes)
235
  {
236
    final BigInteger p = ((DSAPrivateKey) privateKey).getParams().getP();
237
    final BigInteger q = ((DSAPrivateKey) privateKey).getParams().getQ();
238
    final BigInteger g = ((DSAPrivateKey) privateKey).getParams().getG();
239
    final BigInteger x = ((DSAPrivateKey) privateKey).getX();
240
    final BigInteger m = new BigInteger(1, digestBytes);
241
    BigInteger k, r, s;
242
    final byte[] kb = new byte[20]; // we'll use 159 bits only
243
    while (true)
244
      {
245
        this.nextRandomBytes(kb);
246
        k = new BigInteger(1, kb);
247
        k.clearBit(159);
248
        r = g.modPow(k, p).mod(q);
249
        if (r.equals(BigInteger.ZERO))
250
          continue;
251
 
252
        s = m.add(x.multiply(r)).multiply(k.modInverse(q)).mod(q);
253
        if (s.equals(BigInteger.ZERO))
254
          continue;
255
 
256
        break;
257
      }
258
    return new BigInteger[] { r, s };
259
  }
260
 
261
  private boolean checkRS(final BigInteger[] rs, final byte[] digestBytes)
262
  {
263
    final BigInteger r = rs[0];
264
    final BigInteger s = rs[1];
265
    final BigInteger g = ((DSAPublicKey) publicKey).getParams().getG();
266
    final BigInteger p = ((DSAPublicKey) publicKey).getParams().getP();
267
    final BigInteger q = ((DSAPublicKey) publicKey).getParams().getQ();
268
    final BigInteger y = ((DSAPublicKey) publicKey).getY();
269
    final BigInteger w = s.modInverse(q);
270
    final BigInteger u1 = w.multiply(new BigInteger(1, digestBytes)).mod(q);
271
    final BigInteger u2 = r.multiply(w).mod(q);
272
    final BigInteger v = g.modPow(u1, p).multiply(y.modPow(u2, p)).mod(p).mod(q);
273
    return v.equals(r);
274
  }
275
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.