001: package org.bouncycastle.asn1.teletrust;
002:
003: import org.bouncycastle.asn1.DERObjectIdentifier;
004: import org.bouncycastle.asn1.x9.X9ECParameters;
005: import org.bouncycastle.asn1.x9.X9ECParametersHolder;
006: import org.bouncycastle.math.ec.ECCurve;
007: import org.bouncycastle.util.Strings;
008: import org.bouncycastle.util.encoders.Hex;
009:
010: import java.math.BigInteger;
011: import java.util.Enumeration;
012: import java.util.Hashtable;
013:
014: /**
015: * elliptic curves defined in "ECC Brainpool Standard Curves and Curve Generation"
016: * http://www.ecc-brainpool.org/download/draft_pkix_additional_ecc_dp.txt
017: */
018: public class TeleTrusTNamedCurves {
019: static X9ECParametersHolder brainpoolP160r1 = new X9ECParametersHolder() {
020: protected X9ECParameters createParameters() {
021: ECCurve curve = new ECCurve.Fp(new BigInteger(
022: "E95E4A5F737059DC60DFC7AD95B3D8139515620F", 16), // q
023: new BigInteger(
024: "340E7BE2A280EB74E2BE61BADA745D97E8F7C300",
025: 16), // a
026: new BigInteger(
027: "1E589A8595423412134FAA2DBDEC95C8D8675E58",
028: 16)); // b
029:
030: return new X9ECParameters(
031: curve,
032: curve
033: .decodePoint(Hex
034: .decode("04BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC31667CB477A1A8EC338F94741669C976316DA6321")), // G
035: new BigInteger(
036: "E95E4A5F737059DC60DF5991D45029409E60FC09",
037: 16), //n
038: new BigInteger("01", 16)); // h
039: }
040: };
041:
042: static X9ECParametersHolder brainpoolP160t1 = new X9ECParametersHolder() {
043: protected X9ECParameters createParameters() {
044: ECCurve curve = new ECCurve.Fp(
045: // new BigInteger("24DBFF5DEC9B986BBFE5295A29BFBAE45E0F5D0B", 16), // Z
046: new BigInteger(
047: "E95E4A5F737059DC60DFC7AD95B3D8139515620F",
048: 16), // q
049: new BigInteger(
050: "E95E4A5F737059DC60DFC7AD95B3D8139515620C",
051: 16), // a'
052: new BigInteger(
053: "7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380",
054: 16)); // b'
055:
056: return new X9ECParameters(
057: curve,
058: curve
059: .decodePoint(Hex
060: .decode("04B199B13B9B34EFC1397E64BAEB05ACC265FF2378ADD6718B7C7C1961F0991B842443772152C9E0AD")), // G
061: new BigInteger(
062: "E95E4A5F737059DC60DF5991D45029409E60FC09",
063: 16), //n
064: new BigInteger("01", 16)); // h
065: }
066: };
067:
068: static X9ECParametersHolder brainpoolP192r1 = new X9ECParametersHolder() {
069: protected X9ECParameters createParameters() {
070: ECCurve curve = new ECCurve.Fp(
071: new BigInteger(
072: "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297",
073: 16), // q
074: new BigInteger(
075: "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF",
076: 16), // a
077: new BigInteger(
078: "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9",
079: 16)); // b
080:
081: return new X9ECParameters(
082: curve,
083: curve
084: .decodePoint(Hex
085: .decode("04C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD614B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F")), // G
086: new BigInteger(
087: "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1",
088: 16), //n
089: new BigInteger("01", 16)); // h
090: }
091: };
092:
093: static X9ECParametersHolder brainpoolP192t1 = new X9ECParametersHolder() {
094: protected X9ECParameters createParameters() {
095: ECCurve curve = new ECCurve.Fp(
096: //new BigInteger("1B6F5CC8DB4DC7AF19458A9CB80DC2295E5EB9C3732104CB") //Z
097: new BigInteger(
098: "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297",
099: 16), // q
100: new BigInteger(
101: "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294",
102: 16), // a'
103: new BigInteger(
104: "13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79",
105: 16)); // b'
106:
107: return new X9ECParameters(
108: curve,
109: curve
110: .decodePoint(Hex
111: .decode("043AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9")), // G'
112: new BigInteger(
113: "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1",
114: 16), //n
115: new BigInteger("01", 16)); // h
116: }
117: };
118:
119: static X9ECParametersHolder brainpoolP224r1 = new X9ECParametersHolder() {
120: protected X9ECParameters createParameters() {
121: ECCurve curve = new ECCurve.Fp(
122: new BigInteger(
123: "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF",
124: 16), // q
125: new BigInteger(
126: "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43",
127: 16), // a
128: new BigInteger(
129: "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B",
130: 16)); // b
131:
132: return new X9ECParameters(
133: curve,
134: curve
135: .decodePoint(Hex
136: .decode("040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD")), // G
137: new BigInteger(
138: "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F",
139: 16), //n
140: new BigInteger("01", 16)); // n
141: }
142: };
143: static X9ECParametersHolder brainpoolP224t1 = new X9ECParametersHolder() {
144: protected X9ECParameters createParameters() {
145: ECCurve curve = new ECCurve.Fp(
146: //new BigInteger("2DF271E14427A346910CF7A2E6CFA7B3F484E5C2CCE1C8B730E28B3F") //Z
147: new BigInteger(
148: "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF",
149: 16), // q
150: new BigInteger(
151: "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC",
152: 16), // a'
153: new BigInteger(
154: "4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D",
155: 16)); // b'
156:
157: return new X9ECParameters(
158: curve,
159: curve
160: .decodePoint(Hex
161: .decode("046AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D5800374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C")), // G'
162: new BigInteger(
163: "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F",
164: 16), //n
165: new BigInteger("01", 16)); // h
166: }
167: };
168: static X9ECParametersHolder brainpoolP256r1 = new X9ECParametersHolder() {
169: protected X9ECParameters createParameters() {
170: ECCurve curve = new ECCurve.Fp(
171: new BigInteger(
172: "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377",
173: 16), // q
174: new BigInteger(
175: "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9",
176: 16), // a
177: new BigInteger(
178: "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6",
179: 16)); // b
180:
181: return new X9ECParameters(
182: curve,
183: curve
184: .decodePoint(Hex
185: .decode("048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997")), // G
186: new BigInteger(
187: "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7",
188: 16), //n
189: new BigInteger("01", 16)); // h
190: }
191: };
192: static X9ECParametersHolder brainpoolP256t1 = new X9ECParametersHolder() {
193: protected X9ECParameters createParameters() {
194: ECCurve curve = new ECCurve.Fp(
195: //new BigInteger("3E2D4BD9597B58639AE7AA669CAB9837CF5CF20A2C852D10F655668DFC150EF0") //Z
196: new BigInteger(
197: "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377",
198: 16), // q
199: new BigInteger(
200: "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374",
201: 16), // a'
202: new BigInteger(
203: "662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04",
204: 16)); // b'
205:
206: return new X9ECParameters(
207: curve,
208: curve
209: .decodePoint(Hex
210: .decode("04A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F42D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE")), // G'
211: new BigInteger(
212: "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7",
213: 16), //n
214: new BigInteger("01", 16)); // h
215: }
216: };
217: static X9ECParametersHolder brainpoolP320r1 = new X9ECParametersHolder() {
218: protected X9ECParameters createParameters() {
219: ECCurve curve = new ECCurve.Fp(
220: new BigInteger(
221: "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27",
222: 16), // q
223: new BigInteger(
224: "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4",
225: 16), // a
226: new BigInteger(
227: "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6",
228: 16)); // b
229:
230: return new X9ECParameters(
231: curve,
232: curve
233: .decodePoint(Hex
234: .decode("0443BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E2061114FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1")), // G
235: new BigInteger(
236: "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311",
237: 16), //n
238: new BigInteger("01", 16)); // h
239: }
240: };
241: static X9ECParametersHolder brainpoolP320t1 = new X9ECParametersHolder() {
242: protected X9ECParameters createParameters() {
243: ECCurve curve = new ECCurve.Fp(
244: //new BigInteger("15F75CAF668077F7E85B42EB01F0A81FF56ECD6191D55CB82B7D861458A18FEFC3E5AB7496F3C7B1") //Z
245: new BigInteger(
246: "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27",
247: 16), // q
248: new BigInteger(
249: "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E24",
250: 16), // a'
251: new BigInteger(
252: "A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CEB5B4FEF422340353",
253: 16)); // b'
254:
255: return new X9ECParameters(
256: curve,
257: curve
258: .decodePoint(Hex
259: .decode("04925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF3357F624A21BED5263BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B1B9BC0455FB0D2C3")), // G'
260: new BigInteger(
261: "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311",
262: 16), //n
263: new BigInteger("01", 16)); // h
264: }
265: };
266: static X9ECParametersHolder brainpoolP384r1 = new X9ECParametersHolder() {
267: protected X9ECParameters createParameters() {
268: ECCurve curve = new ECCurve.Fp(
269: new BigInteger(
270: "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53",
271: 16), // q
272: new BigInteger(
273: "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826",
274: 16), // a
275: new BigInteger(
276: "4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11",
277: 16)); // b
278:
279: return new X9ECParameters(
280: curve,
281: curve
282: .decodePoint(Hex
283: .decode("041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315")), // G
284: new BigInteger(
285: "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565",
286: 16), //n
287: new BigInteger("01", 16)); // h
288: }
289: };
290: static X9ECParametersHolder brainpoolP384t1 = new X9ECParametersHolder() {
291: protected X9ECParameters createParameters() {
292: ECCurve curve = new ECCurve.Fp(
293: //new BigInteger("41DFE8DD399331F7166A66076734A89CD0D2BCDB7D068E44E1F378F41ECBAE97D2D63DBC87BCCDDCCC5DA39E8589291C") //Z
294: new BigInteger(
295: "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53",
296: 16), // q
297: new BigInteger(
298: "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC50",
299: 16), // a'
300: new BigInteger(
301: "7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE",
302: 16)); // b'
303:
304: return new X9ECParameters(
305: curve,
306: curve
307: .decodePoint(Hex
308: .decode("0418DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946A5F54D8D0AA2F418808CC25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC2B2912675BF5B9E582928")), // G'
309: new BigInteger(
310: "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565",
311: 16), //n
312: new BigInteger("01", 16)); // h
313: }
314: };
315: static X9ECParametersHolder brainpoolP512r1 = new X9ECParametersHolder() {
316: protected X9ECParameters createParameters() {
317: ECCurve curve = new ECCurve.Fp(
318: new BigInteger(
319: "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3",
320: 16), // q
321: new BigInteger(
322: "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA",
323: 16), // a
324: new BigInteger(
325: "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723",
326: 16)); // b
327:
328: return new X9ECParameters(
329: curve,
330: curve
331: .decodePoint(Hex
332: .decode("0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892")), // G
333: new BigInteger(
334: "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069",
335: 16), //n
336: new BigInteger("01", 16)); // h
337: }
338: };
339: static X9ECParametersHolder brainpoolP512t1 = new X9ECParametersHolder() {
340: protected X9ECParameters createParameters() {
341: ECCurve curve = new ECCurve.Fp(
342: //new BigInteger("12EE58E6764838B69782136F0F2D3BA06E27695716054092E60A80BEDB212B64E585D90BCE13761F85C3F1D2A64E3BE8FEA2220F01EBA5EEB0F35DBD29D922AB") //Z
343: new BigInteger(
344: "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3",
345: 16), // q
346: new BigInteger(
347: "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0",
348: 16), // a'
349: new BigInteger(
350: "7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E",
351: 16)); // b'
352:
353: return new X9ECParameters(
354: curve,
355: curve
356: .decodePoint(Hex
357: .decode("04640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332")), // G'
358: new BigInteger(
359: "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069",
360: 16), //n
361: new BigInteger("01", 16)); // h
362: }
363: };
364:
365: static final Hashtable objIds = new Hashtable();
366: static final Hashtable curves = new Hashtable();
367: static final Hashtable names = new Hashtable();
368:
369: static void defineCurve(String name, DERObjectIdentifier oid,
370: X9ECParametersHolder holder) {
371: objIds.put(name, oid);
372: names.put(oid, name);
373: curves.put(oid, holder);
374: }
375:
376: static {
377: defineCurve("brainpoolp160r1",
378: TeleTrusTObjectIdentifiers.brainpoolP160r1,
379: brainpoolP160r1);
380: defineCurve("brainpoolp160t1",
381: TeleTrusTObjectIdentifiers.brainpoolP160t1,
382: brainpoolP160t1);
383: defineCurve("brainpoolp192r1",
384: TeleTrusTObjectIdentifiers.brainpoolP192r1,
385: brainpoolP192r1);
386: defineCurve("brainpoolp192t1",
387: TeleTrusTObjectIdentifiers.brainpoolP192t1,
388: brainpoolP192t1);
389: defineCurve("brainpoolp224r1",
390: TeleTrusTObjectIdentifiers.brainpoolP224r1,
391: brainpoolP224r1);
392: defineCurve("brainpoolp224t1",
393: TeleTrusTObjectIdentifiers.brainpoolP224t1,
394: brainpoolP224t1);
395: defineCurve("brainpoolp256r1",
396: TeleTrusTObjectIdentifiers.brainpoolP256r1,
397: brainpoolP256r1);
398: defineCurve("brainpoolp256t1",
399: TeleTrusTObjectIdentifiers.brainpoolP256t1,
400: brainpoolP256t1);
401: defineCurve("brainpoolp320r1",
402: TeleTrusTObjectIdentifiers.brainpoolP320r1,
403: brainpoolP320r1);
404: defineCurve("brainpoolp320t1",
405: TeleTrusTObjectIdentifiers.brainpoolP320t1,
406: brainpoolP320t1);
407: defineCurve("brainpoolp384r1",
408: TeleTrusTObjectIdentifiers.brainpoolP384r1,
409: brainpoolP384r1);
410: defineCurve("brainpoolp384t1",
411: TeleTrusTObjectIdentifiers.brainpoolP384t1,
412: brainpoolP384t1);
413: defineCurve("brainpoolp512r1",
414: TeleTrusTObjectIdentifiers.brainpoolP512r1,
415: brainpoolP512r1);
416: defineCurve("brainpoolp512t1",
417: TeleTrusTObjectIdentifiers.brainpoolP512t1,
418: brainpoolP512t1);
419: }
420:
421: public static X9ECParameters getByName(String name) {
422: DERObjectIdentifier oid = (DERObjectIdentifier) objIds
423: .get(Strings.toLowerCase(name));
424:
425: if (oid != null) {
426: return getByOID(oid);
427: }
428:
429: return null;
430: }
431:
432: /**
433: * return the X9ECParameters object for the named curve represented by
434: * the passed in object identifier. Null if the curve isn't present.
435: *
436: * @param oid an object identifier representing a named curve, if present.
437: */
438: public static X9ECParameters getByOID(DERObjectIdentifier oid) {
439: X9ECParametersHolder holder = (X9ECParametersHolder) curves
440: .get(oid);
441:
442: if (holder != null) {
443: return holder.getParameters();
444: }
445:
446: return null;
447: }
448:
449: /**
450: * return the object identifier signified by the passed in name. Null
451: * if there is no object identifier associated with name.
452: *
453: * @return the object identifier associated with name, if present.
454: */
455: public static DERObjectIdentifier getOID(String name) {
456: return (DERObjectIdentifier) objIds.get(Strings
457: .toLowerCase(name));
458: }
459:
460: /**
461: * return the named curve name represented by the given object identifier.
462: */
463: public static String getName(DERObjectIdentifier oid) {
464: return (String) names.get(oid);
465: }
466:
467: /**
468: * returns an enumeration containing the name strings for curves
469: * contained in this structure.
470: */
471: public static Enumeration getNames() {
472: return objIds.keys();
473: }
474:
475: public static DERObjectIdentifier getOID(short curvesize,
476: boolean twisted) {
477: return getOID("brainpoolP" + curvesize + (twisted ? "t" : "r")
478: + "1");
479: }
480: }
|