001/*
002 * nimbus-jose-jwt
003 *
004 * Copyright 2012-2016, Connect2id Ltd.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.jose.jwk;
019
020
021import java.math.BigInteger;
022import java.security.spec.ECFieldFp;
023import java.security.spec.ECParameterSpec;
024import java.security.spec.ECPoint;
025import java.security.spec.EllipticCurve;
026
027
028/**
029 * Elliptic curve parameter table.
030 *
031 * <p>Supports the following standard EC JWK curves:
032 *
033 * <ul>
034 *     <li>{@link com.nimbusds.jose.jwk.Curve#P_256}
035 *     <li>{@link com.nimbusds.jose.jwk.Curve#SECP256K1}
036 *     <li>{@link com.nimbusds.jose.jwk.Curve#P_384}
037 *     <li>{@link com.nimbusds.jose.jwk.Curve#P_521}
038 * </ul>
039 *
040 * @author Vladimir Dzhuvinov
041 * @author Aleksei Doroganov
042 * @version 2022-04-22
043 */
044public class ECParameterTable {
045
046
047        /**
048         * The parameter spec for a
049         * {@link com.nimbusds.jose.jwk.Curve#P_256} curve.
050         */
051        private static final ECParameterSpec P_256_SPEC;
052        
053
054        /**
055         * The parameter spec for a
056         * {@link com.nimbusds.jose.jwk.Curve#SECP256K1} curve.
057         */
058        private static final ECParameterSpec SECP256K1_SPEC;
059
060        
061        /**
062         * The parameter spec for a
063         * {@link com.nimbusds.jose.jwk.Curve#P_384} curve.
064         */
065        private static final ECParameterSpec P_384_SPEC;
066
067        
068        /**
069         * The parameter spec for a
070         * {@link com.nimbusds.jose.jwk.Curve#P_521} curve.
071         */
072        private static final ECParameterSpec P_521_SPEC;
073
074
075        static {
076                // Values obtained from org.bouncycastle.jce.ECNamedCurveTable
077
078                P_256_SPEC = new ECParameterSpec(
079                        new EllipticCurve(
080                                new ECFieldFp(new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951")),
081                                new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853948"),
082                                new BigInteger("41058363725152142129326129780047268409114441015993725554835256314039467401291")),
083                        new ECPoint(
084                                new BigInteger("48439561293906451759052585252797914202762949526041747995844080717082404635286"),
085                                new BigInteger("36134250956749795798585127919587881956611106672985015071877198253568414405109")),
086                        new BigInteger("115792089210356248762697446949407573529996955224135760342422259061068512044369"),
087                        1);
088
089                SECP256K1_SPEC = new ECParameterSpec(
090                        new EllipticCurve(
091                                new ECFieldFp(new BigInteger("115792089237316195423570985008687907853269984665640564039457584007908834671663")),
092                                new BigInteger("0"),
093                                new BigInteger("7")),
094                        new ECPoint(
095                                new BigInteger("55066263022277343669578718895168534326250603453777594175500187360389116729240"),
096                                new BigInteger("32670510020758816978083085130507043184471273380659243275938904335757337482424")),
097                        new BigInteger("115792089237316195423570985008687907852837564279074904382605163141518161494337"),
098                        1);
099
100                P_384_SPEC = new ECParameterSpec(
101                        new EllipticCurve(
102                                new ECFieldFp(new BigInteger("39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319")),
103                                new BigInteger("39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112316"),
104                                new BigInteger("27580193559959705877849011840389048093056905856361568521428707301988689241309860865136260764883745107765439761230575")),
105                        new ECPoint(
106                                new BigInteger("26247035095799689268623156744566981891852923491109213387815615900925518854738050089022388053975719786650872476732087"),
107                                new BigInteger("8325710961489029985546751289520108179287853048861315594709205902480503199884419224438643760392947333078086511627871")),
108                        new BigInteger("39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643"),
109                        1);
110
111                P_521_SPEC = new ECParameterSpec(
112                        new EllipticCurve(
113                                new ECFieldFp(new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151")),
114                                new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057148"),
115                                new BigInteger("1093849038073734274511112390766805569936207598951683748994586394495953116150735016013708737573759623248592132296706313309438452531591012912142327488478985984")),
116                        new ECPoint(
117                                new BigInteger("2661740802050217063228768716723360960729859168756973147706671368418802944996427808491545080627771902352094241225065558662157113545570916814161637315895999846"),
118                                new BigInteger("3757180025770020463545507224491183603594455134769762486694567779615544477440556316691234405012945539562144444537289428522585666729196580810124344277578376784")),
119                        new BigInteger("6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449"),
120                        1);
121        }
122
123
124        /**
125         * Gets the parameter specification for the specified elliptic curve.
126         *
127         * @param curve The JWK elliptic curve. May be {@code null}.
128         *
129         * @return The EC parameter spec, {@code null} if it cannot be
130         *         determined.
131         */
132        public static ECParameterSpec get(final Curve curve) {
133
134                if (Curve.P_256.equals(curve)) {
135                        return P_256_SPEC;
136                } else if (Curve.SECP256K1.equals(curve)) {
137                        return SECP256K1_SPEC;
138                } else if (Curve.P_384.equals(curve)) {
139                        return P_384_SPEC;
140                } else if (Curve.P_521.equals(curve)) {
141                        return P_521_SPEC;
142                } else {
143                        return null;
144                }
145        }
146
147
148        /**
149         * Gets the JWK elliptic curve for the specified parameter
150         * specification.
151         *
152         * @param spec The EC parameter spec. May be {@code null}.
153         *
154         * @return The JWK elliptic curve, {@code null} if it cannot be
155         *         determined.
156         */
157        public static Curve get(final ECParameterSpec spec) {
158
159                if (spec == null) {
160                        return null;
161                }
162
163                if (spec.getCurve().getField().getFieldSize() == P_256_SPEC.getCurve().getField().getFieldSize() &&
164                        spec.getCurve().getA().equals(P_256_SPEC.getCurve().getA()) &&
165                        spec.getCurve().getB().equals(P_256_SPEC.getCurve().getB()) &&
166                        spec.getGenerator().getAffineX().equals(P_256_SPEC.getGenerator().getAffineX()) &&
167                        spec.getGenerator().getAffineY().equals(P_256_SPEC.getGenerator().getAffineY()) &&
168                        spec.getOrder().equals(P_256_SPEC.getOrder()) &&
169                        spec.getCofactor() == P_256_SPEC.getCofactor()) {
170
171                        return Curve.P_256;
172
173                } else if (spec.getCurve().getField().getFieldSize() == SECP256K1_SPEC.getCurve().getField().getFieldSize() &&
174                        spec.getCurve().getA().equals(SECP256K1_SPEC.getCurve().getA()) &&
175                        spec.getCurve().getB().equals(SECP256K1_SPEC.getCurve().getB()) &&
176                        spec.getGenerator().getAffineX().equals(SECP256K1_SPEC.getGenerator().getAffineX()) &&
177                        spec.getGenerator().getAffineY().equals(SECP256K1_SPEC.getGenerator().getAffineY()) &&
178                        spec.getOrder().equals(SECP256K1_SPEC.getOrder()) &&
179                        spec.getCofactor() == SECP256K1_SPEC.getCofactor()) {
180
181                        return Curve.SECP256K1;
182
183                } else if (spec.getCurve().getField().getFieldSize() == P_384_SPEC.getCurve().getField().getFieldSize() &&
184                        spec.getCurve().getA().equals(P_384_SPEC.getCurve().getA()) &&
185                        spec.getCurve().getB().equals(P_384_SPEC.getCurve().getB()) &&
186                        spec.getGenerator().getAffineX().equals(P_384_SPEC.getGenerator().getAffineX()) &&
187                        spec.getGenerator().getAffineY().equals(P_384_SPEC.getGenerator().getAffineY()) &&
188                        spec.getOrder().equals(P_384_SPEC.getOrder()) &&
189                        spec.getCofactor() == P_384_SPEC.getCofactor()) {
190
191                        return Curve.P_384;
192
193                } else if (spec.getCurve().getField().getFieldSize() == P_521_SPEC.getCurve().getField().getFieldSize() &&
194                        spec.getCurve().getA().equals(P_521_SPEC.getCurve().getA()) &&
195                        spec.getCurve().getB().equals(P_521_SPEC.getCurve().getB()) &&
196                        spec.getGenerator().getAffineX().equals(P_521_SPEC.getGenerator().getAffineX()) &&
197                        spec.getGenerator().getAffineY().equals(P_521_SPEC.getGenerator().getAffineY()) &&
198                        spec.getOrder().equals(P_521_SPEC.getOrder()) &&
199                        spec.getCofactor() == P_521_SPEC.getCofactor()) {
200
201                        return Curve.P_521;
202
203                } else {
204                        return null;
205                }
206        }
207
208
209        /**
210         * Prevents public instantiation.
211         */
212        private ECParameterTable() {
213
214        }
215}