summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2023-12-05 13:24:04 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2023-12-05 13:24:04 +0700
commit00721e6cd0c40535c58b734d33790245bafaba0d (patch)
treecb414158b44c89ce1e2186ec17469ce67a121208
parentAdd TODO[api] (diff)
downloadBouncyCastle.NET-ed25519-00721e6cd0c40535c58b734d33790245bafaba0d.tar.xz
Refactor ECCurve primality checks
-rw-r--r--crypto/src/asn1/anssi/ANSSINamedCurves.cs2
-rw-r--r--crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs16
-rw-r--r--crypto/src/asn1/gm/GMNamedCurves.cs4
-rw-r--r--crypto/src/asn1/sec/SECNamedCurves.cs30
-rw-r--r--crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs28
-rw-r--r--crypto/src/asn1/x9/X962NamedCurves.cs14
-rw-r--r--crypto/src/math/ec/ECCurve.cs60
-rw-r--r--crypto/src/math/ec/custom/gm/SM2P256V1Curve.cs2
-rw-r--r--crypto/src/math/ec/custom/sec/SecP128R1Curve.cs2
-rw-r--r--crypto/src/math/ec/custom/sec/SecP160K1Curve.cs2
-rw-r--r--crypto/src/math/ec/custom/sec/SecP160R1Curve.cs2
-rw-r--r--crypto/src/math/ec/custom/sec/SecP160R2Curve.cs2
-rw-r--r--crypto/src/math/ec/custom/sec/SecP192K1Curve.cs2
-rw-r--r--crypto/src/math/ec/custom/sec/SecP192R1Curve.cs2
-rw-r--r--crypto/src/math/ec/custom/sec/SecP224K1Curve.cs2
-rw-r--r--crypto/src/math/ec/custom/sec/SecP224R1Curve.cs2
-rw-r--r--crypto/src/math/ec/custom/sec/SecP256K1Curve.cs2
-rw-r--r--crypto/src/math/ec/custom/sec/SecP256R1Curve.cs2
-rw-r--r--crypto/src/math/ec/custom/sec/SecP384R1Curve.cs2
-rw-r--r--crypto/src/math/ec/custom/sec/SecP521R1Curve.cs2
20 files changed, 93 insertions, 87 deletions
diff --git a/crypto/src/asn1/anssi/ANSSINamedCurves.cs b/crypto/src/asn1/anssi/ANSSINamedCurves.cs
index 2e164989a..ab6cd888c 100644
--- a/crypto/src/asn1/anssi/ANSSINamedCurves.cs
+++ b/crypto/src/asn1/anssi/ANSSINamedCurves.cs
@@ -45,7 +45,7 @@ namespace Org.BouncyCastle.Asn1.Anssi
                 BigInteger n = FromHex("F1FD178C0B3AD58F10126DE8CE42435B53DC67E140D2BF941FFDD459C6D655E1");
                 BigInteger h = BigInteger.One;
 
-                return ConfigureCurve(new FpCurve(p, a, b, n, h, true));
+                return ConfigureCurve(new FpCurve(p, a, b, n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
diff --git a/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs b/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs
index 8e0f55001..cb702794c 100644
--- a/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs
+++ b/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs
@@ -47,7 +47,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
                     mod_p,
                     FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94"),
                     FromHex("A6"),
-                    mod_q, BigInteger.One, true));
+                    mod_q, BigInteger.One, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -79,7 +79,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
                     mod_p,
                     FromHex("8000000000000000000000000000000000000000000000000000000000000C96"),
                     FromHex("3E1AF419A269A5F866A7D3C25C3DF80AE979259373FF2B182F49D4CE7E1BBC8B"),
-                    mod_q, BigInteger.One, true));
+                    mod_q, BigInteger.One, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -111,7 +111,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
                     mod_p,
                     FromHex("9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598"),
                     FromHex("805A"),
-                    mod_q, BigInteger.One, true));
+                    mod_q, BigInteger.One, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -143,7 +143,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
                     mod_p,
                     FromHex("9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598"),
                     FromHex("805A"),
-                    mod_q, BigInteger.One, true));
+                    mod_q, BigInteger.One, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -175,7 +175,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
                     mod_p,
                     FromHex("C2173F1513981673AF4892C23035A27CE25E2013BF95AA33B22C656F277E7335"),
                     FromHex("295F9BAE7428ED9CCC20E7C359A9D41A22FCCD9108E17BF7BA9337A6F8AE9513"),
