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}