001: package org.bouncycastle.jce.provider.test;
002:
003: import java.io.ByteArrayInputStream;
004: import java.io.IOException;
005: import java.math.BigInteger;
006: import java.security.KeyFactory;
007: import java.security.PrivateKey;
008: import java.security.PublicKey;
009: import java.security.SecureRandom;
010: import java.security.Security;
011: import java.security.Signature;
012:
013: import org.bouncycastle.asn1.ASN1InputStream;
014: import org.bouncycastle.asn1.ASN1Sequence;
015: import org.bouncycastle.asn1.DERInteger;
016: import org.bouncycastle.jce.provider.BouncyCastleProvider;
017: import org.bouncycastle.jce.spec.ECParameterSpec;
018: import org.bouncycastle.jce.spec.ECPrivateKeySpec;
019: import org.bouncycastle.jce.spec.ECPublicKeySpec;
020: import org.bouncycastle.math.ec.ECCurve;
021: import org.bouncycastle.util.BigIntegers;
022: import org.bouncycastle.util.encoders.Hex;
023: import org.bouncycastle.util.test.FixedSecureRandom;
024: import org.bouncycastle.util.test.SimpleTest;
025:
026: public class ECNRTest extends SimpleTest {
027: byte[] k1 = Hex.decode("d5014e4b60ef2ba8b6211b4062ba3224e0427dd3");
028: byte[] k2 = Hex
029: .decode("345e8d05c075c3a508df729a1685690e68fcfb8c8117847e89063bca1f85d968fd281540b6e13bd1af989a1fbf17e06462bf511f9d0b140fb48ac1b1baa5bded");
030:
031: SecureRandom random = new FixedSecureRandom(new byte[][] { k1, k2 });
032:
033: /**
034: * X9.62 - 1998,<br>
035: * J.3.2, Page 155, ECDSA over the field Fp<br>
036: * an example with 239 bit prime
037: */
038: private void testECNR239bitPrime() throws Exception {
039: BigInteger r = new BigInteger(
040: "308636143175167811492623515537541734843573549327605293463169625072911693");
041: BigInteger s = new BigInteger(
042: "852401710738814635664888632022555967400445256405412579597015412971797143");
043:
044: byte[] kData = BigIntegers
045: .asUnsignedByteArray(new BigInteger(
046: "700000017569056646655505781757157107570501575775705779575555657156756655"));
047:
048: SecureRandom k = new FixedSecureRandom(kData);
049:
050: ECCurve curve = new ECCurve.Fp(
051: new BigInteger(
052: "883423532389192164791648750360308885314476597252960362792450860609699839"), // q
053: new BigInteger(
054: "7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc",
055: 16), // a
056: new BigInteger(
057: "6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a",
058: 16)); // b
059:
060: ECParameterSpec spec = new ECParameterSpec(
061: curve,
062: curve
063: .decodePoint(Hex
064: .decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G
065: new BigInteger(
066: "883423532389192164791648750360308884807550341691627752275345424702807307")); // n
067:
068: ECPrivateKeySpec priKey = new ECPrivateKeySpec(
069: new BigInteger(
070: "876300101507107567501066130761671078357010671067781776716671676178726717"), // d
071: spec);
072:
073: ECPublicKeySpec pubKey = new ECPublicKeySpec(
074: curve
075: .decodePoint(Hex
076: .decode("025b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c70")), // Q
077: spec);
078:
079: Signature sgr = Signature.getInstance("SHA1withECNR", "BC");
080: KeyFactory f = KeyFactory.getInstance("ECDSA", "BC");
081:
082: byte[] message = new byte[] { (byte) 'a', (byte) 'b',
083: (byte) 'c' };
084:
085: checkSignature(239, priKey, pubKey, sgr, k, message, r, s);
086: }
087:
088: // -------------------------------------------------------------------------
089:
090: /**
091: * X9.62 - 1998,<br>
092: * Page 104-105, ECDSA over the field Fp<br>
093: * an example with 192 bit prime
094: */
095: private void testECNR192bitPrime() throws Exception {
096: BigInteger r = new BigInteger(
097: "2474388605162950674935076940284692598330235697454145648371");
098: BigInteger s = new BigInteger(
099: "2997192822503471356158280167065034437828486078932532073836");
100:
101: byte[] kData = BigIntegers
102: .asUnsignedByteArray(new BigInteger(
103: "dcc5d1f1020906df2782360d36b2de7a17ece37d503784af",
104: 16));
105:
106: SecureRandom k = new FixedSecureRandom(kData);
107:
108: ECCurve.Fp curve = new ECCurve.Fp(
109: new BigInteger(
110: "6277101735386680763835789423207666416083908700390324961279"), // q (or p)
111: new BigInteger(
112: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
113: 16), // a
114: new BigInteger(
115: "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
116: 16)); // b
117:
118: ECParameterSpec spec = new ECParameterSpec(
119: curve,
120: curve
121: .decodePoint(Hex
122: .decode("03188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")), // G
123: new BigInteger(
124: "6277101735386680763835789423176059013767194773182842284081")); // n
125:
126: ECPrivateKeySpec priKey = new ECPrivateKeySpec(
127: new BigInteger(
128: "651056770906015076056810763456358567190100156695615665659"), // d
129: spec);
130:
131: ECPublicKeySpec pubKey = new ECPublicKeySpec(
132: curve
133: .decodePoint(Hex
134: .decode("0262B12D60690CDCF330BABAB6E69763B471F994DD702D16A5")), // Q
135: spec);
136:
137: Signature sgr = Signature.getInstance("SHA1withECNR", "BC");
138: KeyFactory f = KeyFactory.getInstance("ECDSA", "BC");
139:
140: byte[] message = new byte[] { (byte) 'a', (byte) 'b',
141: (byte) 'c' };
142:
143: checkSignature(192, priKey, pubKey, sgr, k, message, r, s);
144: }
145:
146: // -------------------------------------------------------------------------
147:
148: /**
149: * SEC 2: Recommended Elliptic Curve Domain Parameters - September 2000,<br>
150: * Page 17-19, Recommended 521-bit Elliptic Curve Domain Parameters over Fp<br>
151: * an ECC example with a 521 bit prime and a 512 bit hash
152: */
153: private void testECNR521bitPrime() throws Exception {
154: BigInteger r = new BigInteger(
155: "1820641608112320695747745915744708800944302281118541146383656165330049339564439316345159057453301092391897040509935100825960342573871340486684575368150970954");
156: BigInteger s = new BigInteger(
157: "6358277176448326821136601602749690343031826490505780896013143436153111780706227024847359990383467115737705919410755190867632280059161174165591324242446800763");
158:
159: byte[] kData = BigIntegers
160: .asUnsignedByteArray(new BigInteger(
161: "cdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
162: 16));
163:
164: SecureRandom k = new FixedSecureRandom(kData);
165:
166: ECCurve.Fp curve = new ECCurve.Fp(
167: new BigInteger(
168: "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"), // q (or p)
169: new BigInteger(
170: "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
171: 16), // a
172: new BigInteger(
173: "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
174: 16)); // b
175:
176: ECParameterSpec spec = new ECParameterSpec(
177: curve,
178: curve
179: .decodePoint(Hex
180: .decode("02C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")), // G
181: new BigInteger(
182: "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
183: 16)); // n
184:
185: ECPrivateKeySpec priKey = new ECPrivateKeySpec(
186: new BigInteger(
187: "5769183828869504557786041598510887460263120754767955773309066354712783118202294874205844512909370791582896372147797293913785865682804434049019366394746072023"), // d
188: spec);
189:
190: ECPublicKeySpec pubKey = new ECPublicKeySpec(
191: curve
192: .decodePoint(Hex
193: .decode("026BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q
194: spec);
195:
196: Signature sgr = Signature.getInstance("SHA512withECNR", "BC");
197: byte[] message = new byte[] { (byte) 'a', (byte) 'b',
198: (byte) 'c' };
199:
200: checkSignature(521, priKey, pubKey, sgr, k, message, r, s);
201: }
202:
203: private void checkSignature(int size, ECPrivateKeySpec priKey,
204: ECPublicKeySpec pubKey, Signature sgr, SecureRandom k,
205: byte[] message, BigInteger r, BigInteger s)
206: throws Exception {
207: KeyFactory f = KeyFactory.getInstance("ECDSA", "BC");
208: PrivateKey sKey = f.generatePrivate(priKey);
209: PublicKey vKey = f.generatePublic(pubKey);
210:
211: sgr.initSign(sKey, k);
212:
213: sgr.update(message);
214:
215: byte[] sigBytes = sgr.sign();
216:
217: sgr.initVerify(vKey);
218:
219: sgr.update(message);
220:
221: if (!sgr.verify(sigBytes)) {
222: fail(size + " bit EC verification failed");
223: }
224:
225: BigInteger[] sig = derDecode(sigBytes);
226:
227: if (!r.equals(sig[0])) {
228: fail(size + "bit" + ": r component wrong."
229: + System.getProperty("line.separator")
230: + " expecting: " + r
231: + System.getProperty("line.separator")
232: + " got : " + sig[0]);
233: }
234:
235: if (!s.equals(sig[1])) {
236: fail(size + "bit" + ": s component wrong."
237: + System.getProperty("line.separator")
238: + " expecting: " + s
239: + System.getProperty("line.separator")
240: + " got : " + sig[1]);
241: }
242: }
243:
244: protected BigInteger[] derDecode(byte[] encoding)
245: throws IOException {
246: ByteArrayInputStream bIn = new ByteArrayInputStream(encoding);
247: ASN1InputStream aIn = new ASN1InputStream(bIn);
248: ASN1Sequence s = (ASN1Sequence) aIn.readObject();
249:
250: BigInteger[] sig = new BigInteger[2];
251:
252: sig[0] = ((DERInteger) s.getObjectAt(0)).getValue();
253: sig[1] = ((DERInteger) s.getObjectAt(1)).getValue();
254:
255: return sig;
256: }
257:
258: public String getName() {
259: return "ECNR";
260: }
261:
262: public void performTest() throws Exception {
263: testECNR192bitPrime();
264: testECNR239bitPrime();
265: testECNR521bitPrime();
266: }
267:
268: public static void main(String[] args) {
269: Security.addProvider(new BouncyCastleProvider());
270:
271: runTest(new ECNRTest());
272: }
273: }
|