-                    mod_q, BigInteger.Four, true));
+                    mod_q, BigInteger.Four, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -207,7 +207,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
                     mod_p,
                     FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC4"),
                     FromHex("E8C2505DEDFC86DDC1BD0B2B6667F1DA34B82574761CB0E879BD081CFD0B6265EE3CB090F30D27614CB4574010DA90DD862EF9D4EBEE4761503190785A71C760"),
-                    mod_q, BigInteger.One, true));
+                    mod_q, BigInteger.One, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -239,7 +239,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
                     mod_p,
                     FromHex("8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006C"),
                     FromHex("687D1B459DC841457E3E06CF6F5E2517B97C7D614AF138BCBF85DC806C4B289F3E965D2DB1416D217F8B276FAD1AB69C50F78BEE1FA3106EFB8CCBC7C5140116"),
-                    mod_q, BigInteger.One, true));
+                    mod_q, BigInteger.One, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -271,7 +271,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro
                     mod_p,
                     FromHex("DC9203E514A721875485A529D2C722FB187BC8980EB866644DE41C68E143064546E861C0E2C9EDD92ADE71F46FCF50FF2AD97F951FDA9F2A2EB6546F39689BD3"),
                     FromHex("B4C4EE28CEBC6C2C8AC12952CF37F16AC7EFB6A9F69F4B57FFDA2E4F0DE5ADE038CBC2FFF719D2C18DE0284B8BFEF3B52B8CC7A5F5BF0A3C8D2319A5312557E1"),
-                    mod_q, BigInteger.Four, true));
+                    mod_q, BigInteger.Four, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
diff --git a/crypto/src/asn1/gm/GMNamedCurves.cs b/crypto/src/asn1/gm/GMNamedCurves.cs
index bfa83e6a3..dc915910b 100644
--- a/crypto/src/asn1/gm/GMNamedCurves.cs
+++ b/crypto/src/asn1/gm/GMNamedCurves.cs
@@ -45,7 +45,7 @@ namespace Org.BouncyCastle.Asn1.GM
                 BigInteger n = FromHex("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123");
                 BigInteger h = BigInteger.One;
 
