From fbec51725599f0f8b8f8c5a1f3e752932eb1a91d Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Thu, 8 Nov 2018 15:18:17 -0600 Subject: [PATCH] Better test boundary cases of ec_cmp_x_coordinate. This is done in preparation of generalizing the optimization to all our EC_METHODs. Wycheproof happily does cover the case where x needed a reduction, but they don't appear to check x being just above or below n, only x = p - 1 (adjusted downwards). Also we can tailor the test vectors a bit to the x == r*z^2 (mod p) strategy to make sure we don't mess that up. Additionally, the scenario is different for n > p. There is also the nuisance of EC_FELEM vs EC_SCALAR having different widths. All our built-in curves are well-behaved (same width, and consistently p < n), but secp160r1 is reachable from custom curves and violates both properties. Generate some tests to cover it as well. Change-Id: Iefa5ebfe689a81870be21f04f5962ab161d38dab Reviewed-on: https://boringssl-review.googlesource.com/c/32985 Commit-Queue: David Benjamin CQ-Verified: CQ bot account: commit-bot@chromium.org Reviewed-by: Adam Langley --- crypto/fipsmodule/ecdsa/ecdsa_test.cc | 51 ++- .../fipsmodule/ecdsa/ecdsa_verify_tests.txt | 343 ++++++++++++++++++ 2 files changed, 392 insertions(+), 2 deletions(-) diff --git a/crypto/fipsmodule/ecdsa/ecdsa_test.cc b/crypto/fipsmodule/ecdsa/ecdsa_test.cc index 258c128c..4c95df9e 100644 --- a/crypto/fipsmodule/ecdsa/ecdsa_test.cc +++ b/crypto/fipsmodule/ecdsa/ecdsa_test.cc @@ -68,6 +68,45 @@ #include "../../test/file_test.h" +static bssl::UniquePtr HexToBIGNUM(const char *hex) { + BIGNUM *bn = nullptr; + BN_hex2bn(&bn, hex); + return bssl::UniquePtr(bn); +} + +// Though we do not support secp160r1, it is reachable from the deprecated +// custom curve APIs and has some unique properties (n is larger than p with the +// difference crossing a word boundary on 32-bit), so test it explicitly. +static bssl::UniquePtr NewSecp160r1Group() { + static const char kP[] = "ffffffffffffffffffffffffffffffff7fffffff"; + static const char kA[] = "ffffffffffffffffffffffffffffffff7ffffffc"; + static const char kB[] = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45"; + static const char kX[] = "4a96b5688ef573284664698968c38bb913cbfc82"; + static const char kY[] = "23a628553168947d59dcc912042351377ac5fb32"; + static const char kN[] = "0100000000000000000001f4c8f927aed3ca752257"; + + bssl::UniquePtr p = HexToBIGNUM(kP), a = HexToBIGNUM(kA), + b = HexToBIGNUM(kB), x = HexToBIGNUM(kX), + y = HexToBIGNUM(kY), n = HexToBIGNUM(kN); + if (!p || !a || !b || !x || !y || !n) { + return nullptr; + } + + bssl::UniquePtr group( + EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), nullptr)); + if (!group) { + return nullptr; + } + bssl::UniquePtr g(EC_POINT_new(group.get())); + if (!g || + !EC_POINT_set_affine_coordinates_GFp(group.get(), g.get(), x.get(), + y.get(), nullptr) || + !EC_GROUP_set_generator(group.get(), g.get(), n.get(), BN_value_one())) { + return nullptr; + } + return group; +} + enum API { kEncodedAPI, kRawAPI, @@ -151,13 +190,18 @@ TEST(ECDSATest, BuiltinCurves) { { NID_X9_62_prime256v1, "secp256r1" }, { NID_secp384r1, "secp384r1" }, { NID_secp521r1, "secp521r1" }, + { NID_secp160r1, "secp160r1" }, }; for (const auto &curve : kCurves) { SCOPED_TRACE(curve.name); - int nid = curve.nid; - bssl::UniquePtr group(EC_GROUP_new_by_curve_name(nid)); + bssl::UniquePtr group; + if (curve.nid == NID_secp160r1) { + group = NewSecp160r1Group(); + } else { + group.reset(EC_GROUP_new_by_curve_name(curve.nid)); + } ASSERT_TRUE(group); const BIGNUM *order = EC_GROUP_get0_order(group.get()); @@ -278,6 +322,9 @@ static bssl::UniquePtr GetCurve(FileTest *t, const char *key) { if (curve_name == "P-521") { return bssl::UniquePtr(EC_GROUP_new_by_curve_name(NID_secp521r1)); } + if (curve_name == "secp160r1") { + return NewSecp160r1Group(); + } ADD_FAILURE() << "Unknown curve: " << curve_name; return nullptr; diff --git a/crypto/fipsmodule/ecdsa/ecdsa_verify_tests.txt b/crypto/fipsmodule/ecdsa/ecdsa_verify_tests.txt index aa2fbd3c..9c4b889b 100644 --- a/crypto/fipsmodule/ecdsa/ecdsa_verify_tests.txt +++ b/crypto/fipsmodule/ecdsa/ecdsa_verify_tests.txt @@ -2431,3 +2431,346 @@ Y = 01862ed4f9d235afcc4e6b45e491da363104d4db7b97f12d869c40ab09a3c8c72519a9712ca7 Digest = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff R = 00ec0b91fa4386a8acdc0e46dd9c1d1775abbe0da8ead424aa4ace58e284a5be00e2c1ef95b6f4d861615564e1e7305656567f95275ce63b534420eae77ec37492c2 S = 01e1099fb389db498ab4cf23b4f06a74b9326878ae3c76ea13832e50702b30fe8303093a59cc9a0995f1dfc15e6f7dabca8a2acaf03ec005447d29fb429a252064ec + + +# The following tests are intended to stress the final comparison in ECDSA. +# ECDSA verification computes some curve point (x, y), picking the fully-reduced +# representive of x mod p, and checking that x mod n is r. (n is the order of +# the group and p defines the underlying prime field.) +# +# This makes the computation sensitive to values near n and p, and which of n or +# p is larger. Additionally, there is an optimization that performs the +# comparison mod p rather than n and compensates for the difference. +# +# These tests were generated by picking a target value of r and x, adjusting +# both until x corresponded to a point on the curve, and then computing the +# public key by solving for P in ECDSA's (x, y) = u1*G + u2*P. The digest is the +# hash of "hello, world" with the suitably-sized SHA-2 hash, so the test vectors +# are suitable for both message- and digest-based APIs. +# +# "x" in the comments refer to the x-coordinate of the computed point, not that +# of the public key. + +# r = 3, x = 3 is valid. +Curve = P-224 +X = f43eeb550591547d6a6479726b72be181d4ea26dea5516ae1c0b0ab3 +Y = e127deeb94536c67793ac172ba31f3a6f81efbbf2ab3d7868d0cc9f9 +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = 00000000000000000000000000000000000000000000000000000003 +S = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3a + +# r = 3 + n, x = 3 is invalid. r must already be reduced. +Curve = P-224 +X = f43eeb550591547d6a6479726b72be181d4ea26dea5516ae1c0b0ab3 +Y = e127deeb94536c67793ac172ba31f3a6f81efbbf2ab3d7868d0cc9f9 +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a40 +S = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3a +Invalid = + +# r = n-1, x = n-1 is the largest x without a reduction. +Curve = P-224 +X = 32acb8d348f6ec350822227c4a90048733640317f7833dc9093a78f1 +Y = dd45cab24ef90b8d6437f128437ea847036a8912322a6738dccceaa3 +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3c +S = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3a + +# r = n-2, x = n-1 is incorrect. +Curve = P-224 +X = 32acb8d348f6ec350822227c4a90048733640317f7833dc9093a78f1 +Y = dd45cab24ef90b8d6437f128437ea847036a8912322a6738dccceaa3 +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3b +S = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3a +Invalid = + +# r = 3, x = n+3 is the smallest x with a reduction. +Curve = P-224 +X = d7afcc97eefcf32becf100cf967588c68f9c149fa18344ac08e245b4 +Y = 3b853f6c6d955587d9ac080c8f10bf355f9992a0103a27aa30dac7e8 +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = 00000000000000000000000000000000000000000000000000000003 +S = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3a + +# r = 4, x = n+3 is incorrect. +Curve = P-224 +X = d7afcc97eefcf32becf100cf967588c68f9c149fa18344ac08e245b4 +Y = 3b853f6c6d955587d9ac080c8f10bf355f9992a0103a27aa30dac7e8 +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = 00000000000000000000000000000000000000000000000000000004 +S = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3a +Invalid = + +# r = p-3-n, x = p-3 is the largest valid x. +Curve = P-224 +X = cdacee2255448c72d1558eb866b14831acef41ed348bd938cce655be +Y = d0b409693b64f3597468ae5535338052436158a6771c6318b68025de +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = 0000000000000000000000000000e95c1f470fc1ec22d6baa3a3d5c1 +S = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3a + +# r = p-n+3, x = 3 is incorrect. r is too large to compare r+n with x. +Curve = P-224 +X = cdacee2255448c72d1558eb866b14831acef41ed348bd938cce655be +Y = d0b409693b64f3597468ae5535338052436158a6771c6318b68025de +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = 0000000000000000000000000000e95c1f470fc1ec22d6baa3a3d5c7 +S = ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3a +Invalid = + +# r = 5, x = 5 is valid. +Curve = P-256 +X = 264d796a0dab9b376d34eea6fe297dde1c7b73e53944bc96c8f1e8a6850bb6c9 +Y = cf5308020eed460c649ddae61d4ef8bb79958113f106befaf4f18876d12a5e64 +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = 0000000000000000000000000000000000000000000000000000000000000005 +S = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e + +# r = 5 + n, x = 5 is invalid. r must already be reduced. +Curve = P-256 +X = 264d796a0dab9b376d34eea6fe297dde1c7b73e53944bc96c8f1e8a6850bb6c9 +Y = cf5308020eed460c649ddae61d4ef8bb79958113f106befaf4f18876d12a5e64 +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632556 +S = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e +Invalid = + +# r = n-2, x = n-2 is the largest x without a reduction. +Curve = P-256 +X = 50a50c01132bf79e42b31fb278f7317b29515e9e1c973a41266b69048826fb8e +Y = aac53e7df37b5eb25ce4ddb705fc7135c6b1e00a7f56e30744f62f258afa5537 +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f +S = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e + +# r = n-3, x = n-2 is incorrect. +Curve = P-256 +X = 50a50c01132bf79e42b31fb278f7317b29515e9e1c973a41266b69048826fb8e +Y = aac53e7df37b5eb25ce4ddb705fc7135c6b1e00a7f56e30744f62f258afa5537 +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e +S = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e +Invalid = + +# r = 3, x = n+3 is the smallest x with a reduction. +Curve = P-256 +X = ce24c99032d52ac6ead23c0ae3ec68ef41e51a281fd457808c83136d7dcce90e +Y = 8f7a154b551e9f39c59279357aa491b2a62bdebc2bb78613883fc72936c057e0 +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = 0000000000000000000000000000000000000000000000000000000000000003 +S = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e + +# r = 4, x = n+3 is incorrect. +Curve = P-256 +X = ce24c99032d52ac6ead23c0ae3ec68ef41e51a281fd457808c83136d7dcce90e +Y = 8f7a154b551e9f39c59279357aa491b2a62bdebc2bb78613883fc72936c057e0 +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = 0000000000000000000000000000000000000000000000000000000000000004 +S = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e +Invalid = + +# r = p-3-n, x = p-3 is the largest valid x. +Curve = P-256 +X = 768a0d300a595005a520130e50927d403395c8e1e40be997b48fc048410f7cdb +Y = 16f217d8e1c02bd887e5de388a17783b182e61b5d534152dc2c4be8d75fdd706 +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = 000000000000000000000000000000004319055358e8617b0c46353d039cdaab +S = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e + +# r = p-n+5, x = 5 is incorrect. r is too large to compare r+n with x. +Curve = P-256 +X = 768a0d300a595005a520130e50927d403395c8e1e40be997b48fc048410f7cdb +Y = 16f217d8e1c02bd887e5de388a17783b182e61b5d534152dc2c4be8d75fdd706 +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = 000000000000000000000000000000004319055358e8617b0c46353d039cdab3 +S = ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254e +Invalid = + +# r = 2, x = 2 is valid. +Curve = P-384 +X = 016d2db67561bc126ad6c344d6eeb2713a9e2892c649af0f015c6b7617f160c8a3b3a88add669d7155025073c5ac5b4f +Y = 43bf2ed0088af08645c80aa0a24a567a94ba2d794e9689d3ad4b185bc5d2dd008333e2dd2ebb5069a9b32251a3cac71e +Digest = 1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e +R = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002 +S = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970 + +# r = 2 + n, x = 2 is invalid. r must already be reduced. +Curve = P-384 +X = 016d2db67561bc126ad6c344d6eeb2713a9e2892c649af0f015c6b7617f160c8a3b3a88add669d7155025073c5ac5b4f +Y = 43bf2ed0088af08645c80aa0a24a567a94ba2d794e9689d3ad4b185bc5d2dd008333e2dd2ebb5069a9b32251a3cac71e +Digest = 1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e +R = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52975 +S = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970 +Invalid = + +# r = n-1, x = n-1 is the largest x without a reduction. +Curve = P-384 +X = b5b375264c09acf145ca91d12ab10a096092a41ec43f4d718e129ea1c12b2dea62c7785efc52f46f009fb1dba133e811 +Y = bc0b2af172b4b3068d032a798080e76f4d56f72069519e3c19a43682a41794e52cb3ca139348d6bbc923e6a4f7945cb1 +Digest = 1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e +R = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52972 +S = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970 + +# r = n-2, x = n-1 is incorrect. +Curve = P-384 +X = b5b375264c09acf145ca91d12ab10a096092a41ec43f4d718e129ea1c12b2dea62c7785efc52f46f009fb1dba133e811 +Y = bc0b2af172b4b3068d032a798080e76f4d56f72069519e3c19a43682a41794e52cb3ca139348d6bbc923e6a4f7945cb1 +Digest = 1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e +R = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52971 +S = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970 +Invalid = + +# r = 2, x = n+2 is the smallest x with a reduction. +Curve = P-384 +X = 01b54a697305092bac2939fb906d7471b411c4eba8654169166a5da3810e1fc96795df921f7abbf519be4a027435176c +Y = a19012a3518773d508106d4153adee43c3c384fa62ce36a4addea08f593ec9c76b09a6b9c69d29bd7d47eb48e167dd2f +Digest = 1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e +R = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002 +S = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970 + +# r = 3, x = n+2 is incorrect. +Curve = P-384 +X = 01b54a697305092bac2939fb906d7471b411c4eba8654169166a5da3810e1fc96795df921f7abbf519be4a027435176c +Y = a19012a3518773d508106d4153adee43c3c384fa62ce36a4addea08f593ec9c76b09a6b9c69d29bd7d47eb48e167dd2f +Digest = 1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e +R = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003 +S = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970 +Invalid = + +# r = p-1-n, x = p-1 is the largest valid x. +Curve = P-384 +X = c4fd8e68006b83f7b7b20b731ae405813aa05f6e57374589b36ae1cecd1d49cae1418c22f398188bcf4ef02e89fe7394 +Y = dd1164b3707f59e05129fa228b8448031db159985f035d93470dc42b3ab4129f0760c46cf201d42e73a7e33ba7402ea6 +Digest = 1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e +R = 000000000000000000000000000000000000000000000000389cb27e0bc8d21fa7e5f24cb74f58851313e696333ad68b +S = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970 + +# r = p-n+2, x = 2 is incorrect. r is too large to compare r+n with x. +Curve = P-384 +X = c4fd8e68006b83f7b7b20b731ae405813aa05f6e57374589b36ae1cecd1d49cae1418c22f398188bcf4ef02e89fe7394 +Y = dd1164b3707f59e05129fa228b8448031db159985f035d93470dc42b3ab4129f0760c46cf201d42e73a7e33ba7402ea6 +Digest = 1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e +R = 000000000000000000000000000000000000000000000000389cb27e0bc8d21fa7e5f24cb74f58851313e696333ad68e +S = ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970 +Invalid = + +# r = 1, x = 1 is valid. +Curve = P-521 +X = 00f07e0b593332d09ec4fd0bae93f648a3da04dd224faae3f64cc490ec8fce3a6fe53d1b2c9e326be076cafb921b7e3f8b2288db491819522d65472870668c3808c9 +Y = 018e42509aca542a8de421589c38ba653e8cfd69322336217042a9dc0f67f6d7ae2cd4e385f480ffaf8981f715c7ca3765d9867dfd5a02947b0895f82eaf8b257e88 +Digest = 8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9 +R = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 +S = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406 + +# r = 1 + n, x = 1 is invalid. r must already be reduced. +Curve = P-521 +X = 00f07e0b593332d09ec4fd0bae93f648a3da04dd224faae3f64cc490ec8fce3a6fe53d1b2c9e326be076cafb921b7e3f8b2288db491819522d65472870668c3808c9 +Y = 018e42509aca542a8de421589c38ba653e8cfd69322336217042a9dc0f67f6d7ae2cd4e385f480ffaf8981f715c7ca3765d9867dfd5a02947b0895f82eaf8b257e88 +Digest = 8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9 +R = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640a +S = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406 +Invalid = + +# r = n-2, x = n-2 is the largest x without a reduction. +Curve = P-521 +X = 002a61afb982e49f030dd4e6ba0e495703abe0442b1283ee693fffc1b558f49f0a4cb4f138ea0604e667958495b86c61f358dce7e7f170da47372be3e4168408a260 +Y = 01baa19e8929fc8e7208e854e706a3d7f21479d1f6922a65ae3490fd5f52ae6580513b1fdd5bee927d002a9608abbb925b6727bdc110a3145fc8622d1fa8154c82d8 +Digest = 8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9 +R = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386407 +S = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406 + +# r = n-3, x = n-2 is incorrect. +Curve = P-521 +X = 002a61afb982e49f030dd4e6ba0e495703abe0442b1283ee693fffc1b558f49f0a4cb4f138ea0604e667958495b86c61f358dce7e7f170da47372be3e4168408a260 +Y = 01baa19e8929fc8e7208e854e706a3d7f21479d1f6922a65ae3490fd5f52ae6580513b1fdd5bee927d002a9608abbb925b6727bdc110a3145fc8622d1fa8154c82d8 +Digest = 8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9 +R = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406 +S = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406 +Invalid = + +# r = 1, x = n+1 is the smallest x with a reduction. +Curve = P-521 +X = 0049bbb2d3267a6eab2c59fac5b138b9e9c383db6637fcfe5d9f430e4c4c2ba0332340975448bd86c92a55c1a8288adf7f774096022419aa8c497499dafee7b93257 +Y = 00bb52fd444ec497ce228135f2498d40fb84eb6f674df1245d3aaac3c75b55ff5fff8e90b6f0189a3132cb9fd8d6e74fda5866fe2b9fc7484c628fde97e0b00f2b67 +Digest = 8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9 +R = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 +S = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406 + +# r = 2, x = n+1 is incorrect. +Curve = P-521 +X = 0049bbb2d3267a6eab2c59fac5b138b9e9c383db6637fcfe5d9f430e4c4c2ba0332340975448bd86c92a55c1a8288adf7f774096022419aa8c497499dafee7b93257 +Y = 00bb52fd444ec497ce228135f2498d40fb84eb6f674df1245d3aaac3c75b55ff5fff8e90b6f0189a3132cb9fd8d6e74fda5866fe2b9fc7484c628fde97e0b00f2b67 +Digest = 8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9 +R = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002 +S = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406 +Invalid = + +# r = p-1-n, x = p-1 is the largest valid x. +Curve = P-521 +X = 00f651d53d45bf6fd55a5f184e580d11259bc65200387dbc1bf7fb867d2d12a207d2962204ccf38e9d37d23ed95bd01ec576c457127766ecb8ad00342a476ea82078 +Y = 0196caedf64fbaa9a12c16836e0564e36f733957375706edb5f32911991a994c2d6a1ea5db2ee764835a9d6aff379e195f722b48e8d2b60fc50de2a5160c77c3f06c +Digest = 8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9 +R = 00000000000000000000000000000000000000000000000000000000000000000005ae79787c40d069948033feb708f65a2fc44a36477663b851449048e16ec79bf5 +S = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406 + +# r = p-n+1, x = 1 is incorrect. r is too large to compare r+n with x. +Curve = P-521 +X = 00f651d53d45bf6fd55a5f184e580d11259bc65200387dbc1bf7fb867d2d12a207d2962204ccf38e9d37d23ed95bd01ec576c457127766ecb8ad00342a476ea82078 +Y = 0196caedf64fbaa9a12c16836e0564e36f733957375706edb5f32911991a994c2d6a1ea5db2ee764835a9d6aff379e195f722b48e8d2b60fc50de2a5160c77c3f06c +Digest = 8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9 +R = 00000000000000000000000000000000000000000000000000000000000000000005ae79787c40d069948033feb708f65a2fc44a36477663b851449048e16ec79bf7 +S = 01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386406 +Invalid = + +# Although we do not support secp160r1, all our built-in curves have p > n, +# while n > p is reachable from custom curve logic. Moreover, p and n have +# different word widths on 32-bit machines. We include some test vectors to +# cover these cases. +# +# When n > p, the reduction mod n never occurs, but an optimized implementation, +# working mod p, may incorrectly accept, e.g., r = p+4 instead of r = 4. + +# r = 4, x = 4 is valid. +Curve = secp160r1 +X = 39891bd61138e775cd012518ff00f59ae01c4733 +Y = 25026b77b1c44affb1592dcf711b4290e9404c9f +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = 000000000000000000000000000000000000000004 +S = 0100000000000000000001f4c8f927aed3ca752254 + +# r = 4 + n, x = 4 is invalid. r must already be reduced. +Curve = secp160r1 +X = 39891bd61138e775cd012518ff00f59ae01c4733 +Y = 25026b77b1c44affb1592dcf711b4290e9404c9f +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = 0100000000000000000001f4c8f927aed3ca75225b +S = 0100000000000000000001f4c8f927aed3ca752254 +Invalid = + +# r = p-3, x = p-3 are the largest valid values of x and r. +Curve = secp160r1 +X = d88d902a0d8d942333c7b846a933d4794fcb5807 +Y = d24c4f405689b86cd5c61fe104e6365d254d5222 +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = 00ffffffffffffffffffffffffffffffff7ffffffc +S = 0100000000000000000001f4c8f927aed3ca752254 + +# r = p-4, x = p-3 is incorrect. +Curve = secp160r1 +X = d88d902a0d8d942333c7b846a933d4794fcb5807 +Y = d24c4f405689b86cd5c61fe104e6365d254d5222 +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = 00ffffffffffffffffffffffffffffffff7ffffffb +S = 0100000000000000000001f4c8f927aed3ca752254 +Invalid = + +# r = p+4, x = 4 is incorrect. They should be compared modulo the order, not p, +# so r >= p is never valid. +Curve = secp160r1 +X = d8add22064027856c162243ab09ea96642975297 +Y = 8822a506712385ab3ebe5c61737c3bbb722b06b9 +Digest = 09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b +R = 00ffffffffffffffffffffffffffffffff80000003 +S = 0100000000000000000001f4c8f927aed3ca752254 +Invalid =