-                return ConfigureCurve(new FpCurve(p, a, b, n, h, true));
+                return ConfigureCurve(new FpCurve(p, a, b, n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -75,7 +75,7 @@ namespace Org.BouncyCastle.Asn1.GM
                 BigInteger n = FromHex("BDB6F4FE3E8B1D9E0DA8C0D40FC962195DFAE76F56564677");
                 BigInteger h = BigInteger.One;
 
-                return ConfigureCurve(new FpCurve(p, a, b, n, h, true));
+                return ConfigureCurve(new FpCurve(p, a, b, n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
diff --git a/crypto/src/asn1/sec/SECNamedCurves.cs b/crypto/src/asn1/sec/SECNamedCurves.cs
index 8a97af388..d6ebbdcb2 100644
--- a/crypto/src/asn1/sec/SECNamedCurves.cs
+++ b/crypto/src/asn1/sec/SECNamedCurves.cs
@@ -52,7 +52,7 @@ namespace Org.BouncyCastle.Asn1.Sec
                 BigInteger n = FromHex("DB7C2ABF62E35E7628DFAC6561C5");
                 BigInteger h = BigInteger.One;
 
-                return ConfigureCurve(new FpCurve(p, a, b, n, h, true));
+                return ConfigureCurve(new FpCurve(p, a, b, n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -83,7 +83,7 @@ namespace Org.BouncyCastle.Asn1.Sec
                 BigInteger n = FromHex("36DF0AAFD8B8D7597CA10520D04B");
                 BigInteger h = BigInteger.ValueOf(4);
 
-                return ConfigureCurve(new FpCurve(p, a, b, n, h, true));
+                return ConfigureCurve(new FpCurve(p, a, b, n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -114,7 +114,7 @@ namespace Org.BouncyCastle.Asn1.Sec
                 BigInteger n = FromHex("FFFFFFFE0000000075A30D1B9038A115");
                 BigInteger h = BigInteger.One;
 
-                return ConfigureCurve(new FpCurve(p, a, b, n, h, true));
+                return ConfigureCurve(new FpCurve(p, a, b, n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -145,7 +145,7 @@ namespace Org.BouncyCastle.Asn1.Sec
                 BigInteger n = FromHex("3FFFFFFF7FFFFFFFBE0024720613B5A3");
                 BigInteger h = BigInteger.ValueOf(4);
 
-                return ConfigureCurve(new FpCurve(p, a, b, n, h, true));
+                return ConfigureCurve(new FpCurve(p, a, b, n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -190,7 +190,7 @@ namespace Org.BouncyCastle.Asn1.Sec
                         new BigInteger("96341f1138933bc2f503fd44", 16),
                         176));
 
-                return ConfigureCurveGlv(new FpCurve(p, a, b, n, h, true), glv);
+                return ConfigureCurveGlv(new FpCurve(p, a, b, n, h, isInternal: true), glv);
             }
 
             protected override X9ECParameters CreateParameters()
@@ -221,7 +221,7 @@ namespace Org.BouncyCastle.Asn1.Sec
                 BigInteger n = FromHex("0100000000000000000001F4C8F927AED3CA752257");
                 BigInteger h = BigInteger.One;
 
-                return ConfigureCurve(new FpCurve(p, a, b, n, h, true));
+                return ConfigureCurve(new FpCurve(p, a, b, n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -252,7 +252,7 @@ namespace Org.BouncyCastle.Asn1.Sec
                 BigInteger n = FromHex("0100000000000000000000351EE786A818F3A1A16B");
                 BigInteger h = BigInteger.One;
 
-                return ConfigureCurve(new FpCurve(p, a, b, n, h, true));
+                return ConfigureCurve(new FpCurve(p, a, b, n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -297,7 +297,7 @@ namespace Org.BouncyCastle.Asn1.Sec
                         new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
                         208));
 
-                return ConfigureCurveGlv(new FpCurve(p, a, b, n, h, true), glv);
+                return ConfigureCurveGlv(new FpCurve(p, a, b, n, h, isInternal: true), glv);
             }
 
             protected override X9ECParameters CreateParameters()
@@ -328,7 +328,7 @@ namespace Org.BouncyCastle.Asn1.Sec
                 BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831");
                 BigInteger h = BigInteger.One;
 
-                return ConfigureCurve(new FpCurve(p, a, b, n, h, true));
+                return ConfigureCurve(new FpCurve(p, a, b, n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -373,7 +373,7 @@ namespace Org.BouncyCastle.Asn1.Sec
                         new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
                         240));
 
-                return ConfigureCurveGlv(new FpCurve(p, a, b, n, h, true), glv);
+                return ConfigureCurveGlv(new FpCurve(p, a, b, n, h, isInternal: true), glv);
             }
 
             protected override X9ECParameters CreateParameters()
@@ -404,7 +404,7 @@ namespace Org.BouncyCastle.Asn1.Sec
                 BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D");
                 BigInteger h = BigInteger.One;
 
-                return ConfigureCurve(new FpCurve(p, a, b, n, h, true));
+                return ConfigureCurve(new FpCurve(p, a, b, n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -449,7 +449,7 @@ namespace Org.BouncyCastle.Asn1.Sec
                         new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
                         272));
 
-                return ConfigureCurveGlv(new FpCurve(p, a, b, n, h, true), glv);
+                return ConfigureCurveGlv(new FpCurve(p, a, b, n, h, isInternal: true), glv);
             }
 
             protected override X9ECParameters CreateParameters()
@@ -480,7 +480,7 @@ namespace Org.BouncyCastle.Asn1.Sec
                 BigInteger n = FromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551");
                 BigInteger h = BigInteger.One;
 
-                return ConfigureCurve(new FpCurve(p, a, b, n, h, true));
+                return ConfigureCurve(new FpCurve(p, a, b, n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -511,7 +511,7 @@ namespace Org.BouncyCastle.Asn1.Sec
                 BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973");
                 BigInteger h = BigInteger.One;
 
-                return ConfigureCurve(new FpCurve(p, a, b, n, h, true));
+                return ConfigureCurve(new FpCurve(p, a, b, n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -543,7 +543,7 @@ namespace Org.BouncyCastle.Asn1.Sec
                 BigInteger n = FromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409");
                 BigInteger h = BigInteger.One;
 
-                return ConfigureCurve(new FpCurve(p, a, b, n, h, true));
+                return ConfigureCurve(new FpCurve(p, a, b, n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
diff --git a/crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs b/crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs
index d022ab8a5..a85bd9125 100644
--- a/crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs
+++ b/crypto/src/asn1/teletrust/TeleTrusTNamedCurves.cs
@@ -47,7 +47,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust
                     FromHex("E95E4A5F737059DC60DFC7AD95B3D8139515620F"), // q
                     FromHex("340E7BE2A280EB74E2BE61BADA745D97E8F7C300"), // a
                     FromHex("1E589A8595423412134FAA2DBDEC95C8D8675E58"), // b
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -78,7 +78,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust
                     FromHex("E95E4A5F737059DC60DFC7AD95B3D8139515620F"), // q
                     FromHex("E95E4A5F737059DC60DFC7AD95B3D8139515620C"), // a
                     FromHex("7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380"), // b
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -108,7 +108,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust
                     FromHex("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297"), // q
                     FromHex("6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF"), // a
                     FromHex("469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9"), // b
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -139,7 +139,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust
                     FromHex("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297"), // q
                     FromHex("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294"), // a
                     FromHex("13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79"), // b
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -169,7 +169,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust
                     FromHex("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF"), // q
                     FromHex("68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43"), // a
                     FromHex("2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B"), // b
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -200,7 +200,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust
                     FromHex("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF"), // q
                     FromHex("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC"), // a
                     FromHex("4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D"), // b
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -230,7 +230,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust
                     FromHex("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377"), // q
                     FromHex("7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9"), // a
                     FromHex("26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6"), // b
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -261,7 +261,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust
                     FromHex("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377"), // q
                     FromHex("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374"), // a
                     FromHex("662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04"), // b
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -291,7 +291,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust
                     FromHex("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27"), // q
                     FromHex("3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4"), // a
                     FromHex("520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6"), // b
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -322,7 +322,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust
                     FromHex("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27"), // q
                     FromHex("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E24"), // a
                     FromHex("A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CEB5B4FEF422340353"), // b
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -352,7 +352,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust
                     FromHex("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53"), // q
                     FromHex("7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826"), // a
                     FromHex("04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11"), // b
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -383,7 +383,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust
                     FromHex("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53"), // q
                     FromHex("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC50"), // a
                     FromHex("7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE"), // b
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -413,7 +413,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust
                     FromHex("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3"), // q
                     FromHex("7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA"), // a
                     FromHex("3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723"), // b
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -444,7 +444,7 @@ namespace Org.BouncyCastle.Asn1.TeleTrust
                     FromHex("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3"), // q
                     FromHex("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0"), // a
                     FromHex("7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E"), // b
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
diff --git a/crypto/src/asn1/x9/X962NamedCurves.cs b/crypto/src/asn1/x9/X962NamedCurves.cs
index 893371fd4..231e78f4b 100644
--- a/crypto/src/asn1/x9/X962NamedCurves.cs
+++ b/crypto/src/asn1/x9/X962NamedCurves.cs
@@ -45,7 +45,7 @@ namespace Org.BouncyCastle.Asn1.X9
                     FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
                     FromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
                     FromHex("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1"),
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -76,7 +76,7 @@ namespace Org.BouncyCastle.Asn1.X9
                     FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
                     FromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
                     FromHex("cc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953"),
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -107,7 +107,7 @@ namespace Org.BouncyCastle.Asn1.X9
                     FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"),
                     FromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"),
                     FromHex("22123dc2395a05caa7423daeccc94760a7d462256bd56916"),
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -138,7 +138,7 @@ namespace Org.BouncyCastle.Asn1.X9
                     new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
                     FromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
                     FromHex("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a"),
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -169,7 +169,7 @@ namespace Org.BouncyCastle.Asn1.X9
                     new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
                     FromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
                     FromHex("617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c"),
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -200,7 +200,7 @@ namespace Org.BouncyCastle.Asn1.X9
                     new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"),
                     FromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"),
                     FromHex("255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e"),
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
@@ -231,7 +231,7 @@ namespace Org.BouncyCastle.Asn1.X9
                     new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951"),
                     FromHex("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc"),
                     FromHex("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b"),
-                    n, h, true));
+                    n, h, isInternal: true));
             }
 
             protected override X9ECParameters CreateParameters()
diff --git a/crypto/src/math/ec/ECCurve.cs b/crypto/src/math/ec/ECCurve.cs
index 624495051..a540c719e 100644
--- a/crypto/src/math/ec/ECCurve.cs
+++ b/crypto/src/math/ec/ECCurve.cs
@@ -1,7 +1,7 @@
 using System;
+using System.Collections.Concurrent;
 using System.Collections.Generic;
 
-using Org.BouncyCastle.Math.EC.Abc;
 using Org.BouncyCastle.Math.EC.Endo;
 using Org.BouncyCastle.Math.EC.Multiplier;
 using Org.BouncyCastle.Math.Field;
@@ -675,40 +675,26 @@ namespace Org.BouncyCastle.Math.EC
     public abstract class AbstractFpCurve
         : ECCurve
     {
-        private static readonly HashSet<BigInteger> KnownQs = new HashSet<BigInteger>();
+        private static readonly ConcurrentDictionary<BigInteger, bool> KnownPrimes =
+            new ConcurrentDictionary<BigInteger, bool>();
 
         protected AbstractFpCurve(BigInteger q)
-            : this(q, false)
+            : this(q, isInternal: false)
         {
         }
 
         internal AbstractFpCurve(BigInteger q, bool isInternal)
             : base(FiniteFields.GetPrimeField(q))
         {
-            if (!isInternal)
+            if (isInternal)
             {
-                bool unknownQ;
-                lock (KnownQs) unknownQ = !KnownQs.Contains(q);
-
-                if (unknownQ)
-                {
-                    int maxBitLength = ImplGetInteger("Org.BouncyCastle.EC.Fp_MaxSize", 1042); // 2 * 521
-                    int certainty = ImplGetInteger("Org.BouncyCastle.EC.Fp_Certainty", 100);
-
-                    int qBitLength = q.BitLength;
-                    if (maxBitLength < qBitLength)
-                        throw new ArgumentException("Fp q value out of range");
-
-                    if (Primes.HasAnySmallFactors(q) ||
-                        !Primes.IsMRProbablePrime(q, SecureRandom.ArbitraryRandom,
-                            ImplGetNumberOfIterations(qBitLength, certainty)))
-                    {
-                        throw new ArgumentException("Fp q value not prime");
-                    }
-                }
+                KnownPrimes.AddOrUpdate(q, true, (key, value) => true);
+            }
+            else if (!KnownPrimes.ContainsKey(q))
+            {
+                ImplCheckPrime(q);
+                KnownPrimes.TryAdd(q, false);
             }
-
-            lock (KnownQs) KnownQs.Add(q);
         }
 
         public override bool IsValidFieldElement(BigInteger x)
@@ -761,6 +747,26 @@ namespace Org.BouncyCastle.Math.EC
             return CreateRawPoint(x, y);
         }
 
+        private static void ImplCheckPrime(BigInteger q)
+        {
+            int maxBitLength = ImplGetInteger("Org.BouncyCastle.EC.Fp_MaxSize", 1042); // 2 * 521
+
+            int qBitLength = q.BitLength;
+            if (maxBitLength < qBitLength)
+                throw new ArgumentException("Fp q value out of range");
+
+            if (!Primes.HasAnySmallFactors(q))
+            {
+                int certainty = ImplGetInteger("Org.BouncyCastle.EC.Fp_Certainty", 100);
+                int iterations = ImplGetIterations(qBitLength, certainty);
+
+                if (Primes.IsMRProbablePrime(q, SecureRandom.ArbitraryRandom, iterations))
+                    return;
+            }
+
+            throw new ArgumentException("Fp q value not prime");
+        }
+
         private static int ImplGetInteger(string envVariable, int defaultValue)
         {
             string v = Platform.GetEnvironmentVariable(envVariable);
@@ -770,7 +776,7 @@ namespace Org.BouncyCastle.Math.EC
             return int.Parse(v);
         }
 
-        private static int ImplGetNumberOfIterations(int bits, int certainty)
+        private static int ImplGetIterations(int bits, int certainty)
         {
             /*
              * NOTE: We enforce a minimum 'certainty' of 100 for bits >= 1024 (else 80). Where the
@@ -864,7 +870,7 @@ namespace Org.BouncyCastle.Math.EC
 
         internal FpCurve(BigInteger q, BigInteger r, ECFieldElement a, ECFieldElement b, BigInteger order,
             BigInteger cofactor)
-            : base(q, true)
+            : base(q, isInternal: true)
         {
             this.m_q = q;
             this.m_r = r;
diff --git a/crypto/src/math/ec/custom/gm/SM2P256V1Curve.cs b/crypto/src/math/ec/custom/gm/SM2P256V1Curve.cs
index 3147ccf98..6456120a6 100644
--- a/crypto/src/math/ec/custom/gm/SM2P256V1Curve.cs
+++ b/crypto/src/math/ec/custom/gm/SM2P256V1Curve.cs
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.GM
         protected readonly SM2P256V1Point m_infinity;
 
         public SM2P256V1Curve()
-            : base(q, true)
+            : base(q, isInternal: true)
         {
             this.m_infinity = new SM2P256V1Point(this, null, null);
 
diff --git a/crypto/src/math/ec/custom/sec/SecP128R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP128R1Curve.cs
index 5fa18d470..b96fa75d0 100644
--- a/crypto/src/math/ec/custom/sec/SecP128R1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP128R1Curve.cs
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
         protected readonly SecP128R1Point m_infinity;
 
         public SecP128R1Curve()
-            : base(q, true)
+            : base(q, isInternal: true)
         {
             this.m_infinity = new SecP128R1Point(this, null, null);
 
diff --git a/crypto/src/math/ec/custom/sec/SecP160K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP160K1Curve.cs
index b757659d2..471f7f992 100644
--- a/crypto/src/math/ec/custom/sec/SecP160K1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP160K1Curve.cs
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
         protected readonly SecP160K1Point m_infinity;
 
         public SecP160K1Curve()
-            : base(q, true)
+            : base(q, isInternal: true)
         {
             this.m_infinity = new SecP160K1Point(this, null, null);
 
diff --git a/crypto/src/math/ec/custom/sec/SecP160R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP160R1Curve.cs
index 3b7e1aa06..491b10fd3 100644
--- a/crypto/src/math/ec/custom/sec/SecP160R1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP160R1Curve.cs
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
         protected readonly SecP160R1Point m_infinity;
 
         public SecP160R1Curve()
-            : base(q, true)
+            : base(q, isInternal: true)
         {
             this.m_infinity = new SecP160R1Point(this, null, null);
 
diff --git a/crypto/src/math/ec/custom/sec/SecP160R2Curve.cs b/crypto/src/math/ec/custom/sec/SecP160R2Curve.cs
index 0f226ad19..97d8b6d00 100644
--- a/crypto/src/math/ec/custom/sec/SecP160R2Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP160R2Curve.cs
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
         protected readonly SecP160R2Point m_infinity;
 
         public SecP160R2Curve()
-            : base(q, true)
+            : base(q, isInternal: true)
         {
             this.m_infinity = new SecP160R2Point(this, null, null);
 
diff --git a/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs
index b9ff71ac8..b4a884e83 100644
--- a/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
         protected readonly SecP192K1Point m_infinity;
 
         public SecP192K1Curve()
-            : base(q, true)
+            : base(q, isInternal: true)
         {
             this.m_infinity = new SecP192K1Point(this, null, null);
 
diff --git a/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs
index 77524b362..accb5a786 100644
--- a/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
         protected readonly SecP192R1Point m_infinity;
 
         public SecP192R1Curve()
-            : base(q, true)
+            : base(q, isInternal: true)
         {
             this.m_infinity = new SecP192R1Point(this, null, null);
 
diff --git a/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs
index 04be47202..7f828bc87 100644
--- a/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
         protected readonly SecP224K1Point m_infinity;
 
         public SecP224K1Curve()
-            : base(q, true)
+            : base(q, isInternal: true)
         {
             this.m_infinity = new SecP224K1Point(this, null, null);
 
diff --git a/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs
index 8cd2b7272..ca2b876af 100644
--- a/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
         protected readonly SecP224R1Point m_infinity;
 
         public SecP224R1Curve()
-            : base(q, true)
+            : base(q, isInternal: true)
         {
             this.m_infinity = new SecP224R1Point(this, null, null);
 
diff --git a/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs
index 804b65d60..391ac7b17 100644
--- a/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
         protected readonly SecP256K1Point m_infinity;
 
         public SecP256K1Curve()
-            : base(q, true)
+            : base(q, isInternal: true)
         {
             this.m_infinity = new SecP256K1Point(this, null, null);
 
diff --git a/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs
index dd2b964c6..a9d1a4a2b 100644
--- a/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
         protected readonly SecP256R1Point m_infinity;
 
         public SecP256R1Curve()
-            : base(q, true)
+            : base(q, isInternal: true)
         {
             this.m_infinity = new SecP256R1Point(this, null, null);
 
diff --git a/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs
index f54dd44c2..4704bb16f 100644
--- a/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
         protected readonly SecP384R1Point m_infinity;
 
         public SecP384R1Curve()
-            : base(q, true)
+            : base(q, isInternal: true)
         {
             this.m_infinity = new SecP384R1Point(this, null, null);
 
diff --git a/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs
index a5f4cf957..136af8a1a 100644
--- a/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs
@@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
         protected readonly SecP521R1Point m_infinity;
 
         public SecP521R1Curve()
-            : base(q, true)
+            : base(q, isInternal: true)
         {
             this.m_infinity = new SecP521R1Point(this, null, null);