external/boringssl: Sync to ea52ec98a56a40879b37493f3d1da1a1679e1fba.

This includes the following changes:

https://boringssl.googlesource.com/boringssl/+log/21baf6421a7e1e03f85cf2243c3c2404f5765072..ea52ec98a56a40879b37493f3d1da1a1679e1fba

Test: BoringSSL CTS Presubmits.
Change-Id: I6ebeb5f2aa7daa462c9d8933d9d5388011054fac
diff --git a/BORINGSSL_REVISION b/BORINGSSL_REVISION
index 994505d..49d8788 100644
--- a/BORINGSSL_REVISION
+++ b/BORINGSSL_REVISION
@@ -1 +1 @@
-21baf6421a7e1e03f85cf2243c3c2404f5765072
+ea52ec98a56a40879b37493f3d1da1a1679e1fba
diff --git a/crypto_test_data.cc b/crypto_test_data.cc
index 75c355c..e1ca010 100644
--- a/crypto_test_data.cc
+++ b/crypto_test_data.cc
@@ -2432,20 +2432,20 @@
     "f9d0e58056e653104925b9fe6c9\n\n# The same key, but with the redundant parameters in the ECPrivateKey mismatched.\nPrivateKey = P-256-BadInnerParameters\nInput = 308190020100301306072a8648ce3d020106082a8648ce3d0301070476307402010104208a872fb62893c4d1ffc5b9f0f91758069f8352e08fa05a49f8db926cb5728725a00706052b81040022a144034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nError = GROUP_MISMATCH\n\n# The public half of the same key encoded as a PublicKey.\nPublicKey = P-256-SPKI\nType = EC\nInput = 3059301306072a8648ce3d020106082a8648ce3d030107034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\n\n# The same as above, but with the curve explicitly spelled out.\nPublicKey = P-256-SPKI\nInput = 3082014b3082010306072a8648ce3d02013081f7020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff305b0420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b031500c49d360886e704936a6678e1139d26b7819f7e900441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020101034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nError = DECODE_ERROR\n\n# The same as above, but with trailing data after the curve name.\nPublicKey = P-256-SPKI\nInput = 305b301506072a8648ce3d020106082a8648ce3d0301070500034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9\nError = DECODE_ERROR\n\n# A DSA private key.\nPrivateKey = DSA-1024\nType = DSA\nInput = 308202650201003082023906072a8648ce3804013082022c02820101009e12fab3de12213501dd82aa10ca2d101d2d4ebfef4d2a3f8daa0fe0cedad8d6af85616aa2f3252c0a2b5a6db09e6f14900e0ddb8311876dd8f9669525f99ed65949e184d5064793271169a228680b95ec12f59a8e20b21f2b58eb2a2012d35bde2ee351822fe8f32d0a330565dcce5c672b7259c14b2433d0b5b2ca2b2db0ab626e8f13f47fe0345d904e7294bb038e9ce21a9e580b83356278706cfe768436c69de149ccff98b4aab8cb4f6385c9f102ce59346eaeef27e0ad222d53d6e89cc8cde5776dd00057b03f2d88ab3cedbafd7b585f0b7f7835e17a3728bbf25ea62572f245dc111f3ce39cb6ffacc31b0a2790e7bde90224ea9b09315362af3d2b022100f381dcf53ebf724f8b2e5ca82c010fb4b5eda9358d0fd88ed278589488b54fc3028201000c402a725dcc3a62e02bf4cf43cd17f4a493591220223669cf4193edab423ad08dfb552e308a6a57a5ffbc7cd0fb2087f81f8df0cb08ab2133287d2b6968714a94f633c940845a48a3e16708dde761cc6a8eab2d84db21b6ea5b07681493cc9c31fbc368b243f6ddf8c932a8b4038f44e7b15ca876344a147859f2b43b39458668ad5e0a1a9a669546dd2812e3b3617a0aef99d58e3bb4cc87fd94225e01d2dcc469a77268146c51918f18e8b4d70aa1f0c7623bcc52cf3731d38641b2d2830b7eecb2f09552ff137d046e494e7f33c3590002b16d1b97d936fda28f90c3ed3ca35338168ac16f77c3c57adc2e8f7c6c2256e41a5f65450590dbb5bcf06d66610423022100b0c768702743bc51242993a971a52889795444f7c6452203d0ce84fe6117d46e\n\n# A DSA public key.\nPublicKey = DSA-1024-SPKI\nType = DSA\nInput = 308201b73082012c06072a8648ce3804013082011f02818100b3429b8b128c9079f9b72e86857e98d265e5d91661ed8b5f4cc56e5eed1e571da30186983a9dd76297eab73ee13a1db841f8800d04a7cab478af6cde2ea4a2868531af169a24858c6268efa39ceb7ed0d4227eb5bbb01124a2a5a26038c7bcfb8cc827f68f5202345166e4718596799b65c9def82828ce44e62e38e41a0d24b1021500c5a56c81ddd87f47e676546c56d05706421624cf0281810094de40d27314fe929e47ff9b1ac65cfc73ef38c4d381c890be6217b15039ae18190e6b421af8c0bda35a5cfd050f58ae2644adce83e68c8e5ba11729df56bbb21e227a60b816cc033fa799a38fe1ba5b4aa1801b6f841ce3df99feb3b4fb96950c960af13fa2ce920aabc12dd24ad2044a35063ea0e25f67f560f4cfbdc5598303818400028180258c30ebbb7f34fdc873ce679f6cea373c7886d75d4421b90920db034daedd292c64d8edd8cdbdd7f3ad23d74cfa2135247d0cef6ecf2e14f99e19d22a8c1266bd8fb8719c0e5667c716c45c7adbdabe548085bdad2dfee636f8d52fd6adb2193df6c4f0520fbd171b91882e0e4f321f8250ffecf4dbea00e114427d3ef96c1a\n\n# The same key as above, but without the parameters.\nPublicKey = DSA-1024-SPKI-No-Params\nType = DSA\nInput = 308192300906072a8648ce38040103818400028180258c30ebbb7f34fdc873ce679f6cea373c7886d75d4421b90920db034daedd292c64d8edd8cdbdd7f3ad23d74cfa2135247d0cef6ecf2e14f99e19d22a8c1266bd8fb8719c0e5667c716c45c7adbdabe548085bdad2dfee636f8d52fd6adb2193df6c4f0520fbd171b91882e0e4f321f8250ffecf4dbea00e114427d3ef96c1a\n\n# Private keys from RFC 8032.\nPrivateKey = Ed25519\nType = Ed25519\nInput = 302e020100300506032b6570042204209d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60\n\nPrivateKey = Ed25519-2\nType = Ed25519\nInput = 302e020100300506032b6570042204204ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb\n\nPrivateKey = Ed25519-3\nType = Ed25519\nInput = 302e020100300506032b657004220420c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7\n\nPrivateKey = Ed25519-4\nType = Ed25519\nInput = 302e020100300506032b657004220420f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5\n\nPrivateKey = Ed25519-5\nType = Ed25519\nInput = 302e020100300506032b657004220420833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42\n\n# Public keys from RFC 8032.\nPublicKey = Ed25519-SPKI\nType = Ed25519\nInput = 302a300506032b6570032100d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a\n\nPublicKey = Ed25519-SPKI-2\nType = Ed25519\nInput = 302a300506032b65700321003d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c\n\nPublicKey = Ed25519-SPKI-3\nType = Ed25519\nInput = 302a300506032b6570032100fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025\n\nPublicKey = Ed25519-SPKI-4\nType = Ed25519\nInput = 302a300506032b6570032100278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e\n\nPublicKey = Ed25519-SPKI-5\nType = Ed25519\nInput = 302a300506032b6570032100ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf\n\n# The first key, private and public, with invalid NULL parameters.\nPrivateKey = Ed25519-NULL\nInput = 3030020100300706032b65700500042204209d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60\nError = DECODE_ERROR\n\nPublicKey = Ed25519-SPKI-NULL\nInput = 302c300706032b65700500032100d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a\nError = DECODE_ERROR\n\n# Sample public key from draft-ietf-curdle-pkix-04.\nPublicKey = Ed25519-SPKI-Spec\nType = Ed25519\nInput = 302a300506032b657003210019bf44096984cdfe8541bac167dc3b96c85086aa30b6b6cb0c5c38ad703166e1\n\n# Sample private key from draft-ietf-curdle-pkix-04.\nPrivateKey = Ed25519-Spec\nType = Ed25519\nInput = 302e020100300506032b657004220420d4ee72dbf913584ad5b6d8f1f769f8ad3afe7c28cbf1d4fbe097a88f44755842\n\n\n# RSA tests\n\nSign = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\n\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\n\nVerify = RSA-2048-SPKI\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d",
     "4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\n\n# Digest too long\nSign = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF12345\"\nError = INVALID_MESSAGE_LENGTH\n\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF12345\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\nError = INVALID_MESSAGE_LENGTH\n\n# Digest too short\nSign = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF123\"\nError = INVALID_MESSAGE_LENGTH\n\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF123\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\nError = INVALID_MESSAGE_LENGTH\n\n# Digest too large for key.\nSign = RSA-512\nDigest = SHA512\nInput = \"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"\nError = DIGEST_TOO_BIG_FOR_RSA_KEY\n\n# Mismatched digest\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1233\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad\nError = BAD_SIGNATURE\n\n# Corrupted signature\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1233\"\nOutput = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ae\nError = BLOCK_TYPE_IS_NOT_01\n\n# parameter missing (NOTE: this differs from upstream)\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3ec3fc29eb6e122bd7aa361cd09fe1bcbe85311096a7b9e4799cedfb2351ce0ab7fe4e75b4f6b37f67edd9c60c800f9ab941c0c157d7d880ca9de40c951d60fd293ae220d4bc510b1572d6e85a1bbbd8605b52e05f1c64fafdae59a1c2fbed214b7844d0134619de62851d5a0522e32e556e5950f3f97b8150e3f0dffee612c924201c27cd9bc8b423a71533380c276d3d59fcba35a2e80a1a192ec266a6c2255012cd86a349fe90a542b355fa3355b04da6cdf1df77f0e7bd44a90e880e1760266d233e465226f5db1c68857847d82072861ee266ddfc2e596845b77e1803274a579835ab5e4975d81d20b7df9cec7795489e4a2bdb8c1cf6a6b359945ac92c\nError = BAD_SIGNATURE\n\n# embedded digest too long\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = afec9a0d5330a08f54283bb4a9d4e7e7e70fc1342336c4c766fba713f66970151c6e27413c48c33864ea45a0238787004f338ed3e21b53b0fe9c1151c42c388cbc7cba5a06b706c407a5b48324fbe994dc7afc3a19fb3d2841e66222596c14cd72a0f0a7455a019d8eb554f59c0183f9552b75aa96fee8bf935945e079ca283d2bd3534a86f11351f6d6181fbf433e5b01a6d1422145c7a72214d3aacdd5d3af12b2d6bf6438f9f9a64010d8aeed801c87f0859412b236150b86a545f7239be022f4a7ad246b59df87514294cb4a4c7c5a997ee53c66054d9f38ca4e76c1f7af83c30f737ef70f83a45aebe18238ddb95e1998814ca4fc72388f1533147c169d\nError = BAD_SIGNATURE\n\n# embedded digest too short\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = afec9a0d5330a08f54283bb4a9d4e7e7e70fc1342336c4c766fba713f66970151c6e27413c48c33864ea45a0238787004f338ed3e21b53b0fe9c1151c42c388cbc7cba5a06b706c407a5b48324fbe994dc7afc3a19fb3d2841e66222596c14cd72a0f0a7455a019d8eb554f59c0183f9552b75aa96fee8bf935945e079ca283d2bd3534a86f11351f6d6181fbf433e5b01a6d1422145c7a72214d3aacdd5d3af12b2d6bf6438f9f9a64010d8aeed801c87f0859412b236150b86a545f7239be022f4a7ad246b59df87514294cb4a4c7c5a997ee53c66054d9f38ca4e76c1f7af83c30f737ef70f83a45aebe18238ddb95e1998814ca4fc72388f1533147c169d\nError = BAD_SIGNATURE\n\n# Garbage after DigestInfo\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 9ee34872d4271a7d8808af0a4052a145a6d6a8437d00da3ed14428c7f087cd39f4d43334c41af63e7fa1ba363fee7bcef401d9d36a662abbab55ce89a696e1be0dfa19a5d09ca617dd488787b6048baaefeb29bc8688b2fe3882de2b77c905b5a8b56cf9616041e5ec934ba6de863efe93acc4eef783fe7f72a00fa65d6093ed32bf98ce527e62ccb1d56317f4be18b7e0f55d7c36617d2d0678a306e3350956b662ac15df45215dd8f6b314babb9788e6c272fa461e4c9b512a11a4b92bc77c3a4c95c903fccb238794eca5c750477bf56ea6ee6a167367d881b485ae3889e7c489af8fdf38e0c0f2aed780831182e34abedd43c39281b290774bf35cc25274\nError = BAD_SIGNATURE\n\n# invalid tag for parameter\nVerify = RSA-2048\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 49525db4d44c755e560cba980b1d85ea604b0e077fcadd4ba44072a3487bbddb835016200a7d8739cce2dc3223d9c20cbdd25059ab02277f1f21318efd18e21038ec89aa9d40680987129e8b41ba33bceb86518bdf47268b921cce2037acabca6575d832499538d6f40cdba0d40bd7f4d8ea6ca6e2eec87f294efc971407857f5d7db09f6a7b31e301f571c6d82a5e3d08d2bb3a36e673d28b910f5bec57f0fcc4d968fd7c94d0b9226dec17f5192ad8b42bcab6f26e1bea1fdc3b958199acb00f14ebcb2a352f3afcedd4c09000128a603bbeb9696dea13040445253972d46237a25c7845e3b464e6984c2348ea1f1210a9ff0b00d2d72b50db00c009bb39f9\nError = BAD_SIGNATURE\n\n\n# RSA-PSS tests.\n\n# Zero salt length makes the output deterministic\nSign = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\n\n# Verify of above signature\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\n\n# A non-zero salt length must be checked by round-tripping.\nSign = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 32\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nCheckVerify\n\n# Auto-detected salt length\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = -2\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7",
     "d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\n\n# Signing with salt length -1 means to match the digest length.\nSign = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = -1\nVerifyPSSSaltLength = 32\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nCheckVerify\n\n# Signing with salt length -2 means to maximize the salt length.\nSign = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = -2\nVerifyPSSSaltLength = 222  # 256 - 32 - 2\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nCheckVerify\n\n# Wrong digest\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"00000000000000000000000000000000\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = BAD_SIGNATURE\n\n# Digest too short\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDE\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = INVALID_MESSAGE_LENGTH\n\n# Digest too long\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF0\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = INVALID_MESSAGE_LENGTH\n\n# Wrong salt length\nVerify = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 2\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = SLEN_CHECK_FAILED\n\n# Wrong salt length using implicit hash length\nVerify = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = -1\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = SLEN_CHECK_FAILED\n\n# Wrong MGF1 digest, SHA-1\nVerify = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nMGF1Digest = SHA1\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\n# If SHA-1, this input happens to succeed recovering a salt length, but it does\n# not match.\nError = SLEN_CHECK_FAILED\n\n# Wrong MGF1 digest, SHA-384\nVerify = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nMGF1Digest = SHA384\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\n# If SHA-384, this input happens fail to recover the salt length altogether.\nError = SLEN_RECOVERY_FAILED\n\n# The salt length is too large for the modulus (signing).\nSign = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 223\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nError = DATA_TOO_LARGE\n\n# The salt length is too large for the modulus (verifying).\nVerify = RSA-2048\nRSAPadding = PSS\nPSSSaltLength = 223\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4de433d5844043ef08d354da03cb29068780d52706d7d1e4d50efb7d58c9d547d83a747ddd0635a96b28f854e50145518482cb49e963054621b53c60c498d07c16e9c2789c893cf38d4d86900de71bde463bd2761d1271e358c7480a1ac0bab930ddf39602ad1bc165b5d7436b516b7a7858e8eb7ab1c420eeb482f4d207f0e462b1724959320a084e13848d11d10fb593e66bf680bf6d3f345fc3e9c3de60abbac37e1c6ec80a268c8d9fc49626c679097aa690bc1aa662b95eb8db70390861aa0898229f9349b4b5fdd030d4928c47084708a933144be23bd3c6e661b85b2c0ef9ed36d498d5b7320e8194d363d4ad478c059bae804181965e0b81b663158a\nError = DATA_TOO_LARGE\n\n# The hash is too large for the modulus (signing).\nSign = RSA-512\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA512\nInput = \"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"\nError = DATA_TOO_LARGE\n\nSign = RSA-512\nRSAPadding = PSS\nPSSSaltLength = -2\nDigest = SHA512\nInput = \"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"\nError = DATA_TOO_LARGE\n\n# The hash is too large for the modulus (verifying).\nVerify = RSA-512\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA512\nInput = \"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"\nOutput = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\nError = DATA_TOO_LARGE\n\nVerify = RSA-512\nRSAPadding = PSS\nPSSSaltLength = -2\nDigest = SHA512\nInput = \"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\"\nOutput = 457001d9ca50a93385fc5ec721c9dbbe7a0f2e9e4a2f846a30a8811dde66347b83901c7492039243537c7a667fafffd69049bcbd36afd0010d9b425e2d8785c1\nError = DATA_TOO_LARGE\n\n# Sample RSA-515 signature.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 00c5926600f160f85e7fe950cfe123908384211cd8fe25c90cb8e8cc0593308e9aa2efe3acbf100ec1658ded8f72f506525fc2c44f06251b08d896e7bb3f05b135\n\n# T",
-    "he above, but with too few leading zeros.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = c5926600f160f85e7fe950cfe123908384211cd8fe25c90cb8e8cc0593308e9aa2efe3acbf100ec1658ded8f72f506525fc2c44f06251b08d896e7bb3f05b135\nError = DATA_LEN_NOT_EQUAL_TO_MOD_LEN\n\n# The above, but with too many leading zeros.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 0000c5926600f160f85e7fe950cfe123908384211cd8fe25c90cb8e8cc0593308e9aa2efe3acbf100ec1658ded8f72f506525fc2c44f06251b08d896e7bb3f05b135\nError = DATA_LEN_NOT_EQUAL_TO_MOD_LEN\n\n# The above with an invalid leading byte. The top few bits of EM are required to\n# be cleared.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 007f803c832a2090aea04013d9fa9c1630732a1625232826d235f0950f7050d3fb0eb06ef9ea8b260fad68e1165a2d770a8c7fc7a8aaa68620b021fc19c97e0041\nError = FIRST_OCTET_INVALID\n\n# The above with an invalid trailing byte.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 03e68555035891eb08d96c0967db22328cd892ad2856d88516ecb946bfdba732bb029b5c0dfa2119ed7349897d2324e95e86d91d0c4afc82700a36db8933abbf58\nError = LAST_OCTET_INVALID\n\n# Non-zero salt length.\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 32\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4065b284b0a6e98d4c41a8427007f878d8dd61599c87764fa79b8bf03f030c48127a4b1a5af5a6e0cf9055e57a1f47e5b0c0d8c600e78369cf1c39374899fac91a812692aa2216ba10900ce85a5cf7fddcafb726e4b83479c5bb7b3b84b08ffe183b4c2973aa3193ec7b7d4ea73bf1b579c6657b78ad7800e1975a4838c28ffe353fafef96be27b5c69677760a71b6f4df65ba6fe6b3565580a536f966928294c6e9ece807a90c1477779bcbfa3a250e98d685097c162c1c8c56ab02bd2e16eec7a019b51c067bdba7fa8cd5460796e22c607a8b6d12e1deb9be51c6943c46590f416800c48bb4cbb8c409d316573e59eadf7d3b9e6e5c2d0e570692e511e139\n\n# Non-zero salt length, wrong salt length.\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 31\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4065b284b0a6e98d4c41a8427007f878d8dd61599c87764fa79b8bf03f030c48127a4b1a5af5a6e0cf9055e57a1f47e5b0c0d8c600e78369cf1c39374899fac91a812692aa2216ba10900ce85a5cf7fddcafb726e4b83479c5bb7b3b84b08ffe183b4c2973aa3193ec7b7d4ea73bf1b579c6657b78ad7800e1975a4838c28ffe353fafef96be27b5c69677760a71b6f4df65ba6fe6b3565580a536f966928294c6e9ece807a90c1477779bcbfa3a250e98d685097c162c1c8c56ab02bd2e16eec7a019b51c067bdba7fa8cd5460796e22c607a8b6d12e1deb9be51c6943c46590f416800c48bb4cbb8c409d316573e59eadf7d3b9e6e5c2d0e570692e511e139\nError = SLEN_CHECK_FAILED\n\n# Non-zero salt length, match hash length.\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = -1\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4065b284b0a6e98d4c41a8427007f878d8dd61599c87764fa79b8bf03f030c48127a4b1a5af5a6e0cf9055e57a1f47e5b0c0d8c600e78369cf1c39374899fac91a812692aa2216ba10900ce85a5cf7fddcafb726e4b83479c5bb7b3b84b08ffe183b4c2973aa3193ec7b7d4ea73bf1b579c6657b78ad7800e1975a4838c28ffe353fafef96be27b5c69677760a71b6f4df65ba6fe6b3565580a536f966928294c6e9ece807a90c1477779bcbfa3a250e98d685097c162c1c8c56ab02bd2e16eec7a019b51c067bdba7fa8cd5460796e22c607a8b6d12e1deb9be51c6943c46590f416800c48bb4cbb8c409d316573e59eadf7d3b9e6e5c2d0e570692e511e139\n\n# Non-zero salt length, auto-detected.\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = -2\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4065b284b0a6e98d4c41a8427007f878d8dd61599c87764fa79b8bf03f030c48127a4b1a5af5a6e0cf9055e57a1f47e5b0c0d8c600e78369cf1c39374899fac91a812692aa2216ba10900ce85a5cf7fddcafb726e4b83479c5bb7b3b84b08ffe183b4c2973aa3193ec7b7d4ea73bf1b579c6657b78ad7800e1975a4838c28ffe353fafef96be27b5c69677760a71b6f4df65ba6fe6b3565580a536f966928294c6e9ece807a90c1477779bcbfa3a250e98d685097c162c1c8c56ab02bd2e16eec7a019b51c067bdba7fa8cd5460796e22c607a8b6d12e1deb9be51c6943c46590f416800c48bb4cbb8c409d316573e59eadf7d3b9e6e5c2d0e570692e511e139\n\n\n# RSA decrypt\n\nDecrypt = RSA-2048\nInput = 550af55a2904e7b9762352f8fb7fa235a9cb053aacb2d5fcb8ca48453cb2ee3619746c701abf2d4cc67003471a187900b05aa812bd25ed05c675dfc8c97a24a7bf49bd6214992cad766d05a9a2b57b74f26a737e0237b8b76c45f1f226a836d7cfbc75ba999bdbe48dbc09227aa46c88f21dccba7840141ad5a5d71fd122e6bd6ac3e564780dfe623fc1ca9b995a6037bf0bbd43b205a84ac5444f34202c05ce9113087176432476576de6ffff9a52ea57c08be3ec2f49676cb8e12f762ac71fa3c321e00ac988910c85ff52f93825666ce0d40ffaa0592078919d4493f46d95ccf76364c6d57760dd0b64805f9afc76a2365a5575ca301d5103f0ea76cb9a78\nOutput = \"Hello World\"\n\n# Corrupted ciphertext\nDecrypt = RSA-2048\nInput = 550af55a2904e7b9762352f8fb7fa235a9cb053aacb2d5fcb8ca48453cb2ee3619746c701abf2d4cc67003471a187900b05aa812bd25ed05c675dfc8c97a24a7bf49bd6214992cad766d05a9a2b57b74f26a737e0237b8b76c45f1f226a836d7cfbc75ba999bdbe48dbc09227aa46c88f21dccba7840141ad5a5d71fd122e6bd6ac3e564780dfe623fc1ca9b995a6037bf0bbd43b205a84ac5444f34202c05ce9113087176432476576de6ffff9a52ea57c08be3ec2f49676cb8e12f762ac71fa3c321e00ac988910c85ff52f93825666ce0d40ffaa0592078919d4493f46d95ccf76364c6d57760dd0b64805f9afc76a2365a5575ca301d5103f0ea76cb9a79\nError = PKCS_DECODING_ERROR\n\n# OAEP padding\nDecrypt = RSA-2048\nRSAPadding = OAEP\nInput = 458708dfbd42a1297ce7a9c86c7087ab80b1754810929b89c5107ca55368587686986fce94d86cc1595b3fb736223a656ec0f34d18ba1cc5665593610f56c58e26b272d584f3d983a5c91085700755aebd921fb280bba3eda7046ec07b43e7298e52d59edc92be4639a8ce08b2f85976ecf6d98cc469eeb9d5d8e2a32ea8a6626edafe1038b3df455668a9f3c77cad8b92fb872e00058c3d2a7ede1a1f03fc5622084ae04d9d24f6bf0995c58d35b93b699b9763595e123f2ab0863cc9229eb290e2ede7715c7a8f39e0b9a3e2e1b56ebb62f1cbfbb5986fb212ebd785b83d01d968b11d1756c7337f70c1f1a63bff03608e24f3a2fd44e67f832a8701c5d5af\nOutput = \"Hello World\"\n\n# OAEP padding with label and custom hash.\nDecrypt = RSA-2048\nRSAPadding = OAEP\nOAEPDigest = SHA512\nOAEPLabel = 00112233445566778899aabbccddeeff\nInput = 48b956c22b8e40cc38f0893672ddf488fc806cf1fcc6239c66dd8345eb543d6b5cac589e6c7ae86dac1c2436c4d72c48009a737b2c649e6000dbab17203e4d9c078bd70b649700a0830d4ddc396af0c48973177a229e48259d93247f04f76474c7611b530c66f020c4da2cc861c2e4104831ecc0336e0cb10d6520fdefd0b33606f5cdd736dd439583b9b6011cce99623c93caf5f76e21e9fefab414795dd5ac12cba551be74ebf266834fcffab182c5e7c9b6c064df154cb26ddfd4fe2fd87590005f4bf45e776a0082803e9f68995b8eeb4c6802c67b5ef349e5b2dc0cf7a12fc097030f2bd28f0253f17129b04c82993a12957728b35880fdd2f8d0cc469f\nOutput = \"Hello World\"\n\n# OAEP padding, corrupted ciphertext\nDecrypt = RSA-2048\nRSAPadding = OAEP\nInput = 458708dfbd42a1297ce7a9c86c7087ab80b1754810929b89c5107ca55368587686986fce94d86cc1595b3fb736223a656ec0f34d18ba1cc5665593610f56c58e26b272d584f3d983a5c91085700755aebd921fb280bba3eda7046ec07b43e7298e52d59edc92be4639a8ce08b2f85976ecf6d98cc469eeb9d5d8e2a32ea8a6626edafe1038b3df455668a9f3c77cad8b92fb872e00058c3d2a7ede1a1f03fc5622084ae04d9d24f6bf0995c58d35b93b699b9763595e123f2ab0863cc9229eb290e2ede7715c7a8f39e0b9a3e2e1b56ebb62f1cbfbb5986fb212ebd785b83d01d968b11d1756c7337f70c1f1a63bff03608e24f3a2fd44e67f832a8701c5d5ac\nError = OAEP_DECODING_ERROR\n\n# Test that RSA encryption successfully round-trips through decryption\n# with various parameters.\nEncrypt = RSA-2048\nInput = \"Hello World\"\nCheckDecrypt\n\nEncrypt = RSA-2048\nRSAPadding = OAEP\nInput = \"Hello World\"\nCheckDecrypt\n\nEncrypt = RSA-2048\nRSAPadding = OAEP\nOAEPDigest = SHA512\nOAEPLabel = 00112233445566778899aabbccddeeff\nInput = \"Hello World\"\nCheckDecrypt\n\n\n# EC tests\n\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\n\nVerify = P-256-SPKI\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\n\n# Digest too long\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF12345\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83",
-    "a21bc945006746e3b7cea52234e043ec8\nError = BAD_SIGNATURE\n\n# Digest too short\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF123\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\nError = BAD_SIGNATURE\n\n# Digest invalid\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1235\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\nError = BAD_SIGNATURE\n\n# Invalid signature\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec7\nError = BAD_SIGNATURE\n\n# Garbage after signature\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec800\nError = BAD_SIGNATURE\n\n# BER signature\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3080022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec80000\nError = BAD_SIGNATURE\n\n\n# Additional RSA-PSS and RSA-OAEP tests converted from\n# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip\n\nPublicKey = RSA-PSS-1\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d0030818902818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a21370203010001\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = cd8b6538cb8e8de566b68bd067569dbf1ee2718e\nOutput = 9074308fb598e9701b2294388e52f971faac2b60a5145af185df5287b5ed2887e57ce7fd44dc8634e407c8e0e4360bc226f3ec227f9d9e54638e8d31f5051215df6ebb9c2f9579aa77598a38f914b5b9c1bd83c4e2f9f382a0d0aa3542ffee65984a601bc69eb28deb27dca12c82c2d4c3f66cd500f1ff2b994d8a4e30cbb33c\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = e35befc17a1d160b9ce35fbd8eb16e7ee491d3fd\nOutput = 3ef7f46e831bf92b32274142a585ffcefbdca7b32ae90d10fb0f0c729984f04ef29a9df0780775ce43739b97838390db0a5505e63de927028d9d29b219ca2c4517832558a55d694a6d25b9dab66003c4cccd907802193be5170d26147d37b93590241be51c25055f47ef62752cfbe21418fafe98c22c4d4d47724fdb5669e843\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 0652ec67bcee30f9d2699122b91c19abdba89f91\nOutput = 666026fba71bd3e7cf13157cc2c51a8e4aa684af9778f91849f34335d141c00154c4197621f9624a675b5abc22ee7d5baaffaae1c9baca2cc373b3f33e78e6143c395a91aa7faca664eb733afd14d8827259d99a7550faca501ef2b04e33c23aa51f4b9e8282efdb728cc0ab09405a91607c6369961bc8270d2d4f39fce612b1\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 39c21c4cceda9c1adf839c744e1212a6437575ec\nOutput = 4609793b23e9d09362dc21bb47da0b4f3a7622649a47d464019b9aeafe53359c178c91cd58ba6bcb78be0346a7bc637f4b873d4bab38ee661f199634c547a1ad8442e03da015b136e543f7ab07c0c13e4225b8de8cce25d4f6eb8400f81f7e1833b7ee6e334d370964ca79fdb872b4d75223b5eeb08101591fb532d155a6de87\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 36dae913b77bd17cae6e7b09453d24544cebb33c\nOutput = 1d2aad221ca4d31ddf13509239019398e3d14b32dc34dc5af4aeaea3c095af73479cf0a45e5629635a53a018377615b16cb9b13b3e09d671eb71e387b8545c5960da5a64776e768e82b2c93583bf104c3fdb23512b7b4e89f633dd0063a530db4524b01c3f384c09310e315a79dcd3d684022a7f31c865a664e316978b759fad\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 45eef191f4f79c31fe5d2ede7e5098994e929d2d\nOutput = 2a34f6125e1f6b0bf971e84fbd41c632be8f2c2ace7de8b6926e31ff93e9af987fbc06e51e9be14f5198f91f3f953bd67da60a9df59764c3dc0fe08e1cbef0b75f868d10ad3fba749fef59fb6dac46a0d6e504369331586f58e4628f39aa278982543bc0eeb537dc61958019b394fb273f215858a0a01ac4d650b955c67f4c58\n\nPublicKey = RSA-PSS-2\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d0030818902818101d40c1bcf97a68ae7cdbd8a7bf3e34fa19dcca4ef75a47454375f94514d88fed006fb829f8419ff87d6315da68a1ff3a0938e9abb3464011c303ad99199cf0c7c7a8b477dce829e8844f625b115e5e9c4a59cf8f8113b6834336a2fd2689b472cbb5e5cabe674350c59b6c17e176874fb42f8fc3d176a017edc61fd326c4b33c90203010001\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 5c81a3e2a658246628cd0ee8b00bb4c012bc9739\nOutput = 014c5ba5338328ccc6e7a90bf1c0ab3fd606ff4796d3c12e4b639ed9136a5fec6c16d8884bdd99cfdc521456b0742b736868cf90de099adb8d5ffd1deff39ba4007ab746cefdb22d7df0e225f54627dc65466131721b90af445363a8358b9f607642f78fab0ab0f43b7168d64bae70d8827848d8ef1e421c5754ddf42c2589b5b3\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 27f71611446aa6eabf037f7dedeede3203244991\nOutput = 010991656cca182b7f29d2dbc007e7ae0fec158eb6759cb9c45c5ff87c7635dd46d150882f4de1e9ae65e7f7d9018f6836954a47c0a81a8a6b6f83f2944d6081b1aa7c759b254b2c34b691da67cc0226e20b2f18b42212761dcd4b908a62b371b5918c5742af4b537e296917674fb914194761621cc19a41f6fb953fbcbb649dea\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 03ecc2c33e93f05fc7224fcc0d461356cb897217\nOutput = 007f0030018f53cdc71f23d03659fde54d4241f758a750b42f185f87578520c30742afd84359b6e6e8d3ed959dc6fe486bedc8e2cf001f63a7abe16256a1b84df0d249fc05d3194ce5f0912742dbbf80dd174f6c51f6bad7f16cf3364eba095a06267dc3793803ac7526aebe0a475d38b8c2247ab51c4898df7047dc6adf52c6c4\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 246c727b4b9494849dddb068d582e179ac20999c\nOutput = 009cd2f4edbe23e12346ae8c76dd9ad3230a62076141f16c152ba18513a48ef6f010e0e37fd3df10a1ec629a0cb5a3b5d2893007298c30936a95903b6ba85555d9ec3673a06108fd62a2fda56d1ce2e85c4db6b24a81ca3b496c36d4fd06eb7c9166d8e94877c42bea622b3bfe9251fdc21d8d5371badad78a488214796335b40b\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = e8617ca3ea66ce6a58ede2d11af8c3ba8a6ba912\nOutput = 00ec430824931ebd3baa43034dae98ba646b8c36013d1671c3cf1cf8260c374b19f8e1cc8d965012405e7e9bf7378612dfcc85fce12cda11f950bd0ba8876740436c1d2595a64a1b32efcfb74a21c873b3cc33aaf4e3dc3953de67f0674c0453b4fd9f604406d441b816098cb106fe3472bc251f815f59db2e4378a3addc181ecf\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 7a6fdc1a4e434ecbc35d657ad49a2f4fafd43bc8\nOutput = 00475b1648f814a8dc0abdc37b5527f543b666bb6e39d30e5b49d3b876dccc58eac14e32a2d55c2616014456ad2f246fc8e3d560da3ddf379a1c0bd200f10221df078c219a151bc8d4ec9d2fc2564467811014ef15d8ea01c2ebbff8c2c8efab38096e55fcbe3285c7aa558851254faffa92c1c72b78758663ef4582843139d7a6\n\nPublicKey = RSA-PSS-3\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d0030818902818102f246ef451ed3eebb9a310200cc25859c048e4be798302991112eb68ce6db674e280da21feded1ae74880ca522b18db249385012827c515f0e466a1ffa691d98170574e9d0eadb087586ca48933da3cc953d95bd0ed50de10ddcb6736107d6c831c7f663e833ca4c097e700ce0fb945f88fb85fe8e5a773172565b914a471a4430203010001\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 3552be69dd74bdc56d2cf8c38ef7bafe269040fe\nOutput = 0088b135fb1794b6b96c4a3e678197f8cac52b64b2fe907d6f27de761124964a99a01a882740ecfaed6c01a47464bb05182313c01338a8cd097214cd68ca103bd57d3bc9e816213e61d784f182467abf8a01cf253e99a156eaa8e3e1f90e3c6e4e3aa2d83ed0345b89fafc9c26077c14b6ac51454fa26e446e3a2f153b2b16797f\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 609143ff7240e55c062aba8b9e4426a781919bc9\nOutput = 02a5f0a858a0864a4f65017a7d69454f3f973a2999839b7bbc48bf78641169179556f595fa41f6ff18e286c2783079bc0910ee9cc34f49ba681124f923dfa88f426141a368a5f5a930c628c2c3c200e18a7644721a0cbec6dd3f6279bde3e8f2be5e2d4ee56f97e7ceaf33054be7042bd91a63bb09f897bd41e81197dee99b11af\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 0afd22f879a9cda7c584f4135f8f1c961db114c0\nOutput = 0244bcd1c8c16955736c803be401272e18cb990811b14f72db964124d5fa760649cbb57afb8755dbb62bf51f466cf23a0a1607576e983d778fceffa92df7548aea8ea4ecad2c29dd9f95bc07fe91ecf8bee255bfe8762fd7690aa9bfa4fa0849ef728c2c42c4532364522df2ab7f9f8a03b63f7a499175828668f5ef5a29e3802c\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 405dd5",
-    "6d395ef0f01b555c48f748cc32b210650b\nOutput = 0196f12a005b98129c8df13c4cb16f8aa887d3c40d96df3a88e7532ef39cd992f273abc370bc1be6f097cfebbf0118fd9ef4b927155f3df22b904d90702d1f7ba7a52bed8b8942f412cd7bd676c9d18e170391dcd345c06a730964b3f30bcce0bb20ba106f9ab0eeb39cf8a6607f75c0347f0af79f16afa081d2c92d1ee6f836b8\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = a2c313b0440c8a0c47233b87f0a160c61af3eae7\nOutput = 021eca3ab4892264ec22411a752d92221076d4e01c0e6f0dde9afd26ba5acf6d739ef987545d16683e5674c9e70f1de649d7e61d48d0caeb4fb4d8b24fba84a6e3108fee7d0705973266ac524b4ad280f7ae17dc59d96d3351586b5a3bdb895d1e1f7820ac6135d8753480998382ba32b7349559608c38745290a85ef4e9f9bd83\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = f1bf6ca7b4bbdbb6bf20a4bf55728725d177154a\nOutput = 012fafec862f56e9e92f60ab0c77824f4299a0ca734ed26e0644d5d222c7f0bde03964f8e70a5cb65ed44e44d56ae0edf1ff86ca032cc5dd4404dbb76ab854586c44eed8336d08d457ce6c03693b45c0f1efef93624b95b8ec169c616d20e5538ebc0b6737a6f82b4bc0570924fc6b35759a3348426279f8b3d7744e2d222426ce\n\nPublicKey = RSA-PSS-4\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d00308189028181054adb7886447efe6f57e0368f06cf52b0a3370760d161cef126b91be7f89c421b62a6ec1da3c311d75ed50e0ab5fff3fd338acc3aa8a4e77ee26369acb81ba900fa83f5300cf9bb6c53ad1dc8a178b815db4235a9a9da0c06de4e615ea1277ce559e9c108de58c14a81aa77f5a6f8d1335494498848c8b95940740be7bf7c37050203010001\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = f8b0abf70fec0bca74f0accbc24f75e6e90d3bfd\nOutput = 0323d5b7bf20ba4539289ae452ae4297080feff4518423ff4811a817837e7d82f1836cdfab54514ff0887bddeebf40bf99b047abc3ecfa6a37a3ef00f4a0c4a88aae0904b745c846c4107e8797723e8ac810d9e3d95dfa30ff4966f4d75d13768d20857f2b1406f264cfe75e27d7652f4b5ed3575f28a702f8c4ed9cf9b2d44948\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 04a10944bfe11ab801e77889f3fd3d7f4ff0b629\nOutput = 049d0185845a264d28feb1e69edaec090609e8e46d93abb38371ce51f4aa65a599bdaaa81d24fba66a08a116cb644f3f1e653d95c89db8bbd5daac2709c8984000178410a7c6aa8667ddc38c741f710ec8665aa9052be929d4e3b16782c1662114c5414bb0353455c392fc28f3db59054b5f365c49e1d156f876ee10cb4fd70598\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = ba01243db223eb97fb86d746c3148adaaa0ca344\nOutput = 03fbc410a2ced59500fb99f9e2af2781ada74e13145624602782e2994813eefca0519ecd253b855fb626a90d771eae028b0c47a199cbd9f8e3269734af4163599090713a3fa910fa0960652721432b971036a7181a2bc0cab43b0b598bc6217461d7db305ff7e954c5b5bb231c39e791af6bcfa76b147b081321f72641482a2aad\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 934bb0d38d6836daec9de82a9648d4593da67cd2\nOutput = 0486644bc66bf75d28335a6179b10851f43f09bded9fac1af33252bb9953ba4298cd6466b27539a70adaa3f89b3db3c74ab635d122f4ee7ce557a61e59b82ffb786630e5f9db53c77d9a0c12fab5958d4c2ce7daa807cd89ba2cc7fcd02ff470ca67b229fcce814c852c73cc93bea35be68459ce478e9d4655d121c8472f371d4f\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = ec35d81abd1cceac425a935758b683465c8bd879\nOutput = 022a80045353904cb30cbb542d7d4990421a6eec16a8029a8422adfd22d6aff8c4cc0294af110a0c067ec86a7d364134459bb1ae8ff836d5a8a2579840996b320b19f13a13fad378d931a65625dae2739f0c53670b35d9d3cbac08e733e4ec2b83af4b9196d63e7c4ff1ddeae2a122791a125bfea8deb0de8ccf1f4ffaf6e6fb0a\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 72ce251d17b04dd3970d6ff1fbe3624899e9e941\nOutput = 00938dcb6d583046065f69c78da7a1f1757066a7fa75125a9d2929f0b79a60b627b082f11f5b196f28eb9daa6f21c05e5140f6aef1737d2023075c05ecf04a028c686a2ab3e7d5a0664f295ce12995e890908b6ad21f0839eb65b70393a7b5afd9871de0caa0cedec5b819626756209d13ab1e7bb9546a26ff37e9a51af9fd562e\n\nPublicKey = RSA-PSS-5\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d003081890281810d10f661f29940f5ed39aa260966deb47843679d2b6fb25b3de370f3ac7c19916391fd25fb527ebfa6a4b4df45a1759d996c4bb4ebd18828c44fc52d0191871740525f47a4b0cc8da325ed8aa676b0d0f626e0a77f07692170acac8082f42faa7dc7cd123e730e31a87985204cabcbe6670d43a2dd2b2ddef5e05392fc213bc5070203010001\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = d98b7061943510bc3dd9162f7169aabdbdcd0222\nOutput = 0ba373f76e0921b70a8fbfe622f0bf77b28a3db98e361051c3d7cb92ad0452915a4de9c01722f6823eeb6adf7e0ca8290f5de3e549890ac2a3c5950ab217ba58590894952de96f8df111b2575215da6c161590c745be612476ee578ed384ab33e3ece97481a252f5c79a98b5532ae00cdd62f2ecc0cd1baefe80d80b962193ec1d\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 7ae8e699f754988f4fd645e463302e49a2552072\nOutput = 08180de825e4b8b014a32da8ba761555921204f2f90d5f24b712908ff84f3e220ad17997c0dd6e706630ba3e84add4d5e7ab004e58074b549709565d43ad9e97b5a7a1a29e85b9f90f4aafcdf58321de8c5974ef9abf2d526f33c0f2f82e95d158ea6b81f1736db8d1af3d6ac6a83b32d18bae0ff1b2fe27de4c76ed8c7980a34e\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 8d46c7c05534c1ba2cc7624500d48a4531604bff\nOutput = 05e0fdbdf6f756ef733185ccfa8ced2eb6d029d9d56e35561b5db8e70257ee6fd019d2f0bbf669fe9b9821e78df6d41e31608d58280f318ee34f559941c8df13287574bac000b7e58dc4f414ba49fb127f9d0f8936638c76e85356c994f79750f7fa3cf4fd482df75e3fb9978cd061f7abb17572e6e63e0bde12cbdcf18c68b979\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = ee3de96783fd0a157c8b20bf5566124124dcfe65\nOutput = 0bc989853bc2ea86873271ce183a923ab65e8a53100e6df5d87a24c4194eb797813ee2a187c097dd872d591da60c568605dd7e742d5af4e33b11678ccb63903204a3d080b0902c89aba8868f009c0f1c0cb85810bbdd29121abb8471ff2d39e49fd92d56c655c8e037ad18fafbdc92c95863f7f61ea9efa28fea401369d19daea1\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 1204df0b03c2724e2709c23fc71789a21b00ae4c\nOutput = 0aefa943b698b9609edf898ad22744ac28dc239497cea369cbbd84f65c95c0ad776b594740164b59a739c6ff7c2f07c7c077a86d95238fe51e1fcf33574a4ae0684b42a3f6bf677d91820ca89874467b2c23add77969c80717430d0efc1d3695892ce855cb7f7011630f4df26def8ddf36fc23905f57fa6243a485c770d5681fcd\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 29926bc3280c841f601acd0d6f17ea38023eddbc\nOutput = 02802dccfa8dfaf5279bf0b4a29ba1b157611faeaaf419b8919d15941900c1339e7e92e6fae562c53e6cc8e84104b110bce03ad18525e3c49a0eadad5d3f28f244a8ed89edbafbb686277cfa8ae909714d6b28f4bf8e293aa04c41efe7c0a81266d5c061e2575be032aa464674ff71626219bd74cc45f0e7ed4e3ff96eee758e8f\n\nPublicKey = RSA-PSS-6\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d00308189028181164ca31cff609f3a0e7101b039f2e4fe6dd37519ab98598d179e174996598071f47d3a04559158d7be373cf1aa53f0aa6ef09039e5678c2a4c63900514c8c4f8aaed5de12a5f10b09c311af8c0ffb5b7a297f2efc63b8d6b0510931f0b98e48bf5fc6ec4e7b8db1ffaeb08c38e02adb8f03a48229c99e969431f61cb8c4dc698d10203010001\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = ab464e8cb65ae5fdea47a53fa84b234d6bfd52f6\nOutput = 04c0cfacec04e5badbece159a5a1103f69b3f32ba593cb4cc4b1b7ab455916a96a27cd2678ea0f46ba37f7fc9c86325f29733b389f1d97f43e7201c0f348fc45fe42892335362eee018b5b161f2f9393031225c713012a576bc88e23052489868d9010cbf033ecc568e8bc152bdc59d560e41291915d28565208e22aeec9ef85d1\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 92d0bcae82b641f578f040f5151be8eda6d42299\nOutput = 0a2314250cf52b6e4e908de5b35646bcaa24361da8160fb0f9257590ab3ace42b0dc3e77ad2db7c203a20bd952fbb56b1567046ecfaa933d7b1000c3de9ff05b7d989ba46fd43bc4c2d0a3986b7ffa13471d37eb5b47d64707bd290cfd6a9f393ad08ec1e3bd71bb5792615035cdaf2d8929aed3be098379377e777ce79aaa4773\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 3569bd8fd2e28f2443375efa94f186f6911ffc2b\nOutput = 086df6b500098c120f24ff8423f727d9c61a5c9007d3b6a31ce7cf8f3cbec1a26bb20e2bd4a046793299e03e37a21b40194fb045f90b18bf20a47992ccd799cf9c059c299c0526854954aade8a6ad9d97ec91a1145383f42468b231f4d72f23706d9853c3fa43ce8ace8bfe7484987a1ec6a16c8daf81f7c8bf42774707a9df456\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 7abbb7b42de335730a0b641f1e314b6950b84f98\nOutput = 0b5b11ad549863ffa9c51a14a1106c2a72cc8b646e5c7262509786105a984776534ca9b54c1cc64bf2d5a44fd7e8a69db699d5ea52087a4748fd2abc1afed1e5d6f7c89025530bdaa2213d7e030fa55df6f34bcf1ce46d2edf4e3ae4f3b01891a068c9e3a44bbc43133edad6ecb9f35400c4252a5762d65744b99cb9f4c559329f\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 55b7eb27be7a787a59eb7e5fac468",
-    "db8917a7725\nOutput = 02d71fa9b53e4654fefb7f08385cf6b0ae3a817942ebf66c35ac67f0b069952a3ce9c7e1f1b02e480a9500836de5d64cdb7ecde04542f7a79988787e24c2ba05f5fd482c023ed5c30e04839dc44bed2a3a3a4fee01113c891a47d32eb8025c28cb050b5cdb576c70fe76ef523405c08417faf350b037a43c379339fcb18d3a356b\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = de2fa0367ef49083ff89b9905d3fd646fcc12c38\nOutput = 0a40a16e2fe2b38d1df90546167cf9469c9e3c3681a3442b4b2c2f581deb385ce99fc6188bb02a841d56e76d301891e24560550fcc2a26b55f4ccb26d837d350a154bcaca8392d98fa67959e9727b78cad03269f56968fc56b68bd679926d83cc9cb215550645ccda31c760ff35888943d2d8a1d351e81e5d07b86182e751081ef\n\nPublicKey = RSA-PSS-7\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d0030818902818137c9da4a66c8c408b8da27d0c9d79f8ccb1eafc1d2fe48746d940b7c4ef5dee18ad12647cefaa0c4b3188b221c515386759b93f02024b25ab9242f8357d8f3fd49640ee5e643eaf6c64deefa7089727c8ff03993333915c6ef21bf5975b6e50d118b51008ec33e9f01a0a545a10a836a43ddbca9d8b5c5d3548022d7064ea29ab30203010001\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 8be4afbdd76bd8d142c5f4f46dba771ee5d6d29d\nOutput = 187f390723c8902591f0154bae6d4ecbffe067f0e8b795476ea4f4d51ccc810520bb3ca9bca7d0b1f2ea8a17d873fa27570acd642e3808561cb9e975ccfd80b23dc5771cdb3306a5f23159dacbd3aa2db93d46d766e09ed15d900ad897a8d274dc26b47e994a27e97e2268a766533ae4b5e42a2fcaf755c1c4794b294c60555823\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 402140dc605b2f5c5ec0d15bce9f9ba8857fe117\nOutput = 10fd89768a60a67788abb5856a787c8561f3edcf9a83e898f7dc87ab8cce79429b43e56906941a886194f137e591fe7c339555361fbbe1f24feb2d4bcdb80601f3096bc9132deea60ae13082f44f9ad41cd628936a4d51176e42fc59cb76db815ce5ab4db99a104aafea68f5d330329ebf258d4ede16064bd1d00393d5e1570eb8\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 3e885205892ff2b6b37c2c4eb486c4bf2f9e7f20\nOutput = 2b31fde99859b977aa09586d8e274662b25a2a640640b457f594051cb1e7f7a911865455242926cf88fe80dfa3a75ba9689844a11e634a82b075afbd69c12a0df9d25f84ad4945df3dc8fe90c3cefdf26e95f0534304b5bdba20d3e5640a2ebfb898aac35ae40f26fce5563c2f9f24f3042af76f3c7072d687bbfb959a88460af1\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 1fc2201d0c442a4736cd8b2cd00c959c47a3bf42\nOutput = 32c7ca38ff26949a15000c4ba04b2b13b35a3810e568184d7ecabaa166b7ffabddf2b6cf4ba07124923790f2e5b1a5be040aea36fe132ec130e1f10567982d17ac3e89b8d26c3094034e762d2e031264f01170beecb3d1439e05846f25458367a7d9c02060444672671e64e877864559ca19b2074d588a281b5804d23772fbbe19\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = e4351b66819e5a31501f89acc7faf57030e9aac5\nOutput = 07eb651d75f1b52bc263b2e198336e99fbebc4f332049a922a10815607ee2d989db3a4495b7dccd38f58a211fb7e193171a3d891132437ebca44f318b280509e52b5fa98fcce8205d9697c8ee4b7ff59d4c59c79038a1970bd2a0d451ecdc5ef11d9979c9d35f8c70a6163717607890d586a7c6dc01c79f86a8f28e85235f8c2f1\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 49f6cc58365e514e1a3f301f4de16f9fb5347ff2\nOutput = 18da3cdcfe79bfb77fd9c32f377ad399146f0a8e810620233271a6e3ed3248903f5cdc92dc79b55d3e11615aa056a795853792a3998c349ca5c457e8ca7d29d796aa24f83491709befcfb1510ea513c92829a3f00b104f655634f320752e130ec0ccf6754ff893db302932bb025eb60e87822598fc619e0e981737a9a4c4152d33\n\nPublicKey = RSA-PSS-8\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d00308189028181495370a1fb18543c16d3631e3163255df62be6eee890d5f25509e4f778a8ea6fbbbcdf85dff64e0d972003ab3681fbba6dd41fd541829b2e582de9f2a4a4e0a2d0900bef4753db3cee0ee06c7dfae8b1d53b5953218f9cceea695b08668edeaadced9463b1d790d5ebf27e9115b46cad4d9a2b8efab0561b0810344739ada0733f0203010001\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = a1dd230d8ead860199b6277c2ecfe3d95f6d9160\nOutput = 0262ac254bfa77f3c1aca22c5179f8f040422b3c5bafd40a8f21cf0fa5a667ccd5993d42dbafb409c520e25fce2b1ee1e716577f1efa17f3da28052f40f0419b23106d7845aaf01125b698e7a4dfe92d3967bb00c4d0d35ba3552ab9a8b3eef07c7fecdbc5424ac4db1e20cb37d0b2744769940ea907e17fbbca673b20522380c5\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = f6e68e53c602c5c65fa67b5aa6d786e5524b12ab\nOutput = 2707b9ad5115c58c94e932e8ec0a280f56339e44a1b58d4ddcff2f312e5f34dcfe39e89c6a94dcee86dbbdae5b79ba4e0819a9e7bfd9d982e7ee6c86ee68396e8b3a14c9c8f34b178eb741f9d3f121109bf5c8172fada2e768f9ea1433032c004a8aa07eb990000a48dc94c8bac8aabe2b09b1aa46c0a2aa0e12f63fbba775ba7e\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = d6f9fcd3ae27f32bb2c7c93536782eba52af1f76\nOutput = 2ad20509d78cf26d1b6c406146086e4b0c91a91c2bd164c87b966b8faa42aa0ca446022323ba4b1a1b89706d7f4c3be57d7b69702d168ab5955ee290356b8c4a29ed467d547ec23cbadf286ccb5863c6679da467fc9324a151c7ec55aac6db4084f82726825cfe1aa421bc64049fb42f23148f9c25b2dc300437c38d428aa75f96\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 7ff2a53ce2e2d900d468e498f230a5f5dd0020de\nOutput = 1e24e6e58628e5175044a9eb6d837d48af1260b0520e87327de7897ee4d5b9f0df0be3e09ed4dea8c1454ff3423bb08e1793245a9df8bf6ab3968c8eddc3b5328571c77f091cc578576912dfebd164b9de5454fe0be1c1f6385b328360ce67ec7a05f6e30eb45c17c48ac70041d2cab67f0a2ae7aafdcc8d245ea3442a6300ccc7\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 4eb309f7022ba0b03bb78601b12931ec7c1be8d3\nOutput = 33341ba3576a130a50e2a5cf8679224388d5693f5accc235ac95add68e5eb1eec31666d0ca7a1cda6f70a1aa762c05752a51950cdb8af3c5379f18cfe6b5bc55a4648226a15e912ef19ad77adeea911d67cfefd69ba43fa4119135ff642117ba985a7e0100325e9519f1ca6a9216bda055b5785015291125e90dcd07a2ca9673ee\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 65033bc2f67d6aba7d526acb873b8d9241e5e4d9\nOutput = 1ed1d848fb1edb44129bd9b354795af97a069a7a00d0151048593e0c72c3517ff9ff2a41d0cb5a0ac860d736a199704f7cb6a53986a88bbd8abcc0076a2ce847880031525d449da2ac78356374c536e343faa7cba42a5aaa6506087791c06a8e989335aed19bfab2d5e67e27fb0c2875af896c21b6e8e7309d04e4f6727e69463e\n\nPublicKey = RSA-PSS-9\nType = RSA\nInput = 3081df300d06092a864886f70d01010105000381cd003081c90281c100e6bd692ac96645790403fdd0f5beb8b9bf92ed10007fc365046419dd06c05c5b5b2f48ecf989e4ce269109979cbb40b4a0ad24d22483d1ee315ad4ccb1534268352691c524f6dd8e6c29d224cf246973aec86c5bf6b1401a850d1b9ad1bb8cbcec47b06f0f8c7f45d3fc8f319299c5433ddbc2b3053b47ded2ecd4a4caefd614833dc8bb622f317ed076b8057fe8de3f84480ad5e83e4a61904a4f248fb397027357e1d30e463139815c6fd4fd5ac5b8172a45230ecb6318a04f1455d84e5a8b0203010001\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 2715a49b8b0012cd7aee84c116446e6dfe3faec0\nOutput = 586107226c3ce013a7c8f04d1a6a2959bb4b8e205ba43a27b50f124111bc35ef589b039f5932187cb696d7d9a32c0c38300a5cdda4834b62d2eb240af33f79d13dfbf095bf599e0d9686948c1964747b67e89c9aba5cd85016236f566cc5802cb13ead51bc7ca6bef3b94dcbdbb1d570469771df0e00b1a8a06777472d2316279edae86474668d4e1efff95f1de61c6020da32ae92bbf16520fef3cf4d88f61121f24bbd9fe91b59caf1235b2a93ff81fc403addf4ebdea84934a9cdaf8e1a9e\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 2dac956d53964748ac364d06595827c6b4f143cd\nOutput = 80b6d643255209f0a456763897ac9ed259d459b49c2887e5882ecb4434cfd66dd7e1699375381e51cd7f554f2c271704b399d42b4be2540a0eca61951f55267f7c2878c122842dadb28b01bd5f8c025f7e228418a673c03d6bc0c736d0a29546bd67f786d9d692ccea778d71d98c2063b7a71092187a4d35af108111d83e83eae46c46aa34277e06044589903788f1d5e7cee25fb485e92949118814d6f2c3ee361489016f327fb5bc517eb50470bffa1afa5f4ce9aa0ce5b8ee19bf5501b958\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 28d98c46cccafbd3bc04e72f967a54bd3ea12298\nOutput = 484408f3898cd5f53483f80819efbf2708c34d27a8b2a6fae8b322f9240237f981817aca1846f1084daa6d7c0795f6e5bf1af59c38e1858437ce1f7ec419b98c8736adf6dd9a00b1806d2bd3ad0a73775e05f52dfef3a59ab4b08143f0df05cd1ad9d04bececa6daa4a2129803e200cbc77787caf4c1d0663a6c5987b605952019782caf2ec1426d68fb94ed1d4be816a7ed081b77e6ab330b3ffc073820fecde3727fcbe295ee61a050a343658637c3fd659cfb63736de32d9f90d3c2f63eca\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 0866d2ff5a79f25ef668cd6f31b42dee421e4c0e\nOutput = 84ebeb481be59845b46468bafb471c0112e02b235d84b5d911cbd1926ee5074ae0424495cb20e82308b8ebb65f419a03fb40e72b78981d88aad143053685172c97b29c8b7bf0ae73b5b2263c403da0ed2f80ff7450af7828eb8b86f0028bd2a8b176a4d228cccea18394f238b09ff758cc00bc0430115235",
-    "5742f282b54e663a919e709d8da24ade5500a7b9aa50226e0ca52923e6c2d860ec50ff480fa57477e82b0565f4379f79c772d5c2da80af9fbf325ece6fc20b00961614bee89a183e\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 6a5b4be4cd36cc97dfde9995efbf8f097a4a991a\nOutput = 82102df8cb91e7179919a04d26d335d64fbc2f872c44833943241de8454810274cdf3db5f42d423db152af7135f701420e39b494a67cbfd19f9119da233a23da5c6439b5ba0d2bc373eee3507001378d4a4073856b7fe2aba0b5ee93b27f4afec7d4d120921c83f606765b02c19e4d6a1a3b95fa4c422951be4f52131077ef17179729cddfbdb56950dbaceefe78cb16640a099ea56d24389eef10f8fecb31ba3ea3b227c0a86698bb89e3e9363905bf22777b2a3aa521b65b4cef76d83bde4c\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = b9dfd1df76a461c51e6576c6c8ed0a923d1c50e7\nOutput = a7fdb0d259165ca2c88d00bbf1028a867d337699d061193b17a9648e14ccbbaadeacaacdec815e7571294ebb8a117af205fa078b47b0712c199e3ad05135c504c24b81705115740802487992ffd511d4afc6b854491eb3f0dd523139542ff15c3101ee85543517c6a3c79417c67e2dd9aa741e9a29b06dcb593c2336b3670ae3afbac7c3e76e215473e866e338ca244de00b62624d6b9426822ceae9f8cc460895f41250073fd45c5a1e7b425c204a423a699159f6903e710b37a7bb2bc8049f\n\nPublicKey = RSA-PSS-10\nType = RSA\nInput = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100a5dd867ac4cb02f90b9457d48c14a770ef991c56c39c0ec65fd11afa8937cea57b9be7ac73b45c0017615b82d622e318753b6027c0fd157be12f8090fee2a7adcd0eef759f88ba4997c7a42d58c9aa12cb99ae001fe521c13bb5431445a8d5ae4f5e4c7e948ac227d3604071f20e577e905fbeb15dfaf06d1de5ae6253d63a6a2120b31a5da5dabc9550600e20f27d3739e2627925fea3cc509f21dff04e6eea4549c540d6809ff9307eede91fff58733d8385a237d6d3705a33e391900992070df7adf1357cf7e3700ce3667de83f17b8df1778db381dce09cb4ad058a511001a738198ee27cf55a13b754539906582ec8b174bd58d5d1f3d767c613721ae050203010001\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 9596bb630cf6a8d4ea4600422b9eba8b13675dd4\nOutput = 82c2b160093b8aa3c0f7522b19f87354066c77847abf2a9fce542d0e84e920c5afb49ffdfdace16560ee94a1369601148ebad7a0e151cf16331791a5727d05f21e74e7eb811440206935d744765a15e79f015cb66c532c87a6a05961c8bfad741a9a6657022894393e7223739796c02a77455d0f555b0ec01ddf259b6207fd0fd57614cef1a5573baaff4ec00069951659b85f24300a25160ca8522dc6e6727e57d019d7e63629b8fe5e89e25cc15beb3a647577559299280b9b28f79b0409000be25bbd96408ba3b43cc486184dd1c8e62553fa1af4040f60663de7f5e49c04388e257f1ce89c95dab48a315d9b66b1b7628233876ff2385230d070d07e1666\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = b503319399277fd6c1c8f1033cbf04199ea21716\nOutput = 14ae35d9dd06ba92f7f3b897978aed7cd4bf5ff0b585a40bd46ce1b42cd2703053bb9044d64e813d8f96db2dd7007d10118f6f8f8496097ad75e1ff692341b2892ad55a633a1c55e7f0a0ad59a0e203a5b8278aec54dd8622e2831d87174f8caff43ee6c46445345d84a59659bfb92ecd4c818668695f34706f66828a89959637f2bf3e3251c24bdba4d4b7649da0022218b119c84e79a6527ec5b8a5f861c159952e23ec05e1e717346faefe8b1686825bd2b262fb2531066c0de09acde2e4231690728b5d85e115a2f6b92b79c25abc9bd9399ff8bcf825a52ea1f56ea76dd26f43baafa18bfa92a504cbd35699e26d1dcc5a2887385f3c63232f06f3244c3\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 50aaede8536b2c307208b275a67ae2df196c7628\nOutput = 6e3e4d7b6b15d2fb46013b8900aa5bbb3939cf2c095717987042026ee62c74c54cffd5d7d57efbbf950a0f5c574fa09d3fc1c9f513b05b4ff50dd8df7edfa20102854c35e592180119a70ce5b085182aa02d9ea2aa90d1df03f2daae885ba2f5d05afdac97476f06b93b5bc94a1a80aa9116c4d615f333b098892b25fface266f5db5a5a3bcc10a824ed55aad35b727834fb8c07da28fcf416a5d9b2224f1f8b442b36f91e456fdea2d7cfe3367268de0307a4c74e924159ed33393d5e0655531c77327b89821bdedf880161c78cd4196b5419f7acc3f13e5ebf161b6e7c6724716ca33b85c2e25640192ac2859651d50bde7eb976e51cec828b98b6563b86bb\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = aa0b72b8b371ddd10c8ae474425ccccf8842a294\nOutput = 34047ff96c4dc0dc90b2d4ff59a1a361a4754b255d2ee0af7d8bf87c9bc9e7ddeede33934c63ca1c0e3d262cb145ef932a1f2c0a997aa6a34f8eaee7477d82ccf09095a6b8acad38d4eec9fb7eab7ad02da1d11d8e54c1825e55bf58c2a23234b902be124f9e9038a8f68fa45dab72f66e0945bf1d8bacc9044c6f07098c9fcec58a3aab100c805178155f030a124c450e5acbda47d0e4f10b80a23f803e774d023b0015c20b9f9bbe7c91296338d5ecb471cafb032007b67a60be5f69504a9f01abb3cb467b260e2bce860be8d95bf92c0c8e1496ed1e528593a4abb6df462dde8a0968dffe4683116857a232f5ebf6c85be238745ad0f38f767a5fdbf486fb\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = fad3902c9750622a2bc672622c48270cc57d3ea8\nOutput = 7e0935ea18f4d6c1d17ce82eb2b3836c55b384589ce19dfe743363ac9948d1f346b7bfddfe92efd78adb21faefc89ade42b10f374003fe122e67429a1cb8cbd1f8d9014564c44d120116f4990f1a6e38774c194bd1b8213286b077b0499d2e7b3f434ab12289c556684deed78131934bb3dd6537236f7c6f3dcb09d476be07721e37e1ceed9b2f7b406887bd53157305e1c8b4f84d733bc1e186fe06cc59b6edb8f4bd7ffefdf4f7ba9cfb9d570689b5a1a4109a746a690893db3799255a0cb9215d2d1cd490590e952e8c8786aa0011265252470c041dfbc3eec7c3cbf71c24869d115c0cb4a956f56d530b80ab589acfefc690751ddf36e8d383f83cedd2cc\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 122196deb5d122bd8c6fc781ff6924d7c695aade\nOutput = 6d3b5b87f67ea657af21f75441977d2180f91b2c5f692de82955696a686730d9b9778d970758ccb26071c2209ffbd6125be2e96ea81b67cb9b9308239fda17f7b2b64ecda096b6b935640a5a1cb42a9155b1c9ef7a633a02c59f0d6ee59b852c43b35029e73c940ff0410e8f114eed46bbd0fae165e42be2528a401c3b28fd818ef3232dca9f4d2a0f5166ec59c42396d6c11dbc1215a56fa17169db9575343ef34f9de32a49cdc3174922f229c23e18e45df9353119ec4319cedce7a17c64088c1f6f52be29634100b3919d38f3d1ed94e6891e66a73b8fb849f5874df59459e298c7bbce2eee782a195aa66fe2d0732b25e595f57d3e061b1fc3e4063bf98f\n\nPrivateKey = RSA-OAEP-1\nType = RSA\nInput = 30820276020100300d06092a864886f70d0101010500048202603082025c02010002818100a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb020301000102818053339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1024100d32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c2f26a471dcad212eac7ca39d024100cc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb33d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af72bfe9a030e860b0288b5d7702400e12bf1718e9cef5599ba1c3882fe8046a90874eefce8f2ccc20e4f2741fb0a33a3848aec9c9305fbecbd2d76819967d4671acc6431e4037968db37878e695c102410095297b0f95a2fa67d00707d609dfd4fc05c89dafc2ef6d6ea55bec771ea333734d9251e79082ecda866efef13c459e1a631386b7e354c899f5f112ca85d7158302404f456c502493bdc0ed2ab756a3a6ed4d67352a697d4216e93212b127a63d5411ce6fa98d5dbefd73263e3728142743818166ed7dd63687dd2a8ca1d2f4fbd8e1\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 354fe67b4a126d5d35fe36c777791a3f7ba13def484e2d3908aff722fad468fb21696de95d0be911c2d3174f8afcc201035f7b6d8e69402de5451618c21a535fa9d7bfc5b8dd9fc243f8cf927db31322d6e881eaa91a996170e657a05a266426d98c88003f8477c1227094a0d9fa1e8c4024309ce1ecccb5210035d47ac72e8a\nOutput = 6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 640db1acc58e0568fe5407e5f9b701dff8c3c91e716c536fc7fcec6cb5b71c1165988d4a279e1577d730fc7a29932e3f00c81515236d8d8e31017a7a09df4352d904cdeb79aa583adcc31ea698a4c05283daba9089be5491f67c1a4ee48dc74bbbe6643aef846679b4cb395a352d5ed115912df696ffe0702932946d71492b44\nOutput = 750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 423736ed035f6026af276c35c0b3741b365e5f76ca091b4e8c29e2f0befee603595aa8322d602d2e625e95eb81b2f1c9724e822eca76db8618cf09c5343503a4360835b5903bc637e3879fb05e0ef32685d5aec5067cd7cc96fe4b2670b6eac3066b1fcf5686b68589aafb7d629b02d8f8625ca3833624d4800fb081b1cf94eb\nOutput = d94ae0832e6445ce42331cb06d531a82b1db4baad30f746dc916df24d4e3c2451fff59a6423eb0e1d02d4fe646cf699dfd818c6e97b051\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 45ead4ca551e662c9800f1aca8283b0525e6abae30be4b4aba762fa40",
-    "fd3d38e22abefc69794f6ebbbc05ddbb11216247d2f412fd0fba87c6e3acd888813646fd0e48e785204f9c3f73d6d8239562722dddd8771fec48b83a31ee6f592c4cfd4bc88174f3b13a112aae3b9f7b80e0fc6f7255ba880dc7d8021e22ad6a85f0755\nOutput = 52e650d98e7f2a048b4f86852153b97e01dd316f346a19f67a85\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 36f6e34d94a8d34daacba33a2139d00ad85a9345a86051e73071620056b920e219005855a213a0f23897cdcd731b45257c777fe908202befdd0b58386b1244ea0cf539a05d5d10329da44e13030fd760dcd644cfef2094d1910d3f433e1c7c6dd18bc1f2df7f643d662fb9dd37ead9059190f4fa66ca39e869c4eb449cbdc439\nOutput = 8da89fd9e5f974a29feffb462b49180f6cf9e802\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 42cee2617b1ecea4db3f4829386fbd61dafbf038e180d837c96366df24c097b4ab0fac6bdf590d821c9f10642e681ad05b8d78b378c0f46ce2fad63f74e0ad3df06b075d7eb5f5636f8d403b9059ca761b5c62bb52aa45002ea70baace08ded243b9d8cbd62a68ade265832b56564e43a6fa42ed199a099769742df1539e8255\nOutput = 26521050844271\n\nPrivateKey = RSA-OAEP-2\nType = RSA\nInput = 30820276020100300d06092a864886f70d0101010500048202603082025c02010002818101947c7fce90425f47279e70851f25d5e62316fe8a1df19371e3e628e260543e4901ef6081f68c0b8141190d2ae8daba7d1250ec6db636e944ec3722877c7c1d0a67f14b1694c5f0379451a43e49a32dde83670b73da91a1c99bc23b436a60055c610f0baf99c1a079565b95a3f1526632d1d4da60f20eda25e653c4f002766f4502030100010281800823f20fadb5da89088a9d00893e21fa4a1b11fbc93c64a3be0baaea97fb3b93c3ff713704c19c963c1d107aae99054739f79e02e186de86f87a6ddefea6d8ccd1d3c81a47bfa7255be20601a4a4b2f08a167b5e279d715b1b455bdd7eab245941d9768b9acefb3ccda5952da3cee72525b4501663a8ee15c9e992d92462fe3902410159dbde04a33ef06fb608b80b190f4d3e22bcc13ac8e4a081033abfa416edb0b338aa08b57309ea5a5240e7dc6e54378c69414c31d97ddb1f406db3769cc41a430241012b652f30403b38b40995fd6ff41a1acc8ada70373236b7202d39b2ee30cfb46db09511f6f307cc61cc21606c18a75b8a62f822df031ba0df0dafd5506f568bd70240436ef508de736519c2da4c580d98c82cb7452a3fb5efadc3b9c7789a1bc6584f795addbbd32439c74686552ecb6c2c307a4d3af7f539eec157248c7b31f1a2550241012b15a89f3dfb2b39073e73f02bdd0c1a7b379dd435f05cdde2eff9e462948b7cec62ee9050d5e0816e0785a856b49108dcb75f3683874d1ca6329a19013066ff02400270db17d5914b018d76118b24389a7350ec836b0063a21721236fd8edb6d89b51e7eeb87b611b7132cb7ea7356c23151c1e7751507c786d9ee1794170a8c8e8\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0181af8922b9fcb4d79d92ebe19815992fc0c1439d8bcd491398a0f4ad3a329a5bd9385560db532683c8b7da04e4b12aed6aacdf471c34c9cda891addcc2df3456653aa6382e9ae59b54455257eb099d562bbe10453f2b6d13c59c02e10f1f8abb5da0d0570932dacf2d0901db729d0fefcc054e70968ea540c81b04bcaefe720e\nOutput = 8ff00caa605c702830634d9a6c3d42c652b58cf1d92fec570beee7\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 018759ff1df63b2792410562314416a8aeaf2ac634b46f940ab82d64dbf165eee33011da749d4bab6e2fcd18129c9e49277d8453112b429a222a8471b070993998e758861c4d3f6d749d91c4290d332c7a4ab3f7ea35ff3a07d497c955ff0ffc95006b62c6d296810d9bfab024196c7934012c2df978ef299aba239940cba10245\nOutput = 2d\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 018802bab04c60325e81c4962311f2be7c2adce93041a00719c88f957575f2c79f1b7bc8ced115c706b311c08a2d986ca3b6a9336b147c29c6f229409ddec651bd1fdd5a0b7f610c9937fdb4a3a762364b8b3206b4ea485fd098d08f63d4aa8bb2697d027b750c32d7f74eaf5180d2e9b66b17cb2fa55523bc280da10d14be2053\nOutput = 74fc88c51bc90f77af9d5e9a4a70133d4b4e0b34da3c37c7ef8e\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00a4578cbc176318a638fba7d01df15746af44d4f6cd96d7e7c495cbf425b09c649d32bf886da48fbaf989a2117187cafb1fb580317690e3ccd446920b7af82b31db5804d87d01514acbfa9156e782f867f6bed9449e0e9a2c09bcecc6aa087636965e34b3ec766f2fe2e43018a2fddeb140616a0e9d82e5331024ee0652fc7641\nOutput = a7eb2a5036931d27d4e891326d99692ffadda9bf7efd3e34e622c4adc085f721dfe885072c78a203b151739be540fa8c153a10f00a\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00ebc5f5fda77cfdad3c83641a9025e77d72d8a6fb33a810f5950f8d74c73e8d931e8634d86ab1246256ae07b6005b71b7f2fb98351218331ce69b8ffbdc9da08bbc9c704f876deb9df9fc2ec065cad87f9090b07acc17aa7f997b27aca48806e897f771d95141fe4526d8a5301b678627efab707fd40fbebd6e792a25613e7aec\nOutput = 2ef2b066f854c33f3bdcbb5994a435e73d6c6c\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 010839ec20c27b9052e55befb9b77e6fc26e9075d7a54378c646abdf51e445bd5715de81789f56f1803d9170764a9e93cb78798694023ee7393ce04bc5d8f8c5a52c171d43837e3aca62f609eb0aa5ffb0960ef04198dd754f57f7fbe6abf765cf118b4ca443b23b5aab266f952326ac4581100644325f8b721acd5d04ff14ef3a\nOutput = 8a7fb344c8b6cb2cf2ef1f643f9a3218f6e19bba89c0\n\nPrivateKey = RSA-OAEP-3\nType = RSA\nInput = 30820277020100300d06092a864886f70d0101010500048202613082025d02010002818102b58fec039a860700a4d7b6462f93e6cdd491161ddd74f4e810b40e3c1652006a5c277b2774c11305a4cbab5a78efa57e17a86df7a3fa36fc4b1d2249f22ec7c2dd6a463232accea906d66ebe80b5704b10729da6f833234abb5efdd4a292cbfad33b4d33fa7a14b8c397b56e3acd21203428b77cdfa33a6da706b3d8b0fc43e9020301000102818015b48a5b5683a94670e23b5718f814fa0e13f85038f50711182cba61510581f3d22c7e232ef937e22e551d68b86e2f8cb1aad8be2e488f5df7efd279e3f568d4eaf36f80cf7141ace60fcc9113fb6c4a841fd50bbc7c512ffcbeff21487aa811eb3ca8c62005346a86de86bfa1d8a948fd3f348c22eaadf333c3ce6ce13208fd024101bf01d216d73595cf0270c2beb78d40a0d8447d31da919a983f7eea781b77d85fe371b3e9373e7b69217d3150a02d8958de7fad9d555160958b4454127e0e7eaf0241018d3399658166db3829816d7b295416759e9c91987f5b2d8aecd63b04b48bd7b2fcf229bb7f8a6dc88ba13dd2e39ad55b6d1a06160708f9700be80b8fd3744ce7024006c0a249d20a6f2ee75c88b494d53f6aae99aa427c88c28b163a769445e5f390cf40c274fd6ea6329a5ce7c7ce03a2158396ee2a7845786e09e2885a9728e4e5024100d1d27c29fedd92d86c348edd0ccbfac14f746e051ce1d1811df35d61f2ee1c97d4bf2804802f6427187ba8e90a8af44243b4079b03445e602e29fa5193e64fe90241008cb2f756bd8941b1d3b770e5ad31ee373b28acda69ff9b6f40fe578b9f1afb85836f9627d37acff73c2779e634bb26011c2c8f7f3361ae2a9ea65ed689e3639a\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 026a0485d96aebd96b4382085099b962e6a2bdec3d90c8db625e14372de85e2d5b7baab65c8faf91bb5504fb495afce5c988b3f6a52e20e1d6cbd3566c5cd1f2b8318bb542cc0ea25c4aab9932afa20760eaddec784396a07ea0ef24d4e6f4d37e5052a7a31e146aa480a111bbe926401307e00f410033842b6d82fe5ce4dfae80\nOutput = 087820b569e8fa8d\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 024db89c7802989be0783847863084941bf209d761987e38f97cb5f6f1bc88da72a50b73ebaf11c879c4f95df37b850b8f65d7622e25b1b889e80fe80baca2069d6e0e1d829953fc459069de98ea9798b451e557e99abf8fe3d9ccf9096ebbf3e5255d3b4e1c6d2ecadf067a359eea86405acd47d5e165517ccafd47d6dbee4bf5\nOutput = 4653acaf171960b01f52a7be63a3ab21dc368ec43b50d82ec3781e04\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0239bce681032441528877d6d1c8bb28aa3bc97f1df584563618995797683844ca86664732f4bed7a0aab083aaabfb7238f582e30958c2024e44e57043b97950fd543da977c90cdde5337d618442f99e60d7783ab59ce6dd9d69c47ad1e962bec22d05895cff8d3f64ed5261d92b2678510393484990ba3f7f06818ae6ffce8a3a\nOutput = d94cd0e08fa404ed89\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 02994c62afd76f498ba1fd2cf642857fca81f4373cb08f1cbaee6f025c3b512b42c3e8779113476648039dbe0493f9246292fac28950600e7c0f32edf9c81b9dec45c3bde0cc8d8847590169907b7dc5991ceb29bb0714d613d96df0f12ec5d8d3507c8ee7ae78dd83f216fa61de100363aca48a7e914ae9f42ddfbe943b09d9a0\nOutput = 6cc641b6b61e6f963974dad23a9013284ef1\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0162042ff6969592a6167031811a239834ce638abf54fec8b99478122afe2ee67f8c5b18b0339805bfdbc5a4e6720b37c59cfba942464c597ff532a119821545fd2e59b114e61daf71820529f5029cf524954327c34ec5e6f5ba7efcc4de943ab8ad4ed787b1454329f70db798a3a8f4d92f8274e2b2948ade627ce8ee33e43c60\nOutput = df5151832b61f4f25891fb4172f328d2eddf8371ffcfdbe997939295f30eca6918017cfda1153bf7a6af87593223\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00112051e75d064943bc4478075e43482fd59cee0679de6893eec3a943daa490b9691c93dfc0464b6623b9f3dbd3e70083264f034b374f74164e1a00763725e574744ba0b9db83434f31df96f6e2a26f6d8eba348bd4686c2238ac07c37aac3785d1c7eea2f819fd91491798ed8e9cef5e43b781b0e0276e37c43ff9492d005730\nOutput = 3c3bad893c544a6d520ab022319188c8d504b7a788b850903",
-    "b85972eaa18552e1134a7ad6098826254ff7ab672b3d8eb3158fac6d4cbaef1\n\nPrivateKey = RSA-OAEP-4\nType = RSA\nInput = 30820277020100300d06092a864886f70d0101010500048202613082025d020100028181051240b6cc0004fa48d0134671c078c7c8dec3b3e2f25bc2564467339db38853d06b85eea5b2de353bff42ac2e46bc97fae6ac9618da9537a5c8f553c1e357625991d6108dcd7885fb3a25413f53efcad948cb35cd9b9ae9c1c67626d113d57dde4c5bea76bb5bb7de96c00d07372e9685a6d75cf9d239fa148d70931b5f3fb03902030100010281800411ffca3b7ca5e9e9be7fe38a85105e353896db05c5796aecd2a725161eb3651c8629a9b862b904d7b0c7b37f8cb5a1c2b54001018a00a1eb2cafe4ee4e9492c348bc2bedab4b9ebbf064e8eff322b9009f8eec653905f40df88a3cdc49d4567f75627d41aca624129b46a0b7c698e5e65f2b7ba102c749a10135b6540d04010241027458c19ec1636919e736c9af25d609a51b8f561d19c6bf6943dd1ee1ab8a4a3f232100bd40b88decc6ba235548b6ef792a11c9de823d0a7922c7095b6eba570102410210ee9b33ab61716e27d251bd465f4b35a1a232e2da00901c294bf22350ce490d099f642b5375612db63ba1f20386492bf04d34b3c22bceb909d13441b53b5139024039fa028b826e88c1121b750a8b242fa9a35c5b66bdfd1fa637d3cc48a84a4f457a194e7727e49f7bcc6e5a5a412657fc470c7322ebc37416ef458c307a8c09010241015d99a84195943979fa9e1be2c3c1b69f432f46fd03e47d5befbbbfd6b1d1371d83efb330a3e020942b2fed115e5d02be24fd92c9019d1cecd6dd4cf1e54cc899024101f0b7015170b3f5e42223ba30301c41a6d87cbb70e30cb7d3c67d25473db1f6cbf03e3f9126e3e97968279a865b2c2b426524cfc52a683d31ed30eb984be412ba\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 04cce19614845e094152a3fe18e54e3330c44e5efbc64ae16886cb1869014cc5781b1f8f9e045384d0112a135ca0d12e9c88a8e4063416deaae3844f60d6e96fe155145f4525b9a34431ca3766180f70e15a5e5d8e8b1a516ff870609f13f896935ced188279a58ed13d07114277d75c6568607e0ab092fd803a223e4a8ee0b1a8\nOutput = 4a86609534ee434a6cbca3f7e962e76d455e3264c19f605f6e5ff6137c65c56d7fb344cd52bc93374f3d166c9f0c6f9c506bad19330972d2\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0097b698c6165645b303486fbf5a2a4479c0ee85889b541a6f0b858d6b6597b13b854eb4f839af03399a80d79bda6578c841f90d645715b280d37143992dd186c80b949b775cae97370e4ec97443136c6da484e970ffdb1323a20847821d3b18381de13bb49aaea66530c4a4b8271f3eae172cd366e07e6636f1019d2a28aed15e\nOutput = b0adc4f3fe11da59ce992773d9059943c03046497ee9d9f9a06df1166db46d98f58d27ec074c02eee6cbe2449c8b9fc5080c5c3f4433092512ec46aa793743c8\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0301f935e9c47abcb48acbbe09895d9f5971af14839da4ff95417ee453d1fd77319072bb7297e1b55d7561cd9d1bb24c1a9a37c619864308242804879d86ebd001dce5183975e1506989b70e5a83434154d5cbfd6a24787e60eb0c658d2ac193302d1192c6e622d4a12ad4b53923bca246df31c6395e37702c6a78ae081fb9d065\nOutput = bf6d42e701707b1d0206b0c8b45a1c72641ff12889219a82bdea965b5e79a96b0d0163ed9d578ec9ada20f2fbcf1ea3c4089d83419ba81b0c60f3606da99\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 02d110ad30afb727beb691dd0cf17d0af1a1e7fa0cc040ec1a4ba26a42c59d0a796a2e22c8f357ccc98b6519aceb682e945e62cb734614a529407cd452bee3e44fece8423cc19e55548b8b994b849c7ecde4933e76037e1d0ce44275b08710c68e430130b929730ed77e09b015642c5593f04e4ffb9410798102a8e96ffdfe11e4\nOutput = fb2ef112f5e766eb94019297934794f7be2f6fc1c58e\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00dbb8a7439d90efd919a377c54fae8fe11ec58c3b858362e23ad1b8a44310799066b99347aa525691d2adc58d9b06e34f288c170390c5f0e11c0aa3645959f18ee79e8f2be8d7ac5c23d061f18dd74b8c5f2a58fcb5eb0c54f99f01a83247568292536583340948d7a8c97c4acd1e98d1e29dc320e97a260532a8aa7a758a1ec2\nOutput = 28ccd447bb9e85166dabb9e5b7d1adadc4b9d39f204e96d5e440ce9ad928bc1c2284\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00a5ffa4768c8bbecaee2db77e8f2eec99595933545520835e5ba7db9493d3e17cddefe6a5f567624471908db4e2d83a0fbee60608fc84049503b2234a07dc83b27b22847ad8920ff42f674ef79b76280b00233d2b51b8cb2703a9d42bfbc8250c96ec32c051e57f1b4ba528db89c37e4c54e27e6e64ac69635ae887d9541619a9\nOutput = f22242751ec6b1\n\nPrivateKey = RSA-OAEP-5\nType = RSA\nInput = 30820279020100300d06092a864886f70d0101010500048202633082025f0201000281810aadf3f9c125e5d891f31ac448e993defe580f802b45f9d7f22ba5021e9c47576b5a1e68031ba9db4e6dabe4d96a1d6f3d267268cff408005f118efcadb99888d1c234467166b2a2b849a05a889c060ac0da0c5fae8b55f309ba62e703742fa0326f2d10b011021489ff497770190d895fd39f52293c39efd73a698bdab9f10ed902030100010281810256eb4cba7067f2d2be540dcdff4582a36b7d31d1c9099bb214b79848466a268f80f58a49ac04c0e3648934a0206c04537c19b236643a6082732144df75fa217588f794682be89168276dc726c5c0cbdb84d31bbf26d0a43af495717f7d528acfee341561f6ff3cae05c578f8470d9682f9c0d072f9f6068b56d5880f682be2c5024103b0d3962f6d17549cbfca11294348dcf0e7e39f8c2bc6824f2164b606d687860dae1e632393cfedf513228229069e2f60e4acd7e633a436063f82385f48993707024102e4c32e2f517269b7072309f00c0e31365f7ce28b236b82912df239abf39572cf0ed604b02982e53564c52d6a05397de5c052a2fddc141ef7189836346aeb331f024101e84b119d25161fa67b00256a5bd9b645d2b232ecb05b015180029a88622adc3f09b3aeacde6161ab7cde22c2ad26e7797df54e072cbd3b2673800b3e4338dbd5024100eb90aa1a40135b4cea07197cedc8819be1e7cbff2547662116f465a4a9f487ab12f3ba4fef13822265a65297d98b7bded9372e3ffe81a38b3e9600fed055754f0241012f7f8138f9404062eb85a42924520b38f5bb886a0196f48bb8dcea60fd92cc027f18e78158a34a5c5d5f860a0f6c04071a7d01312c065062f1eb48b79d1c83cb\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 036046a4a47d9ed3ba9a89139c105038eb7492b05a5d68bfd53accff4597f7a68651b47b4a4627d927e485eed7b4566420e8b409879e5d606eae251d22a5df799f7920bfc117b992572a53b1263146bcea03385cc5e853c9a101c8c3e1bda31a519807496c6cb5e5efb408823a352b8fa0661fb664efadd593deb99fff5ed000e5\nOutput = af71a901e3a61d3132f0fc1fdb474f9ea6579257ffc24d164170145b3dbde8\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 03d6eb654edce615bc59f455265ed4e5a18223cbb9be4e4069b473804d5de96f54dcaaa603d049c5d94aa1470dfcd2254066b7c7b61ff1f6f6770e3215c51399fd4e34ec5082bc48f089840ad04354ae66dc0f1bd18e461a33cc1258b443a2837a6df26759aa2302334986f87380c9cc9d53be9f99605d2c9a97da7b0915a4a7ad\nOutput = a3b844a08239a8ac41605af17a6cfda4d350136585903a417a79268760519a4b4ac3303ec73f0f87cfb32399\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0770952181649f9f9f07ff626ff3a22c35c462443d905d456a9fd0bff43cac2ca7a9f554e9478b9acc3ac838b02040ffd3e1847de2e4253929f9dd9ee4044325a9b05cabb808b2ee840d34e15d105a3f1f7b27695a1a07a2d73fe08ecaaa3c9c9d4d5a89ff890d54727d7ae40c0ec1a8dd86165d8ee2c6368141016a48b55b6967\nOutput = 308b0ecbd2c76cb77fc6f70c5edd233fd2f20929d629f026953bb62a8f4a3a314bde195de85b5f816da2aab074d26cb6acddf323ae3b9c678ac3cf12fbdde7\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0812b76768ebcb642d040258e5f4441a018521bd96687e6c5e899fcd6c17588ff59a82cc8ae03a4b45b31299af1788c329f7dcd285f8cf4ced82606b97612671a45bedca133442144d1617d114f802857f0f9d739751c57a3f9ee400912c61e2e6992be031a43dd48fa6ba14eef7c422b5edc4e7afa04fdd38f402d1c8bb719abf\nOutput = 15c5b9ee1185\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 07b60e14ec954bfd29e60d0047e789f51d57186c63589903306793ced3f68241c743529aba6a6374f92e19e0163efa33697e196f7661dfaaa47aac6bde5e51deb507c72c589a2ca1693d96b1460381249b2cdb9eac44769f2489c5d3d2f99f0ee3c7ee5bf64a5ac79c42bd433f149be8cb59548361640595513c97af7bc2509723\nOutput = 21026e6800c7fa728fcaaba0d196ae28d7a2ac4ffd8abce794f0985f60c8a6737277365d3fea11db8923a2029a\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 08c36d4dda33423b2ed6830d85f6411ba1dcf470a1fae0ebefee7c089f256cef74cb96ea69c38f60f39abee44129bcb4c92de7f797623b20074e3d9c2899701ed9071e1efa0bdd84d4c3e5130302d8f0240baba4b84a71cc032f2235a5ff0fae277c3e8f9112bef44c9ae20d175fc9a4058bfc930ba31b02e2e4f444483710f24a\nOutput = 541e37b68b6c8872b84c02\n\nPrivateKey = RSA-OAEP-6\nType = RSA\nInput = 30820279020100300d06092a864886f70d0101010500048202633082025f02010002818112b17f6dad2ecd19ff46dc13f7860f09e0e0cfb677b38a52592305ceaf022c166db90d04ac29e33f7dd12d9faf66e0816bb63ead267cc7d46c17c37be214bca2a22d723a64e44407436b6fc965729aefc2554f376cd5dcea68293780a62bf39d0029485a160bbb9e5dc0972d21a504f52e5ee028aa416332f510b2e9cff5f722af02030100010281810295eca3560618369559cecd303aa9cfdafc1d9f06959df75ffef929aa896961bcd190dc6997eda7f5963e724d07b4dc11f3065e5ae97d96835112280b9084bb14f2a21ebd4e889d41b9c4132ec1956fcab8bb2fed0575884936522c5ff7d33261",
-    "904824e7cadee4e0bb372d2457cf78e2bd1286228ff83f10731ce63c90cff3f9024104a6ce8b7358dfa69bdcf742617005afb5385f5f3a58a24ef74a22a8c05cb7cc38ebd4cc9d9a9d789a62cd0f60f0cb941d3423c9692efa4fe3adff290c4749a38b02410404c9a803371fedb4c5be39f3c00b009e5e08a63be1e40035cdaca5011cc701cf7eebcb99f0ffe17cfd0a4bf7befd2dd536ac946db797fdbc4abe8f29349b91ed024103961c8f760aa2bd5154c7aafd77225b3bacd0139ae7b5948ea3311fccd86fb95c75afa767284b9b2de559572f15d8d044c7eb83a1be5fadf2cc377c0d8475294b0241022197e066742196aabc03fa2feeb4e70b15cb787d617acd31bb75c7bc234ad706f7c48d2182d1f0ff9c228dcf41967b6c0ba6d2c0ad110a1b857831ec245e2cb102410401c4c0c53d45dbdb5e9d96d0fecf4275df0974bc4a0736b4a74c3269053efb686ace2406e22c9e058ddb4ae540627ae2fdb08261e8e7e4bcbc994daafa305c45\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0630eebcd2856c24f798806e41f9e67345eda9ceda386acc9facaea1eeed06ace583709718d9d169fadf414d5c76f92996833ef305b75b1e4b95f662a20faedc3bae0c4827a8bf8a88edbd57ec203a27a841f02e43a615bab1a8cac0701de34debdef62a088089b55ec36ea7522fd3ec8d06b6a073e6df833153bc0aefd93bd1a3\nOutput = 4046ca8baa3347ca27f49e0d81f9cc1d71be9ba517d4\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0ebc37376173a4fd2f89cc55c2ca62b26b11d51c3c7ce49e8845f74e7607317c436bc8d23b9667dfeb9d087234b47bc6837175ae5c0559f6b81d7d22416d3e50f4ac533d8f0812f2db9e791fe9c775ac8b6ad0f535ad9ceb23a4a02014c58ab3f8d3161499a260f39348e714ae2a1d3443208fd8b722ccfdfb393e98011f99e63f\nOutput = 5cc72c60231df03b3d40f9b57931bc31109f972527f28b19e7480c7288cb3c92b22512214e4be6c914792ddabdf57faa8aa7\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0a98bf1093619394436cf68d8f38e2f158fde8ea54f3435f239b8d06b8321844202476aeed96009492480ce3a8d705498c4c8c68f01501dc81db608f60087350c8c3b0bd2e9ef6a81458b7c801b89f2e4fe99d4900ba6a4b5e5a96d865dc676c7755928794130d6280a8160a190f2df3ea7cf9aa0271d88e9e6905ecf1c5152d65\nOutput = b20e651303092f4bccb43070c0f86d23049362ed96642fc5632c27db4a52e3d831f2ab068b23b149879c002f6bf3feee97591112562c\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 008e7a67cacfb5c4e24bec7dee149117f19598ce8c45808fef88c608ff9cd6e695263b9a3c0ad4b8ba4c95238e96a8422b8535629c8d5382374479ad13fa39974b242f9a759eeaf9c83ad5a8ca18940a0162ba755876df263f4bd50c6525c56090267c1f0e09ce0899a0cf359e88120abd9bf893445b3cae77d3607359ae9a52f8\nOutput = 684e3038c5c041f7\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00003474416c7b68bdf961c385737944d7f1f40cb395343c693cc0b4fe63b31fedf1eaeeac9ccc0678b31dc32e0977489514c4f09085f6298a9653f01aea4045ff582ee887be26ae575b73eef7f3774921e375a3d19adda0ca31aa1849887c1f42cac9677f7a2f4e923f6e5a868b38c084ef187594dc9f7f048fea2e02955384ab\nOutput = 32488cb262d041d6e4dd35f987bf3ca696db1f06ac29a44693\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0a026dda5fc8785f7bd9bf75327b63e85e2c0fdee5dadb65ebdcac9ae1de95c92c672ab433aa7a8e69ce6a6d8897fac4ac4a54de841ae5e5bbce7687879d79634cea7a30684065c714d52409b928256bbf53eabcd5231eb7259504537399bd29164b726d33a46da701360a4168a091ccab72d44a62fed246c0ffea5b1348ab5470\nOutput = 50ba14be8462720279c306ba\n\nPrivateKey = RSA-OAEP-7\nType = RSA\nInput = 30820278020100300d06092a864886f70d0101010500048202623082025e020100028181311179f0bcfc9b9d3ca315d00ef30d7bdd3a2cfae9911bfedcb948b3a4782d0732b6ab44aa4bf03741a644dc01bec3e69b01a033e675d8acd7c4925c6b1aec3119051dfd89762d215d45475ffcb59f908148623f37177156f6ae86dd7a7c5f43dc1e1f908254058a284a5f06c0021793a87f1ac5feff7dcaee69c5e51a3789e3730203010001028181070cfcff2feb8276e27432c45dfee48f49b7917d6530e1f0ca3460f32e0276174487c56e22a45d2500d7775495219d7d165a9cf3bd92c32af9a98d8dc9cc296800adc94a0a54fb40f34291bf84ee8ea12b6f109359c6d3542a50f9c767f5cfff05a681c2e656fb77caaadb4be9468d8abcd4df98f58e86d2053fa1349f748e21b102410749262c111cd470ec2566e6b3732fc09329469aa19071d3b9c01906514c6f1d26baa14beab0971c8b7e611a4f79009d6fea776928ca25285b0de3643d1a3f8c71024106bc1e50e96c02bf636e9eea8b899bbebf7651de77dd474c3e9bc23bad8182b61904c7d97dfbebfb1e00108878b6e67e415391d67942c2b2bf9b4435f88b0cb023024103bc7ea7f0aab143abc6ce8b97118636a30172e4cfe02c8fa0dda3b7baaf90f8092982985525f488bdfcb4bd726e22639ac64a3092ab7ffcbf1d5334cfa50b5bf102410262a6aa29c2a3c67dc5346c06381afd987aa3cc93cfbfecf54fdd9f9d787d7f59a523d398979da137a2f6381fe94801f7c94da21518dc34cb40870c4697994ad90240649d4c17b6ee1721e772d0389a559c3d3cdf9550d457c46b037b74641b1d52166af8a213c8396206cdfba4422f18d6f61dbcb5d214c971bf482aeb976a7370c2\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 1688e4ce7794bba6cb7014169ecd559cede2a30b56a52b68d9fe18cf1973ef97b2a03153951c755f6294aa49adbdb55845ab6875fb3986c93ecf927962840d282f9e54ce8b690f7c0cb8bbd73440d9571d1b16cd9260f9eab4783cc482e5223dc60973871783ec27b0ae0fd47732cbc286a173fc92b00fb4ba6824647cd93c85c1\nOutput = 47aae909\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 1052ed397b2e01e1d0ee1c50bf24363f95e504f4a03434a08fd822574ed6b9736edbb5f390db10321479a8a139350e2bd4977c3778ef331f3e78ae118b268451f20a2f01d471f5d53c566937171b2dbc2d4bde459a5799f0372d6574239b2323d245d0bb81c286b63c89a361017337e4902f88a467f4c7f244bfd5ab46437ff3b6\nOutput = 1d9b2e2223d9bc13bfb9f162ce735db48ba7c68f6822a0a1a7b6ae165834e7\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 2155cd843ff24a4ee8badb7694260028a490813ba8b369a4cbf106ec148e5298707f5965be7d101c1049ea8584c24cd63455ad9c104d686282d3fb803a4c11c1c2e9b91c7178801d1b6640f003f5728df007b8a4ccc92bce05e41a27278d7c85018c52414313a5077789001d4f01910b72aad05d220aa14a58733a7489bc54556b\nOutput = d976fc\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0ab14c373aeb7d4328d0aaad8c094d88b9eb098b95f21054a29082522be7c27a312878b637917e3d819e6c3c568db5d843802b06d51d9e98a2be0bf40c031423b00edfbff8320efb9171bd2044653a4cb9c5122f6c65e83cda2ec3c126027a9c1a56ba874d0fea23f380b82cf240b8cf540004758c4c77d934157a74f3fc12bfac\nOutput = d4738623df223aa43843df8467534c41d013e0c803c624e263666b239bde40a5f29aeb8de79e3daa61dd0370f49bd4b013834b98212aef6b1c5ee373b3cb\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 028387a318277434798b4d97f460068df5298faba5041ba11761a1cb7316b24184114ec500257e2589ed3b607a1ebbe97a6cc2e02bf1b681f42312a33b7a77d8e7855c4a6de03e3c04643f786b91a264a0d6805e2cea91e68177eb7a64d9255e4f27e713b7ccec00dc200ebd21c2ea2bb890feae4942df941dc3f97890ed347478\nOutput = bb47231ca5ea1d3ad46c99345d9a8a61\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 14c678a94ad60525ef39e959b2f3ba5c097a94ff912b67dbace80535c187abd47d075420b1872152bba08f7fc31f313bbf9273c912fc4c0149a9b0cfb79807e346eb332069611bec0ff9bcd168f1f7c33e77313cea454b94e2549eecf002e2acf7f6f2d2845d4fe0aab2e5a92ddf68c480ae11247935d1f62574842216ae674115\nOutput = 2184827095d35c3f86f600e8e59754013296\n\nPrivateKey = RSA-OAEP-8\nType = RSA\nInput = 30820279020100300d06092a864886f70d0101010500048202633082025f0201000281815bdf0e30d321dda5147f882408fa69195480df8f80d3f6e8bf5818504f36427ca9b1f5540b9c65a8f6974cf8447a244d9280201bb49fcbbe6378d1944cd227e230f96e3d10f819dcef276c64a00b2a4b6701e7d01de5fabde3b1e9a0df82f4631359cd22669647fbb1717246134ed7b497cfffbdc42b59c73a96ed90166212dff702030100010281810f7d1e9e5aaa25fd13e4a0663ae144e0d15f5cd18bcdb09df2cc7e64e3c5e915ad62645304161d098c715bb7ab8bd01d07eaf3fed7c7ed08af2a8a62ef44ab16b320e14af72a48f96afe262a0ae4cf65e635e910790cd4ee5cea768a4b2639f7e6f677b3f0bb6be32b75747d8909036f0264f58d401cdba131716157a75ecf633102410a02ef8448d9fad8bbd0d004c8c2aa9751ef9721c1b0d03236a54b0df947cbaed5a255ee9e8e20d491ea1723fe094704a9762e88afd16ebb5994412ca966dc4f9f0241092d362e7ed3a0bfd9e9fd0e6c0301b6df29159cf50cc83b9b0cf4d6eea71a61e002b46e0ae9f2de62d25b5d7452d498b81c9ac6fc58593d4c3fb4f5d72dfbb0a9024107c71410af103962db367404e37ae850baa4e9c29dd92145815294a67c7d1c6ded263aa030a9b633ae50303e14035d1af014123eba687820308d8ebc85b6957d7d024100ae2c75380c02c016ad05891b3301de881f28ae1171182b6b2c83bea7c515eca9ca298c7b1cab5817a597068fc85060de4da8a016378aae43c7f967bcc37904b902410598d1059e3ada4f6320752c09d805ff7d1f1ae0d017aeeee9cefa0d7dd7ff775e44b578322f6405d6211da19519666aa87fdc4cd8c88f6b6e3d67e961dcbba3d0\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 09b3683d8a2eb0fb295b62ed1fb9290b714457b7825319f4647872af889b30409472020ad12912bf19b11d4819f49614824ffd84d09c0a17e7d17309d1291",
-    "9790410aa2995699f6a86dbe3242b5acc23af45691080d6b1ae810fb3e3057087f0970092ce00be9562ff4053b6262ce0caa93e13723d2e3a5ba075d45f0d61b54b61\nOutput = 050b755e5e6880f7b9e9d692a74c37aae449b31bfea6deff83747a897f6c2c825bb1adbf850a3c96994b5de5b33cbc7d4a17913a7967\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 2ecf15c97c5a15b1476ae986b371b57a24284f4a162a8d0c8182e7905e792256f1812ba5f83f1f7a130e42dcc02232844edc14a31a68ee97ae564a383a3411656424c5f62ddb646093c367be1fcda426cf00a06d8acb7e57776fbbd855ac3df506fc16b1d7c3f2110f3d8068e91e186363831c8409680d8da9ecd8cf1fa20ee39d\nOutput = 4eb68dcd93ca9b19df111bd43608f557026fe4aa1d5cfac227a3eb5ab9548c18a06dded23f81825986b2fcd71109ecef7eff88873f075c2aa0c469f69c92bc\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 4bc89130a5b2dabb7c2fcf90eb5d0eaf9e681b7146a38f3173a3d9cfec52ea9e0a41932e648a9d69344c50da763f51a03c95762131e8052254dcd2248cba40fd31667786ce05a2b7b531ac9dac9ed584a59b677c1a8aed8c5d15d68c05569e2be780bf7db638fd2bfd2a85ab276860f3777338fca989ffd743d13ee08e0ca9893f\nOutput = 8604ac56328c1ab5ad917861\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 2e456847d8fc36ff0147d6993594b9397227d577752c79d0f904fcb039d4d812fea605a7b574dd82ca786f93752348438ee9f5b5454985d5f0e1699e3e7ad175a32e15f03deb042ab9fe1dd9db1bb86f8c089ccb45e7ef0c5ee7ca9b7290ca6b15bed47039788a8a93ff83e0e8d6244c71006362deef69b6f416fb3c684383fbd0\nOutput = fdda5fbf6ec361a9d9a4ac68af216a0686f438b1e0e5c36b955f74e107f39c0dddcc\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 1fb9356fd5c4b1796db2ebf7d0d393cc810adf6145defc2fce714f79d93800d5e2ac211ea8bbecca4b654b94c3b18b30dd576ce34dc95436ef57a09415645923359a5d7b4171ef22c24670f1b229d3603e91f76671b7df97e7317c97734476d5f3d17d21cf82b5ba9f83df2e588d36984fd1b584468bd23b2e875f32f68953f7b2\nOutput = 4a5f4914bee25de3c69341de07\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 3afd9c6600147b21798d818c655a0f4c9212db26d0b0dfdc2a7594ccb3d22f5bf1d7c3e112cd73fc7d509c7a8bafdd3c274d1399009f9609ec4be6477e453f075aa33db382870c1c3409aef392d7386ae3a696b99a94b4da0589447e955d16c98b17602a59bd736279fcd8fb280c4462d590bfa9bf13fed570eafde97330a2c210\nOutput = 8e07d66f7b880a72563abcd3f35092bc33409fb7f88f2472be\n\nPrivateKey = RSA-OAEP-9\nType = RSA\nInput = 30820397020100300d06092a864886f70d0101010500048203813082037d0201000281c100cf2cd41e34ca3a728ea5cb8aff64c36d27bdef5364e336fd68d3123c5a196a8c287013e853d5156d58d151954520fb4f6d7b17abb6817765909c576119659d902b1906ed8a2b10c155c24d124528dab9eeae379beac66e4a411786dcb8fd0062ebc030de1219a04c2a8c1b7dd3131e4d6b6caee2e31a5ed41ac1509b2ef1ee2ab18364be568ca941c25ecc84ff9d643b5ec1aaae102a20d73f479b780fd6da91075212d9eac03a0674d899eba2e431f4c44b615b6ba2232bd4b33baed73d625d02030100010281c0198c141e23715a92bccf6a119a5bc11389468d2811f548d727e17b4ab0eb986d6f211efb53b71f7ccbea87ee69c75ee615008c5332deb52bf390abdfbfe37d7205368159b2638c1de326e21d22251f0fb5848b3bf15005d2a74330f0afe916ee62ccc1344d1d83a709e60676273840f7f377424a5e0a4da75f01b31ff76819cf9cbfdd215243c3917c03ef38199312e567b3bf7aed3ab457f371ef8a1423f45b68c6e282ec111bba2833b987fd69fad83bc1b8c613c5e1ea16c11ed125ea7ec1026100fc8d6c04bec4eb9a8192ca7900cbe536e2e8b519decf33b2459798c6909df4f176db7d23190fc72b8865a718af895f1bcd9145298027423b605e70a47cf58390a8c3e88fc8c48e8b32e3da210dfbe3e881ea5674b6a348c21e93f9e55ea65efd026100d200d45e788aacea606a401d0460f87dd5c1027e12dc1a0d7586e8939d9cf789b40f51ac0442961de7d21cc21e05c83155c1f2aa9193387cfdf956cb48d153ba270406f9bbba537d4987d9e2f9942d7a14cbfffea74fecdda928d23e259f5ee1026100db16802f79a2f0d45f358d69fd33e44b81fae828622e93a54253e997d01b0743759da0e812b4aa4e6c8beab2328d5431955a418a67ff26a8c5c807a5da354e05ef31cc8cf758f463732950b03e265726fb94e39d6a572a26244ab08db75752ad026100a0a317cfe7df1423f87a6dee8451f4e2b4a67e5497f29b4f1e4e830b9fadd9401167026f5596e5a39c97817e0f5f16e27e19ec9902e01d7ea6fb9aa3c760afee1e381b69de6ac9c07585a06ad9c4ba00bf75c8ad2fa898a479e80ae294fed2a102600b21f335c353342eb44c3aa24445780c2d655b940174cae38c7c8a4e6493c0ba9fd303748267b083b9a7a6cb61e42db362b8c9896db7064e02ad5ae61587da15b4649c90594909feb37dbcb654beb7268ec801e5a8b4aa3911bebd88542f05be\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 267bcd118acab1fc8ba81c85d73003cb8610fa55c1d97da8d48a7c7f06896a4db751aa284255b9d36ad65f37653d829f1b37f97b8001942545b2fc2c55a7376ca7a1be4b1760c8e05a33e5aa2526b8d98e317088e7834c755b2a59b12631a182c05d5d43ab1779264f8456f515ce57dfdf512d5493dab7b7338dc4b7d78db9c091ac3baf537a69fc7f549d979f0eff9a94fda4169bd4d1d19a69c99e33c3b55490d501b39b1edae118ff6793a153261584d3a5f39f6e682e3d17c8cd1261fa72\nOutput = f735fd55ba92592c3b52b8f9c4f69aaa1cbef8fe88add095595412467f9cf4ec0b896c59eda16210e7549c8abb10cdbc21a12ec9b6b5b8fd2f10399eb6\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 93ac9f0671ec29acbb444effc1a5741351d60fdb0e393fbf754acf0de49761a14841df7772e9bc82773966a1584c4d72baea00118f83f35cca6e537cbd4d811f5583b29783d8a6d94cd31be70d6f526c10ff09c6fa7ce069795a3fcd0511fd5fcb564bcc80ea9c78f38b80012539d8a4ddf6fe81e9cddb7f50dbbbbcc7e5d86097ccf4ec49189fb8bf318be6d5a0715d516b49af191258cd32dc833ce6eb4673c03a19bbace88cc54895f636cc0c1ec89096d11ce235a265ca1764232a689ae8\nOutput = 81b906605015a63aabe42ddf11e1978912f5404c7474b26dce3ed482bf961ecc818bf420c54659\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 81ebdd95054b0c822ef9ad7693f5a87adfb4b4c4ce70df2df84ed49c04da58ba5fc20a19e1a6e8b7a3900b22796dc4e869ee6b42792d15a8eceb56c09c69914e813cea8f6931e4b8ed6f421af298d595c97f4789c7caa612c7ef360984c21b93edc5401068b5af4c78a8771b984d53b8ea8adf2f6a7d4a0ba76c75e1dd9f658f20ded4a46071d46d7791b56803d8fea7f0b0f8e41ae3f09383a6f9585fe7753eaaffd2bf94563108beecc207bbb535f5fcc705f0dde9f708c62f49a9c90371d3\nOutput = fd326429df9b890e09b54b18b8f34f1e24\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = bcc35f94cde66cb1136625d625b94432a35b22f3d2fa11a613ff0fca5bd57f87b902ccdc1cd0aebcb0715ee869d1d1fe395f6793003f5eca465059c88660d446ff5f0818552022557e38c08a67ead991262254f10682975ec56397768537f4977af6d5f6aaceb7fb25dec5937230231fd8978af49119a29f29e424ab8272b47562792d5c94f774b8829d0b0d9f1a8c9eddf37574d5fa248eefa9c5271fc5ec2579c81bdd61b410fa61fe36e424221c113addb275664c801d34ca8c6351e4a858\nOutput = f1459b5f0c92f01a0f723a2e5662484d8f8c0a20fc29dad6acd43bb5f3effdf4e1b63e07fdfe6628d0d74ca19bf2d69e4a0abf86d293925a796772f8088e\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 232afbc927fa08c2f6a27b87d4a5cb09c07dc26fae73d73a90558839f4fd66d281b87ec734bce237ba166698ed829106a7de6942cd6cdce78fed8d2e4d81428e66490d036264cef92af941d3e35055fe3981e14d29cbb9a4f67473063baec79a1179f5a17c9c1832f2838fd7d5e59bb9659d56dce8a019edef1bb3accc697cc6cc7a778f60a064c7f6f5d529c6210262e003de583e81e3167b89971fb8c0e15d44fffef89b53d8d64dd797d159b56d2b08ea5307ea12c241bd58d4ee278a1f2e\nOutput = 53e6e8c729d6f9c319dd317e74b0db8e4ccca25f3c8305746e137ac63a63ef3739e7b595abb96e8d55e54f7bd41ab433378ffb911d\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 438cc7dc08a68da249e42505f8573ba60e2c2773d5b290f4cf9dff718e842081c383e67024a0f29594ea987b9d25e4b738f285970d195abb3a8c8054e3d79d6b9c9a8327ba596f1259e27126674766907d8d582ff3a8476154929adb1e6d1235b2ccb4ec8f663ba9cc670a92bebd853c8dbf69c6436d016f61add836e94732450434207f9fd4c43dec2a12a958efa01efe2669899b5e604c255c55fb7166de5589e369597bb09168c06dd5db177e06a1740eb2d5c82faeca6d92fcee9931ba9f\nOutput = b6b28ea2198d0c1008bc64\n\nPrivateKey = RSA-OAEP-10\nType = RSA\nInput = 308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100ae45ed5601cec6b8cc05f803935c674ddbe0d75c4c09fd7951fc6b0caec313a8df39970c518bffba5ed68f3f0d7f22a4029d413f1ae07e4ebe9e4177ce23e7f5404b569e4ee1bdcf3c1fb03ef113802d4f855eb9b5134b5a7c8085adcae6fa2fa1417ec3763be171b0c62b760ede23c12ad92b980884c641f5a8fac26bdad4a03381a22fe1b754885094c82506d4019a535a286afeb271bb9ba592de18dcf600c2aeeae56e02f7cf79fc14cf3bdc7cd84febbbf950ca90304b2219a7aa063aefa2c3c1980e560cd64afe779585b6107657b957857efde6010988ab7de417fc88d8f384c4e6e72c3f943e0c31c0c4a5cc36f879d8a3ac9d7d59860eaada6b83bb020301000102820100056b04216fe5f354ac77250a4b6b0c8525a85c59b0bd80c56450a22d5f438e596a333aa875e291dd43f48cb88b9d5fc0d499f9fcd1c397f9afc070cd9e398c8d19e61db7c7410a6b2675dfbf5d345b804d201add502d5ce2d",
-    "fcb091ce9997bbebe57306f383e4d588103f036f7e85d1934d152a323e4a8db451d6f4a5b1b0f102cc150e02feee2b88dea4ad4c1baccb24d84072d14e1d24a6771f7408ee30564fb86d4393a34bcf0b788501d193303f13a2284b001f0f649eaf79328d4ac5c430ab4414920a9460ed1b7bc40ec653e876d09abc509ae45b525190116a0c26101848298509c1c3bf3a483e7274054e15e97075036e989f60932807b5257751e7902818100ecf5aecd1e5515fffacbd75a2816c6ebf49018cdfb4638e185d66a7396b6f8090f8018c7fd95cc34b857dc17f0cc6516bb1346ab4d582cadad7b4103352387b70338d084047c9d9539b6496204b3dd6ea442499207bec01f964287ff6336c3984658336846f56e46861881c10233d2176bf15a5e96ddc780bc868aa77d3ce76902818100bc46c464fc6ac4ca783b0eb08a3c841b772f7e9b2f28babd588ae885e1a0c61e4858a0fb25ac299990f35be85164c259ba1175cdd7192707135184992b6c29b746dd0d2cabe142835f7d148cc161524b4a09946d48b828473f1ce76b6cb6886c345c03e05f41d51b5c3a90a3f24073c7d74a4fe25d9cf21c75960f3fc386318302818100c73564571d00fb15d08a3de9957a50915d7126e9442dacf42bc82e862e5673ff6a008ed4d2e374617df89f17a160b43b7fda9cb6b6b74218609815f7d45ca263c159aa32d272d127faf4bc8ca2d77378e8aeb19b0ad7da3cb3de0ae7314980f62b6d4b0a875d1df03c1bae39ccd833ef6cd7e2d9528bf084d1f969e794e9f6c10281802658b37f6df9c1030be1db68117fa9d87e39ea2b693b7e6d3a2f70947413eec6142e18fb8dfcb6ac545d7c86a0ad48f8457170f0efb26bc48126c53efd1d16920198dc2a1107dc282db6a80cd3062360ba3fa13f70e4312ff1a6cd6b8fc4cd9c5c3db17c6d6a57212f73ae29f619327bad59b153858585ba4e28b60a62a45e490281806f38526b3925085534ef3e415a836ede8b86158a2c7cbfeccb0bd834304fec683ba8d4f479c433d43416e63269623cea100776d85aff401d3fff610ee65411ce3b1363d63a9709eede42647cea561493d54570a879c18682cd97710b96205ec31117d73b5f36223fadd6e8ba90dd7c0ee61d44e163251e20c7f66eb305117cb8\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 53ea5dc08cd260fb3b858567287fa91552c30b2febfba213f0ae87702d068d19bab07fe574523dfb42139d68c3c5afeee0bfe4cb7969cbf382b804d6e61396144e2d0e60741f8993c3014b58b9b1957a8babcd23af854f4c356fb1662aa72bfcc7e586559dc4280d160c126785a723ebeebeff71f11594440aaef87d10793a8774a239d4a04c87fe1467b9daf85208ec6c7255794a96cc29142f9a8bd418e3c1fd67344b0cd0829df3b2bec60253196293c6b34d3f75d32f213dd45c6273d505adf4cced1057cb758fc26aeefa441255ed4e64c199ee075e7f16646182fdb464739b68ab5daff0e63e9552016824f054bf4d3c8c90a97bb6b6553284eb429fcc\nOutput = 8bba6bf82a6c0f86d5f1756e97956870b08953b06b4eb205bc1694ee\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = a2b1a430a9d657e2fa1c2bb5ed43ffb25c05a308fe9093c01031795f5874400110828ae58fb9b581ce9dddd3e549ae04a0985459bde6c626594e7b05dc4278b2a1465c1368408823c85e96dc66c3a30983c639664fc4569a37fe21e5a195b5776eed2df8d8d361af686e750229bbd663f161868a50615e0c337bec0ca35fec0bb19c36eb2e0bbcc0582fa1d93aacdb061063f59f2ce1ee43605e5d89eca183d2acdfe9f81011022ad3b43a3dd417dac94b4e11ea81b192966e966b182082e71964607b4f8002f36299844a11f2ae0faeac2eae70f8f4f98088acdcd0ac556e9fccc511521908fad26f04c64201450305778758b0538bf8b5bb144a828e629795\nOutput = e6ad181f053b58a904f2457510373e57\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 9886c3e6764a8b9a84e84148ebd8c3b1aa8050381a78f668714c16d9cfd2a6edc56979c535d9dee3b44b85c18be8928992371711472216d95dda98d2ee8347c9b14dffdff84aa48d25ac06f7d7e65398ac967b1ce90925f67dce049b7f812db0742997a74d44fe81dbe0e7a3feaf2e5c40af888d550ddbbe3bc20657a29543f8fc2913b9bd1a61b2ab2256ec409bbd7dc0d17717ea25c43f42ed27df8738bf4afc6766ff7aff0859555ee283920f4c8a63c4a7340cbafddc339ecdb4b0515002f96c932b5b79167af699c0ad3fccfdf0f44e85a70262bf2e18fe34b850589975e867ff969d48eabf212271546cdc05a69ecb526e52870c836f307bd798780ede\nOutput = 510a2cf60e866fa2340553c94ea39fbc256311e83e94454b4124\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 6318e9fb5c0d05e5307e1683436e903293ac4642358aaa223d7163013aba87e2dfda8e60c6860e29a1e92686163ea0b9175f329ca3b131a1edd3a77759a8b97bad6a4f8f4396f28cf6f39ca58112e48160d6e203daa5856f3aca5ffed577af499408e3dfd233e3e604dbe34a9c4c9082de65527cac6331d29dc80e0508a0fa7122e7f329f6cca5cfa34d4d1da417805457e008bec549e478ff9e12a763c477d15bbb78f5b69bd57830fc2c4ed686d79bc72a95d85f88134c6b0afe56a8ccfbc855828bb339bd17909cf1d70de3335ae07039093e606d655365de6550b872cd6de1d440ee031b61945f629ad8a353b0d40939e96a3c450d2a8d5eee9f678093c8\nOutput = bcdd190da3b7d300df9a06e22caae2a75f10c91ff667b7c16bde8b53064a2649a94045c9\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 75290872ccfd4a4505660d651f56da6daa09ca1301d890632f6a992f3d565cee464afded40ed3b5be9356714ea5aa7655f4a1366c2f17c728f6f2c5a5d1f8e28429bc4e6f8f2cff8da8dc0e0a9808e45fd09ea2fa40cb2b6ce6ffff5c0e159d11b68d90a85f7b84e103b09e682666480c657505c0929259468a314786d74eab131573cf234bf57db7d9e66cc6748192e002dc0deea930585f0831fdcd9bc33d51f79ed2ffc16bcf4d59812fcebcaa3f9069b0e445686d644c25ccf63b456ee5fa6ffe96f19cdf751fed9eaf35957754dbf4bfea5216aa1844dc507cb2d080e722eba150308c2b5ff1193620f1766ecf4481bafb943bd292877f2136ca494aba0\nOutput = a7dd6c7dc24b46f9dd5f1e91ada4c3b3df947e877232a9\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 2d207a73432a8fb4c03051b3f73b28a61764098dfa34c47a20995f8115aa6816679b557e82dbee584908c6e69782d7deb34dbd65af063d57fca76a5fd069492fd6068d9984d209350565a62e5c77f23038c12cb10c6634709b547c46f6b4a709bd85ca122d74465ef97762c29763e06dbc7a9e738c78bfca0102dc5e79d65b973f28240caab2e161a78b57d262457ed8195d53e3c7ae9da021883c6db7c24afdd2322eac972ad3c354c5fcef1e146c3a0290fb67adf007066e00428d2cec18ce58f9328698defef4b2eb5ec76918fde1c198cbb38b7afc67626a9aefec4322bfd90d2563481c9a221f78c8272c82d1b62ab914e1c69f6af6ef30ca5260db4a46\nOutput = eaf1a73a1b0c4609537de69cd9228bbcfb9a8ca8c6c3efaf056fe4a7f4634ed00b7c39ec6922d7b8ea2c04ebac\n\n\n# Single-shot signing tests.\n\nSignMessage = RSA-2048\nDigest = SHA256\nInput = \"Hello world\"\nOutput = 301894798b49d6ec55d32dcc74314f04230591a515781f3eb4492f5324b56046836c4bc3e25942af341e88558cb4c3814a849207575d343189147989b16e296b5138dbbc717116dc416f201dfa35943d15060493953cda1f04a13ff89845cf7fd69e1a78d5d38522a77bb234e5d0ba2ae17ada6e22fdae27a4052fdb8ac267507dfe06ed7a865e61a52b530bbbf65c7caa89739613df10ae3b0e62ff6831ee0770086aad39c329462aede9f1b29a501bc3d09e0fe4034aa5d6831d44491d508111d88a1d7ba50cee5ef7e701b3a589adc09a752a974a6805956f4a1a0582f66309a1e02e9fb6b10d2c820fe98bb2eb04f435bc8a649cc9ab6c5a4c03e83800d1\n\nVerifyMessage = RSA-2048\nDigest = SHA256\nInput = \"Hello world\"\nOutput = 301894798b49d6ec55d32dcc74314f04230591a515781f3eb4492f5324b56046836c4bc3e25942af341e88558cb4c3814a849207575d343189147989b16e296b5138dbbc717116dc416f201dfa35943d15060493953cda1f04a13ff89845cf7fd69e1a78d5d38522a77bb234e5d0ba2ae17ada6e22fdae27a4052fdb8ac267507dfe06ed7a865e61a52b530bbbf65c7caa89739613df10ae3b0e62ff6831ee0770086aad39c329462aede9f1b29a501bc3d09e0fe4034aa5d6831d44491d508111d88a1d7ba50cee5ef7e701b3a589adc09a752a974a6805956f4a1a0582f66309a1e02e9fb6b10d2c820fe98bb2eb04f435bc8a649cc9ab6c5a4c03e83800d1\n\nVerifyMessage = RSA-2048-SPKI\nDigest = SHA256\nInput = \"Hello world\"\nOutput = 301894798b49d6ec55d32dcc74314f04230591a515781f3eb4492f5324b56046836c4bc3e25942af341e88558cb4c3814a849207575d343189147989b16e296b5138dbbc717116dc416f201dfa35943d15060493953cda1f04a13ff89845cf7fd69e1a78d5d38522a77bb234e5d0ba2ae17ada6e22fdae27a4052fdb8ac267507dfe06ed7a865e61a52b530bbbf65c7caa89739613df10ae3b0e62ff6831ee0770086aad39c329462aede9f1b29a501bc3d09e0fe4034aa5d6831d44491d508111d88a1d7ba50cee5ef7e701b3a589adc09a752a974a6805956f4a1a0582f66309a1e02e9fb6b10d2c820fe98bb2eb04f435bc8a649cc9ab6c5a4c03e83800d1\n\nVerifyMessage = P-256\nDigest = SHA256\nInput = \"Hello world\"\nOutput = 304502204c66004635c267394bd6857c1e0b53b22a2bab1ca7dff9d5c1b42143858b3ea7022100ae81228510e03cd49a8863d2ebd1c05fe0c87eacd1150433132b909994cd0dbd\n\n# Digest can't be omitted in many algorithms.\nSignMessage = RSA-2048\nInput = \"Hello world\"\nError = NO_DEFAULT_DIGEST\n\nVerifyMessage = RSA-2048\nInput = \"Hello world\"\nOutput = 301894798b49d6ec55d32dcc74314f04230591a515781f3eb4492f5324b56046836c4bc3e25942af341e88558cb4c3814a849207575d343189147989b16e296b5138dbbc717116dc416f201dfa35943d15060493953cda1f04a13ff89845cf7fd69e1a78d5d38522a77bb234e5d0ba2ae17ada6e22fdae27a4052fdb8ac267507dfe06ed7a865e61a52b530bbbf65c7caa89739613df10ae3b0e62ff6831ee0770086aad39c329462aede9f1b29a501bc3d09e0fe4034aa5d6831d44491d508111d88a1d7ba50cee5ef7e701b3a589adc09a752a974a6805956f4a1a0582f66309a1e02e9fb6b10d2c820fe9",
-    "8bb2eb04f435bc8a649cc9ab6c5a4c03e83800d1\nError = NO_DEFAULT_DIGEST\n\n# Signing test vectors from RFC 8032.\nSignMessage = Ed25519\nInput = \"\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\n\nSignMessage = Ed25519-2\nInput = 72\nOutput = 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00\n\nSignMessage = Ed25519-3\nInput = af82\nOutput = 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a\n\nSignMessage = Ed25519-4\nInput = 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0\nOutput = 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03\n\nSignMessage = Ed25519-5\nInput = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f\nOutput = dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704\n\n# Signing with public keys is not allowed.\nSignMessage = Ed25519-SPKI\nInput = \"\"\nError = NOT_A_PRIVATE_KEY\n\n# Verify test vectors from RFC 8032. Test verifying with both the public and\n# private key.\nVerifyMessage = Ed25519\nInput = \"\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\n\nVerifyMessage = Ed25519-SPKI\nInput = \"\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\n\nVerifyMessage = Ed25519-2\nInput = 72\nOutput = 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00\n\nVerifyMessage = Ed25519-SPKI-2\nInput = 72\nOutput = 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00\n\nVerifyMessage = Ed25519-3\nInput = af82\nOutput = 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a\n\nVerifyMessage = Ed25519-SPKI-3\nInput = af82\nOutput = 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a\n\nVerifyMessage = Ed25519-4\nInput = 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0\nOutput = 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03\n\nVerifyMessage = Ed25519-SPKI-4\nInput = 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419",
-    "c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0\nOutput = 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03\n\nVerifyMessage = Ed25519-5\nInput = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f\nOutput = dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704\n\nVerifyMessage = Ed25519-SPKI-5\nInput = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f\nOutput = dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704\n\n# Length is wrong.\nVerifyMessage = Ed25519-SPKI\nInput = \"\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a10\nError = INVALID_SIGNATURE\n\n# Message is wrong.\nVerifyMessage = Ed25519-SPKI\nInput = \"Hello world\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\nError = INVALID_SIGNATURE\n\n# Ed25519 does not support configuring a digest.\nSignMessage = Ed25519\nInput = \"\"\nDigest = SHA256\nError = COMMAND_NOT_SUPPORTED\n\n# Ed25519 does not support signing a pre-hashed value.\nSign = Ed25519\nInput = \"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"\nError = OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\n\nVerify = Ed25519\nInput = \"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\nError = OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\n",
+    "he above, but with too few leading zeros.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = c5926600f160f85e7fe950cfe123908384211cd8fe25c90cb8e8cc0593308e9aa2efe3acbf100ec1658ded8f72f506525fc2c44f06251b08d896e7bb3f05b135\nError = DATA_LEN_NOT_EQUAL_TO_MOD_LEN\n\n# The above, but with too many leading zeros.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 0000c5926600f160f85e7fe950cfe123908384211cd8fe25c90cb8e8cc0593308e9aa2efe3acbf100ec1658ded8f72f506525fc2c44f06251b08d896e7bb3f05b135\nError = DATA_LEN_NOT_EQUAL_TO_MOD_LEN\n\n# The above with an invalid leading byte. The top few bits of EM are required to\n# be cleared.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 007f803c832a2090aea04013d9fa9c1630732a1625232826d235f0950f7050d3fb0eb06ef9ea8b260fad68e1165a2d770a8c7fc7a8aaa68620b021fc19c97e0041\nError = FIRST_OCTET_INVALID\n\n# The above with an invalid trailing byte.\nVerify = RSA-515\nRSAPadding = PSS\nPSSSaltLength = 0\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 03e68555035891eb08d96c0967db22328cd892ad2856d88516ecb946bfdba732bb029b5c0dfa2119ed7349897d2324e95e86d91d0c4afc82700a36db8933abbf58\nError = LAST_OCTET_INVALID\n\n# Non-zero salt length.\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 32\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4065b284b0a6e98d4c41a8427007f878d8dd61599c87764fa79b8bf03f030c48127a4b1a5af5a6e0cf9055e57a1f47e5b0c0d8c600e78369cf1c39374899fac91a812692aa2216ba10900ce85a5cf7fddcafb726e4b83479c5bb7b3b84b08ffe183b4c2973aa3193ec7b7d4ea73bf1b579c6657b78ad7800e1975a4838c28ffe353fafef96be27b5c69677760a71b6f4df65ba6fe6b3565580a536f966928294c6e9ece807a90c1477779bcbfa3a250e98d685097c162c1c8c56ab02bd2e16eec7a019b51c067bdba7fa8cd5460796e22c607a8b6d12e1deb9be51c6943c46590f416800c48bb4cbb8c409d316573e59eadf7d3b9e6e5c2d0e570692e511e139\n\n# Non-zero salt length, wrong salt length.\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = 31\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4065b284b0a6e98d4c41a8427007f878d8dd61599c87764fa79b8bf03f030c48127a4b1a5af5a6e0cf9055e57a1f47e5b0c0d8c600e78369cf1c39374899fac91a812692aa2216ba10900ce85a5cf7fddcafb726e4b83479c5bb7b3b84b08ffe183b4c2973aa3193ec7b7d4ea73bf1b579c6657b78ad7800e1975a4838c28ffe353fafef96be27b5c69677760a71b6f4df65ba6fe6b3565580a536f966928294c6e9ece807a90c1477779bcbfa3a250e98d685097c162c1c8c56ab02bd2e16eec7a019b51c067bdba7fa8cd5460796e22c607a8b6d12e1deb9be51c6943c46590f416800c48bb4cbb8c409d316573e59eadf7d3b9e6e5c2d0e570692e511e139\nError = SLEN_CHECK_FAILED\n\n# Non-zero salt length, match hash length.\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = -1\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4065b284b0a6e98d4c41a8427007f878d8dd61599c87764fa79b8bf03f030c48127a4b1a5af5a6e0cf9055e57a1f47e5b0c0d8c600e78369cf1c39374899fac91a812692aa2216ba10900ce85a5cf7fddcafb726e4b83479c5bb7b3b84b08ffe183b4c2973aa3193ec7b7d4ea73bf1b579c6657b78ad7800e1975a4838c28ffe353fafef96be27b5c69677760a71b6f4df65ba6fe6b3565580a536f966928294c6e9ece807a90c1477779bcbfa3a250e98d685097c162c1c8c56ab02bd2e16eec7a019b51c067bdba7fa8cd5460796e22c607a8b6d12e1deb9be51c6943c46590f416800c48bb4cbb8c409d316573e59eadf7d3b9e6e5c2d0e570692e511e139\n\n# Non-zero salt length, auto-detected.\nVerify = RSA-2048-SPKI\nRSAPadding = PSS\nPSSSaltLength = -2\nDigest = SHA256\nInput = \"0123456789ABCDEF0123456789ABCDEF\"\nOutput = 4065b284b0a6e98d4c41a8427007f878d8dd61599c87764fa79b8bf03f030c48127a4b1a5af5a6e0cf9055e57a1f47e5b0c0d8c600e78369cf1c39374899fac91a812692aa2216ba10900ce85a5cf7fddcafb726e4b83479c5bb7b3b84b08ffe183b4c2973aa3193ec7b7d4ea73bf1b579c6657b78ad7800e1975a4838c28ffe353fafef96be27b5c69677760a71b6f4df65ba6fe6b3565580a536f966928294c6e9ece807a90c1477779bcbfa3a250e98d685097c162c1c8c56ab02bd2e16eec7a019b51c067bdba7fa8cd5460796e22c607a8b6d12e1deb9be51c6943c46590f416800c48bb4cbb8c409d316573e59eadf7d3b9e6e5c2d0e570692e511e139\n\n\n# RSA decrypt\n\nDecrypt = RSA-2048\nInput = 550af55a2904e7b9762352f8fb7fa235a9cb053aacb2d5fcb8ca48453cb2ee3619746c701abf2d4cc67003471a187900b05aa812bd25ed05c675dfc8c97a24a7bf49bd6214992cad766d05a9a2b57b74f26a737e0237b8b76c45f1f226a836d7cfbc75ba999bdbe48dbc09227aa46c88f21dccba7840141ad5a5d71fd122e6bd6ac3e564780dfe623fc1ca9b995a6037bf0bbd43b205a84ac5444f34202c05ce9113087176432476576de6ffff9a52ea57c08be3ec2f49676cb8e12f762ac71fa3c321e00ac988910c85ff52f93825666ce0d40ffaa0592078919d4493f46d95ccf76364c6d57760dd0b64805f9afc76a2365a5575ca301d5103f0ea76cb9a78\nOutput = \"Hello World\"\n\n# Corrupted ciphertext\nDecrypt = RSA-2048\nInput = 550af55a2904e7b9762352f8fb7fa235a9cb053aacb2d5fcb8ca48453cb2ee3619746c701abf2d4cc67003471a187900b05aa812bd25ed05c675dfc8c97a24a7bf49bd6214992cad766d05a9a2b57b74f26a737e0237b8b76c45f1f226a836d7cfbc75ba999bdbe48dbc09227aa46c88f21dccba7840141ad5a5d71fd122e6bd6ac3e564780dfe623fc1ca9b995a6037bf0bbd43b205a84ac5444f34202c05ce9113087176432476576de6ffff9a52ea57c08be3ec2f49676cb8e12f762ac71fa3c321e00ac988910c85ff52f93825666ce0d40ffaa0592078919d4493f46d95ccf76364c6d57760dd0b64805f9afc76a2365a5575ca301d5103f0ea76cb9a79\nError = PKCS_DECODING_ERROR\n\n# OAEP padding\nDecrypt = RSA-2048\nRSAPadding = OAEP\nInput = 458708dfbd42a1297ce7a9c86c7087ab80b1754810929b89c5107ca55368587686986fce94d86cc1595b3fb736223a656ec0f34d18ba1cc5665593610f56c58e26b272d584f3d983a5c91085700755aebd921fb280bba3eda7046ec07b43e7298e52d59edc92be4639a8ce08b2f85976ecf6d98cc469eeb9d5d8e2a32ea8a6626edafe1038b3df455668a9f3c77cad8b92fb872e00058c3d2a7ede1a1f03fc5622084ae04d9d24f6bf0995c58d35b93b699b9763595e123f2ab0863cc9229eb290e2ede7715c7a8f39e0b9a3e2e1b56ebb62f1cbfbb5986fb212ebd785b83d01d968b11d1756c7337f70c1f1a63bff03608e24f3a2fd44e67f832a8701c5d5af\nOutput = \"Hello World\"\n\n# OAEP padding with label and custom hash.\nDecrypt = RSA-2048\nRSAPadding = OAEP\nOAEPDigest = SHA512\nOAEPLabel = 00112233445566778899aabbccddeeff\nInput = 48b956c22b8e40cc38f0893672ddf488fc806cf1fcc6239c66dd8345eb543d6b5cac589e6c7ae86dac1c2436c4d72c48009a737b2c649e6000dbab17203e4d9c078bd70b649700a0830d4ddc396af0c48973177a229e48259d93247f04f76474c7611b530c66f020c4da2cc861c2e4104831ecc0336e0cb10d6520fdefd0b33606f5cdd736dd439583b9b6011cce99623c93caf5f76e21e9fefab414795dd5ac12cba551be74ebf266834fcffab182c5e7c9b6c064df154cb26ddfd4fe2fd87590005f4bf45e776a0082803e9f68995b8eeb4c6802c67b5ef349e5b2dc0cf7a12fc097030f2bd28f0253f17129b04c82993a12957728b35880fdd2f8d0cc469f\nOutput = \"Hello World\"\n\n# OAEP padding, corrupted ciphertext\nDecrypt = RSA-2048\nRSAPadding = OAEP\nInput = 458708dfbd42a1297ce7a9c86c7087ab80b1754810929b89c5107ca55368587686986fce94d86cc1595b3fb736223a656ec0f34d18ba1cc5665593610f56c58e26b272d584f3d983a5c91085700755aebd921fb280bba3eda7046ec07b43e7298e52d59edc92be4639a8ce08b2f85976ecf6d98cc469eeb9d5d8e2a32ea8a6626edafe1038b3df455668a9f3c77cad8b92fb872e00058c3d2a7ede1a1f03fc5622084ae04d9d24f6bf0995c58d35b93b699b9763595e123f2ab0863cc9229eb290e2ede7715c7a8f39e0b9a3e2e1b56ebb62f1cbfbb5986fb212ebd785b83d01d968b11d1756c7337f70c1f1a63bff03608e24f3a2fd44e67f832a8701c5d5ac\nError = OAEP_DECODING_ERROR\n\n# Test that RSA encryption successfully round-trips through decryption\n# with various parameters.\nEncrypt = RSA-2048\nInput = \"Hello World\"\nCheckDecrypt\n\nEncrypt = RSA-2048\nRSAPadding = OAEP\nInput = \"Hello World\"\nCheckDecrypt\n\nEncrypt = RSA-2048\nRSAPadding = OAEP\nOAEPDigest = SHA512\nOAEPLabel = 00112233445566778899aabbccddeeff\nInput = \"Hello World\"\nCheckDecrypt\n\n# Though we will never generate such a key, test that RSA keys where p < q work\n# properly.\nPrivateKey = RSA-Swapped\nType = RSA\nInput = 30820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100ab28f98747934779011417d5bbb4095eae6f48ed09e13081616cf390aac75b10a206a98953d402647dfef7fa363be2765a303b05ec388bd9a1d75123a1205b4ecb43c33f2e37d3e30842181d694a3acfc39afc52554946e699d97d97066596a46725ce6dea322623afcafecbd2884d9a0c5eae9c4d7da8874c29c19edb762e1902030100010281800d637ea568e169f15ab6be288f6ec55edd29425c9c6dbb941b5160fa1b89cda34ef15378b5107c016d63b0f52721e71497f876dd7f3d6b1f228c4bc20c3c12384644200e91130c9195660d1e706f55b",
+    "2accf00c5e2174a1d9ee289f0e763ee58860485ec97d19d7fa2df38af5b5910b1fa52087768d288e6ec4c8d5eca23c8d3024100be757a24dc2c923692d964693b2d71ca33ccb2f946f9e5232d2090b715a97dca554068fab8876105bc9ed6dccfd0917c5e0b80339306535c3eeb787e89397bc7024100e60f5c9e52434da079b8c641791a81a96daa4d9921a07e5b48292a9fce230df7c9fc2b97b5e38834ed5caaa387a0bca35c474e989a68dd65b79a6f691a74471f0240438ccf017bc5a3260ff76291a01782204136fcd344c524ebd0f997da17a8c1a09d93f6a7d602cdfa86e79f3539cfb389f4a1079b432e1f2abc762f8a51893dc9024046604ca4e1e554c9d27283b363a888219c3a8ca25b770d303f52d8872a37eefdedfc0619d2ba57e058fc0ff71676453e73ec1c4ef26d41ccebed824754a05d6102404445374d8450e753e0a42085b56b0d6d500b3e3518536dc8f12ec8fd77aa75491835327ac0e12d73b5c3f1b09d03f6a24fe63b9c551dee6559b625435ec92429\n\nSign = RSA-Swapped\nDigest = SHA256\nInput = \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\nOutput = 07fa4e3de9c002c41c952dc292ef5a814c4c17dc1a6cf958c4c971e8089676d6661b442270ef9295c41e5385c9628aa1bdee2cc2558b8473ba212f2ba04b9ff2264c19187b9506b1d0a1cc2751844cc8dedf555d62ce81bc0e70bfe83d0184ee964593af91b9b327c0fb272c799148cd8737d412cbf36c2ad25fd66977bf805f\n\n# Though we will never generate such a key, test that RSA keys where p and q are\n# different sizes work properly.\nPrivateKey = RSA-PrimeMismatch\nType = RSA\nInput = 30820295020100300d06092a864886f70d01010105000482027f3082027b02010002818100c766f4fef89f5e9a8e13ed500fb38523ea94d7f8be066900eee58c913b4c6fdcb13d63d39b9108feabcefd1ffd04776403dc58f968ae817977d0809e567d8af512d604a0e9cb448fa5e402204ee519712a5ebbfd002faf8169495a782f54366b4665aac0d968bfec63c5446b6f9b13061c7f3d1f3f1b6bede8fff881b410a66f0203010001028180528c062f49485c771a0b18ca747d8a47f8941ea63c305626cb3f1f067e6861c4441c432687dbd08d484aac3b01f3ffdc3b762c719167f7cb22e565aa6acd597306ef6f7828b9720e9d440816186d940c4c5a9720dddf71fe0b59483f02a751515c8c27e43c575d6725d55f5bb77e0f977773b00afc058cfab6617ec90d0b62a9026100cb8f97c37b4fbc298b645bc3dc0526f8a4274e9a193b33c3acb76499b5b96330e4b586cbaa56368ffc12644952322253bc669496d572c0980f125fd7273739cf790d24401052b13732114d397c8c16a44716dc62d2320fb1ced99290dfd53e07022100fac51ac653609cdaba53280c6b6f209052e270be0c3c68fe8b37d6bf05fbba59026038dff2f04c58d7e2e7ae6fb1469d2de954bc22cb0d77ac1be4fb0ca1a1d39d7240c4b357de4cde4bd68b30f8077e38771af1b25c7e60e48cd7d1337402e1fc460ab57046720918b8aa4589452196669119c7ba65e602d4bdc264a9fdce7c5f2b0220773af0180bdc8bb7938fa6230191bcb1e236b7d4248d347e9242e25fc0c0874102605c4894cde334889f5b52ed8f86a2ee9c1fbe4166287e24ce44f3093bff383962f08043842f6ff3e6002104b0e29442c4a4483c5d06e2254fbe5e3930de3d0e28af10e96c6e341a4b8859382dbba24536a38ae71118e3e22413a93f298a7f744c\n\nSign = RSA-PrimeMismatch\nDigest = SHA256\nInput = \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\nOutput = 6192b1ce630c87d02e8245fd74d4f6ecac37eef979d188c8fa48c4d355fbe814e7dd3152f42bb020d769b540d11867af5b947387b8c99158d56901ff3708e423931178213916ae1002f162c9d497aacacdcb20e6ffe7ed40138a253fc943ddf3587433df5831a3ce46aeefce358a009bf6bad12d82d77424c2755d984d7da196\n\n\n# EC tests\n\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\n\nVerify = P-256-SPKI\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\n\n# Digest too long\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF12345\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\nError = BAD_SIGNATURE\n\n# Digest too short\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF123\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\nError = BAD_SIGNATURE\n\n# Digest invalid\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1235\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8\nError = BAD_SIGNATURE\n\n# Invalid signature\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec7\nError = BAD_SIGNATURE\n\n# Garbage after signature\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec800\nError = BAD_SIGNATURE\n\n# BER signature\nVerify = P-256\nDigest = SHA1\nInput = \"0123456789ABCDEF1234\"\nOutput = 3080022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec80000\nError = BAD_SIGNATURE\n\n\n# Additional RSA-PSS and RSA-OAEP tests converted from\n# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip\n\nPublicKey = RSA-PSS-1\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d0030818902818100a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a21370203010001\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = cd8b6538cb8e8de566b68bd067569dbf1ee2718e\nOutput = 9074308fb598e9701b2294388e52f971faac2b60a5145af185df5287b5ed2887e57ce7fd44dc8634e407c8e0e4360bc226f3ec227f9d9e54638e8d31f5051215df6ebb9c2f9579aa77598a38f914b5b9c1bd83c4e2f9f382a0d0aa3542ffee65984a601bc69eb28deb27dca12c82c2d4c3f66cd500f1ff2b994d8a4e30cbb33c\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = e35befc17a1d160b9ce35fbd8eb16e7ee491d3fd\nOutput = 3ef7f46e831bf92b32274142a585ffcefbdca7b32ae90d10fb0f0c729984f04ef29a9df0780775ce43739b97838390db0a5505e63de927028d9d29b219ca2c4517832558a55d694a6d25b9dab66003c4cccd907802193be5170d26147d37b93590241be51c25055f47ef62752cfbe21418fafe98c22c4d4d47724fdb5669e843\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 0652ec67bcee30f9d2699122b91c19abdba89f91\nOutput = 666026fba71bd3e7cf13157cc2c51a8e4aa684af9778f91849f34335d141c00154c4197621f9624a675b5abc22ee7d5baaffaae1c9baca2cc373b3f33e78e6143c395a91aa7faca664eb733afd14d8827259d99a7550faca501ef2b04e33c23aa51f4b9e8282efdb728cc0ab09405a91607c6369961bc8270d2d4f39fce612b1\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 39c21c4cceda9c1adf839c744e1212a6437575ec\nOutput = 4609793b23e9d09362dc21bb47da0b4f3a7622649a47d464019b9aeafe53359c178c91cd58ba6bcb78be0346a7bc637f4b873d4bab38ee661f199634c547a1ad8442e03da015b136e543f7ab07c0c13e4225b8de8cce25d4f6eb8400f81f7e1833b7ee6e334d370964ca79fdb872b4d75223b5eeb08101591fb532d155a6de87\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 36dae913b77bd17cae6e7b09453d24544cebb33c\nOutput = 1d2aad221ca4d31ddf13509239019398e3d14b32dc34dc5af4aeaea3c095af73479cf0a45e5629635a53a018377615b16cb9b13b3e09d671eb71e387b8545c5960da5a64776e768e82b2c93583bf104c3fdb23512b7b4e89f633dd0063a530db4524b01c3f384c09310e315a79dcd3d684022a7f31c865a664e316978b759fad\n\nVerify = RSA-PSS-1\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 45eef191f4f79c31fe5d2ede7e5098994e929d2d\nOutput = 2a34f6125e1f6b0bf971e84fbd41c632be8f2c2ace7de8b6926e31ff93e9af987fbc06e51e9be14f5198f91f3f953bd67da60a9df59764c3dc0fe08e1cbef0b75f868d10ad3fba749fef59fb6dac46a0d6e504369331586f58e4628f39aa278982543bc0eeb537dc61958019b394fb273f215858a0a01ac4d650b955c67f4c58\n\nPublicKey = RSA-PSS-2\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d0030818902818101d40c1bcf97a68ae7cdbd8a7bf3e34fa19dcca4ef75a47454375f94514d88fed006fb829f8419ff87d6315da68a1ff3a0938e9abb3464011c303ad99199cf0c7c7a8b477dce829e8844f625b115e5e9c4a59cf8f8113b6834336a2fd2689b472cbb5e5cabe674350c59b6c17e176874fb42f8fc3d176a017edc61fd326c4b33c90203010001\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 5c81a3e2a658246628cd0ee8b00bb4c012bc9739\nOutput = 014c5ba5338328ccc6e7a90bf1c0ab3fd606ff4796d3c12e4b639ed9136a5fec6c16d8884bd",
+    "d99cfdc521456b0742b736868cf90de099adb8d5ffd1deff39ba4007ab746cefdb22d7df0e225f54627dc65466131721b90af445363a8358b9f607642f78fab0ab0f43b7168d64bae70d8827848d8ef1e421c5754ddf42c2589b5b3\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 27f71611446aa6eabf037f7dedeede3203244991\nOutput = 010991656cca182b7f29d2dbc007e7ae0fec158eb6759cb9c45c5ff87c7635dd46d150882f4de1e9ae65e7f7d9018f6836954a47c0a81a8a6b6f83f2944d6081b1aa7c759b254b2c34b691da67cc0226e20b2f18b42212761dcd4b908a62b371b5918c5742af4b537e296917674fb914194761621cc19a41f6fb953fbcbb649dea\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 03ecc2c33e93f05fc7224fcc0d461356cb897217\nOutput = 007f0030018f53cdc71f23d03659fde54d4241f758a750b42f185f87578520c30742afd84359b6e6e8d3ed959dc6fe486bedc8e2cf001f63a7abe16256a1b84df0d249fc05d3194ce5f0912742dbbf80dd174f6c51f6bad7f16cf3364eba095a06267dc3793803ac7526aebe0a475d38b8c2247ab51c4898df7047dc6adf52c6c4\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 246c727b4b9494849dddb068d582e179ac20999c\nOutput = 009cd2f4edbe23e12346ae8c76dd9ad3230a62076141f16c152ba18513a48ef6f010e0e37fd3df10a1ec629a0cb5a3b5d2893007298c30936a95903b6ba85555d9ec3673a06108fd62a2fda56d1ce2e85c4db6b24a81ca3b496c36d4fd06eb7c9166d8e94877c42bea622b3bfe9251fdc21d8d5371badad78a488214796335b40b\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = e8617ca3ea66ce6a58ede2d11af8c3ba8a6ba912\nOutput = 00ec430824931ebd3baa43034dae98ba646b8c36013d1671c3cf1cf8260c374b19f8e1cc8d965012405e7e9bf7378612dfcc85fce12cda11f950bd0ba8876740436c1d2595a64a1b32efcfb74a21c873b3cc33aaf4e3dc3953de67f0674c0453b4fd9f604406d441b816098cb106fe3472bc251f815f59db2e4378a3addc181ecf\n\nVerify = RSA-PSS-2\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 7a6fdc1a4e434ecbc35d657ad49a2f4fafd43bc8\nOutput = 00475b1648f814a8dc0abdc37b5527f543b666bb6e39d30e5b49d3b876dccc58eac14e32a2d55c2616014456ad2f246fc8e3d560da3ddf379a1c0bd200f10221df078c219a151bc8d4ec9d2fc2564467811014ef15d8ea01c2ebbff8c2c8efab38096e55fcbe3285c7aa558851254faffa92c1c72b78758663ef4582843139d7a6\n\nPublicKey = RSA-PSS-3\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d0030818902818102f246ef451ed3eebb9a310200cc25859c048e4be798302991112eb68ce6db674e280da21feded1ae74880ca522b18db249385012827c515f0e466a1ffa691d98170574e9d0eadb087586ca48933da3cc953d95bd0ed50de10ddcb6736107d6c831c7f663e833ca4c097e700ce0fb945f88fb85fe8e5a773172565b914a471a4430203010001\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 3552be69dd74bdc56d2cf8c38ef7bafe269040fe\nOutput = 0088b135fb1794b6b96c4a3e678197f8cac52b64b2fe907d6f27de761124964a99a01a882740ecfaed6c01a47464bb05182313c01338a8cd097214cd68ca103bd57d3bc9e816213e61d784f182467abf8a01cf253e99a156eaa8e3e1f90e3c6e4e3aa2d83ed0345b89fafc9c26077c14b6ac51454fa26e446e3a2f153b2b16797f\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 609143ff7240e55c062aba8b9e4426a781919bc9\nOutput = 02a5f0a858a0864a4f65017a7d69454f3f973a2999839b7bbc48bf78641169179556f595fa41f6ff18e286c2783079bc0910ee9cc34f49ba681124f923dfa88f426141a368a5f5a930c628c2c3c200e18a7644721a0cbec6dd3f6279bde3e8f2be5e2d4ee56f97e7ceaf33054be7042bd91a63bb09f897bd41e81197dee99b11af\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 0afd22f879a9cda7c584f4135f8f1c961db114c0\nOutput = 0244bcd1c8c16955736c803be401272e18cb990811b14f72db964124d5fa760649cbb57afb8755dbb62bf51f466cf23a0a1607576e983d778fceffa92df7548aea8ea4ecad2c29dd9f95bc07fe91ecf8bee255bfe8762fd7690aa9bfa4fa0849ef728c2c42c4532364522df2ab7f9f8a03b63f7a499175828668f5ef5a29e3802c\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 405dd56d395ef0f01b555c48f748cc32b210650b\nOutput = 0196f12a005b98129c8df13c4cb16f8aa887d3c40d96df3a88e7532ef39cd992f273abc370bc1be6f097cfebbf0118fd9ef4b927155f3df22b904d90702d1f7ba7a52bed8b8942f412cd7bd676c9d18e170391dcd345c06a730964b3f30bcce0bb20ba106f9ab0eeb39cf8a6607f75c0347f0af79f16afa081d2c92d1ee6f836b8\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = a2c313b0440c8a0c47233b87f0a160c61af3eae7\nOutput = 021eca3ab4892264ec22411a752d92221076d4e01c0e6f0dde9afd26ba5acf6d739ef987545d16683e5674c9e70f1de649d7e61d48d0caeb4fb4d8b24fba84a6e3108fee7d0705973266ac524b4ad280f7ae17dc59d96d3351586b5a3bdb895d1e1f7820ac6135d8753480998382ba32b7349559608c38745290a85ef4e9f9bd83\n\nVerify = RSA-PSS-3\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = f1bf6ca7b4bbdbb6bf20a4bf55728725d177154a\nOutput = 012fafec862f56e9e92f60ab0c77824f4299a0ca734ed26e0644d5d222c7f0bde03964f8e70a5cb65ed44e44d56ae0edf1ff86ca032cc5dd4404dbb76ab854586c44eed8336d08d457ce6c03693b45c0f1efef93624b95b8ec169c616d20e5538ebc0b6737a6f82b4bc0570924fc6b35759a3348426279f8b3d7744e2d222426ce\n\nPublicKey = RSA-PSS-4\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d00308189028181054adb7886447efe6f57e0368f06cf52b0a3370760d161cef126b91be7f89c421b62a6ec1da3c311d75ed50e0ab5fff3fd338acc3aa8a4e77ee26369acb81ba900fa83f5300cf9bb6c53ad1dc8a178b815db4235a9a9da0c06de4e615ea1277ce559e9c108de58c14a81aa77f5a6f8d1335494498848c8b95940740be7bf7c37050203010001\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = f8b0abf70fec0bca74f0accbc24f75e6e90d3bfd\nOutput = 0323d5b7bf20ba4539289ae452ae4297080feff4518423ff4811a817837e7d82f1836cdfab54514ff0887bddeebf40bf99b047abc3ecfa6a37a3ef00f4a0c4a88aae0904b745c846c4107e8797723e8ac810d9e3d95dfa30ff4966f4d75d13768d20857f2b1406f264cfe75e27d7652f4b5ed3575f28a702f8c4ed9cf9b2d44948\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 04a10944bfe11ab801e77889f3fd3d7f4ff0b629\nOutput = 049d0185845a264d28feb1e69edaec090609e8e46d93abb38371ce51f4aa65a599bdaaa81d24fba66a08a116cb644f3f1e653d95c89db8bbd5daac2709c8984000178410a7c6aa8667ddc38c741f710ec8665aa9052be929d4e3b16782c1662114c5414bb0353455c392fc28f3db59054b5f365c49e1d156f876ee10cb4fd70598\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = ba01243db223eb97fb86d746c3148adaaa0ca344\nOutput = 03fbc410a2ced59500fb99f9e2af2781ada74e13145624602782e2994813eefca0519ecd253b855fb626a90d771eae028b0c47a199cbd9f8e3269734af4163599090713a3fa910fa0960652721432b971036a7181a2bc0cab43b0b598bc6217461d7db305ff7e954c5b5bb231c39e791af6bcfa76b147b081321f72641482a2aad\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 934bb0d38d6836daec9de82a9648d4593da67cd2\nOutput = 0486644bc66bf75d28335a6179b10851f43f09bded9fac1af33252bb9953ba4298cd6466b27539a70adaa3f89b3db3c74ab635d122f4ee7ce557a61e59b82ffb786630e5f9db53c77d9a0c12fab5958d4c2ce7daa807cd89ba2cc7fcd02ff470ca67b229fcce814c852c73cc93bea35be68459ce478e9d4655d121c8472f371d4f\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = ec35d81abd1cceac425a935758b683465c8bd879\nOutput = 022a80045353904cb30cbb542d7d4990421a6eec16a8029a8422adfd22d6aff8c4cc0294af110a0c067ec86a7d364134459bb1ae8ff836d5a8a2579840996b320b19f13a13fad378d931a65625dae2739f0c53670b35d9d3cbac08e733e4ec2b83af4b9196d63e7c4ff1ddeae2a122791a125bfea8deb0de8ccf1f4ffaf6e6fb0a\n\nVerify = RSA-PSS-4\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 72ce251d17b04dd3970d6ff1fbe3624899e9e941\nOutput = 00938dcb6d583046065f69c78da7a1f1757066a7fa75125a9d2929f0b79a60b627b082f11f5b196f28eb9daa6f21c05e5140f6aef1737d2023075c05ecf04a028c686a2ab3e7d5a0664f295ce12995e890908b6ad21f0839eb65b70393a7b5afd9871de0caa0cedec5b819626756209d13ab1e7bb9546a26ff37e9a51af9fd562e\n\nPublicKey = RSA-PSS-5\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d003081890281810d10f661f29940f5ed39aa260966deb47843679d2b6fb25b3de370f3ac7c19916391fd25fb527ebfa6a4b4df45a1759d996c4bb4ebd18828c44fc52d0191871740525f47a4b0cc8da325ed8aa676b0d0f626e0a77f07692170acac8082f42faa7dc7cd123e730e31a87985204cabcbe6670d43a2dd2b2ddef5e05392fc213bc5070203010001\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = d98b7061943510bc3dd9162f7169aabdbdcd0222\nOutput = 0ba373f76e0921b70a8fbfe622f0bf77b28a3db98e361051c3d7cb92ad0452915a4de9c01722f6823eeb6adf7e0ca8290f5de3e549890ac2a3c5950ab217ba58590894952de96f8df111b2575215da6c161590c745be612476ee578ed384ab33e3ece97481a252f5c79a98b5532ae00cdd62f2ecc0cd1baefe80d80b962193ec1d\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 7ae8e699f754988f4fd645e463302e49a2552072\nOutput = 08180de825e4b8b014a32da8ba761555921204f2f90d5f24b712908ff84f3e220ad17997c0dd6e706630ba3e84add4d5e7",
+    "ab004e58074b549709565d43ad9e97b5a7a1a29e85b9f90f4aafcdf58321de8c5974ef9abf2d526f33c0f2f82e95d158ea6b81f1736db8d1af3d6ac6a83b32d18bae0ff1b2fe27de4c76ed8c7980a34e\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 8d46c7c05534c1ba2cc7624500d48a4531604bff\nOutput = 05e0fdbdf6f756ef733185ccfa8ced2eb6d029d9d56e35561b5db8e70257ee6fd019d2f0bbf669fe9b9821e78df6d41e31608d58280f318ee34f559941c8df13287574bac000b7e58dc4f414ba49fb127f9d0f8936638c76e85356c994f79750f7fa3cf4fd482df75e3fb9978cd061f7abb17572e6e63e0bde12cbdcf18c68b979\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = ee3de96783fd0a157c8b20bf5566124124dcfe65\nOutput = 0bc989853bc2ea86873271ce183a923ab65e8a53100e6df5d87a24c4194eb797813ee2a187c097dd872d591da60c568605dd7e742d5af4e33b11678ccb63903204a3d080b0902c89aba8868f009c0f1c0cb85810bbdd29121abb8471ff2d39e49fd92d56c655c8e037ad18fafbdc92c95863f7f61ea9efa28fea401369d19daea1\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 1204df0b03c2724e2709c23fc71789a21b00ae4c\nOutput = 0aefa943b698b9609edf898ad22744ac28dc239497cea369cbbd84f65c95c0ad776b594740164b59a739c6ff7c2f07c7c077a86d95238fe51e1fcf33574a4ae0684b42a3f6bf677d91820ca89874467b2c23add77969c80717430d0efc1d3695892ce855cb7f7011630f4df26def8ddf36fc23905f57fa6243a485c770d5681fcd\n\nVerify = RSA-PSS-5\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 29926bc3280c841f601acd0d6f17ea38023eddbc\nOutput = 02802dccfa8dfaf5279bf0b4a29ba1b157611faeaaf419b8919d15941900c1339e7e92e6fae562c53e6cc8e84104b110bce03ad18525e3c49a0eadad5d3f28f244a8ed89edbafbb686277cfa8ae909714d6b28f4bf8e293aa04c41efe7c0a81266d5c061e2575be032aa464674ff71626219bd74cc45f0e7ed4e3ff96eee758e8f\n\nPublicKey = RSA-PSS-6\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d00308189028181164ca31cff609f3a0e7101b039f2e4fe6dd37519ab98598d179e174996598071f47d3a04559158d7be373cf1aa53f0aa6ef09039e5678c2a4c63900514c8c4f8aaed5de12a5f10b09c311af8c0ffb5b7a297f2efc63b8d6b0510931f0b98e48bf5fc6ec4e7b8db1ffaeb08c38e02adb8f03a48229c99e969431f61cb8c4dc698d10203010001\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = ab464e8cb65ae5fdea47a53fa84b234d6bfd52f6\nOutput = 04c0cfacec04e5badbece159a5a1103f69b3f32ba593cb4cc4b1b7ab455916a96a27cd2678ea0f46ba37f7fc9c86325f29733b389f1d97f43e7201c0f348fc45fe42892335362eee018b5b161f2f9393031225c713012a576bc88e23052489868d9010cbf033ecc568e8bc152bdc59d560e41291915d28565208e22aeec9ef85d1\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 92d0bcae82b641f578f040f5151be8eda6d42299\nOutput = 0a2314250cf52b6e4e908de5b35646bcaa24361da8160fb0f9257590ab3ace42b0dc3e77ad2db7c203a20bd952fbb56b1567046ecfaa933d7b1000c3de9ff05b7d989ba46fd43bc4c2d0a3986b7ffa13471d37eb5b47d64707bd290cfd6a9f393ad08ec1e3bd71bb5792615035cdaf2d8929aed3be098379377e777ce79aaa4773\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 3569bd8fd2e28f2443375efa94f186f6911ffc2b\nOutput = 086df6b500098c120f24ff8423f727d9c61a5c9007d3b6a31ce7cf8f3cbec1a26bb20e2bd4a046793299e03e37a21b40194fb045f90b18bf20a47992ccd799cf9c059c299c0526854954aade8a6ad9d97ec91a1145383f42468b231f4d72f23706d9853c3fa43ce8ace8bfe7484987a1ec6a16c8daf81f7c8bf42774707a9df456\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 7abbb7b42de335730a0b641f1e314b6950b84f98\nOutput = 0b5b11ad549863ffa9c51a14a1106c2a72cc8b646e5c7262509786105a984776534ca9b54c1cc64bf2d5a44fd7e8a69db699d5ea52087a4748fd2abc1afed1e5d6f7c89025530bdaa2213d7e030fa55df6f34bcf1ce46d2edf4e3ae4f3b01891a068c9e3a44bbc43133edad6ecb9f35400c4252a5762d65744b99cb9f4c559329f\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 55b7eb27be7a787a59eb7e5fac468db8917a7725\nOutput = 02d71fa9b53e4654fefb7f08385cf6b0ae3a817942ebf66c35ac67f0b069952a3ce9c7e1f1b02e480a9500836de5d64cdb7ecde04542f7a79988787e24c2ba05f5fd482c023ed5c30e04839dc44bed2a3a3a4fee01113c891a47d32eb8025c28cb050b5cdb576c70fe76ef523405c08417faf350b037a43c379339fcb18d3a356b\n\nVerify = RSA-PSS-6\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = de2fa0367ef49083ff89b9905d3fd646fcc12c38\nOutput = 0a40a16e2fe2b38d1df90546167cf9469c9e3c3681a3442b4b2c2f581deb385ce99fc6188bb02a841d56e76d301891e24560550fcc2a26b55f4ccb26d837d350a154bcaca8392d98fa67959e9727b78cad03269f56968fc56b68bd679926d83cc9cb215550645ccda31c760ff35888943d2d8a1d351e81e5d07b86182e751081ef\n\nPublicKey = RSA-PSS-7\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d0030818902818137c9da4a66c8c408b8da27d0c9d79f8ccb1eafc1d2fe48746d940b7c4ef5dee18ad12647cefaa0c4b3188b221c515386759b93f02024b25ab9242f8357d8f3fd49640ee5e643eaf6c64deefa7089727c8ff03993333915c6ef21bf5975b6e50d118b51008ec33e9f01a0a545a10a836a43ddbca9d8b5c5d3548022d7064ea29ab30203010001\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 8be4afbdd76bd8d142c5f4f46dba771ee5d6d29d\nOutput = 187f390723c8902591f0154bae6d4ecbffe067f0e8b795476ea4f4d51ccc810520bb3ca9bca7d0b1f2ea8a17d873fa27570acd642e3808561cb9e975ccfd80b23dc5771cdb3306a5f23159dacbd3aa2db93d46d766e09ed15d900ad897a8d274dc26b47e994a27e97e2268a766533ae4b5e42a2fcaf755c1c4794b294c60555823\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 402140dc605b2f5c5ec0d15bce9f9ba8857fe117\nOutput = 10fd89768a60a67788abb5856a787c8561f3edcf9a83e898f7dc87ab8cce79429b43e56906941a886194f137e591fe7c339555361fbbe1f24feb2d4bcdb80601f3096bc9132deea60ae13082f44f9ad41cd628936a4d51176e42fc59cb76db815ce5ab4db99a104aafea68f5d330329ebf258d4ede16064bd1d00393d5e1570eb8\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 3e885205892ff2b6b37c2c4eb486c4bf2f9e7f20\nOutput = 2b31fde99859b977aa09586d8e274662b25a2a640640b457f594051cb1e7f7a911865455242926cf88fe80dfa3a75ba9689844a11e634a82b075afbd69c12a0df9d25f84ad4945df3dc8fe90c3cefdf26e95f0534304b5bdba20d3e5640a2ebfb898aac35ae40f26fce5563c2f9f24f3042af76f3c7072d687bbfb959a88460af1\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 1fc2201d0c442a4736cd8b2cd00c959c47a3bf42\nOutput = 32c7ca38ff26949a15000c4ba04b2b13b35a3810e568184d7ecabaa166b7ffabddf2b6cf4ba07124923790f2e5b1a5be040aea36fe132ec130e1f10567982d17ac3e89b8d26c3094034e762d2e031264f01170beecb3d1439e05846f25458367a7d9c02060444672671e64e877864559ca19b2074d588a281b5804d23772fbbe19\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = e4351b66819e5a31501f89acc7faf57030e9aac5\nOutput = 07eb651d75f1b52bc263b2e198336e99fbebc4f332049a922a10815607ee2d989db3a4495b7dccd38f58a211fb7e193171a3d891132437ebca44f318b280509e52b5fa98fcce8205d9697c8ee4b7ff59d4c59c79038a1970bd2a0d451ecdc5ef11d9979c9d35f8c70a6163717607890d586a7c6dc01c79f86a8f28e85235f8c2f1\n\nVerify = RSA-PSS-7\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 49f6cc58365e514e1a3f301f4de16f9fb5347ff2\nOutput = 18da3cdcfe79bfb77fd9c32f377ad399146f0a8e810620233271a6e3ed3248903f5cdc92dc79b55d3e11615aa056a795853792a3998c349ca5c457e8ca7d29d796aa24f83491709befcfb1510ea513c92829a3f00b104f655634f320752e130ec0ccf6754ff893db302932bb025eb60e87822598fc619e0e981737a9a4c4152d33\n\nPublicKey = RSA-PSS-8\nType = RSA\nInput = 30819f300d06092a864886f70d010101050003818d00308189028181495370a1fb18543c16d3631e3163255df62be6eee890d5f25509e4f778a8ea6fbbbcdf85dff64e0d972003ab3681fbba6dd41fd541829b2e582de9f2a4a4e0a2d0900bef4753db3cee0ee06c7dfae8b1d53b5953218f9cceea695b08668edeaadced9463b1d790d5ebf27e9115b46cad4d9a2b8efab0561b0810344739ada0733f0203010001\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = a1dd230d8ead860199b6277c2ecfe3d95f6d9160\nOutput = 0262ac254bfa77f3c1aca22c5179f8f040422b3c5bafd40a8f21cf0fa5a667ccd5993d42dbafb409c520e25fce2b1ee1e716577f1efa17f3da28052f40f0419b23106d7845aaf01125b698e7a4dfe92d3967bb00c4d0d35ba3552ab9a8b3eef07c7fecdbc5424ac4db1e20cb37d0b2744769940ea907e17fbbca673b20522380c5\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = f6e68e53c602c5c65fa67b5aa6d786e5524b12ab\nOutput = 2707b9ad5115c58c94e932e8ec0a280f56339e44a1b58d4ddcff2f312e5f34dcfe39e89c6a94dcee86dbbdae5b79ba4e0819a9e7bfd9d982e7ee6c86ee68396e8b3a14c9c8f34b178eb741f9d3f121109bf5c8172fada2e768f9ea1433032c004a8aa07eb990000a48dc94c8bac8aabe2b09b1aa46c0a2aa0e12f63fbba775ba7e\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = d6f9fcd3ae27f32bb2c7c93536782eba52af1f76\nOutput = 2ad20509d78cf26d1b6c406146086e4b0c91a91c2bd164c87b966b8faa42aa0ca446022323ba4b1a1b89706d7f4c3be57d7b69702d168ab5955ee2903",
+    "56b8c4a29ed467d547ec23cbadf286ccb5863c6679da467fc9324a151c7ec55aac6db4084f82726825cfe1aa421bc64049fb42f23148f9c25b2dc300437c38d428aa75f96\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 7ff2a53ce2e2d900d468e498f230a5f5dd0020de\nOutput = 1e24e6e58628e5175044a9eb6d837d48af1260b0520e87327de7897ee4d5b9f0df0be3e09ed4dea8c1454ff3423bb08e1793245a9df8bf6ab3968c8eddc3b5328571c77f091cc578576912dfebd164b9de5454fe0be1c1f6385b328360ce67ec7a05f6e30eb45c17c48ac70041d2cab67f0a2ae7aafdcc8d245ea3442a6300ccc7\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 4eb309f7022ba0b03bb78601b12931ec7c1be8d3\nOutput = 33341ba3576a130a50e2a5cf8679224388d5693f5accc235ac95add68e5eb1eec31666d0ca7a1cda6f70a1aa762c05752a51950cdb8af3c5379f18cfe6b5bc55a4648226a15e912ef19ad77adeea911d67cfefd69ba43fa4119135ff642117ba985a7e0100325e9519f1ca6a9216bda055b5785015291125e90dcd07a2ca9673ee\n\nVerify = RSA-PSS-8\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 65033bc2f67d6aba7d526acb873b8d9241e5e4d9\nOutput = 1ed1d848fb1edb44129bd9b354795af97a069a7a00d0151048593e0c72c3517ff9ff2a41d0cb5a0ac860d736a199704f7cb6a53986a88bbd8abcc0076a2ce847880031525d449da2ac78356374c536e343faa7cba42a5aaa6506087791c06a8e989335aed19bfab2d5e67e27fb0c2875af896c21b6e8e7309d04e4f6727e69463e\n\nPublicKey = RSA-PSS-9\nType = RSA\nInput = 3081df300d06092a864886f70d01010105000381cd003081c90281c100e6bd692ac96645790403fdd0f5beb8b9bf92ed10007fc365046419dd06c05c5b5b2f48ecf989e4ce269109979cbb40b4a0ad24d22483d1ee315ad4ccb1534268352691c524f6dd8e6c29d224cf246973aec86c5bf6b1401a850d1b9ad1bb8cbcec47b06f0f8c7f45d3fc8f319299c5433ddbc2b3053b47ded2ecd4a4caefd614833dc8bb622f317ed076b8057fe8de3f84480ad5e83e4a61904a4f248fb397027357e1d30e463139815c6fd4fd5ac5b8172a45230ecb6318a04f1455d84e5a8b0203010001\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 2715a49b8b0012cd7aee84c116446e6dfe3faec0\nOutput = 586107226c3ce013a7c8f04d1a6a2959bb4b8e205ba43a27b50f124111bc35ef589b039f5932187cb696d7d9a32c0c38300a5cdda4834b62d2eb240af33f79d13dfbf095bf599e0d9686948c1964747b67e89c9aba5cd85016236f566cc5802cb13ead51bc7ca6bef3b94dcbdbb1d570469771df0e00b1a8a06777472d2316279edae86474668d4e1efff95f1de61c6020da32ae92bbf16520fef3cf4d88f61121f24bbd9fe91b59caf1235b2a93ff81fc403addf4ebdea84934a9cdaf8e1a9e\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 2dac956d53964748ac364d06595827c6b4f143cd\nOutput = 80b6d643255209f0a456763897ac9ed259d459b49c2887e5882ecb4434cfd66dd7e1699375381e51cd7f554f2c271704b399d42b4be2540a0eca61951f55267f7c2878c122842dadb28b01bd5f8c025f7e228418a673c03d6bc0c736d0a29546bd67f786d9d692ccea778d71d98c2063b7a71092187a4d35af108111d83e83eae46c46aa34277e06044589903788f1d5e7cee25fb485e92949118814d6f2c3ee361489016f327fb5bc517eb50470bffa1afa5f4ce9aa0ce5b8ee19bf5501b958\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 28d98c46cccafbd3bc04e72f967a54bd3ea12298\nOutput = 484408f3898cd5f53483f80819efbf2708c34d27a8b2a6fae8b322f9240237f981817aca1846f1084daa6d7c0795f6e5bf1af59c38e1858437ce1f7ec419b98c8736adf6dd9a00b1806d2bd3ad0a73775e05f52dfef3a59ab4b08143f0df05cd1ad9d04bececa6daa4a2129803e200cbc77787caf4c1d0663a6c5987b605952019782caf2ec1426d68fb94ed1d4be816a7ed081b77e6ab330b3ffc073820fecde3727fcbe295ee61a050a343658637c3fd659cfb63736de32d9f90d3c2f63eca\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 0866d2ff5a79f25ef668cd6f31b42dee421e4c0e\nOutput = 84ebeb481be59845b46468bafb471c0112e02b235d84b5d911cbd1926ee5074ae0424495cb20e82308b8ebb65f419a03fb40e72b78981d88aad143053685172c97b29c8b7bf0ae73b5b2263c403da0ed2f80ff7450af7828eb8b86f0028bd2a8b176a4d228cccea18394f238b09ff758cc00bc04301152355742f282b54e663a919e709d8da24ade5500a7b9aa50226e0ca52923e6c2d860ec50ff480fa57477e82b0565f4379f79c772d5c2da80af9fbf325ece6fc20b00961614bee89a183e\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 6a5b4be4cd36cc97dfde9995efbf8f097a4a991a\nOutput = 82102df8cb91e7179919a04d26d335d64fbc2f872c44833943241de8454810274cdf3db5f42d423db152af7135f701420e39b494a67cbfd19f9119da233a23da5c6439b5ba0d2bc373eee3507001378d4a4073856b7fe2aba0b5ee93b27f4afec7d4d120921c83f606765b02c19e4d6a1a3b95fa4c422951be4f52131077ef17179729cddfbdb56950dbaceefe78cb16640a099ea56d24389eef10f8fecb31ba3ea3b227c0a86698bb89e3e9363905bf22777b2a3aa521b65b4cef76d83bde4c\n\nVerify = RSA-PSS-9\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = b9dfd1df76a461c51e6576c6c8ed0a923d1c50e7\nOutput = a7fdb0d259165ca2c88d00bbf1028a867d337699d061193b17a9648e14ccbbaadeacaacdec815e7571294ebb8a117af205fa078b47b0712c199e3ad05135c504c24b81705115740802487992ffd511d4afc6b854491eb3f0dd523139542ff15c3101ee85543517c6a3c79417c67e2dd9aa741e9a29b06dcb593c2336b3670ae3afbac7c3e76e215473e866e338ca244de00b62624d6b9426822ceae9f8cc460895f41250073fd45c5a1e7b425c204a423a699159f6903e710b37a7bb2bc8049f\n\nPublicKey = RSA-PSS-10\nType = RSA\nInput = 30820122300d06092a864886f70d01010105000382010f003082010a0282010100a5dd867ac4cb02f90b9457d48c14a770ef991c56c39c0ec65fd11afa8937cea57b9be7ac73b45c0017615b82d622e318753b6027c0fd157be12f8090fee2a7adcd0eef759f88ba4997c7a42d58c9aa12cb99ae001fe521c13bb5431445a8d5ae4f5e4c7e948ac227d3604071f20e577e905fbeb15dfaf06d1de5ae6253d63a6a2120b31a5da5dabc9550600e20f27d3739e2627925fea3cc509f21dff04e6eea4549c540d6809ff9307eede91fff58733d8385a237d6d3705a33e391900992070df7adf1357cf7e3700ce3667de83f17b8df1778db381dce09cb4ad058a511001a738198ee27cf55a13b754539906582ec8b174bd58d5d1f3d767c613721ae050203010001\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 9596bb630cf6a8d4ea4600422b9eba8b13675dd4\nOutput = 82c2b160093b8aa3c0f7522b19f87354066c77847abf2a9fce542d0e84e920c5afb49ffdfdace16560ee94a1369601148ebad7a0e151cf16331791a5727d05f21e74e7eb811440206935d744765a15e79f015cb66c532c87a6a05961c8bfad741a9a6657022894393e7223739796c02a77455d0f555b0ec01ddf259b6207fd0fd57614cef1a5573baaff4ec00069951659b85f24300a25160ca8522dc6e6727e57d019d7e63629b8fe5e89e25cc15beb3a647577559299280b9b28f79b0409000be25bbd96408ba3b43cc486184dd1c8e62553fa1af4040f60663de7f5e49c04388e257f1ce89c95dab48a315d9b66b1b7628233876ff2385230d070d07e1666\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = b503319399277fd6c1c8f1033cbf04199ea21716\nOutput = 14ae35d9dd06ba92f7f3b897978aed7cd4bf5ff0b585a40bd46ce1b42cd2703053bb9044d64e813d8f96db2dd7007d10118f6f8f8496097ad75e1ff692341b2892ad55a633a1c55e7f0a0ad59a0e203a5b8278aec54dd8622e2831d87174f8caff43ee6c46445345d84a59659bfb92ecd4c818668695f34706f66828a89959637f2bf3e3251c24bdba4d4b7649da0022218b119c84e79a6527ec5b8a5f861c159952e23ec05e1e717346faefe8b1686825bd2b262fb2531066c0de09acde2e4231690728b5d85e115a2f6b92b79c25abc9bd9399ff8bcf825a52ea1f56ea76dd26f43baafa18bfa92a504cbd35699e26d1dcc5a2887385f3c63232f06f3244c3\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 50aaede8536b2c307208b275a67ae2df196c7628\nOutput = 6e3e4d7b6b15d2fb46013b8900aa5bbb3939cf2c095717987042026ee62c74c54cffd5d7d57efbbf950a0f5c574fa09d3fc1c9f513b05b4ff50dd8df7edfa20102854c35e592180119a70ce5b085182aa02d9ea2aa90d1df03f2daae885ba2f5d05afdac97476f06b93b5bc94a1a80aa9116c4d615f333b098892b25fface266f5db5a5a3bcc10a824ed55aad35b727834fb8c07da28fcf416a5d9b2224f1f8b442b36f91e456fdea2d7cfe3367268de0307a4c74e924159ed33393d5e0655531c77327b89821bdedf880161c78cd4196b5419f7acc3f13e5ebf161b6e7c6724716ca33b85c2e25640192ac2859651d50bde7eb976e51cec828b98b6563b86bb\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = aa0b72b8b371ddd10c8ae474425ccccf8842a294\nOutput = 34047ff96c4dc0dc90b2d4ff59a1a361a4754b255d2ee0af7d8bf87c9bc9e7ddeede33934c63ca1c0e3d262cb145ef932a1f2c0a997aa6a34f8eaee7477d82ccf09095a6b8acad38d4eec9fb7eab7ad02da1d11d8e54c1825e55bf58c2a23234b902be124f9e9038a8f68fa45dab72f66e0945bf1d8bacc9044c6f07098c9fcec58a3aab100c805178155f030a124c450e5acbda47d0e4f10b80a23f803e774d023b0015c20b9f9bbe7c91296338d5ecb471cafb032007b67a60be5f69504a9f01abb3cb467b260e2bce860be8d95bf92c0c8e1496ed1e528593a4abb6df462dde8a0968dffe4683116857a232f5ebf6c85be238745ad0f38f767a5fdbf486fb\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = fad3902c9750622a2bc672622c48270cc57d3ea8\nOutput = 7e0935ea18f4d6c1d17ce82eb2b3836c55b384589ce19dfe743363ac9948d1f346b7bfddfe92efd78adb21faefc89ade42b10f374003fe122e67429a1cb8cbd1f8d9014564c44d120116f4990f1a6e38774c194bd1b8213286b077b0499d2e7b3f434ab12",
+    "289c556684deed78131934bb3dd6537236f7c6f3dcb09d476be07721e37e1ceed9b2f7b406887bd53157305e1c8b4f84d733bc1e186fe06cc59b6edb8f4bd7ffefdf4f7ba9cfb9d570689b5a1a4109a746a690893db3799255a0cb9215d2d1cd490590e952e8c8786aa0011265252470c041dfbc3eec7c3cbf71c24869d115c0cb4a956f56d530b80ab589acfefc690751ddf36e8d383f83cedd2cc\n\nVerify = RSA-PSS-10\nRSAPadding = PSS\nMGF1Digest = SHA1\nInput = 122196deb5d122bd8c6fc781ff6924d7c695aade\nOutput = 6d3b5b87f67ea657af21f75441977d2180f91b2c5f692de82955696a686730d9b9778d970758ccb26071c2209ffbd6125be2e96ea81b67cb9b9308239fda17f7b2b64ecda096b6b935640a5a1cb42a9155b1c9ef7a633a02c59f0d6ee59b852c43b35029e73c940ff0410e8f114eed46bbd0fae165e42be2528a401c3b28fd818ef3232dca9f4d2a0f5166ec59c42396d6c11dbc1215a56fa17169db9575343ef34f9de32a49cdc3174922f229c23e18e45df9353119ec4319cedce7a17c64088c1f6f52be29634100b3919d38f3d1ed94e6891e66a73b8fb849f5874df59459e298c7bbce2eee782a195aa66fe2d0732b25e595f57d3e061b1fc3e4063bf98f\n\nPrivateKey = RSA-OAEP-1\nType = RSA\nInput = 30820276020100300d06092a864886f70d0101010500048202603082025c02010002818100a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb020301000102818053339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1024100d32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c2f26a471dcad212eac7ca39d024100cc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb33d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af72bfe9a030e860b0288b5d7702400e12bf1718e9cef5599ba1c3882fe8046a90874eefce8f2ccc20e4f2741fb0a33a3848aec9c9305fbecbd2d76819967d4671acc6431e4037968db37878e695c102410095297b0f95a2fa67d00707d609dfd4fc05c89dafc2ef6d6ea55bec771ea333734d9251e79082ecda866efef13c459e1a631386b7e354c899f5f112ca85d7158302404f456c502493bdc0ed2ab756a3a6ed4d67352a697d4216e93212b127a63d5411ce6fa98d5dbefd73263e3728142743818166ed7dd63687dd2a8ca1d2f4fbd8e1\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 354fe67b4a126d5d35fe36c777791a3f7ba13def484e2d3908aff722fad468fb21696de95d0be911c2d3174f8afcc201035f7b6d8e69402de5451618c21a535fa9d7bfc5b8dd9fc243f8cf927db31322d6e881eaa91a996170e657a05a266426d98c88003f8477c1227094a0d9fa1e8c4024309ce1ecccb5210035d47ac72e8a\nOutput = 6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 640db1acc58e0568fe5407e5f9b701dff8c3c91e716c536fc7fcec6cb5b71c1165988d4a279e1577d730fc7a29932e3f00c81515236d8d8e31017a7a09df4352d904cdeb79aa583adcc31ea698a4c05283daba9089be5491f67c1a4ee48dc74bbbe6643aef846679b4cb395a352d5ed115912df696ffe0702932946d71492b44\nOutput = 750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 423736ed035f6026af276c35c0b3741b365e5f76ca091b4e8c29e2f0befee603595aa8322d602d2e625e95eb81b2f1c9724e822eca76db8618cf09c5343503a4360835b5903bc637e3879fb05e0ef32685d5aec5067cd7cc96fe4b2670b6eac3066b1fcf5686b68589aafb7d629b02d8f8625ca3833624d4800fb081b1cf94eb\nOutput = d94ae0832e6445ce42331cb06d531a82b1db4baad30f746dc916df24d4e3c2451fff59a6423eb0e1d02d4fe646cf699dfd818c6e97b051\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 45ead4ca551e662c9800f1aca8283b0525e6abae30be4b4aba762fa40fd3d38e22abefc69794f6ebbbc05ddbb11216247d2f412fd0fba87c6e3acd888813646fd0e48e785204f9c3f73d6d8239562722dddd8771fec48b83a31ee6f592c4cfd4bc88174f3b13a112aae3b9f7b80e0fc6f7255ba880dc7d8021e22ad6a85f0755\nOutput = 52e650d98e7f2a048b4f86852153b97e01dd316f346a19f67a85\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 36f6e34d94a8d34daacba33a2139d00ad85a9345a86051e73071620056b920e219005855a213a0f23897cdcd731b45257c777fe908202befdd0b58386b1244ea0cf539a05d5d10329da44e13030fd760dcd644cfef2094d1910d3f433e1c7c6dd18bc1f2df7f643d662fb9dd37ead9059190f4fa66ca39e869c4eb449cbdc439\nOutput = 8da89fd9e5f974a29feffb462b49180f6cf9e802\n\nDecrypt = RSA-OAEP-1\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 42cee2617b1ecea4db3f4829386fbd61dafbf038e180d837c96366df24c097b4ab0fac6bdf590d821c9f10642e681ad05b8d78b378c0f46ce2fad63f74e0ad3df06b075d7eb5f5636f8d403b9059ca761b5c62bb52aa45002ea70baace08ded243b9d8cbd62a68ade265832b56564e43a6fa42ed199a099769742df1539e8255\nOutput = 26521050844271\n\nPrivateKey = RSA-OAEP-2\nType = RSA\nInput = 30820276020100300d06092a864886f70d0101010500048202603082025c02010002818101947c7fce90425f47279e70851f25d5e62316fe8a1df19371e3e628e260543e4901ef6081f68c0b8141190d2ae8daba7d1250ec6db636e944ec3722877c7c1d0a67f14b1694c5f0379451a43e49a32dde83670b73da91a1c99bc23b436a60055c610f0baf99c1a079565b95a3f1526632d1d4da60f20eda25e653c4f002766f4502030100010281800823f20fadb5da89088a9d00893e21fa4a1b11fbc93c64a3be0baaea97fb3b93c3ff713704c19c963c1d107aae99054739f79e02e186de86f87a6ddefea6d8ccd1d3c81a47bfa7255be20601a4a4b2f08a167b5e279d715b1b455bdd7eab245941d9768b9acefb3ccda5952da3cee72525b4501663a8ee15c9e992d92462fe3902410159dbde04a33ef06fb608b80b190f4d3e22bcc13ac8e4a081033abfa416edb0b338aa08b57309ea5a5240e7dc6e54378c69414c31d97ddb1f406db3769cc41a430241012b652f30403b38b40995fd6ff41a1acc8ada70373236b7202d39b2ee30cfb46db09511f6f307cc61cc21606c18a75b8a62f822df031ba0df0dafd5506f568bd70240436ef508de736519c2da4c580d98c82cb7452a3fb5efadc3b9c7789a1bc6584f795addbbd32439c74686552ecb6c2c307a4d3af7f539eec157248c7b31f1a2550241012b15a89f3dfb2b39073e73f02bdd0c1a7b379dd435f05cdde2eff9e462948b7cec62ee9050d5e0816e0785a856b49108dcb75f3683874d1ca6329a19013066ff02400270db17d5914b018d76118b24389a7350ec836b0063a21721236fd8edb6d89b51e7eeb87b611b7132cb7ea7356c23151c1e7751507c786d9ee1794170a8c8e8\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0181af8922b9fcb4d79d92ebe19815992fc0c1439d8bcd491398a0f4ad3a329a5bd9385560db532683c8b7da04e4b12aed6aacdf471c34c9cda891addcc2df3456653aa6382e9ae59b54455257eb099d562bbe10453f2b6d13c59c02e10f1f8abb5da0d0570932dacf2d0901db729d0fefcc054e70968ea540c81b04bcaefe720e\nOutput = 8ff00caa605c702830634d9a6c3d42c652b58cf1d92fec570beee7\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 018759ff1df63b2792410562314416a8aeaf2ac634b46f940ab82d64dbf165eee33011da749d4bab6e2fcd18129c9e49277d8453112b429a222a8471b070993998e758861c4d3f6d749d91c4290d332c7a4ab3f7ea35ff3a07d497c955ff0ffc95006b62c6d296810d9bfab024196c7934012c2df978ef299aba239940cba10245\nOutput = 2d\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 018802bab04c60325e81c4962311f2be7c2adce93041a00719c88f957575f2c79f1b7bc8ced115c706b311c08a2d986ca3b6a9336b147c29c6f229409ddec651bd1fdd5a0b7f610c9937fdb4a3a762364b8b3206b4ea485fd098d08f63d4aa8bb2697d027b750c32d7f74eaf5180d2e9b66b17cb2fa55523bc280da10d14be2053\nOutput = 74fc88c51bc90f77af9d5e9a4a70133d4b4e0b34da3c37c7ef8e\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00a4578cbc176318a638fba7d01df15746af44d4f6cd96d7e7c495cbf425b09c649d32bf886da48fbaf989a2117187cafb1fb580317690e3ccd446920b7af82b31db5804d87d01514acbfa9156e782f867f6bed9449e0e9a2c09bcecc6aa087636965e34b3ec766f2fe2e43018a2fddeb140616a0e9d82e5331024ee0652fc7641\nOutput = a7eb2a5036931d27d4e891326d99692ffadda9bf7efd3e34e622c4adc085f721dfe885072c78a203b151739be540fa8c153a10f00a\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00ebc5f5fda77cfdad3c83641a9025e77d72d8a6fb33a810f5950f8d74c73e8d931e8634d86ab1246256ae07b6005b71b7f2fb98351218331ce69b8ffbdc9da08bbc9c704f876deb9df9fc2ec065cad87f9090b07acc17aa7f997b27aca48806e897f771d95141fe4526d8a5301b678627efab707fd40fbebd6e792a25613e7aec\nOutput = 2ef2b066f854c33f3bdcbb5994a435e73d6c6c\n\nDecrypt = RSA-OAEP-2\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 010839ec20c27b9052e55befb9b77e6fc26e9075d7a54378c646abdf51e445bd5715de81789f56f1803d9170764a9e93cb78798694023ee7393ce04bc5d8f8c5a52c171d43837e3aca62f609eb0aa5ffb0960ef04198dd754f57f7fbe6abf765cf118b4ca443b23b5aab266f952326ac4581100644325f8b721acd5d04ff14ef3a\nOutput = 8a7fb344c8b6cb2cf2ef1f643f9a3218f6e19bba",
+    "89c0\n\nPrivateKey = RSA-OAEP-3\nType = RSA\nInput = 30820277020100300d06092a864886f70d0101010500048202613082025d02010002818102b58fec039a860700a4d7b6462f93e6cdd491161ddd74f4e810b40e3c1652006a5c277b2774c11305a4cbab5a78efa57e17a86df7a3fa36fc4b1d2249f22ec7c2dd6a463232accea906d66ebe80b5704b10729da6f833234abb5efdd4a292cbfad33b4d33fa7a14b8c397b56e3acd21203428b77cdfa33a6da706b3d8b0fc43e9020301000102818015b48a5b5683a94670e23b5718f814fa0e13f85038f50711182cba61510581f3d22c7e232ef937e22e551d68b86e2f8cb1aad8be2e488f5df7efd279e3f568d4eaf36f80cf7141ace60fcc9113fb6c4a841fd50bbc7c512ffcbeff21487aa811eb3ca8c62005346a86de86bfa1d8a948fd3f348c22eaadf333c3ce6ce13208fd024101bf01d216d73595cf0270c2beb78d40a0d8447d31da919a983f7eea781b77d85fe371b3e9373e7b69217d3150a02d8958de7fad9d555160958b4454127e0e7eaf0241018d3399658166db3829816d7b295416759e9c91987f5b2d8aecd63b04b48bd7b2fcf229bb7f8a6dc88ba13dd2e39ad55b6d1a06160708f9700be80b8fd3744ce7024006c0a249d20a6f2ee75c88b494d53f6aae99aa427c88c28b163a769445e5f390cf40c274fd6ea6329a5ce7c7ce03a2158396ee2a7845786e09e2885a9728e4e5024100d1d27c29fedd92d86c348edd0ccbfac14f746e051ce1d1811df35d61f2ee1c97d4bf2804802f6427187ba8e90a8af44243b4079b03445e602e29fa5193e64fe90241008cb2f756bd8941b1d3b770e5ad31ee373b28acda69ff9b6f40fe578b9f1afb85836f9627d37acff73c2779e634bb26011c2c8f7f3361ae2a9ea65ed689e3639a\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 026a0485d96aebd96b4382085099b962e6a2bdec3d90c8db625e14372de85e2d5b7baab65c8faf91bb5504fb495afce5c988b3f6a52e20e1d6cbd3566c5cd1f2b8318bb542cc0ea25c4aab9932afa20760eaddec784396a07ea0ef24d4e6f4d37e5052a7a31e146aa480a111bbe926401307e00f410033842b6d82fe5ce4dfae80\nOutput = 087820b569e8fa8d\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 024db89c7802989be0783847863084941bf209d761987e38f97cb5f6f1bc88da72a50b73ebaf11c879c4f95df37b850b8f65d7622e25b1b889e80fe80baca2069d6e0e1d829953fc459069de98ea9798b451e557e99abf8fe3d9ccf9096ebbf3e5255d3b4e1c6d2ecadf067a359eea86405acd47d5e165517ccafd47d6dbee4bf5\nOutput = 4653acaf171960b01f52a7be63a3ab21dc368ec43b50d82ec3781e04\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0239bce681032441528877d6d1c8bb28aa3bc97f1df584563618995797683844ca86664732f4bed7a0aab083aaabfb7238f582e30958c2024e44e57043b97950fd543da977c90cdde5337d618442f99e60d7783ab59ce6dd9d69c47ad1e962bec22d05895cff8d3f64ed5261d92b2678510393484990ba3f7f06818ae6ffce8a3a\nOutput = d94cd0e08fa404ed89\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 02994c62afd76f498ba1fd2cf642857fca81f4373cb08f1cbaee6f025c3b512b42c3e8779113476648039dbe0493f9246292fac28950600e7c0f32edf9c81b9dec45c3bde0cc8d8847590169907b7dc5991ceb29bb0714d613d96df0f12ec5d8d3507c8ee7ae78dd83f216fa61de100363aca48a7e914ae9f42ddfbe943b09d9a0\nOutput = 6cc641b6b61e6f963974dad23a9013284ef1\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0162042ff6969592a6167031811a239834ce638abf54fec8b99478122afe2ee67f8c5b18b0339805bfdbc5a4e6720b37c59cfba942464c597ff532a119821545fd2e59b114e61daf71820529f5029cf524954327c34ec5e6f5ba7efcc4de943ab8ad4ed787b1454329f70db798a3a8f4d92f8274e2b2948ade627ce8ee33e43c60\nOutput = df5151832b61f4f25891fb4172f328d2eddf8371ffcfdbe997939295f30eca6918017cfda1153bf7a6af87593223\n\nDecrypt = RSA-OAEP-3\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00112051e75d064943bc4478075e43482fd59cee0679de6893eec3a943daa490b9691c93dfc0464b6623b9f3dbd3e70083264f034b374f74164e1a00763725e574744ba0b9db83434f31df96f6e2a26f6d8eba348bd4686c2238ac07c37aac3785d1c7eea2f819fd91491798ed8e9cef5e43b781b0e0276e37c43ff9492d005730\nOutput = 3c3bad893c544a6d520ab022319188c8d504b7a788b850903b85972eaa18552e1134a7ad6098826254ff7ab672b3d8eb3158fac6d4cbaef1\n\nPrivateKey = RSA-OAEP-4\nType = RSA\nInput = 30820277020100300d06092a864886f70d0101010500048202613082025d020100028181051240b6cc0004fa48d0134671c078c7c8dec3b3e2f25bc2564467339db38853d06b85eea5b2de353bff42ac2e46bc97fae6ac9618da9537a5c8f553c1e357625991d6108dcd7885fb3a25413f53efcad948cb35cd9b9ae9c1c67626d113d57dde4c5bea76bb5bb7de96c00d07372e9685a6d75cf9d239fa148d70931b5f3fb03902030100010281800411ffca3b7ca5e9e9be7fe38a85105e353896db05c5796aecd2a725161eb3651c8629a9b862b904d7b0c7b37f8cb5a1c2b54001018a00a1eb2cafe4ee4e9492c348bc2bedab4b9ebbf064e8eff322b9009f8eec653905f40df88a3cdc49d4567f75627d41aca624129b46a0b7c698e5e65f2b7ba102c749a10135b6540d04010241027458c19ec1636919e736c9af25d609a51b8f561d19c6bf6943dd1ee1ab8a4a3f232100bd40b88decc6ba235548b6ef792a11c9de823d0a7922c7095b6eba570102410210ee9b33ab61716e27d251bd465f4b35a1a232e2da00901c294bf22350ce490d099f642b5375612db63ba1f20386492bf04d34b3c22bceb909d13441b53b5139024039fa028b826e88c1121b750a8b242fa9a35c5b66bdfd1fa637d3cc48a84a4f457a194e7727e49f7bcc6e5a5a412657fc470c7322ebc37416ef458c307a8c09010241015d99a84195943979fa9e1be2c3c1b69f432f46fd03e47d5befbbbfd6b1d1371d83efb330a3e020942b2fed115e5d02be24fd92c9019d1cecd6dd4cf1e54cc899024101f0b7015170b3f5e42223ba30301c41a6d87cbb70e30cb7d3c67d25473db1f6cbf03e3f9126e3e97968279a865b2c2b426524cfc52a683d31ed30eb984be412ba\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 04cce19614845e094152a3fe18e54e3330c44e5efbc64ae16886cb1869014cc5781b1f8f9e045384d0112a135ca0d12e9c88a8e4063416deaae3844f60d6e96fe155145f4525b9a34431ca3766180f70e15a5e5d8e8b1a516ff870609f13f896935ced188279a58ed13d07114277d75c6568607e0ab092fd803a223e4a8ee0b1a8\nOutput = 4a86609534ee434a6cbca3f7e962e76d455e3264c19f605f6e5ff6137c65c56d7fb344cd52bc93374f3d166c9f0c6f9c506bad19330972d2\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0097b698c6165645b303486fbf5a2a4479c0ee85889b541a6f0b858d6b6597b13b854eb4f839af03399a80d79bda6578c841f90d645715b280d37143992dd186c80b949b775cae97370e4ec97443136c6da484e970ffdb1323a20847821d3b18381de13bb49aaea66530c4a4b8271f3eae172cd366e07e6636f1019d2a28aed15e\nOutput = b0adc4f3fe11da59ce992773d9059943c03046497ee9d9f9a06df1166db46d98f58d27ec074c02eee6cbe2449c8b9fc5080c5c3f4433092512ec46aa793743c8\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0301f935e9c47abcb48acbbe09895d9f5971af14839da4ff95417ee453d1fd77319072bb7297e1b55d7561cd9d1bb24c1a9a37c619864308242804879d86ebd001dce5183975e1506989b70e5a83434154d5cbfd6a24787e60eb0c658d2ac193302d1192c6e622d4a12ad4b53923bca246df31c6395e37702c6a78ae081fb9d065\nOutput = bf6d42e701707b1d0206b0c8b45a1c72641ff12889219a82bdea965b5e79a96b0d0163ed9d578ec9ada20f2fbcf1ea3c4089d83419ba81b0c60f3606da99\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 02d110ad30afb727beb691dd0cf17d0af1a1e7fa0cc040ec1a4ba26a42c59d0a796a2e22c8f357ccc98b6519aceb682e945e62cb734614a529407cd452bee3e44fece8423cc19e55548b8b994b849c7ecde4933e76037e1d0ce44275b08710c68e430130b929730ed77e09b015642c5593f04e4ffb9410798102a8e96ffdfe11e4\nOutput = fb2ef112f5e766eb94019297934794f7be2f6fc1c58e\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00dbb8a7439d90efd919a377c54fae8fe11ec58c3b858362e23ad1b8a44310799066b99347aa525691d2adc58d9b06e34f288c170390c5f0e11c0aa3645959f18ee79e8f2be8d7ac5c23d061f18dd74b8c5f2a58fcb5eb0c54f99f01a83247568292536583340948d7a8c97c4acd1e98d1e29dc320e97a260532a8aa7a758a1ec2\nOutput = 28ccd447bb9e85166dabb9e5b7d1adadc4b9d39f204e96d5e440ce9ad928bc1c2284\n\nDecrypt = RSA-OAEP-4\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00a5ffa4768c8bbecaee2db77e8f2eec99595933545520835e5ba7db9493d3e17cddefe6a5f567624471908db4e2d83a0fbee60608fc84049503b2234a07dc83b27b22847ad8920ff42f674ef79b76280b00233d2b51b8cb2703a9d42bfbc8250c96ec32c051e57f1b4ba528db89c37e4c54e27e6e64ac69635ae887d9541619a9\nOutput = f22242751ec6b1\n\nPrivateKey = RSA-OAEP-5\nType = RSA\nInput = 30820279020100300d06092a864886f70d0101010500048202633082025f0201000281810aadf3f9c125e5d891f31ac448e993defe580f802b45f9d7f22ba5021e9c47576b5a1e68031ba9db4e6dabe4d96a1d6f3d267268cff408005f118efcadb99888d1c234467166b2a2b849a05a889c060ac0da0c5fae8b55f309ba62e703742fa0326f2d10b011021489ff497770190d895fd39f52293c39efd73a698bdab9f10ed902030100010281810256eb4cba7067f2d2be540dcdff4582a36b7d31d1c9099bb214b79848466a268f80f58a49ac04c0e3648934a0206c04537c19b236643a6082732144df75fa217588f794682be89168276dc726c5c0cbdb84d31bbf26d0a43af495717f7d528acfee341561f6ff3cae05c578f8470d9682f9c0d072f9f6068b56d5880f682be2c5024103b0d3962f6d17549cbfca11294348dcf0e7e39f8c2bc6824f2164b606d687860",
+    "dae1e632393cfedf513228229069e2f60e4acd7e633a436063f82385f48993707024102e4c32e2f517269b7072309f00c0e31365f7ce28b236b82912df239abf39572cf0ed604b02982e53564c52d6a05397de5c052a2fddc141ef7189836346aeb331f024101e84b119d25161fa67b00256a5bd9b645d2b232ecb05b015180029a88622adc3f09b3aeacde6161ab7cde22c2ad26e7797df54e072cbd3b2673800b3e4338dbd5024100eb90aa1a40135b4cea07197cedc8819be1e7cbff2547662116f465a4a9f487ab12f3ba4fef13822265a65297d98b7bded9372e3ffe81a38b3e9600fed055754f0241012f7f8138f9404062eb85a42924520b38f5bb886a0196f48bb8dcea60fd92cc027f18e78158a34a5c5d5f860a0f6c04071a7d01312c065062f1eb48b79d1c83cb\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 036046a4a47d9ed3ba9a89139c105038eb7492b05a5d68bfd53accff4597f7a68651b47b4a4627d927e485eed7b4566420e8b409879e5d606eae251d22a5df799f7920bfc117b992572a53b1263146bcea03385cc5e853c9a101c8c3e1bda31a519807496c6cb5e5efb408823a352b8fa0661fb664efadd593deb99fff5ed000e5\nOutput = af71a901e3a61d3132f0fc1fdb474f9ea6579257ffc24d164170145b3dbde8\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 03d6eb654edce615bc59f455265ed4e5a18223cbb9be4e4069b473804d5de96f54dcaaa603d049c5d94aa1470dfcd2254066b7c7b61ff1f6f6770e3215c51399fd4e34ec5082bc48f089840ad04354ae66dc0f1bd18e461a33cc1258b443a2837a6df26759aa2302334986f87380c9cc9d53be9f99605d2c9a97da7b0915a4a7ad\nOutput = a3b844a08239a8ac41605af17a6cfda4d350136585903a417a79268760519a4b4ac3303ec73f0f87cfb32399\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0770952181649f9f9f07ff626ff3a22c35c462443d905d456a9fd0bff43cac2ca7a9f554e9478b9acc3ac838b02040ffd3e1847de2e4253929f9dd9ee4044325a9b05cabb808b2ee840d34e15d105a3f1f7b27695a1a07a2d73fe08ecaaa3c9c9d4d5a89ff890d54727d7ae40c0ec1a8dd86165d8ee2c6368141016a48b55b6967\nOutput = 308b0ecbd2c76cb77fc6f70c5edd233fd2f20929d629f026953bb62a8f4a3a314bde195de85b5f816da2aab074d26cb6acddf323ae3b9c678ac3cf12fbdde7\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0812b76768ebcb642d040258e5f4441a018521bd96687e6c5e899fcd6c17588ff59a82cc8ae03a4b45b31299af1788c329f7dcd285f8cf4ced82606b97612671a45bedca133442144d1617d114f802857f0f9d739751c57a3f9ee400912c61e2e6992be031a43dd48fa6ba14eef7c422b5edc4e7afa04fdd38f402d1c8bb719abf\nOutput = 15c5b9ee1185\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 07b60e14ec954bfd29e60d0047e789f51d57186c63589903306793ced3f68241c743529aba6a6374f92e19e0163efa33697e196f7661dfaaa47aac6bde5e51deb507c72c589a2ca1693d96b1460381249b2cdb9eac44769f2489c5d3d2f99f0ee3c7ee5bf64a5ac79c42bd433f149be8cb59548361640595513c97af7bc2509723\nOutput = 21026e6800c7fa728fcaaba0d196ae28d7a2ac4ffd8abce794f0985f60c8a6737277365d3fea11db8923a2029a\n\nDecrypt = RSA-OAEP-5\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 08c36d4dda33423b2ed6830d85f6411ba1dcf470a1fae0ebefee7c089f256cef74cb96ea69c38f60f39abee44129bcb4c92de7f797623b20074e3d9c2899701ed9071e1efa0bdd84d4c3e5130302d8f0240baba4b84a71cc032f2235a5ff0fae277c3e8f9112bef44c9ae20d175fc9a4058bfc930ba31b02e2e4f444483710f24a\nOutput = 541e37b68b6c8872b84c02\n\nPrivateKey = RSA-OAEP-6\nType = RSA\nInput = 30820279020100300d06092a864886f70d0101010500048202633082025f02010002818112b17f6dad2ecd19ff46dc13f7860f09e0e0cfb677b38a52592305ceaf022c166db90d04ac29e33f7dd12d9faf66e0816bb63ead267cc7d46c17c37be214bca2a22d723a64e44407436b6fc965729aefc2554f376cd5dcea68293780a62bf39d0029485a160bbb9e5dc0972d21a504f52e5ee028aa416332f510b2e9cff5f722af02030100010281810295eca3560618369559cecd303aa9cfdafc1d9f06959df75ffef929aa896961bcd190dc6997eda7f5963e724d07b4dc11f3065e5ae97d96835112280b9084bb14f2a21ebd4e889d41b9c4132ec1956fcab8bb2fed0575884936522c5ff7d33261904824e7cadee4e0bb372d2457cf78e2bd1286228ff83f10731ce63c90cff3f9024104a6ce8b7358dfa69bdcf742617005afb5385f5f3a58a24ef74a22a8c05cb7cc38ebd4cc9d9a9d789a62cd0f60f0cb941d3423c9692efa4fe3adff290c4749a38b02410404c9a803371fedb4c5be39f3c00b009e5e08a63be1e40035cdaca5011cc701cf7eebcb99f0ffe17cfd0a4bf7befd2dd536ac946db797fdbc4abe8f29349b91ed024103961c8f760aa2bd5154c7aafd77225b3bacd0139ae7b5948ea3311fccd86fb95c75afa767284b9b2de559572f15d8d044c7eb83a1be5fadf2cc377c0d8475294b0241022197e066742196aabc03fa2feeb4e70b15cb787d617acd31bb75c7bc234ad706f7c48d2182d1f0ff9c228dcf41967b6c0ba6d2c0ad110a1b857831ec245e2cb102410401c4c0c53d45dbdb5e9d96d0fecf4275df0974bc4a0736b4a74c3269053efb686ace2406e22c9e058ddb4ae540627ae2fdb08261e8e7e4bcbc994daafa305c45\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0630eebcd2856c24f798806e41f9e67345eda9ceda386acc9facaea1eeed06ace583709718d9d169fadf414d5c76f92996833ef305b75b1e4b95f662a20faedc3bae0c4827a8bf8a88edbd57ec203a27a841f02e43a615bab1a8cac0701de34debdef62a088089b55ec36ea7522fd3ec8d06b6a073e6df833153bc0aefd93bd1a3\nOutput = 4046ca8baa3347ca27f49e0d81f9cc1d71be9ba517d4\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0ebc37376173a4fd2f89cc55c2ca62b26b11d51c3c7ce49e8845f74e7607317c436bc8d23b9667dfeb9d087234b47bc6837175ae5c0559f6b81d7d22416d3e50f4ac533d8f0812f2db9e791fe9c775ac8b6ad0f535ad9ceb23a4a02014c58ab3f8d3161499a260f39348e714ae2a1d3443208fd8b722ccfdfb393e98011f99e63f\nOutput = 5cc72c60231df03b3d40f9b57931bc31109f972527f28b19e7480c7288cb3c92b22512214e4be6c914792ddabdf57faa8aa7\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0a98bf1093619394436cf68d8f38e2f158fde8ea54f3435f239b8d06b8321844202476aeed96009492480ce3a8d705498c4c8c68f01501dc81db608f60087350c8c3b0bd2e9ef6a81458b7c801b89f2e4fe99d4900ba6a4b5e5a96d865dc676c7755928794130d6280a8160a190f2df3ea7cf9aa0271d88e9e6905ecf1c5152d65\nOutput = b20e651303092f4bccb43070c0f86d23049362ed96642fc5632c27db4a52e3d831f2ab068b23b149879c002f6bf3feee97591112562c\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 008e7a67cacfb5c4e24bec7dee149117f19598ce8c45808fef88c608ff9cd6e695263b9a3c0ad4b8ba4c95238e96a8422b8535629c8d5382374479ad13fa39974b242f9a759eeaf9c83ad5a8ca18940a0162ba755876df263f4bd50c6525c56090267c1f0e09ce0899a0cf359e88120abd9bf893445b3cae77d3607359ae9a52f8\nOutput = 684e3038c5c041f7\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 00003474416c7b68bdf961c385737944d7f1f40cb395343c693cc0b4fe63b31fedf1eaeeac9ccc0678b31dc32e0977489514c4f09085f6298a9653f01aea4045ff582ee887be26ae575b73eef7f3774921e375a3d19adda0ca31aa1849887c1f42cac9677f7a2f4e923f6e5a868b38c084ef187594dc9f7f048fea2e02955384ab\nOutput = 32488cb262d041d6e4dd35f987bf3ca696db1f06ac29a44693\n\nDecrypt = RSA-OAEP-6\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0a026dda5fc8785f7bd9bf75327b63e85e2c0fdee5dadb65ebdcac9ae1de95c92c672ab433aa7a8e69ce6a6d8897fac4ac4a54de841ae5e5bbce7687879d79634cea7a30684065c714d52409b928256bbf53eabcd5231eb7259504537399bd29164b726d33a46da701360a4168a091ccab72d44a62fed246c0ffea5b1348ab5470\nOutput = 50ba14be8462720279c306ba\n\nPrivateKey = RSA-OAEP-7\nType = RSA\nInput = 30820278020100300d06092a864886f70d0101010500048202623082025e020100028181311179f0bcfc9b9d3ca315d00ef30d7bdd3a2cfae9911bfedcb948b3a4782d0732b6ab44aa4bf03741a644dc01bec3e69b01a033e675d8acd7c4925c6b1aec3119051dfd89762d215d45475ffcb59f908148623f37177156f6ae86dd7a7c5f43dc1e1f908254058a284a5f06c0021793a87f1ac5feff7dcaee69c5e51a3789e3730203010001028181070cfcff2feb8276e27432c45dfee48f49b7917d6530e1f0ca3460f32e0276174487c56e22a45d2500d7775495219d7d165a9cf3bd92c32af9a98d8dc9cc296800adc94a0a54fb40f34291bf84ee8ea12b6f109359c6d3542a50f9c767f5cfff05a681c2e656fb77caaadb4be9468d8abcd4df98f58e86d2053fa1349f748e21b102410749262c111cd470ec2566e6b3732fc09329469aa19071d3b9c01906514c6f1d26baa14beab0971c8b7e611a4f79009d6fea776928ca25285b0de3643d1a3f8c71024106bc1e50e96c02bf636e9eea8b899bbebf7651de77dd474c3e9bc23bad8182b61904c7d97dfbebfb1e00108878b6e67e415391d67942c2b2bf9b4435f88b0cb023024103bc7ea7f0aab143abc6ce8b97118636a30172e4cfe02c8fa0dda3b7baaf90f8092982985525f488bdfcb4bd726e22639ac64a3092ab7ffcbf1d5334cfa50b5bf102410262a6aa29c2a3c67dc5346c06381afd987aa3cc93cfbfecf54fdd9f9d787d7f59a523d398979da137a2f6381fe94801f7c94da21518dc34cb40870c4697994ad90240649d4c17b6ee1721e772d0389a559c3d3cdf9550d457c46b037b74641b1d52166af8a213c8396206cdfba4422f18d6f61dbcb5d214c971bf482aeb976a7370c2\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 1688e4ce7794bba6cb7014169ecd559cede2a30b56a52b68d9fe18cf1973ef97b2a03153951c755f6294aa49adbdb55845ab6875fb3986c93ecf927962840d",
+    "282f9e54ce8b690f7c0cb8bbd73440d9571d1b16cd9260f9eab4783cc482e5223dc60973871783ec27b0ae0fd47732cbc286a173fc92b00fb4ba6824647cd93c85c1\nOutput = 47aae909\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 1052ed397b2e01e1d0ee1c50bf24363f95e504f4a03434a08fd822574ed6b9736edbb5f390db10321479a8a139350e2bd4977c3778ef331f3e78ae118b268451f20a2f01d471f5d53c566937171b2dbc2d4bde459a5799f0372d6574239b2323d245d0bb81c286b63c89a361017337e4902f88a467f4c7f244bfd5ab46437ff3b6\nOutput = 1d9b2e2223d9bc13bfb9f162ce735db48ba7c68f6822a0a1a7b6ae165834e7\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 2155cd843ff24a4ee8badb7694260028a490813ba8b369a4cbf106ec148e5298707f5965be7d101c1049ea8584c24cd63455ad9c104d686282d3fb803a4c11c1c2e9b91c7178801d1b6640f003f5728df007b8a4ccc92bce05e41a27278d7c85018c52414313a5077789001d4f01910b72aad05d220aa14a58733a7489bc54556b\nOutput = d976fc\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 0ab14c373aeb7d4328d0aaad8c094d88b9eb098b95f21054a29082522be7c27a312878b637917e3d819e6c3c568db5d843802b06d51d9e98a2be0bf40c031423b00edfbff8320efb9171bd2044653a4cb9c5122f6c65e83cda2ec3c126027a9c1a56ba874d0fea23f380b82cf240b8cf540004758c4c77d934157a74f3fc12bfac\nOutput = d4738623df223aa43843df8467534c41d013e0c803c624e263666b239bde40a5f29aeb8de79e3daa61dd0370f49bd4b013834b98212aef6b1c5ee373b3cb\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 028387a318277434798b4d97f460068df5298faba5041ba11761a1cb7316b24184114ec500257e2589ed3b607a1ebbe97a6cc2e02bf1b681f42312a33b7a77d8e7855c4a6de03e3c04643f786b91a264a0d6805e2cea91e68177eb7a64d9255e4f27e713b7ccec00dc200ebd21c2ea2bb890feae4942df941dc3f97890ed347478\nOutput = bb47231ca5ea1d3ad46c99345d9a8a61\n\nDecrypt = RSA-OAEP-7\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 14c678a94ad60525ef39e959b2f3ba5c097a94ff912b67dbace80535c187abd47d075420b1872152bba08f7fc31f313bbf9273c912fc4c0149a9b0cfb79807e346eb332069611bec0ff9bcd168f1f7c33e77313cea454b94e2549eecf002e2acf7f6f2d2845d4fe0aab2e5a92ddf68c480ae11247935d1f62574842216ae674115\nOutput = 2184827095d35c3f86f600e8e59754013296\n\nPrivateKey = RSA-OAEP-8\nType = RSA\nInput = 30820279020100300d06092a864886f70d0101010500048202633082025f0201000281815bdf0e30d321dda5147f882408fa69195480df8f80d3f6e8bf5818504f36427ca9b1f5540b9c65a8f6974cf8447a244d9280201bb49fcbbe6378d1944cd227e230f96e3d10f819dcef276c64a00b2a4b6701e7d01de5fabde3b1e9a0df82f4631359cd22669647fbb1717246134ed7b497cfffbdc42b59c73a96ed90166212dff702030100010281810f7d1e9e5aaa25fd13e4a0663ae144e0d15f5cd18bcdb09df2cc7e64e3c5e915ad62645304161d098c715bb7ab8bd01d07eaf3fed7c7ed08af2a8a62ef44ab16b320e14af72a48f96afe262a0ae4cf65e635e910790cd4ee5cea768a4b2639f7e6f677b3f0bb6be32b75747d8909036f0264f58d401cdba131716157a75ecf633102410a02ef8448d9fad8bbd0d004c8c2aa9751ef9721c1b0d03236a54b0df947cbaed5a255ee9e8e20d491ea1723fe094704a9762e88afd16ebb5994412ca966dc4f9f0241092d362e7ed3a0bfd9e9fd0e6c0301b6df29159cf50cc83b9b0cf4d6eea71a61e002b46e0ae9f2de62d25b5d7452d498b81c9ac6fc58593d4c3fb4f5d72dfbb0a9024107c71410af103962db367404e37ae850baa4e9c29dd92145815294a67c7d1c6ded263aa030a9b633ae50303e14035d1af014123eba687820308d8ebc85b6957d7d024100ae2c75380c02c016ad05891b3301de881f28ae1171182b6b2c83bea7c515eca9ca298c7b1cab5817a597068fc85060de4da8a016378aae43c7f967bcc37904b902410598d1059e3ada4f6320752c09d805ff7d1f1ae0d017aeeee9cefa0d7dd7ff775e44b578322f6405d6211da19519666aa87fdc4cd8c88f6b6e3d67e961dcbba3d0\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 09b3683d8a2eb0fb295b62ed1fb9290b714457b7825319f4647872af889b30409472020ad12912bf19b11d4819f49614824ffd84d09c0a17e7d17309d12919790410aa2995699f6a86dbe3242b5acc23af45691080d6b1ae810fb3e3057087f0970092ce00be9562ff4053b6262ce0caa93e13723d2e3a5ba075d45f0d61b54b61\nOutput = 050b755e5e6880f7b9e9d692a74c37aae449b31bfea6deff83747a897f6c2c825bb1adbf850a3c96994b5de5b33cbc7d4a17913a7967\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 2ecf15c97c5a15b1476ae986b371b57a24284f4a162a8d0c8182e7905e792256f1812ba5f83f1f7a130e42dcc02232844edc14a31a68ee97ae564a383a3411656424c5f62ddb646093c367be1fcda426cf00a06d8acb7e57776fbbd855ac3df506fc16b1d7c3f2110f3d8068e91e186363831c8409680d8da9ecd8cf1fa20ee39d\nOutput = 4eb68dcd93ca9b19df111bd43608f557026fe4aa1d5cfac227a3eb5ab9548c18a06dded23f81825986b2fcd71109ecef7eff88873f075c2aa0c469f69c92bc\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 4bc89130a5b2dabb7c2fcf90eb5d0eaf9e681b7146a38f3173a3d9cfec52ea9e0a41932e648a9d69344c50da763f51a03c95762131e8052254dcd2248cba40fd31667786ce05a2b7b531ac9dac9ed584a59b677c1a8aed8c5d15d68c05569e2be780bf7db638fd2bfd2a85ab276860f3777338fca989ffd743d13ee08e0ca9893f\nOutput = 8604ac56328c1ab5ad917861\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 2e456847d8fc36ff0147d6993594b9397227d577752c79d0f904fcb039d4d812fea605a7b574dd82ca786f93752348438ee9f5b5454985d5f0e1699e3e7ad175a32e15f03deb042ab9fe1dd9db1bb86f8c089ccb45e7ef0c5ee7ca9b7290ca6b15bed47039788a8a93ff83e0e8d6244c71006362deef69b6f416fb3c684383fbd0\nOutput = fdda5fbf6ec361a9d9a4ac68af216a0686f438b1e0e5c36b955f74e107f39c0dddcc\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 1fb9356fd5c4b1796db2ebf7d0d393cc810adf6145defc2fce714f79d93800d5e2ac211ea8bbecca4b654b94c3b18b30dd576ce34dc95436ef57a09415645923359a5d7b4171ef22c24670f1b229d3603e91f76671b7df97e7317c97734476d5f3d17d21cf82b5ba9f83df2e588d36984fd1b584468bd23b2e875f32f68953f7b2\nOutput = 4a5f4914bee25de3c69341de07\n\nDecrypt = RSA-OAEP-8\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 3afd9c6600147b21798d818c655a0f4c9212db26d0b0dfdc2a7594ccb3d22f5bf1d7c3e112cd73fc7d509c7a8bafdd3c274d1399009f9609ec4be6477e453f075aa33db382870c1c3409aef392d7386ae3a696b99a94b4da0589447e955d16c98b17602a59bd736279fcd8fb280c4462d590bfa9bf13fed570eafde97330a2c210\nOutput = 8e07d66f7b880a72563abcd3f35092bc33409fb7f88f2472be\n\nPrivateKey = RSA-OAEP-9\nType = RSA\nInput = 30820397020100300d06092a864886f70d0101010500048203813082037d0201000281c100cf2cd41e34ca3a728ea5cb8aff64c36d27bdef5364e336fd68d3123c5a196a8c287013e853d5156d58d151954520fb4f6d7b17abb6817765909c576119659d902b1906ed8a2b10c155c24d124528dab9eeae379beac66e4a411786dcb8fd0062ebc030de1219a04c2a8c1b7dd3131e4d6b6caee2e31a5ed41ac1509b2ef1ee2ab18364be568ca941c25ecc84ff9d643b5ec1aaae102a20d73f479b780fd6da91075212d9eac03a0674d899eba2e431f4c44b615b6ba2232bd4b33baed73d625d02030100010281c0198c141e23715a92bccf6a119a5bc11389468d2811f548d727e17b4ab0eb986d6f211efb53b71f7ccbea87ee69c75ee615008c5332deb52bf390abdfbfe37d7205368159b2638c1de326e21d22251f0fb5848b3bf15005d2a74330f0afe916ee62ccc1344d1d83a709e60676273840f7f377424a5e0a4da75f01b31ff76819cf9cbfdd215243c3917c03ef38199312e567b3bf7aed3ab457f371ef8a1423f45b68c6e282ec111bba2833b987fd69fad83bc1b8c613c5e1ea16c11ed125ea7ec1026100fc8d6c04bec4eb9a8192ca7900cbe536e2e8b519decf33b2459798c6909df4f176db7d23190fc72b8865a718af895f1bcd9145298027423b605e70a47cf58390a8c3e88fc8c48e8b32e3da210dfbe3e881ea5674b6a348c21e93f9e55ea65efd026100d200d45e788aacea606a401d0460f87dd5c1027e12dc1a0d7586e8939d9cf789b40f51ac0442961de7d21cc21e05c83155c1f2aa9193387cfdf956cb48d153ba270406f9bbba537d4987d9e2f9942d7a14cbfffea74fecdda928d23e259f5ee1026100db16802f79a2f0d45f358d69fd33e44b81fae828622e93a54253e997d01b0743759da0e812b4aa4e6c8beab2328d5431955a418a67ff26a8c5c807a5da354e05ef31cc8cf758f463732950b03e265726fb94e39d6a572a26244ab08db75752ad026100a0a317cfe7df1423f87a6dee8451f4e2b4a67e5497f29b4f1e4e830b9fadd9401167026f5596e5a39c97817e0f5f16e27e19ec9902e01d7ea6fb9aa3c760afee1e381b69de6ac9c07585a06ad9c4ba00bf75c8ad2fa898a479e80ae294fed2a102600b21f335c353342eb44c3aa24445780c2d655b940174cae38c7c8a4e6493c0ba9fd303748267b083b9a7a6cb61e42db362b8c9896db7064e02ad5ae61587da15b4649c90594909feb37dbcb654beb7268ec801e5a8b4aa3911bebd88542f05be\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 267bcd118acab1fc8ba81c85d73003cb8610fa55c1d97da8d48a7c7f06896a4db751aa284255b9d36ad65f37653d829f1b37f97b8001942545b2fc2c55a7376ca7a1be4b1760c8e05a33e5aa2526b8d98e317088e7834c755b2a59b12631a182c05d5d43ab1779264f8456f515ce57dfdf512d5493dab7b7338dc4b7d78db9c091ac3baf537a69fc7f549d979f0eff9a94fda4169bd4d1d19a69c99e33c3b55490d501b39b1edae118ff6793a153261584d3a5f39f6e682e3d17c8cd1261fa72\nOutput = f735fd55ba92592c3b52b8f9",
+    "c4f69aaa1cbef8fe88add095595412467f9cf4ec0b896c59eda16210e7549c8abb10cdbc21a12ec9b6b5b8fd2f10399eb6\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 93ac9f0671ec29acbb444effc1a5741351d60fdb0e393fbf754acf0de49761a14841df7772e9bc82773966a1584c4d72baea00118f83f35cca6e537cbd4d811f5583b29783d8a6d94cd31be70d6f526c10ff09c6fa7ce069795a3fcd0511fd5fcb564bcc80ea9c78f38b80012539d8a4ddf6fe81e9cddb7f50dbbbbcc7e5d86097ccf4ec49189fb8bf318be6d5a0715d516b49af191258cd32dc833ce6eb4673c03a19bbace88cc54895f636cc0c1ec89096d11ce235a265ca1764232a689ae8\nOutput = 81b906605015a63aabe42ddf11e1978912f5404c7474b26dce3ed482bf961ecc818bf420c54659\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 81ebdd95054b0c822ef9ad7693f5a87adfb4b4c4ce70df2df84ed49c04da58ba5fc20a19e1a6e8b7a3900b22796dc4e869ee6b42792d15a8eceb56c09c69914e813cea8f6931e4b8ed6f421af298d595c97f4789c7caa612c7ef360984c21b93edc5401068b5af4c78a8771b984d53b8ea8adf2f6a7d4a0ba76c75e1dd9f658f20ded4a46071d46d7791b56803d8fea7f0b0f8e41ae3f09383a6f9585fe7753eaaffd2bf94563108beecc207bbb535f5fcc705f0dde9f708c62f49a9c90371d3\nOutput = fd326429df9b890e09b54b18b8f34f1e24\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = bcc35f94cde66cb1136625d625b94432a35b22f3d2fa11a613ff0fca5bd57f87b902ccdc1cd0aebcb0715ee869d1d1fe395f6793003f5eca465059c88660d446ff5f0818552022557e38c08a67ead991262254f10682975ec56397768537f4977af6d5f6aaceb7fb25dec5937230231fd8978af49119a29f29e424ab8272b47562792d5c94f774b8829d0b0d9f1a8c9eddf37574d5fa248eefa9c5271fc5ec2579c81bdd61b410fa61fe36e424221c113addb275664c801d34ca8c6351e4a858\nOutput = f1459b5f0c92f01a0f723a2e5662484d8f8c0a20fc29dad6acd43bb5f3effdf4e1b63e07fdfe6628d0d74ca19bf2d69e4a0abf86d293925a796772f8088e\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 232afbc927fa08c2f6a27b87d4a5cb09c07dc26fae73d73a90558839f4fd66d281b87ec734bce237ba166698ed829106a7de6942cd6cdce78fed8d2e4d81428e66490d036264cef92af941d3e35055fe3981e14d29cbb9a4f67473063baec79a1179f5a17c9c1832f2838fd7d5e59bb9659d56dce8a019edef1bb3accc697cc6cc7a778f60a064c7f6f5d529c6210262e003de583e81e3167b89971fb8c0e15d44fffef89b53d8d64dd797d159b56d2b08ea5307ea12c241bd58d4ee278a1f2e\nOutput = 53e6e8c729d6f9c319dd317e74b0db8e4ccca25f3c8305746e137ac63a63ef3739e7b595abb96e8d55e54f7bd41ab433378ffb911d\n\nDecrypt = RSA-OAEP-9\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 438cc7dc08a68da249e42505f8573ba60e2c2773d5b290f4cf9dff718e842081c383e67024a0f29594ea987b9d25e4b738f285970d195abb3a8c8054e3d79d6b9c9a8327ba596f1259e27126674766907d8d582ff3a8476154929adb1e6d1235b2ccb4ec8f663ba9cc670a92bebd853c8dbf69c6436d016f61add836e94732450434207f9fd4c43dec2a12a958efa01efe2669899b5e604c255c55fb7166de5589e369597bb09168c06dd5db177e06a1740eb2d5c82faeca6d92fcee9931ba9f\nOutput = b6b28ea2198d0c1008bc64\n\nPrivateKey = RSA-OAEP-10\nType = RSA\nInput = 308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100ae45ed5601cec6b8cc05f803935c674ddbe0d75c4c09fd7951fc6b0caec313a8df39970c518bffba5ed68f3f0d7f22a4029d413f1ae07e4ebe9e4177ce23e7f5404b569e4ee1bdcf3c1fb03ef113802d4f855eb9b5134b5a7c8085adcae6fa2fa1417ec3763be171b0c62b760ede23c12ad92b980884c641f5a8fac26bdad4a03381a22fe1b754885094c82506d4019a535a286afeb271bb9ba592de18dcf600c2aeeae56e02f7cf79fc14cf3bdc7cd84febbbf950ca90304b2219a7aa063aefa2c3c1980e560cd64afe779585b6107657b957857efde6010988ab7de417fc88d8f384c4e6e72c3f943e0c31c0c4a5cc36f879d8a3ac9d7d59860eaada6b83bb020301000102820100056b04216fe5f354ac77250a4b6b0c8525a85c59b0bd80c56450a22d5f438e596a333aa875e291dd43f48cb88b9d5fc0d499f9fcd1c397f9afc070cd9e398c8d19e61db7c7410a6b2675dfbf5d345b804d201add502d5ce2dfcb091ce9997bbebe57306f383e4d588103f036f7e85d1934d152a323e4a8db451d6f4a5b1b0f102cc150e02feee2b88dea4ad4c1baccb24d84072d14e1d24a6771f7408ee30564fb86d4393a34bcf0b788501d193303f13a2284b001f0f649eaf79328d4ac5c430ab4414920a9460ed1b7bc40ec653e876d09abc509ae45b525190116a0c26101848298509c1c3bf3a483e7274054e15e97075036e989f60932807b5257751e7902818100ecf5aecd1e5515fffacbd75a2816c6ebf49018cdfb4638e185d66a7396b6f8090f8018c7fd95cc34b857dc17f0cc6516bb1346ab4d582cadad7b4103352387b70338d084047c9d9539b6496204b3dd6ea442499207bec01f964287ff6336c3984658336846f56e46861881c10233d2176bf15a5e96ddc780bc868aa77d3ce76902818100bc46c464fc6ac4ca783b0eb08a3c841b772f7e9b2f28babd588ae885e1a0c61e4858a0fb25ac299990f35be85164c259ba1175cdd7192707135184992b6c29b746dd0d2cabe142835f7d148cc161524b4a09946d48b828473f1ce76b6cb6886c345c03e05f41d51b5c3a90a3f24073c7d74a4fe25d9cf21c75960f3fc386318302818100c73564571d00fb15d08a3de9957a50915d7126e9442dacf42bc82e862e5673ff6a008ed4d2e374617df89f17a160b43b7fda9cb6b6b74218609815f7d45ca263c159aa32d272d127faf4bc8ca2d77378e8aeb19b0ad7da3cb3de0ae7314980f62b6d4b0a875d1df03c1bae39ccd833ef6cd7e2d9528bf084d1f969e794e9f6c10281802658b37f6df9c1030be1db68117fa9d87e39ea2b693b7e6d3a2f70947413eec6142e18fb8dfcb6ac545d7c86a0ad48f8457170f0efb26bc48126c53efd1d16920198dc2a1107dc282db6a80cd3062360ba3fa13f70e4312ff1a6cd6b8fc4cd9c5c3db17c6d6a57212f73ae29f619327bad59b153858585ba4e28b60a62a45e490281806f38526b3925085534ef3e415a836ede8b86158a2c7cbfeccb0bd834304fec683ba8d4f479c433d43416e63269623cea100776d85aff401d3fff610ee65411ce3b1363d63a9709eede42647cea561493d54570a879c18682cd97710b96205ec31117d73b5f36223fadd6e8ba90dd7c0ee61d44e163251e20c7f66eb305117cb8\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 53ea5dc08cd260fb3b858567287fa91552c30b2febfba213f0ae87702d068d19bab07fe574523dfb42139d68c3c5afeee0bfe4cb7969cbf382b804d6e61396144e2d0e60741f8993c3014b58b9b1957a8babcd23af854f4c356fb1662aa72bfcc7e586559dc4280d160c126785a723ebeebeff71f11594440aaef87d10793a8774a239d4a04c87fe1467b9daf85208ec6c7255794a96cc29142f9a8bd418e3c1fd67344b0cd0829df3b2bec60253196293c6b34d3f75d32f213dd45c6273d505adf4cced1057cb758fc26aeefa441255ed4e64c199ee075e7f16646182fdb464739b68ab5daff0e63e9552016824f054bf4d3c8c90a97bb6b6553284eb429fcc\nOutput = 8bba6bf82a6c0f86d5f1756e97956870b08953b06b4eb205bc1694ee\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = a2b1a430a9d657e2fa1c2bb5ed43ffb25c05a308fe9093c01031795f5874400110828ae58fb9b581ce9dddd3e549ae04a0985459bde6c626594e7b05dc4278b2a1465c1368408823c85e96dc66c3a30983c639664fc4569a37fe21e5a195b5776eed2df8d8d361af686e750229bbd663f161868a50615e0c337bec0ca35fec0bb19c36eb2e0bbcc0582fa1d93aacdb061063f59f2ce1ee43605e5d89eca183d2acdfe9f81011022ad3b43a3dd417dac94b4e11ea81b192966e966b182082e71964607b4f8002f36299844a11f2ae0faeac2eae70f8f4f98088acdcd0ac556e9fccc511521908fad26f04c64201450305778758b0538bf8b5bb144a828e629795\nOutput = e6ad181f053b58a904f2457510373e57\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 9886c3e6764a8b9a84e84148ebd8c3b1aa8050381a78f668714c16d9cfd2a6edc56979c535d9dee3b44b85c18be8928992371711472216d95dda98d2ee8347c9b14dffdff84aa48d25ac06f7d7e65398ac967b1ce90925f67dce049b7f812db0742997a74d44fe81dbe0e7a3feaf2e5c40af888d550ddbbe3bc20657a29543f8fc2913b9bd1a61b2ab2256ec409bbd7dc0d17717ea25c43f42ed27df8738bf4afc6766ff7aff0859555ee283920f4c8a63c4a7340cbafddc339ecdb4b0515002f96c932b5b79167af699c0ad3fccfdf0f44e85a70262bf2e18fe34b850589975e867ff969d48eabf212271546cdc05a69ecb526e52870c836f307bd798780ede\nOutput = 510a2cf60e866fa2340553c94ea39fbc256311e83e94454b4124\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 6318e9fb5c0d05e5307e1683436e903293ac4642358aaa223d7163013aba87e2dfda8e60c6860e29a1e92686163ea0b9175f329ca3b131a1edd3a77759a8b97bad6a4f8f4396f28cf6f39ca58112e48160d6e203daa5856f3aca5ffed577af499408e3dfd233e3e604dbe34a9c4c9082de65527cac6331d29dc80e0508a0fa7122e7f329f6cca5cfa34d4d1da417805457e008bec549e478ff9e12a763c477d15bbb78f5b69bd57830fc2c4ed686d79bc72a95d85f88134c6b0afe56a8ccfbc855828bb339bd17909cf1d70de3335ae07039093e606d655365de6550b872cd6de1d440ee031b61945f629ad8a353b0d40939e96a3c450d2a8d5eee9f678093c8\nOutput = bcdd190da3b7d300df9a06e22caae2a75f10c91ff667b7c16bde8b53064a2649a94045c9\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 75290872ccfd4a4505660d651f56da6daa09ca1301d890632f6a992f3d565cee464afded40ed3b5be9356714ea5aa7655f4a1366c2f17c728f6f2c5a5d1f8e28429bc4e6f8f2cff8da8dc0e0a9808e45fd09ea2fa40cb2b6ce6ffff5c0e159d11b68d90a85f7b84e103b09e682666480c657505c0929259468a314786d74eab131573cf234bf57db7d9e66cc6748192e002dc0deea930585f",
+    "0831fdcd9bc33d51f79ed2ffc16bcf4d59812fcebcaa3f9069b0e445686d644c25ccf63b456ee5fa6ffe96f19cdf751fed9eaf35957754dbf4bfea5216aa1844dc507cb2d080e722eba150308c2b5ff1193620f1766ecf4481bafb943bd292877f2136ca494aba0\nOutput = a7dd6c7dc24b46f9dd5f1e91ada4c3b3df947e877232a9\n\nDecrypt = RSA-OAEP-10\nRSAPadding = OAEP\nMGF1Digest = SHA1\nInput = 2d207a73432a8fb4c03051b3f73b28a61764098dfa34c47a20995f8115aa6816679b557e82dbee584908c6e69782d7deb34dbd65af063d57fca76a5fd069492fd6068d9984d209350565a62e5c77f23038c12cb10c6634709b547c46f6b4a709bd85ca122d74465ef97762c29763e06dbc7a9e738c78bfca0102dc5e79d65b973f28240caab2e161a78b57d262457ed8195d53e3c7ae9da021883c6db7c24afdd2322eac972ad3c354c5fcef1e146c3a0290fb67adf007066e00428d2cec18ce58f9328698defef4b2eb5ec76918fde1c198cbb38b7afc67626a9aefec4322bfd90d2563481c9a221f78c8272c82d1b62ab914e1c69f6af6ef30ca5260db4a46\nOutput = eaf1a73a1b0c4609537de69cd9228bbcfb9a8ca8c6c3efaf056fe4a7f4634ed00b7c39ec6922d7b8ea2c04ebac\n\n\n# Single-shot signing tests.\n\nSignMessage = RSA-2048\nDigest = SHA256\nInput = \"Hello world\"\nOutput = 301894798b49d6ec55d32dcc74314f04230591a515781f3eb4492f5324b56046836c4bc3e25942af341e88558cb4c3814a849207575d343189147989b16e296b5138dbbc717116dc416f201dfa35943d15060493953cda1f04a13ff89845cf7fd69e1a78d5d38522a77bb234e5d0ba2ae17ada6e22fdae27a4052fdb8ac267507dfe06ed7a865e61a52b530bbbf65c7caa89739613df10ae3b0e62ff6831ee0770086aad39c329462aede9f1b29a501bc3d09e0fe4034aa5d6831d44491d508111d88a1d7ba50cee5ef7e701b3a589adc09a752a974a6805956f4a1a0582f66309a1e02e9fb6b10d2c820fe98bb2eb04f435bc8a649cc9ab6c5a4c03e83800d1\n\nVerifyMessage = RSA-2048\nDigest = SHA256\nInput = \"Hello world\"\nOutput = 301894798b49d6ec55d32dcc74314f04230591a515781f3eb4492f5324b56046836c4bc3e25942af341e88558cb4c3814a849207575d343189147989b16e296b5138dbbc717116dc416f201dfa35943d15060493953cda1f04a13ff89845cf7fd69e1a78d5d38522a77bb234e5d0ba2ae17ada6e22fdae27a4052fdb8ac267507dfe06ed7a865e61a52b530bbbf65c7caa89739613df10ae3b0e62ff6831ee0770086aad39c329462aede9f1b29a501bc3d09e0fe4034aa5d6831d44491d508111d88a1d7ba50cee5ef7e701b3a589adc09a752a974a6805956f4a1a0582f66309a1e02e9fb6b10d2c820fe98bb2eb04f435bc8a649cc9ab6c5a4c03e83800d1\n\nVerifyMessage = RSA-2048-SPKI\nDigest = SHA256\nInput = \"Hello world\"\nOutput = 301894798b49d6ec55d32dcc74314f04230591a515781f3eb4492f5324b56046836c4bc3e25942af341e88558cb4c3814a849207575d343189147989b16e296b5138dbbc717116dc416f201dfa35943d15060493953cda1f04a13ff89845cf7fd69e1a78d5d38522a77bb234e5d0ba2ae17ada6e22fdae27a4052fdb8ac267507dfe06ed7a865e61a52b530bbbf65c7caa89739613df10ae3b0e62ff6831ee0770086aad39c329462aede9f1b29a501bc3d09e0fe4034aa5d6831d44491d508111d88a1d7ba50cee5ef7e701b3a589adc09a752a974a6805956f4a1a0582f66309a1e02e9fb6b10d2c820fe98bb2eb04f435bc8a649cc9ab6c5a4c03e83800d1\n\nVerifyMessage = P-256\nDigest = SHA256\nInput = \"Hello world\"\nOutput = 304502204c66004635c267394bd6857c1e0b53b22a2bab1ca7dff9d5c1b42143858b3ea7022100ae81228510e03cd49a8863d2ebd1c05fe0c87eacd1150433132b909994cd0dbd\n\n# Digest can't be omitted in many algorithms.\nSignMessage = RSA-2048\nInput = \"Hello world\"\nError = NO_DEFAULT_DIGEST\n\nVerifyMessage = RSA-2048\nInput = \"Hello world\"\nOutput = 301894798b49d6ec55d32dcc74314f04230591a515781f3eb4492f5324b56046836c4bc3e25942af341e88558cb4c3814a849207575d343189147989b16e296b5138dbbc717116dc416f201dfa35943d15060493953cda1f04a13ff89845cf7fd69e1a78d5d38522a77bb234e5d0ba2ae17ada6e22fdae27a4052fdb8ac267507dfe06ed7a865e61a52b530bbbf65c7caa89739613df10ae3b0e62ff6831ee0770086aad39c329462aede9f1b29a501bc3d09e0fe4034aa5d6831d44491d508111d88a1d7ba50cee5ef7e701b3a589adc09a752a974a6805956f4a1a0582f66309a1e02e9fb6b10d2c820fe98bb2eb04f435bc8a649cc9ab6c5a4c03e83800d1\nError = NO_DEFAULT_DIGEST\n\n# Signing test vectors from RFC 8032.\nSignMessage = Ed25519\nInput = \"\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\n\nSignMessage = Ed25519-2\nInput = 72\nOutput = 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00\n\nSignMessage = Ed25519-3\nInput = af82\nOutput = 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a\n\nSignMessage = Ed25519-4\nInput = 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0\nOutput = 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03\n\nSignMessage = Ed25519-5\nInput = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f\nOutput = dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704\n\n# Signing with public keys is not allowed.\nSignMessage = Ed25519-SPKI\nInput = \"\"\nError = NOT_A_PRIVATE_KEY\n\n# Verify test vectors from RFC 8032. Test verifying with both the public and\n# private key.\nVerifyMessage = Ed25519\nInput = \"\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\n\nVerifyMessage = Ed25519-SPKI\nInput = \"\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\n\nVerifyMessage = Ed25519-2\nInput = 72\nOutput = 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00\n\nVerifyMessage = Ed25519-SPKI-2\nInput = 72\nOutput = 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00\n\nVerifyMessage = Ed25519-3\nInput = af82\nOutput = 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a\n\nVerifyMessage = Ed25519-SPKI-3\nInput = af82\nOutput = 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a\n\nVerifyMessage = Ed25519-4\nInput = 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d",
+    "9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0\nOutput = 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03\n\nVerifyMessage = Ed25519-SPKI-4\nInput = 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0\nOutput = 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03\n\nVerifyMessage = Ed25519-5\nInput = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f\nOutput = dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704\n\nVerifyMessage = Ed25519-SPKI-5\nInput = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f\nOutput = dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704\n\n# Length is wrong.\nVerifyMessage = Ed25519-SPKI\nInput = \"\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a10\nError = INVALID_SIGNATURE\n\n# Message is wrong.\nVerifyMessage = Ed25519-SPKI\nInput = \"Hello world\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\nError = INVALID_SIGNATURE\n\n# Ed25519 does not support configuring a digest.\nSignMessage = Ed25519\nInput = \"\"\nDigest = SHA256\nError = COMMAND_NOT_SUPPORTED\n\n# Ed25519 does not support signing a pre-hashed value.\nSign = Ed25519\nInput = \"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"\nError = OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\n\nVerify = Ed25519\nInput = \"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"\nOutput = e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b\nError = OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\n",
 };
-static const size_t kLen32 = 125220;
+static const size_t kLen32 = 128816;
 
 static const char *kData33[] = {
     "#\n# Copyright 2001-2017 The OpenSSL Project Authors. All Rights Reserved.\n#\n# Licensed under the OpenSSL license (the \"License\").  You may not use\n# this file except in compliance with the License.  You can obtain a copy\n# in the file LICENSE in the source distribution or at\n# https://www.openssl.org/source/license.html\n\nPassword = \"\"\nSalt = \"\"\nN = 16\nr = 1\np = 1\nKey = 77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906\n\nPassword = \"password\"\nSalt = \"NaCl\"\nN = 1024\nr = 8\np = 16\nKey = fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640\n\nPassword = \"pleaseletmein\"\nSalt = \"SodiumChloride\"\nN = 16384\nr = 8\np = 1\nKey = 7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887\n\n# NB: this test requires more than 1GB of memory to run so it is disabled by\n# default. Uncomment it to run.\n# Password = \"pleaseletmein\"\n# Salt = \"SodiumChloride\"\n# N = 1048576\n# r = 8\n# p = 1\n# Key = 2101cb9b6a511aaeaddbbe09cf70f881ec568d574a2ffd4dabe5ee9820adaa478e56fd8f4ba5d09ffa1c6d927c40f4c337304049e8a952fbcbf45c6fa77a41a4\n# MaxMemory = 10000000000\n",
diff --git a/err_data.c b/err_data.c
index dc78ba8..06003ac 100644
--- a/err_data.c
+++ b/err_data.c
@@ -185,43 +185,43 @@
     0x28340c5e,
     0x283480ac,
     0x283500ea,
-    0x2c322c6c,
+    0x2c322c99,
     0x2c3292a5,
-    0x2c332c7a,
-    0x2c33ac8c,
-    0x2c342ca0,
-    0x2c34acb2,
-    0x2c352ccd,
-    0x2c35acdf,
-    0x2c362cf2,
+    0x2c332ca7,
+    0x2c33acb9,
+    0x2c342ccd,
+    0x2c34acdf,
+    0x2c352cfa,
+    0x2c35ad0c,
+    0x2c362d1f,
     0x2c36832d,
-    0x2c372cff,
-    0x2c37ad11,
-    0x2c382d36,
-    0x2c38ad4d,
-    0x2c392d5b,
-    0x2c39ad6b,
-    0x2c3a2d7d,
-    0x2c3aad91,
-    0x2c3b2da2,
-    0x2c3badc1,
+    0x2c372d2c,
+    0x2c37ad3e,
+    0x2c382d63,
+    0x2c38ad7a,
+    0x2c392d88,
+    0x2c39ad98,
+    0x2c3a2daa,
+    0x2c3aadbe,
+    0x2c3b2dcf,
+    0x2c3badee,
     0x2c3c12b7,
     0x2c3c92cd,
-    0x2c3d2dd5,
+    0x2c3d2e02,
     0x2c3d92e6,
-    0x2c3e2df2,
-    0x2c3eae00,
-    0x2c3f2e18,
-    0x2c3fae30,
-    0x2c402e3d,
+    0x2c3e2e1f,
+    0x2c3eae2d,
+    0x2c3f2e45,
+    0x2c3fae5d,
+    0x2c402e6a,
     0x2c4091b8,
-    0x2c412e4e,
-    0x2c41ae61,
+    0x2c412e7b,
+    0x2c41ae8e,
     0x2c42117e,
-    0x2c42ae72,
+    0x2c42ae9f,
     0x2c430720,
-    0x2c43adb3,
-    0x2c442d24,
+    0x2c43ade0,
+    0x2c442d51,
     0x30320000,
     0x30328015,
     0x3033001f,
@@ -399,177 +399,179 @@
     0x40469c71,
     0x40471c7f,
     0x40479ca6,
-    0x40481ce3,
-    0x40489d16,
-    0x40491d2d,
-    0x40499d47,
-    0x404a1d5e,
-    0x404a9d7c,
-    0x404b1d94,
-    0x404b9dab,
-    0x404c1dc1,
-    0x404c9dd3,
-    0x404d1df4,
-    0x404d9e16,
-    0x404e1e2a,
-    0x404e9e37,
-    0x404f1e64,
-    0x404f9e8d,
-    0x40501ec8,
-    0x40509edc,
-    0x40511ef7,
-    0x40521f07,
-    0x40529f2b,
-    0x40531f43,
-    0x40539f56,
-    0x40541f6b,
-    0x40549f8e,
-    0x40551f9c,
-    0x40559fb9,
-    0x40561fc6,
-    0x40569fdf,
-    0x40571ff7,
-    0x4057a00a,
-    0x4058201f,
-    0x4058a046,
-    0x40592075,
-    0x4059a0a2,
-    0x405a20b6,
-    0x405aa0c6,
-    0x405b20de,
-    0x405ba0ef,
-    0x405c2102,
-    0x405ca141,
-    0x405d214e,
-    0x405da165,
-    0x405e21a3,
+    0x40481cf9,
+    0x40489d2c,
+    0x40491d43,
+    0x40499d5d,
+    0x404a1d74,
+    0x404a9d92,
+    0x404b1daa,
+    0x404b9dc1,
+    0x404c1dd7,
+    0x404c9de9,
+    0x404d1e0a,
+    0x404d9e43,
+    0x404e1e57,
+    0x404e9e64,
+    0x404f1e91,
+    0x404f9eba,
+    0x40501ef5,
+    0x40509f09,
+    0x40511f24,
+    0x40521f34,
+    0x40529f58,
+    0x40531f70,
+    0x40539f83,
+    0x40541f98,
+    0x40549fbb,
+    0x40551fc9,
+    0x40559fe6,
+    0x40561ff3,
+    0x4056a00c,
+    0x40572024,
+    0x4057a037,
+    0x4058204c,
+    0x4058a073,
+    0x405920a2,
+    0x4059a0cf,
+    0x405a20e3,
+    0x405aa0f3,
+    0x405b210b,
+    0x405ba11c,
+    0x405c212f,
+    0x405ca16e,
+    0x405d217b,
+    0x405da192,
+    0x405e21d0,
     0x405e8ab1,
-    0x405f21c4,
-    0x405fa1d1,
-    0x406021df,
-    0x4060a201,
-    0x40612245,
-    0x4061a27d,
-    0x40622294,
-    0x4062a2a5,
-    0x406322b6,
-    0x4063a2cb,
-    0x406422e2,
-    0x4064a30e,
-    0x40652329,
-    0x4065a340,
-    0x40662358,
-    0x4066a382,
-    0x406723ad,
-    0x4067a3ce,
-    0x406823f5,
-    0x4068a416,
-    0x40692448,
-    0x4069a476,
-    0x406a2497,
-    0x406aa4b7,
-    0x406b263f,
-    0x406ba662,
-    0x406c2678,
-    0x406ca8f3,
-    0x406d2922,
-    0x406da94a,
-    0x406e2978,
-    0x406ea9c5,
-    0x406f29e4,
-    0x406faa1c,
-    0x40702a2f,
-    0x4070aa4c,
+    0x405f21f1,
+    0x405fa1fe,
+    0x4060220c,
+    0x4060a22e,
+    0x40612272,
+    0x4061a2aa,
+    0x406222c1,
+    0x4062a2d2,
+    0x406322e3,
+    0x4063a2f8,
+    0x4064230f,
+    0x4064a33b,
+    0x40652356,
+    0x4065a36d,
+    0x40662385,
+    0x4066a3af,
+    0x406723da,
+    0x4067a3fb,
+    0x40682422,
+    0x4068a443,
+    0x40692475,
+    0x4069a4a3,
+    0x406a24c4,
+    0x406aa4e4,
+    0x406b266c,
+    0x406ba68f,
+    0x406c26a5,
+    0x406ca920,
+    0x406d294f,
+    0x406da977,
+    0x406e29a5,
+    0x406ea9f2,
+    0x406f2a11,
+    0x406faa49,
+    0x40702a5c,
+    0x4070aa79,
     0x40710800,
-    0x4071aa5e,
-    0x40722a71,
-    0x4072aa8a,
-    0x40732aa2,
+    0x4071aa8b,
+    0x40722a9e,
+    0x4072aab7,
+    0x40732acf,
     0x407394a4,
-    0x40742ab6,
-    0x4074aad0,
-    0x40752ae1,
-    0x4075aaf5,
-    0x40762b03,
+    0x40742ae3,
+    0x4074aafd,
+    0x40752b0e,
+    0x4075ab22,
+    0x40762b30,
     0x4076927b,
-    0x40772b28,
-    0x4077ab4a,
-    0x40782b65,
-    0x4078ab9e,
-    0x40792bb5,
-    0x4079abcb,
-    0x407a2bd7,
-    0x407aabea,
-    0x407b2bff,
-    0x407bac11,
-    0x407c2c42,
-    0x407cac4b,
-    0x407d2431,
-    0x407d9e9d,
-    0x407e2b7a,
-    0x407ea056,
+    0x40772b55,
+    0x4077ab77,
+    0x40782b92,
+    0x4078abcb,
+    0x40792be2,
+    0x4079abf8,
+    0x407a2c04,
+    0x407aac17,
+    0x407b2c2c,
+    0x407bac3e,
+    0x407c2c6f,
+    0x407cac78,
+    0x407d245e,
+    0x407d9eca,
+    0x407e2ba7,
+    0x407ea083,
     0x407f1c93,
     0x407f9a53,
-    0x40801e74,
+    0x40801ea1,
     0x40809cbb,
-    0x40811f19,
-    0x40819e4e,
-    0x40822963,
+    0x40811f46,
+    0x40819e7b,
+    0x40822990,
     0x40829a39,
-    0x40832031,
-    0x4083a2f3,
+    0x4083205e,
+    0x4083a320,
     0x40841ccf,
-    0x4084a08e,
-    0x40852113,
-    0x4085a229,
-    0x40862185,
-    0x40869eb7,
-    0x408729a9,
-    0x4087a25a,
+    0x4084a0bb,
+    0x40852140,
+    0x4085a256,
+    0x408621b2,
+    0x40869ee4,
+    0x408729d6,
+    0x4087a287,
     0x40881a9a,
-    0x4088a3e1,
+    0x4088a40e,
     0x40891ae9,
     0x40899a76,
-    0x408a2698,
+    0x408a26c5,
     0x408a9884,
-    0x408b2c26,
-    0x408ba9f9,
-    0x408c2123,
+    0x408b2c53,
+    0x408baa26,
+    0x408c2150,
     0x408c98a0,
-    0x408d1cfc,
-    0x41f4256a,
-    0x41f925fc,
-    0x41fe24ef,
-    0x41fea6e4,
-    0x41ff27d5,
-    0x42032583,
-    0x420825a5,
-    0x4208a5e1,
-    0x420924d3,
-    0x4209a61b,
-    0x420a252a,
-    0x420aa50a,
-    0x420b254a,
-    0x420ba5c3,
-    0x420c27f1,
-    0x420ca6b1,
-    0x420d26cb,
-    0x420da702,
-    0x4212271c,
-    0x421727b8,
-    0x4217a75e,
-    0x421c2780,
-    0x421f273b,
-    0x42212808,
-    0x4226279b,
-    0x422b28d7,
-    0x422ba885,
-    0x422c28bf,
-    0x422ca844,
-    0x422d2823,
-    0x422da8a4,
-    0x422e286a,
-    0x422ea990,
+    0x408d1d12,
+    0x408d9ce3,
+    0x408e1e2c,
+    0x41f42597,
+    0x41f92629,
+    0x41fe251c,
+    0x41fea711,
+    0x41ff2802,
+    0x420325b0,
+    0x420825d2,
+    0x4208a60e,
+    0x42092500,
+    0x4209a648,
+    0x420a2557,
+    0x420aa537,
+    0x420b2577,
+    0x420ba5f0,
+    0x420c281e,
+    0x420ca6de,
+    0x420d26f8,
+    0x420da72f,
+    0x42122749,
+    0x421727e5,
+    0x4217a78b,
+    0x421c27ad,
+    0x421f2768,
+    0x42212835,
+    0x422627c8,
+    0x422b2904,
+    0x422ba8b2,
+    0x422c28ec,
+    0x422ca871,
+    0x422d2850,
+    0x422da8d1,
+    0x422e2897,
+    0x422ea9bd,
     0x4432072b,
     0x4432873a,
     0x44330746,
@@ -622,69 +624,69 @@
     0x4c4014c9,
     0x4c4092f7,
     0x4c4114ed,
-    0x50322e84,
-    0x5032ae93,
-    0x50332e9e,
-    0x5033aeae,
-    0x50342ec7,
-    0x5034aee1,
-    0x50352eef,
-    0x5035af05,
-    0x50362f17,
-    0x5036af2d,
-    0x50372f46,
-    0x5037af59,
-    0x50382f71,
-    0x5038af82,
-    0x50392f97,
-    0x5039afab,
-    0x503a2fcb,
-    0x503aafe1,
-    0x503b2ff9,
-    0x503bb00b,
-    0x503c3027,
-    0x503cb03e,
-    0x503d3057,
-    0x503db06d,
-    0x503e307a,
-    0x503eb090,
-    0x503f30a2,
+    0x50322eb1,
+    0x5032aec0,
+    0x50332ecb,
+    0x5033aedb,
+    0x50342ef4,
+    0x5034af0e,
+    0x50352f1c,
+    0x5035af32,
+    0x50362f44,
+    0x5036af5a,
+    0x50372f73,
+    0x5037af86,
+    0x50382f9e,
+    0x5038afaf,
+    0x50392fc4,
+    0x5039afd8,
+    0x503a2ff8,
+    0x503ab00e,
+    0x503b3026,
+    0x503bb038,
+    0x503c3054,
+    0x503cb06b,
+    0x503d3084,
+    0x503db09a,
+    0x503e30a7,
+    0x503eb0bd,
+    0x503f30cf,
     0x503f8382,
-    0x504030b5,
-    0x5040b0c5,
-    0x504130df,
-    0x5041b0ee,
-    0x50423108,
-    0x5042b125,
-    0x50433135,
-    0x5043b145,
-    0x50443154,
+    0x504030e2,
+    0x5040b0f2,
+    0x5041310c,
+    0x5041b11b,
+    0x50423135,
+    0x5042b152,
+    0x50433162,
+    0x5043b172,
+    0x50443181,
     0x5044843f,
-    0x50453168,
-    0x5045b186,
-    0x50463199,
-    0x5046b1af,
-    0x504731c1,
-    0x5047b1d6,
-    0x504831fc,
-    0x5048b20a,
-    0x5049321d,
-    0x5049b232,
-    0x504a3248,
-    0x504ab258,
-    0x504b3278,
-    0x504bb28b,
-    0x504c32ae,
-    0x504cb2dc,
-    0x504d32ee,
-    0x504db30b,
-    0x504e3326,
-    0x504eb342,
-    0x504f3354,
-    0x504fb36b,
-    0x5050337a,
+    0x50453195,
+    0x5045b1b3,
+    0x504631c6,
+    0x5046b1dc,
+    0x504731ee,
+    0x5047b203,
+    0x50483229,
+    0x5048b237,
+    0x5049324a,
+    0x5049b25f,
+    0x504a3275,
+    0x504ab285,
+    0x504b32a5,
+    0x504bb2b8,
+    0x504c32db,
+    0x504cb309,
+    0x504d331b,
+    0x504db338,
+    0x504e3353,
+    0x504eb36f,
+    0x504f3381,
+    0x504fb398,
+    0x505033a7,
     0x505086ef,
-    0x5051338d,
+    0x505133ba,
     0x58320f3a,
     0x68320efc,
     0x68328c6a,
@@ -1098,6 +1100,7 @@
     "DTLS_MESSAGE_TOO_BIG\0"
     "DUPLICATE_EXTENSION\0"
     "DUPLICATE_KEY_SHARE\0"
+    "EARLY_DATA_NOT_IN_USE\0"
     "ECC_CERT_NOT_FOR_SIGNING\0"
     "EMPTY_HELLO_RETRY_REQUEST\0"
     "EMS_STATE_INCONSISTENT\0"
@@ -1110,6 +1113,7 @@
     "FRAGMENT_MISMATCH\0"
     "GOT_NEXT_PROTO_WITHOUT_EXTENSION\0"
     "HANDSHAKE_FAILURE_ON_CLIENT_HELLO\0"
+    "HANDSHAKE_NOT_COMPLETE\0"
     "HTTPS_PROXY_REQUEST\0"
     "HTTP_REQUEST\0"
     "INAPPROPRIATE_FALLBACK\0"
diff --git a/ios-aarch64/crypto/fipsmodule/aesv8-armx64.S b/ios-aarch64/crypto/fipsmodule/aesv8-armx64.S
index 90310f6..787cce2 100644
--- a/ios-aarch64/crypto/fipsmodule/aesv8-armx64.S
+++ b/ios-aarch64/crypto/fipsmodule/aesv8-armx64.S
@@ -2,9 +2,7 @@
 
 #if __ARM_MAX_ARCH__>=7
 .text
-#if !defined(__clang__) || defined(BORINGSSL_CLANG_SUPPORTS_DOT_ARCH)
 
-#endif
 .align	5
 Lrcon:
 .long	0x01,0x01,0x01,0x01
diff --git a/ios-aarch64/crypto/fipsmodule/ghashv8-armx64.S b/ios-aarch64/crypto/fipsmodule/ghashv8-armx64.S
index 01d3232..cdf64e6 100644
--- a/ios-aarch64/crypto/fipsmodule/ghashv8-armx64.S
+++ b/ios-aarch64/crypto/fipsmodule/ghashv8-armx64.S
@@ -1,9 +1,7 @@
 #include <openssl/arm_arch.h>
 
 .text
-#if !defined(__clang__) || defined(BORINGSSL_CLANG_SUPPORTS_DOT_ARCH)
 
-#endif
 .globl	_gcm_init_v8
 .private_extern	_gcm_init_v8
 
diff --git a/ios-arm/crypto/chacha/chacha-armv4.S b/ios-arm/crypto/chacha/chacha-armv4.S
index 8c61ca5..2ec7129 100644
--- a/ios-arm/crypto/chacha/chacha-armv4.S
+++ b/ios-arm/crypto/chacha/chacha-armv4.S
@@ -1,5 +1,9 @@
 #include <openssl/arm_arch.h>
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions.
+
+
 .text
 #if defined(__thumb2__) || defined(__clang__)
 .syntax	unified
diff --git a/ios-arm/crypto/fipsmodule/aes-armv4.S b/ios-arm/crypto/fipsmodule/aes-armv4.S
index 516c89b..8d43e36 100644
--- a/ios-arm/crypto/fipsmodule/aes-armv4.S
+++ b/ios-arm/crypto/fipsmodule/aes-armv4.S
@@ -44,6 +44,11 @@
 # define __ARM_ARCH__ __LINUX_ARM_ARCH__
 #endif
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions. (ARMv8 AES
+@ instructions are in aesv8-armx.pl.)
+
+
 .text
 #if defined(__thumb2__) && !defined(__APPLE__)
 .syntax	unified
diff --git a/ios-arm/crypto/fipsmodule/armv4-mont.S b/ios-arm/crypto/fipsmodule/armv4-mont.S
index 1d516ef..fbb341f 100644
--- a/ios-arm/crypto/fipsmodule/armv4-mont.S
+++ b/ios-arm/crypto/fipsmodule/armv4-mont.S
@@ -1,5 +1,9 @@
 #include <openssl/arm_arch.h>
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions.
+
+
 .text
 #if defined(__thumb2__)
 .syntax	unified
diff --git a/ios-arm/crypto/fipsmodule/ghash-armv4.S b/ios-arm/crypto/fipsmodule/ghash-armv4.S
index 0a053c5..ace157f 100644
--- a/ios-arm/crypto/fipsmodule/ghash-armv4.S
+++ b/ios-arm/crypto/fipsmodule/ghash-armv4.S
@@ -1,5 +1,10 @@
 #include <openssl/arm_arch.h>
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions. (ARMv8 PMULL
+@ instructions are in aesv8-armx.pl.)
+
+
 .text
 #if defined(__thumb2__) || defined(__clang__)
 .syntax	unified
diff --git a/ios-arm/crypto/fipsmodule/sha256-armv4.S b/ios-arm/crypto/fipsmodule/sha256-armv4.S
index 2ea6517..7be4b6e 100644
--- a/ios-arm/crypto/fipsmodule/sha256-armv4.S
+++ b/ios-arm/crypto/fipsmodule/sha256-armv4.S
@@ -50,6 +50,11 @@
 # define __ARM_MAX_ARCH__ 7
 #endif
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors. It does have ARMv8-only code, but those
+@ instructions are manually-encoded. (See unsha256.)
+
+
 .text
 #if defined(__thumb2__)
 .syntax	unified
diff --git a/ios-arm/crypto/fipsmodule/sha512-armv4.S b/ios-arm/crypto/fipsmodule/sha512-armv4.S
index b225c99..68aa98d 100644
--- a/ios-arm/crypto/fipsmodule/sha512-armv4.S
+++ b/ios-arm/crypto/fipsmodule/sha512-armv4.S
@@ -63,6 +63,10 @@
 # define VFP_ABI_POP
 #endif
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions.
+
+
 #ifdef __ARMEL__
 # define LO 0
 # define HI 4
diff --git a/linux-aarch64/crypto/fipsmodule/aesv8-armx64.S b/linux-aarch64/crypto/fipsmodule/aesv8-armx64.S
index 51e2464..0903773 100644
--- a/linux-aarch64/crypto/fipsmodule/aesv8-armx64.S
+++ b/linux-aarch64/crypto/fipsmodule/aesv8-armx64.S
@@ -3,9 +3,7 @@
 
 #if __ARM_MAX_ARCH__>=7
 .text
-#if !defined(__clang__) || defined(BORINGSSL_CLANG_SUPPORTS_DOT_ARCH)
 .arch	armv8-a+crypto
-#endif
 .align	5
 .Lrcon:
 .long	0x01,0x01,0x01,0x01
diff --git a/linux-aarch64/crypto/fipsmodule/ghashv8-armx64.S b/linux-aarch64/crypto/fipsmodule/ghashv8-armx64.S
index 89d780f..bc59946 100644
--- a/linux-aarch64/crypto/fipsmodule/ghashv8-armx64.S
+++ b/linux-aarch64/crypto/fipsmodule/ghashv8-armx64.S
@@ -2,9 +2,7 @@
 #include <openssl/arm_arch.h>
 
 .text
-#if !defined(__clang__) || defined(BORINGSSL_CLANG_SUPPORTS_DOT_ARCH)
 .arch	armv8-a+crypto
-#endif
 .globl	gcm_init_v8
 .hidden	gcm_init_v8
 .type	gcm_init_v8,%function
diff --git a/linux-arm/crypto/chacha/chacha-armv4.S b/linux-arm/crypto/chacha/chacha-armv4.S
index 6c94773..bb48d17 100644
--- a/linux-arm/crypto/chacha/chacha-armv4.S
+++ b/linux-arm/crypto/chacha/chacha-armv4.S
@@ -1,6 +1,10 @@
 #if defined(__arm__)
 #include <openssl/arm_arch.h>
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions.
+.arch	armv7-a
+
 .text
 #if defined(__thumb2__) || defined(__clang__)
 .syntax	unified
diff --git a/linux-arm/crypto/fipsmodule/aes-armv4.S b/linux-arm/crypto/fipsmodule/aes-armv4.S
index d401fc7..5e49e08 100644
--- a/linux-arm/crypto/fipsmodule/aes-armv4.S
+++ b/linux-arm/crypto/fipsmodule/aes-armv4.S
@@ -45,6 +45,11 @@
 # define __ARM_ARCH__ __LINUX_ARM_ARCH__
 #endif
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions. (ARMv8 AES
+@ instructions are in aesv8-armx.pl.)
+.arch	armv7-a
+
 .text
 #if defined(__thumb2__) && !defined(__APPLE__)
 .syntax	unified
diff --git a/linux-arm/crypto/fipsmodule/armv4-mont.S b/linux-arm/crypto/fipsmodule/armv4-mont.S
index e77a9ea..1181a45 100644
--- a/linux-arm/crypto/fipsmodule/armv4-mont.S
+++ b/linux-arm/crypto/fipsmodule/armv4-mont.S
@@ -1,6 +1,10 @@
 #if defined(__arm__)
 #include <openssl/arm_arch.h>
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions.
+.arch	armv7-a
+
 .text
 #if defined(__thumb2__)
 .syntax	unified
diff --git a/linux-arm/crypto/fipsmodule/ghash-armv4.S b/linux-arm/crypto/fipsmodule/ghash-armv4.S
index 5f8b50d..2ead979 100644
--- a/linux-arm/crypto/fipsmodule/ghash-armv4.S
+++ b/linux-arm/crypto/fipsmodule/ghash-armv4.S
@@ -1,6 +1,11 @@
 #if defined(__arm__)
 #include <openssl/arm_arch.h>
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions. (ARMv8 PMULL
+@ instructions are in aesv8-armx.pl.)
+.arch	armv7-a
+
 .text
 #if defined(__thumb2__) || defined(__clang__)
 .syntax	unified
diff --git a/linux-arm/crypto/fipsmodule/sha256-armv4.S b/linux-arm/crypto/fipsmodule/sha256-armv4.S
index f37fd7c..3479a75 100644
--- a/linux-arm/crypto/fipsmodule/sha256-armv4.S
+++ b/linux-arm/crypto/fipsmodule/sha256-armv4.S
@@ -51,6 +51,11 @@
 # define __ARM_MAX_ARCH__ 7
 #endif
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors. It does have ARMv8-only code, but those
+@ instructions are manually-encoded. (See unsha256.)
+.arch	armv7-a
+
 .text
 #if defined(__thumb2__)
 .syntax	unified
diff --git a/linux-arm/crypto/fipsmodule/sha512-armv4.S b/linux-arm/crypto/fipsmodule/sha512-armv4.S
index bbeddf9..f02c0ff 100644
--- a/linux-arm/crypto/fipsmodule/sha512-armv4.S
+++ b/linux-arm/crypto/fipsmodule/sha512-armv4.S
@@ -64,6 +64,10 @@
 # define VFP_ABI_POP
 #endif
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions.
+.arch	armv7-a
+
 #ifdef __ARMEL__
 # define LO 0
 # define HI 4
diff --git a/src/BUILDING.md b/src/BUILDING.md
index eab61e2..46f27e3 100644
--- a/src/BUILDING.md
+++ b/src/BUILDING.md
@@ -79,14 +79,15 @@
 
 ### Building for Android
 
-It's possible to build BoringSSL with the Android NDK using CMake. This has
-been tested with version 10d of the NDK.
+It's possible to build BoringSSL with the Android NDK using CMake. Recent
+versions of the NDK include a CMake toolchain file which works with CMake 3.6.0
+or later. This has been tested with version r16b of the NDK.
 
 Unpack the Android NDK somewhere and export `ANDROID_NDK` to point to the
 directory. Then make a build directory as above and run CMake like this:
 
     cmake -DANDROID_ABI=armeabi-v7a \
-          -DCMAKE_TOOLCHAIN_FILE=../third_party/android-cmake/android.toolchain.cmake \
+          -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \
           -DANDROID_NATIVE_API_LEVEL=16 \
           -GNinja ..
 
@@ -94,7 +95,11 @@
 can replace `armeabi-v7a` in the above with `arm64-v8a` and use API level 21 or
 higher to build aarch64 binaries.
 
-For other options, see [android-cmake's documentation](./third_party/android-cmake/README.md).
+For older NDK versions, BoringSSL ships a third-party CMake toolchain file. Use
+`../third_party/android-cmake/android.toolchain.cmake` for
+`CMAKE_TOOLCHAIN_FILE` instead.
+
+For other options, see the documentation in the toolchain file.
 
 ### Building for iOS
 
@@ -145,18 +150,6 @@
 Note that if a feature is enabled in this way, but not actually supported at
 run-time, BoringSSL will likely crash.
 
-## Assembling ARMv8 with Clang
-
-In order to support the ARMv8 crypto instructions, Clang requires that the
-architecture be `armv8-a+crypto`. However, setting that as a general build flag
-would allow the compiler to assume that crypto instructions are *always*
-supported, even without testing for them.
-
-It's possible to set the architecture in an assembly file using the `.arch`
-directive, but only very recent versions of Clang support this. If
-`BORINGSSL_CLANG_SUPPORTS_DOT_ARCH` is defined then `.arch` directives will be
-used with Clang, otherwise you may need to craft acceptable assembler flags.
-
 # Running tests
 
 There are two sets of tests: the C/C++ tests and the blackbox tests. For former
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6674a41..95e2590 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -339,11 +339,11 @@
   message(FATAL_ERROR "Unknown processor:" ${CMAKE_SYSTEM_PROCESSOR})
 endif()
 
-if (ANDROID AND ${ARCH} STREQUAL "arm")
-  # The Android-NDK CMake files somehow fail to set the -march flag for
-  # assembly files. Without this flag, the compiler believes that it's
+if (ANDROID AND NOT ANDROID_NDK_REVISION AND ${ARCH} STREQUAL "arm")
+  # The third-party Android-NDK CMake files somehow fail to set the -march flag
+  # for assembly files. Without this flag, the compiler believes that it's
   # building for ARMv5.
-  set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -march=${CMAKE_SYSTEM_PROCESSOR}")
+  set(CMAKE_ASM_FLAGS "-march=${CMAKE_SYSTEM_PROCESSOR} ${CMAKE_ASM_FLAGS}")
 endif()
 
 if (${ARCH} STREQUAL "x86" AND APPLE AND ${CMAKE_VERSION} VERSION_LESS "3.0")
diff --git a/src/crypto/chacha/asm/chacha-armv4.pl b/src/crypto/chacha/asm/chacha-armv4.pl
index a173939..2a9a7d7 100755
--- a/src/crypto/chacha/asm/chacha-armv4.pl
+++ b/src/crypto/chacha/asm/chacha-armv4.pl
@@ -171,6 +171,10 @@
 $code.=<<___;
 #include <openssl/arm_arch.h>
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions.
+.arch  armv7-a
+
 .text
 #if defined(__thumb2__) || defined(__clang__)
 .syntax	unified
diff --git a/src/crypto/err/ssl.errordata b/src/crypto/err/ssl.errordata
index dec7347..58c9115 100644
--- a/src/crypto/err/ssl.errordata
+++ b/src/crypto/err/ssl.errordata
@@ -52,6 +52,7 @@
 SSL,143,DTLS_MESSAGE_TOO_BIG
 SSL,257,DUPLICATE_EXTENSION
 SSL,264,DUPLICATE_KEY_SHARE
+SSL,283,EARLY_DATA_NOT_IN_USE
 SSL,144,ECC_CERT_NOT_FOR_SIGNING
 SSL,282,EMPTY_HELLO_RETRY_REQUEST
 SSL,145,EMS_STATE_INCONSISTENT
@@ -64,6 +65,7 @@
 SSL,152,FRAGMENT_MISMATCH
 SSL,153,GOT_NEXT_PROTO_WITHOUT_EXTENSION
 SSL,154,HANDSHAKE_FAILURE_ON_CLIENT_HELLO
+SSL,284,HANDSHAKE_NOT_COMPLETE
 SSL,155,HTTPS_PROXY_REQUEST
 SSL,156,HTTP_REQUEST
 SSL,157,INAPPROPRIATE_FALLBACK
diff --git a/src/crypto/evp/evp_tests.txt b/src/crypto/evp/evp_tests.txt
index 2624473..b0f527c 100644
--- a/src/crypto/evp/evp_tests.txt
+++ b/src/crypto/evp/evp_tests.txt
@@ -545,6 +545,28 @@
 Input = "Hello World"
 CheckDecrypt
 
+# Though we will never generate such a key, test that RSA keys where p < q work
+# properly.
+PrivateKey = RSA-Swapped
+Type = RSA
+Input = 30820275020100300d06092a864886f70d01010105000482025f3082025b02010002818100ab28f98747934779011417d5bbb4095eae6f48ed09e13081616cf390aac75b10a206a98953d402647dfef7fa363be2765a303b05ec388bd9a1d75123a1205b4ecb43c33f2e37d3e30842181d694a3acfc39afc52554946e699d97d97066596a46725ce6dea322623afcafecbd2884d9a0c5eae9c4d7da8874c29c19edb762e1902030100010281800d637ea568e169f15ab6be288f6ec55edd29425c9c6dbb941b5160fa1b89cda34ef15378b5107c016d63b0f52721e71497f876dd7f3d6b1f228c4bc20c3c12384644200e91130c9195660d1e706f55b2accf00c5e2174a1d9ee289f0e763ee58860485ec97d19d7fa2df38af5b5910b1fa52087768d288e6ec4c8d5eca23c8d3024100be757a24dc2c923692d964693b2d71ca33ccb2f946f9e5232d2090b715a97dca554068fab8876105bc9ed6dccfd0917c5e0b80339306535c3eeb787e89397bc7024100e60f5c9e52434da079b8c641791a81a96daa4d9921a07e5b48292a9fce230df7c9fc2b97b5e38834ed5caaa387a0bca35c474e989a68dd65b79a6f691a74471f0240438ccf017bc5a3260ff76291a01782204136fcd344c524ebd0f997da17a8c1a09d93f6a7d602cdfa86e79f3539cfb389f4a1079b432e1f2abc762f8a51893dc9024046604ca4e1e554c9d27283b363a888219c3a8ca25b770d303f52d8872a37eefdedfc0619d2ba57e058fc0ff71676453e73ec1c4ef26d41ccebed824754a05d6102404445374d8450e753e0a42085b56b0d6d500b3e3518536dc8f12ec8fd77aa75491835327ac0e12d73b5c3f1b09d03f6a24fe63b9c551dee6559b625435ec92429
+
+Sign = RSA-Swapped
+Digest = SHA256
+Input = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+Output = 07fa4e3de9c002c41c952dc292ef5a814c4c17dc1a6cf958c4c971e8089676d6661b442270ef9295c41e5385c9628aa1bdee2cc2558b8473ba212f2ba04b9ff2264c19187b9506b1d0a1cc2751844cc8dedf555d62ce81bc0e70bfe83d0184ee964593af91b9b327c0fb272c799148cd8737d412cbf36c2ad25fd66977bf805f
+
+# Though we will never generate such a key, test that RSA keys where p and q are
+# different sizes work properly.
+PrivateKey = RSA-PrimeMismatch
+Type = RSA
+Input = 30820295020100300d06092a864886f70d01010105000482027f3082027b02010002818100c766f4fef89f5e9a8e13ed500fb38523ea94d7f8be066900eee58c913b4c6fdcb13d63d39b9108feabcefd1ffd04776403dc58f968ae817977d0809e567d8af512d604a0e9cb448fa5e402204ee519712a5ebbfd002faf8169495a782f54366b4665aac0d968bfec63c5446b6f9b13061c7f3d1f3f1b6bede8fff881b410a66f0203010001028180528c062f49485c771a0b18ca747d8a47f8941ea63c305626cb3f1f067e6861c4441c432687dbd08d484aac3b01f3ffdc3b762c719167f7cb22e565aa6acd597306ef6f7828b9720e9d440816186d940c4c5a9720dddf71fe0b59483f02a751515c8c27e43c575d6725d55f5bb77e0f977773b00afc058cfab6617ec90d0b62a9026100cb8f97c37b4fbc298b645bc3dc0526f8a4274e9a193b33c3acb76499b5b96330e4b586cbaa56368ffc12644952322253bc669496d572c0980f125fd7273739cf790d24401052b13732114d397c8c16a44716dc62d2320fb1ced99290dfd53e07022100fac51ac653609cdaba53280c6b6f209052e270be0c3c68fe8b37d6bf05fbba59026038dff2f04c58d7e2e7ae6fb1469d2de954bc22cb0d77ac1be4fb0ca1a1d39d7240c4b357de4cde4bd68b30f8077e38771af1b25c7e60e48cd7d1337402e1fc460ab57046720918b8aa4589452196669119c7ba65e602d4bdc264a9fdce7c5f2b0220773af0180bdc8bb7938fa6230191bcb1e236b7d4248d347e9242e25fc0c0874102605c4894cde334889f5b52ed8f86a2ee9c1fbe4166287e24ce44f3093bff383962f08043842f6ff3e6002104b0e29442c4a4483c5d06e2254fbe5e3930de3d0e28af10e96c6e341a4b8859382dbba24536a38ae71118e3e22413a93f298a7f744c
+
+Sign = RSA-PrimeMismatch
+Digest = SHA256
+Input = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+Output = 6192b1ce630c87d02e8245fd74d4f6ecac37eef979d188c8fa48c4d355fbe814e7dd3152f42bb020d769b540d11867af5b947387b8c99158d56901ff3708e423931178213916ae1002f162c9d497aacacdcb20e6ffe7ed40138a253fc943ddf3587433df5831a3ce46aeefce358a009bf6bad12d82d77424c2755d984d7da196
+
 
 # EC tests
 
diff --git a/src/crypto/fipsmodule/aes/asm/aes-armv4.pl b/src/crypto/fipsmodule/aes/asm/aes-armv4.pl
index c34d3dc..466a4ba 100644
--- a/src/crypto/fipsmodule/aes/asm/aes-armv4.pl
+++ b/src/crypto/fipsmodule/aes/asm/aes-armv4.pl
@@ -76,6 +76,11 @@
 # define __ARM_ARCH__ __LINUX_ARM_ARCH__
 #endif
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions. (ARMv8 AES
+@ instructions are in aesv8-armx.pl.)
+.arch  armv7-a
+
 .text
 #if defined(__thumb2__) && !defined(__APPLE__)
 .syntax	unified
diff --git a/src/crypto/fipsmodule/aes/asm/aesv8-armx.pl b/src/crypto/fipsmodule/aes/asm/aesv8-armx.pl
index ee07a3a..662814a 100644
--- a/src/crypto/fipsmodule/aes/asm/aesv8-armx.pl
+++ b/src/crypto/fipsmodule/aes/asm/aesv8-armx.pl
@@ -58,11 +58,7 @@
 #if __ARM_MAX_ARCH__>=7
 .text
 ___
-$code.=<<___ if ($flavour =~ /64/);
-#if !defined(__clang__) || defined(BORINGSSL_CLANG_SUPPORTS_DOT_ARCH)
-.arch  armv8-a+crypto
-#endif
-___
+$code.=".arch	armv8-a+crypto\n"			if ($flavour =~ /64/);
 $code.=<<___						if ($flavour !~ /64/);
 .arch	armv7-a	// don't confuse not-so-latest binutils with argv8 :-)
 .fpu	neon
diff --git a/src/crypto/fipsmodule/bcm.c b/src/crypto/fipsmodule/bcm.c
index b506b43..fb16215 100644
--- a/src/crypto/fipsmodule/bcm.c
+++ b/src/crypto/fipsmodule/bcm.c
@@ -67,10 +67,10 @@
 #include "ec/ec_montgomery.c"
 #include "ec/oct.c"
 #include "ec/p224-64.c"
-#include "ec/p256-64.c"
+#include "../../third_party/fiat/p256.c"
 #include "ec/p256-x86_64.c"
 #include "ec/simple.c"
-#include "ec/util-64.c"
+#include "ec/util.c"
 #include "ec/wnaf.c"
 #include "hmac/hmac.c"
 #include "md4/md4.c"
diff --git a/src/crypto/fipsmodule/bn/asm/armv4-mont.pl b/src/crypto/fipsmodule/bn/asm/armv4-mont.pl
index c2020cc..094e3b6 100644
--- a/src/crypto/fipsmodule/bn/asm/armv4-mont.pl
+++ b/src/crypto/fipsmodule/bn/asm/armv4-mont.pl
@@ -97,6 +97,10 @@
 $code=<<___;
 #include <openssl/arm_arch.h>
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions.
+.arch  armv7-a
+
 .text
 #if defined(__thumb2__)
 .syntax	unified
diff --git a/src/crypto/fipsmodule/bn/asm/x86_64-gcc.c b/src/crypto/fipsmodule/bn/asm/x86_64-gcc.c
index 49351c1..30fff21 100644
--- a/src/crypto/fipsmodule/bn/asm/x86_64-gcc.c
+++ b/src/crypto/fipsmodule/bn/asm/x86_64-gcc.c
@@ -52,8 +52,9 @@
 
 #include <openssl/bn.h>
 
-// TODO(davidben): Get this file working on Windows x64.
-#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && defined(__GNUC__)
+// TODO(davidben): Get this file working on MSVC x64.
+#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
+    (defined(__GNUC__) || defined(__clang__))
 
 #include "../internal.h"
 
@@ -537,4 +538,4 @@
 #undef mul_add_c2
 #undef sqr_add_c2
 
-#endif  // !NO_ASM && X86_64 && __GNUC__
+#endif  // !NO_ASM && X86_64 && (__GNUC__ || __clang__)
diff --git a/src/crypto/fipsmodule/bn/div.c b/src/crypto/fipsmodule/bn/div.c
index c92eab3..7f261f1 100644
--- a/src/crypto/fipsmodule/bn/div.c
+++ b/src/crypto/fipsmodule/bn/div.c
@@ -155,18 +155,18 @@
   //
   // These issues aren't specific to x86 and x86_64, so it might be worthwhile
   // to add more assembly language implementations.
-#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) && defined(__GNUC__)
-  __asm__ volatile (
-    "divl %4"
-    : "=a"(*quotient_out), "=d"(*rem_out)
-    : "a"(n1), "d"(n0), "rm"(d0)
-    : "cc" );
-#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && defined(__GNUC__)
-  __asm__ volatile (
-    "divq %4"
-    : "=a"(*quotient_out), "=d"(*rem_out)
-    : "a"(n1), "d"(n0), "rm"(d0)
-    : "cc" );
+#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) && \
+    (defined(__GNUC__) || defined(__clang__))
+  __asm__ volatile("divl %4"
+                   : "=a"(*quotient_out), "=d"(*rem_out)
+                   : "a"(n1), "d"(n0), "rm"(d0)
+                   : "cc");
+#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
+    (defined(__GNUC__) || defined(__clang__))
+  __asm__ volatile("divq %4"
+                   : "=a"(*quotient_out), "=d"(*rem_out)
+                   : "a"(n1), "d"(n0), "rm"(d0)
+                   : "cc");
 #else
 #if defined(BN_ULLONG)
   BN_ULLONG n = (((BN_ULLONG)n0) << BN_BITS2) | n1;
@@ -617,7 +617,7 @@
 }
 
 BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) {
-#ifndef BN_ULLONG
+#ifndef BN_CAN_DIVIDE_ULLONG
   BN_ULONG ret = 0;
 #else
   BN_ULLONG ret = 0;
@@ -628,9 +628,9 @@
     return (BN_ULONG) -1;
   }
 
-#ifndef BN_ULLONG
-  // If |w| is too long and we don't have |BN_ULLONG| then we need to fall back
-  // to using |BN_div_word|.
+#ifndef BN_CAN_DIVIDE_ULLONG
+  // If |w| is too long and we don't have |BN_ULLONG| division then we need to
+  // fall back to using |BN_div_word|.
   if (w > ((BN_ULONG)1 << BN_BITS4)) {
     BIGNUM *tmp = BN_dup(a);
     if (tmp == NULL) {
@@ -643,7 +643,7 @@
 #endif
 
   for (i = a->top - 1; i >= 0; i--) {
-#ifndef BN_ULLONG
+#ifndef BN_CAN_DIVIDE_ULLONG
     ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w;
     ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w;
 #else
diff --git a/src/crypto/fipsmodule/bn/generic.c b/src/crypto/fipsmodule/bn/generic.c
index a39a033..ee80a3c 100644
--- a/src/crypto/fipsmodule/bn/generic.c
+++ b/src/crypto/fipsmodule/bn/generic.c
@@ -64,7 +64,8 @@
 // This file has two other implementations: x86 assembly language in
 // asm/bn-586.pl and x86_64 inline assembly in asm/x86_64-gcc.c.
 #if defined(OPENSSL_NO_ASM) || \
-    !(defined(OPENSSL_X86) || (defined(OPENSSL_X86_64) && defined(__GNUC__)))
+    !(defined(OPENSSL_X86) ||  \
+      (defined(OPENSSL_X86_64) && (defined(__GNUC__) || defined(__clang__))))
 
 #ifdef BN_ULLONG
 #define mul_add(r, a, w, c)               \
diff --git a/src/crypto/fipsmodule/bn/internal.h b/src/crypto/fipsmodule/bn/internal.h
index 75efbfa..706e544 100644
--- a/src/crypto/fipsmodule/bn/internal.h
+++ b/src/crypto/fipsmodule/bn/internal.h
@@ -140,9 +140,12 @@
 
 #if defined(OPENSSL_64_BIT)
 
-#if !defined(_MSC_VER)
+#if defined(BORINGSSL_HAS_UINT128)
 // MSVC doesn't support two-word integers on 64-bit.
 #define BN_ULLONG uint128_t
+#if defined(BORINGSSL_CAN_DIVIDE_UINT128)
+#define BN_CAN_DIVIDE_ULLONG
+#endif
 #endif
 
 #define BN_BITS2 64
@@ -160,6 +163,7 @@
 #elif defined(OPENSSL_32_BIT)
 
 #define BN_ULLONG uint64_t
+#define BN_CAN_DIVIDE_ULLONG
 #define BN_BITS2 32
 #define BN_BYTES 4
 #define BN_BITS4 16
diff --git a/src/crypto/fipsmodule/ec/ec.c b/src/crypto/fipsmodule/ec/ec.c
index 41c2540..47a90ce 100644
--- a/src/crypto/fipsmodule/ec/ec.c
+++ b/src/crypto/fipsmodule/ec/ec.c
@@ -215,13 +215,6 @@
     0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09,
 };
 
-// MSan appears to have a bug that causes code to be miscompiled in opt mode.
-// While that is being looked at, don't run the uint128_t code under MSan.
-#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \
-    !defined(MEMORY_SANITIZER)
-#define BORINGSSL_USE_INT128_CODE
-#endif
-
 DEFINE_METHOD_FUNCTION(struct built_in_curves, OPENSSL_built_in_curves) {
   // 1.3.132.0.35
   static const uint8_t kOIDP521[] = {0x2b, 0x81, 0x04, 0x00, 0x23};
@@ -253,16 +246,12 @@
   out->curves[2].param_len = 32;
   out->curves[2].params = kP256Params;
   out->curves[2].method =
-#if defined(BORINGSSL_USE_INT128_CODE)
 #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
     !defined(OPENSSL_SMALL)
       EC_GFp_nistz256_method();
 #else
       EC_GFp_nistp256_method();
 #endif
-#else
-      EC_GFp_mont_method();
-#endif
 
   // 1.3.132.0.33
   static const uint8_t kOIDP224[] = {0x2b, 0x81, 0x04, 0x00, 0x21};
@@ -273,7 +262,7 @@
   out->curves[3].param_len = 28;
   out->curves[3].params = kP224Params;
   out->curves[3].method =
-#if defined(BORINGSSL_USE_INT128_CODE) && !defined(OPENSSL_SMALL)
+#if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL)
       EC_GFp_nistp224_method();
 #else
       EC_GFp_mont_method();
@@ -883,6 +872,24 @@
   return ret;
 }
 
+int ec_point_mul_scalar_public(const EC_GROUP *group, EC_POINT *r,
+                               const EC_SCALAR *g_scalar, const EC_POINT *p,
+                               const EC_SCALAR *p_scalar, BN_CTX *ctx) {
+  if ((g_scalar == NULL && p_scalar == NULL) ||
+      (p == NULL) != (p_scalar == NULL))  {
+    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
+    return 0;
+  }
+
+  if (EC_GROUP_cmp(group, r->group, NULL) != 0 ||
+      (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) {
+    OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
+    return 0;
+  }
+
+  return group->meth->mul_public(group, r, g_scalar, p, p_scalar, ctx);
+}
+
 int ec_point_mul_scalar(const EC_GROUP *group, EC_POINT *r,
                         const EC_SCALAR *g_scalar, const EC_POINT *p,
                         const EC_SCALAR *p_scalar, BN_CTX *ctx) {
diff --git a/src/crypto/fipsmodule/ec/ec_montgomery.c b/src/crypto/fipsmodule/ec/ec_montgomery.c
index 6670b84..898cf07 100644
--- a/src/crypto/fipsmodule/ec/ec_montgomery.c
+++ b/src/crypto/fipsmodule/ec/ec_montgomery.c
@@ -270,6 +270,7 @@
   out->group_set_curve = ec_GFp_mont_group_set_curve;
   out->point_get_affine_coordinates = ec_GFp_mont_point_get_affine_coordinates;
   out->mul = ec_wNAF_mul /* XXX: Not constant time. */;
+  out->mul_public = ec_wNAF_mul;
   out->field_mul = ec_GFp_mont_field_mul;
   out->field_sqr = ec_GFp_mont_field_sqr;
   out->field_encode = ec_GFp_mont_field_encode;
diff --git a/src/crypto/fipsmodule/ec/internal.h b/src/crypto/fipsmodule/ec/internal.h
index 1b860c6..145c5c4 100644
--- a/src/crypto/fipsmodule/ec/internal.h
+++ b/src/crypto/fipsmodule/ec/internal.h
@@ -115,6 +115,12 @@
   // non-null.
   int (*mul)(const EC_GROUP *group, EC_POINT *r, const EC_SCALAR *g_scalar,
              const EC_POINT *p, const EC_SCALAR *p_scalar, BN_CTX *ctx);
+  // mul_public performs the same computation as mul. It further assumes that
+  // the inputs are public so there is no concern about leaking their values
+  // through timing.
+  int (*mul_public)(const EC_GROUP *group, EC_POINT *r,
+                    const EC_SCALAR *g_scalar, const EC_POINT *p,
+                    const EC_SCALAR *p_scalar, BN_CTX *ctx);
 
   // 'field_mul' and 'field_sqr' can be used by 'add' and 'dbl' so that the
   // same implementations of point operations can be used with different
@@ -195,6 +201,13 @@
                         const EC_SCALAR *g_scalar, const EC_POINT *p,
                         const EC_SCALAR *p_scalar, BN_CTX *ctx);
 
+// ec_point_mul_scalar_public performs the same computation as
+// ec_point_mul_scalar.  It further assumes that the inputs are public so
+// there is no concern about leaking their values through timing.
+int ec_point_mul_scalar_public(const EC_GROUP *group, EC_POINT *r,
+                               const EC_SCALAR *g_scalar, const EC_POINT *p,
+                               const EC_SCALAR *p_scalar, BN_CTX *ctx);
+
 int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const EC_SCALAR *g_scalar,
                 const EC_POINT *p, const EC_SCALAR *p_scalar, BN_CTX *ctx);
 
diff --git a/src/crypto/fipsmodule/ec/p224-64.c b/src/crypto/fipsmodule/ec/p224-64.c
index ba25d22..0097209 100644
--- a/src/crypto/fipsmodule/ec/p224-64.c
+++ b/src/crypto/fipsmodule/ec/p224-64.c
@@ -19,9 +19,6 @@
 
 #include <openssl/base.h>
 
-#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \
-    !defined(OPENSSL_SMALL)
-
 #include <openssl/bn.h>
 #include <openssl/ec.h>
 #include <openssl/err.h>
@@ -34,6 +31,8 @@
 #include "../../internal.h"
 
 
+#if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL)
+
 // Field elements are represented as a_0 + 2^56*a_1 + 2^112*a_2 + 2^168*a_3
 // using 64-bit coefficients called 'limbs', and sometimes (for multiplication
 // results) as b_0 + 2^56*b_1 + 2^112*b_2 + 2^168*b_3 + 2^224*b_4 + 2^280*b_5 +
@@ -1122,10 +1121,11 @@
   out->point_get_affine_coordinates =
       ec_GFp_nistp224_point_get_affine_coordinates;
   out->mul = ec_GFp_nistp224_points_mul;
+  out->mul_public = ec_GFp_nistp224_points_mul;
   out->field_mul = ec_GFp_simple_field_mul;
   out->field_sqr = ec_GFp_simple_field_sqr;
   out->field_encode = NULL;
   out->field_decode = NULL;
 };
 
-#endif  // 64_BIT && !WINDOWS && !SMALL
+#endif  // BORINGSSL_HAS_UINT128 && !SMALL
diff --git a/src/crypto/fipsmodule/ec/p256-64.c b/src/crypto/fipsmodule/ec/p256-64.c
deleted file mode 100644
index d4a8ff6..0000000
--- a/src/crypto/fipsmodule/ec/p256-64.c
+++ /dev/null
@@ -1,1674 +0,0 @@
-/* Copyright (c) 2015, Google Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-
-// A 64-bit implementation of the NIST P-256 elliptic curve point
-// multiplication
-//
-// OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c.
-// Otherwise based on Emilia's P224 work, which was inspired by my curve25519
-// work which got its smarts from Daniel J. Bernstein's work on the same.
-
-#include <openssl/base.h>
-
-#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS)
-
-#include <openssl/bn.h>
-#include <openssl/ec.h>
-#include <openssl/err.h>
-#include <openssl/mem.h>
-
-#include <string.h>
-
-#include "../delocate.h"
-#include "../../internal.h"
-#include "internal.h"
-
-
-// The underlying field. P256 operates over GF(2^256-2^224+2^192+2^96-1). We
-// can serialise an element of this field into 32 bytes. We call this an
-// felem_bytearray.
-typedef uint8_t felem_bytearray[32];
-
-// The representation of field elements.
-// ------------------------------------
-//
-// We represent field elements with either four 128-bit values, eight 128-bit
-// values, or four 64-bit values. The field element represented is:
-//   v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + v[3]*2^192  (mod p)
-// or:
-//   v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + ... + v[8]*2^512  (mod p)
-//
-// 128-bit values are called 'limbs'. Since the limbs are spaced only 64 bits
-// apart, but are 128-bits wide, the most significant bits of each limb overlap
-// with the least significant bits of the next.
-//
-// A field element with four limbs is an 'felem'. One with eight limbs is a
-// 'longfelem'
-//
-// A field element with four, 64-bit values is called a 'smallfelem'. Small
-// values are used as intermediate values before multiplication.
-
-#define NLIMBS 4
-
-typedef uint128_t limb;
-typedef limb felem[NLIMBS];
-typedef limb longfelem[NLIMBS * 2];
-typedef uint64_t smallfelem[NLIMBS];
-
-// This is the value of the prime as four 64-bit words, little-endian.
-static const uint64_t kPrime[4] = {0xfffffffffffffffful, 0xffffffff, 0,
-                              0xffffffff00000001ul};
-static const uint64_t bottom63bits = 0x7ffffffffffffffful;
-
-static uint64_t load_u64(const uint8_t in[8]) {
-  uint64_t ret;
-  OPENSSL_memcpy(&ret, in, sizeof(ret));
-  return ret;
-}
-
-static void store_u64(uint8_t out[8], uint64_t in) {
-  OPENSSL_memcpy(out, &in, sizeof(in));
-}
-
-// bin32_to_felem takes a little-endian byte array and converts it into felem
-// form. This assumes that the CPU is little-endian.
-static void bin32_to_felem(felem out, const uint8_t in[32]) {
-  out[0] = load_u64(&in[0]);
-  out[1] = load_u64(&in[8]);
-  out[2] = load_u64(&in[16]);
-  out[3] = load_u64(&in[24]);
-}
-
-// smallfelem_to_bin32 takes a smallfelem and serialises into a little endian,
-// 32 byte array. This assumes that the CPU is little-endian.
-static void smallfelem_to_bin32(uint8_t out[32], const smallfelem in) {
-  store_u64(&out[0], in[0]);
-  store_u64(&out[8], in[1]);
-  store_u64(&out[16], in[2]);
-  store_u64(&out[24], in[3]);
-}
-
-// To preserve endianness when using BN_bn2bin and BN_bin2bn.
-static void flip_endian(uint8_t *out, const uint8_t *in, size_t len) {
-  for (size_t i = 0; i < len; ++i) {
-    out[i] = in[len - 1 - i];
-  }
-}
-
-// BN_to_felem converts an OpenSSL BIGNUM into an felem.
-static int BN_to_felem(felem out, const BIGNUM *bn) {
-  if (BN_is_negative(bn)) {
-    OPENSSL_PUT_ERROR(EC, EC_R_BIGNUM_OUT_OF_RANGE);
-    return 0;
-  }
-
-  felem_bytearray b_out;
-  // BN_bn2bin eats leading zeroes
-  OPENSSL_memset(b_out, 0, sizeof(b_out));
-  size_t num_bytes = BN_num_bytes(bn);
-  if (num_bytes > sizeof(b_out)) {
-    OPENSSL_PUT_ERROR(EC, EC_R_BIGNUM_OUT_OF_RANGE);
-    return 0;
-  }
-
-  felem_bytearray b_in;
-  num_bytes = BN_bn2bin(bn, b_in);
-  flip_endian(b_out, b_in, num_bytes);
-  bin32_to_felem(out, b_out);
-  return 1;
-}
-
-// felem_to_BN converts an felem into an OpenSSL BIGNUM.
-static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in) {
-  felem_bytearray b_in, b_out;
-  smallfelem_to_bin32(b_in, in);
-  flip_endian(b_out, b_in, sizeof(b_out));
-  return BN_bin2bn(b_out, sizeof(b_out), out);
-}
-
-// Field operations.
-
-static void felem_assign(felem out, const felem in) {
-  out[0] = in[0];
-  out[1] = in[1];
-  out[2] = in[2];
-  out[3] = in[3];
-}
-
-// felem_sum sets out = out + in.
-static void felem_sum(felem out, const felem in) {
-  out[0] += in[0];
-  out[1] += in[1];
-  out[2] += in[2];
-  out[3] += in[3];
-}
-
-// felem_small_sum sets out = out + in.
-static void felem_small_sum(felem out, const smallfelem in) {
-  out[0] += in[0];
-  out[1] += in[1];
-  out[2] += in[2];
-  out[3] += in[3];
-}
-
-// felem_scalar sets out = out * scalar
-static void felem_scalar(felem out, const uint64_t scalar) {
-  out[0] *= scalar;
-  out[1] *= scalar;
-  out[2] *= scalar;
-  out[3] *= scalar;
-}
-
-// longfelem_scalar sets out = out * scalar
-static void longfelem_scalar(longfelem out, const uint64_t scalar) {
-  out[0] *= scalar;
-  out[1] *= scalar;
-  out[2] *= scalar;
-  out[3] *= scalar;
-  out[4] *= scalar;
-  out[5] *= scalar;
-  out[6] *= scalar;
-  out[7] *= scalar;
-}
-
-#define two105m41m9 ((((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9))
-#define two105 (((limb)1) << 105)
-#define two105m41p9 ((((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9))
-
-// zero105 is 0 mod p
-static const felem zero105 = {two105m41m9, two105, two105m41p9, two105m41p9};
-
-// smallfelem_neg sets |out| to |-small|
-// On exit:
-//   out[i] < out[i] + 2^105
-static void smallfelem_neg(felem out, const smallfelem small) {
-  // In order to prevent underflow, we subtract from 0 mod p.
-  out[0] = zero105[0] - small[0];
-  out[1] = zero105[1] - small[1];
-  out[2] = zero105[2] - small[2];
-  out[3] = zero105[3] - small[3];
-}
-
-// felem_diff subtracts |in| from |out|
-// On entry:
-//   in[i] < 2^104
-// On exit:
-//   out[i] < out[i] + 2^105.
-static void felem_diff(felem out, const felem in) {
-  // In order to prevent underflow, we add 0 mod p before subtracting.
-  out[0] += zero105[0];
-  out[1] += zero105[1];
-  out[2] += zero105[2];
-  out[3] += zero105[3];
-
-  out[0] -= in[0];
-  out[1] -= in[1];
-  out[2] -= in[2];
-  out[3] -= in[3];
-}
-
-#define two107m43m11 \
-  ((((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11))
-#define two107 (((limb)1) << 107)
-#define two107m43p11 \
-  ((((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11))
-
-// zero107 is 0 mod p
-static const felem zero107 = {two107m43m11, two107, two107m43p11, two107m43p11};
-
-// An alternative felem_diff for larger inputs |in|
-// felem_diff_zero107 subtracts |in| from |out|
-// On entry:
-//   in[i] < 2^106
-// On exit:
-//   out[i] < out[i] + 2^107.
-static void felem_diff_zero107(felem out, const felem in) {
-  // In order to prevent underflow, we add 0 mod p before subtracting.
-  out[0] += zero107[0];
-  out[1] += zero107[1];
-  out[2] += zero107[2];
-  out[3] += zero107[3];
-
-  out[0] -= in[0];
-  out[1] -= in[1];
-  out[2] -= in[2];
-  out[3] -= in[3];
-}
-
-// longfelem_diff subtracts |in| from |out|
-// On entry:
-//   in[i] < 7*2^67
-// On exit:
-//   out[i] < out[i] + 2^70 + 2^40.
-static void longfelem_diff(longfelem out, const longfelem in) {
-  static const limb two70m8p6 =
-      (((limb)1) << 70) - (((limb)1) << 8) + (((limb)1) << 6);
-  static const limb two70p40 = (((limb)1) << 70) + (((limb)1) << 40);
-  static const limb two70 = (((limb)1) << 70);
-  static const limb two70m40m38p6 = (((limb)1) << 70) - (((limb)1) << 40) -
-                                    (((limb)1) << 38) + (((limb)1) << 6);
-  static const limb two70m6 = (((limb)1) << 70) - (((limb)1) << 6);
-
-  // add 0 mod p to avoid underflow
-  out[0] += two70m8p6;
-  out[1] += two70p40;
-  out[2] += two70;
-  out[3] += two70m40m38p6;
-  out[4] += two70m6;
-  out[5] += two70m6;
-  out[6] += two70m6;
-  out[7] += two70m6;
-
-  // in[i] < 7*2^67 < 2^70 - 2^40 - 2^38 + 2^6
-  out[0] -= in[0];
-  out[1] -= in[1];
-  out[2] -= in[2];
-  out[3] -= in[3];
-  out[4] -= in[4];
-  out[5] -= in[5];
-  out[6] -= in[6];
-  out[7] -= in[7];
-}
-
-#define two64m0 ((((limb)1) << 64) - 1)
-#define two110p32m0 ((((limb)1) << 110) + (((limb)1) << 32) - 1)
-#define two64m46 ((((limb)1) << 64) - (((limb)1) << 46))
-#define two64m32 ((((limb)1) << 64) - (((limb)1) << 32))
-
-// zero110 is 0 mod p.
-static const felem zero110 = {two64m0, two110p32m0, two64m46, two64m32};
-
-// felem_shrink converts an felem into a smallfelem. The result isn't quite
-// minimal as the value may be greater than p.
-//
-// On entry:
-//   in[i] < 2^109
-// On exit:
-//   out[i] < 2^64.
-static void felem_shrink(smallfelem out, const felem in) {
-  felem tmp;
-  uint64_t a, b, mask;
-  int64_t high, low;
-  static const uint64_t kPrime3Test =
-      0x7fffffff00000001ul;  // 2^63 - 2^32 + 1
-
-  // Carry 2->3
-  tmp[3] = zero110[3] + in[3] + ((uint64_t)(in[2] >> 64));
-  // tmp[3] < 2^110
-
-  tmp[2] = zero110[2] + (uint64_t)in[2];
-  tmp[0] = zero110[0] + in[0];
-  tmp[1] = zero110[1] + in[1];
-  // tmp[0] < 2**110, tmp[1] < 2^111, tmp[2] < 2**65
-
-  // We perform two partial reductions where we eliminate the high-word of
-  // tmp[3]. We don't update the other words till the end.
-  a = tmp[3] >> 64;  // a < 2^46
-  tmp[3] = (uint64_t)tmp[3];
-  tmp[3] -= a;
-  tmp[3] += ((limb)a) << 32;
-  // tmp[3] < 2^79
-
-  b = a;
-  a = tmp[3] >> 64;  // a < 2^15
-  b += a;            // b < 2^46 + 2^15 < 2^47
-  tmp[3] = (uint64_t)tmp[3];
-  tmp[3] -= a;
-  tmp[3] += ((limb)a) << 32;
-  // tmp[3] < 2^64 + 2^47
-
-  // This adjusts the other two words to complete the two partial
-  // reductions.
-  tmp[0] += b;
-  tmp[1] -= (((limb)b) << 32);
-
-  // In order to make space in tmp[3] for the carry from 2 -> 3, we
-  // conditionally subtract kPrime if tmp[3] is large enough.
-  high = tmp[3] >> 64;
-  // As tmp[3] < 2^65, high is either 1 or 0
-  high = ~(high - 1);
-  // high is:
-  //   all ones   if the high word of tmp[3] is 1
-  //   all zeros  if the high word of tmp[3] if 0
-  low = tmp[3];
-  mask = low >> 63;
-  // mask is:
-  //   all ones   if the MSB of low is 1
-  //   all zeros  if the MSB of low if 0
-  low &= bottom63bits;
-  low -= kPrime3Test;
-  // if low was greater than kPrime3Test then the MSB is zero
-  low = ~low;
-  low >>= 63;
-  // low is:
-  //   all ones   if low was > kPrime3Test
-  //   all zeros  if low was <= kPrime3Test
-  mask = (mask & low) | high;
-  tmp[0] -= mask & kPrime[0];
-  tmp[1] -= mask & kPrime[1];
-  // kPrime[2] is zero, so omitted
-  tmp[3] -= mask & kPrime[3];
-  // tmp[3] < 2**64 - 2**32 + 1
-
-  tmp[1] += ((uint64_t)(tmp[0] >> 64));
-  tmp[0] = (uint64_t)tmp[0];
-  tmp[2] += ((uint64_t)(tmp[1] >> 64));
-  tmp[1] = (uint64_t)tmp[1];
-  tmp[3] += ((uint64_t)(tmp[2] >> 64));
-  tmp[2] = (uint64_t)tmp[2];
-  // tmp[i] < 2^64
-
-  out[0] = tmp[0];
-  out[1] = tmp[1];
-  out[2] = tmp[2];
-  out[3] = tmp[3];
-}
-
-// smallfelem_expand converts a smallfelem to an felem
-static void smallfelem_expand(felem out, const smallfelem in) {
-  out[0] = in[0];
-  out[1] = in[1];
-  out[2] = in[2];
-  out[3] = in[3];
-}
-
-// smallfelem_square sets |out| = |small|^2
-// On entry:
-//   small[i] < 2^64
-// On exit:
-//   out[i] < 7 * 2^64 < 2^67
-static void smallfelem_square(longfelem out, const smallfelem small) {
-  limb a;
-  uint64_t high, low;
-
-  a = ((uint128_t)small[0]) * small[0];
-  low = a;
-  high = a >> 64;
-  out[0] = low;
-  out[1] = high;
-
-  a = ((uint128_t)small[0]) * small[1];
-  low = a;
-  high = a >> 64;
-  out[1] += low;
-  out[1] += low;
-  out[2] = high;
-
-  a = ((uint128_t)small[0]) * small[2];
-  low = a;
-  high = a >> 64;
-  out[2] += low;
-  out[2] *= 2;
-  out[3] = high;
-
-  a = ((uint128_t)small[0]) * small[3];
-  low = a;
-  high = a >> 64;
-  out[3] += low;
-  out[4] = high;
-
-  a = ((uint128_t)small[1]) * small[2];
-  low = a;
-  high = a >> 64;
-  out[3] += low;
-  out[3] *= 2;
-  out[4] += high;
-
-  a = ((uint128_t)small[1]) * small[1];
-  low = a;
-  high = a >> 64;
-  out[2] += low;
-  out[3] += high;
-
-  a = ((uint128_t)small[1]) * small[3];
-  low = a;
-  high = a >> 64;
-  out[4] += low;
-  out[4] *= 2;
-  out[5] = high;
-
-  a = ((uint128_t)small[2]) * small[3];
-  low = a;
-  high = a >> 64;
-  out[5] += low;
-  out[5] *= 2;
-  out[6] = high;
-  out[6] += high;
-
-  a = ((uint128_t)small[2]) * small[2];
-  low = a;
-  high = a >> 64;
-  out[4] += low;
-  out[5] += high;
-
-  a = ((uint128_t)small[3]) * small[3];
-  low = a;
-  high = a >> 64;
-  out[6] += low;
-  out[7] = high;
-}
-
-//felem_square sets |out| = |in|^2
-// On entry:
-//   in[i] < 2^109
-// On exit:
-//   out[i] < 7 * 2^64 < 2^67.
-static void felem_square(longfelem out, const felem in) {
-  uint64_t small[4];
-  felem_shrink(small, in);
-  smallfelem_square(out, small);
-}
-
-// smallfelem_mul sets |out| = |small1| * |small2|
-// On entry:
-//   small1[i] < 2^64
-//   small2[i] < 2^64
-// On exit:
-//   out[i] < 7 * 2^64 < 2^67.
-static void smallfelem_mul(longfelem out, const smallfelem small1,
-                           const smallfelem small2) {
-  limb a;
-  uint64_t high, low;
-
-  a = ((uint128_t)small1[0]) * small2[0];
-  low = a;
-  high = a >> 64;
-  out[0] = low;
-  out[1] = high;
-
-  a = ((uint128_t)small1[0]) * small2[1];
-  low = a;
-  high = a >> 64;
-  out[1] += low;
-  out[2] = high;
-
-  a = ((uint128_t)small1[1]) * small2[0];
-  low = a;
-  high = a >> 64;
-  out[1] += low;
-  out[2] += high;
-
-  a = ((uint128_t)small1[0]) * small2[2];
-  low = a;
-  high = a >> 64;
-  out[2] += low;
-  out[3] = high;
-
-  a = ((uint128_t)small1[1]) * small2[1];
-  low = a;
-  high = a >> 64;
-  out[2] += low;
-  out[3] += high;
-
-  a = ((uint128_t)small1[2]) * small2[0];
-  low = a;
-  high = a >> 64;
-  out[2] += low;
-  out[3] += high;
-
-  a = ((uint128_t)small1[0]) * small2[3];
-  low = a;
-  high = a >> 64;
-  out[3] += low;
-  out[4] = high;
-
-  a = ((uint128_t)small1[1]) * small2[2];
-  low = a;
-  high = a >> 64;
-  out[3] += low;
-  out[4] += high;
-
-  a = ((uint128_t)small1[2]) * small2[1];
-  low = a;
-  high = a >> 64;
-  out[3] += low;
-  out[4] += high;
-
-  a = ((uint128_t)small1[3]) * small2[0];
-  low = a;
-  high = a >> 64;
-  out[3] += low;
-  out[4] += high;
-
-  a = ((uint128_t)small1[1]) * small2[3];
-  low = a;
-  high = a >> 64;
-  out[4] += low;
-  out[5] = high;
-
-  a = ((uint128_t)small1[2]) * small2[2];
-  low = a;
-  high = a >> 64;
-  out[4] += low;
-  out[5] += high;
-
-  a = ((uint128_t)small1[3]) * small2[1];
-  low = a;
-  high = a >> 64;
-  out[4] += low;
-  out[5] += high;
-
-  a = ((uint128_t)small1[2]) * small2[3];
-  low = a;
-  high = a >> 64;
-  out[5] += low;
-  out[6] = high;
-
-  a = ((uint128_t)small1[3]) * small2[2];
-  low = a;
-  high = a >> 64;
-  out[5] += low;
-  out[6] += high;
-
-  a = ((uint128_t)small1[3]) * small2[3];
-  low = a;
-  high = a >> 64;
-  out[6] += low;
-  out[7] = high;
-}
-
-// felem_mul sets |out| = |in1| * |in2|
-// On entry:
-//   in1[i] < 2^109
-//   in2[i] < 2^109
-// On exit:
-//   out[i] < 7 * 2^64 < 2^67
-static void felem_mul(longfelem out, const felem in1, const felem in2) {
-  smallfelem small1, small2;
-  felem_shrink(small1, in1);
-  felem_shrink(small2, in2);
-  smallfelem_mul(out, small1, small2);
-}
-
-// felem_small_mul sets |out| = |small1| * |in2|
-// On entry:
-//   small1[i] < 2^64
-//   in2[i] < 2^109
-// On exit:
-//   out[i] < 7 * 2^64 < 2^67
-static void felem_small_mul(longfelem out, const smallfelem small1,
-                            const felem in2) {
-  smallfelem small2;
-  felem_shrink(small2, in2);
-  smallfelem_mul(out, small1, small2);
-}
-
-#define two100m36m4 ((((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4))
-#define two100 (((limb)1) << 100)
-#define two100m36p4 ((((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4))
-
-// zero100 is 0 mod p
-static const felem zero100 = {two100m36m4, two100, two100m36p4, two100m36p4};
-
-// Internal function for the different flavours of felem_reduce.
-// felem_reduce_ reduces the higher coefficients in[4]-in[7].
-// On entry:
-//   out[0] >= in[6] + 2^32*in[6] + in[7] + 2^32*in[7]
-//   out[1] >= in[7] + 2^32*in[4]
-//   out[2] >= in[5] + 2^32*in[5]
-//   out[3] >= in[4] + 2^32*in[5] + 2^32*in[6]
-// On exit:
-//   out[0] <= out[0] + in[4] + 2^32*in[5]
-//   out[1] <= out[1] + in[5] + 2^33*in[6]
-//   out[2] <= out[2] + in[7] + 2*in[6] + 2^33*in[7]
-//   out[3] <= out[3] + 2^32*in[4] + 3*in[7]
-static void felem_reduce_(felem out, const longfelem in) {
-  int128_t c;
-  // combine common terms from below
-  c = in[4] + (in[5] << 32);
-  out[0] += c;
-  out[3] -= c;
-
-  c = in[5] - in[7];
-  out[1] += c;
-  out[2] -= c;
-
-  // the remaining terms
-  // 256: [(0,1),(96,-1),(192,-1),(224,1)]
-  out[1] -= (in[4] << 32);
-  out[3] += (in[4] << 32);
-
-  // 320: [(32,1),(64,1),(128,-1),(160,-1),(224,-1)]
-  out[2] -= (in[5] << 32);
-
-  // 384: [(0,-1),(32,-1),(96,2),(128,2),(224,-1)]
-  out[0] -= in[6];
-  out[0] -= (in[6] << 32);
-  out[1] += (in[6] << 33);
-  out[2] += (in[6] * 2);
-  out[3] -= (in[6] << 32);
-
-  // 448: [(0,-1),(32,-1),(64,-1),(128,1),(160,2),(192,3)]
-  out[0] -= in[7];
-  out[0] -= (in[7] << 32);
-  out[2] += (in[7] << 33);
-  out[3] += (in[7] * 3);
-}
-
-// felem_reduce converts a longfelem into an felem.
-// To be called directly after felem_square or felem_mul.
-// On entry:
-//   in[0] < 2^64, in[1] < 3*2^64, in[2] < 5*2^64, in[3] < 7*2^64
-//   in[4] < 7*2^64, in[5] < 5*2^64, in[6] < 3*2^64, in[7] < 2*64
-// On exit:
-//   out[i] < 2^101
-static void felem_reduce(felem out, const longfelem in) {
-  out[0] = zero100[0] + in[0];
-  out[1] = zero100[1] + in[1];
-  out[2] = zero100[2] + in[2];
-  out[3] = zero100[3] + in[3];
-
-  felem_reduce_(out, in);
-
-  // out[0] > 2^100 - 2^36 - 2^4 - 3*2^64 - 3*2^96 - 2^64 - 2^96 > 0
-  // out[1] > 2^100 - 2^64 - 7*2^96 > 0
-  // out[2] > 2^100 - 2^36 + 2^4 - 5*2^64 - 5*2^96 > 0
-  // out[3] > 2^100 - 2^36 + 2^4 - 7*2^64 - 5*2^96 - 3*2^96 > 0
-  //
-  // out[0] < 2^100 + 2^64 + 7*2^64 + 5*2^96 < 2^101
-  // out[1] < 2^100 + 3*2^64 + 5*2^64 + 3*2^97 < 2^101
-  // out[2] < 2^100 + 5*2^64 + 2^64 + 3*2^65 + 2^97 < 2^101
-  // out[3] < 2^100 + 7*2^64 + 7*2^96 + 3*2^64 < 2^101
-}
-
-// felem_reduce_zero105 converts a larger longfelem into an felem.
-// On entry:
-//   in[0] < 2^71
-// On exit:
-//   out[i] < 2^106
-static void felem_reduce_zero105(felem out, const longfelem in) {
-    out[0] = zero105[0] + in[0];
-    out[1] = zero105[1] + in[1];
-    out[2] = zero105[2] + in[2];
-    out[3] = zero105[3] + in[3];
-
-    felem_reduce_(out, in);
-
-    // out[0] > 2^105 - 2^41 - 2^9 - 2^71 - 2^103 - 2^71 - 2^103 > 0
-    // out[1] > 2^105 - 2^71 - 2^103 > 0
-    // out[2] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 > 0
-    // out[3] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 - 2^103 > 0
-    //
-    // out[0] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106
-    // out[1] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106
-    // out[2] < 2^105 + 2^71 + 2^71 + 2^71 + 2^103 < 2^106
-    // out[3] < 2^105 + 2^71 + 2^103 + 2^71 < 2^106
-}
-
-// subtract_u64 sets *result = *result - v and *carry to one if the
-// subtraction underflowed.
-static void subtract_u64(uint64_t *result, uint64_t *carry, uint64_t v) {
-  uint128_t r = *result;
-  r -= v;
-  *carry = (r >> 64) & 1;
-  *result = (uint64_t)r;
-}
-
-// felem_contract converts |in| to its unique, minimal representation. On
-// entry: in[i] < 2^109.
-static void felem_contract(smallfelem out, const felem in) {
-  uint64_t all_equal_so_far = 0, result = 0;
-
-  felem_shrink(out, in);
-  // small is minimal except that the value might be > p
-
-  all_equal_so_far--;
-  // We are doing a constant time test if out >= kPrime. We need to compare
-  // each uint64_t, from most-significant to least significant. For each one, if
-  // all words so far have been equal (m is all ones) then a non-equal
-  // result is the answer. Otherwise we continue.
-  for (size_t i = 3; i < 4; i--) {
-    uint64_t equal;
-    uint128_t a = ((uint128_t)kPrime[i]) - out[i];
-    // if out[i] > kPrime[i] then a will underflow and the high 64-bits
-    // will all be set.
-    result |= all_equal_so_far & ((uint64_t)(a >> 64));
-
-    // if kPrime[i] == out[i] then |equal| will be all zeros and the
-    // decrement will make it all ones.
-    equal = kPrime[i] ^ out[i];
-    equal--;
-    equal &= equal << 32;
-    equal &= equal << 16;
-    equal &= equal << 8;
-    equal &= equal << 4;
-    equal &= equal << 2;
-    equal &= equal << 1;
-    equal = ((int64_t)equal) >> 63;
-
-    all_equal_so_far &= equal;
-  }
-
-  // if all_equal_so_far is still all ones then the two values are equal
-  // and so out >= kPrime is true.
-  result |= all_equal_so_far;
-
-  // if out >= kPrime then we subtract kPrime.
-  uint64_t carry;
-  subtract_u64(&out[0], &carry, result & kPrime[0]);
-  subtract_u64(&out[1], &carry, carry);
-  subtract_u64(&out[2], &carry, carry);
-  subtract_u64(&out[3], &carry, carry);
-
-  subtract_u64(&out[1], &carry, result & kPrime[1]);
-  subtract_u64(&out[2], &carry, carry);
-  subtract_u64(&out[3], &carry, carry);
-
-  subtract_u64(&out[2], &carry, result & kPrime[2]);
-  subtract_u64(&out[3], &carry, carry);
-
-  subtract_u64(&out[3], &carry, result & kPrime[3]);
-}
-
-// felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0
-// otherwise.
-// On entry:
-//   small[i] < 2^64
-static limb smallfelem_is_zero(const smallfelem small) {
-  limb result;
-  uint64_t is_p;
-
-  uint64_t is_zero = small[0] | small[1] | small[2] | small[3];
-  is_zero--;
-  is_zero &= is_zero << 32;
-  is_zero &= is_zero << 16;
-  is_zero &= is_zero << 8;
-  is_zero &= is_zero << 4;
-  is_zero &= is_zero << 2;
-  is_zero &= is_zero << 1;
-  is_zero = ((int64_t)is_zero) >> 63;
-
-  is_p = (small[0] ^ kPrime[0]) | (small[1] ^ kPrime[1]) |
-         (small[2] ^ kPrime[2]) | (small[3] ^ kPrime[3]);
-  is_p--;
-  is_p &= is_p << 32;
-  is_p &= is_p << 16;
-  is_p &= is_p << 8;
-  is_p &= is_p << 4;
-  is_p &= is_p << 2;
-  is_p &= is_p << 1;
-  is_p = ((int64_t)is_p) >> 63;
-
-  is_zero |= is_p;
-
-  result = is_zero;
-  result |= ((limb)is_zero) << 64;
-  return result;
-}
-
-// felem_inv calculates |out| = |in|^{-1}
-//
-// Based on Fermat's Little Theorem:
-//   a^p = a (mod p)
-//   a^{p-1} = 1 (mod p)
-//   a^{p-2} = a^{-1} (mod p)
-static void felem_inv(felem out, const felem in) {
-  felem ftmp, ftmp2;
-  // each e_I will hold |in|^{2^I - 1}
-  felem e2, e4, e8, e16, e32, e64;
-  longfelem tmp;
-
-  felem_square(tmp, in);
-  felem_reduce(ftmp, tmp);  // 2^1
-  felem_mul(tmp, in, ftmp);
-  felem_reduce(ftmp, tmp);  // 2^2 - 2^0
-  felem_assign(e2, ftmp);
-  felem_square(tmp, ftmp);
-  felem_reduce(ftmp, tmp);  // 2^3 - 2^1
-  felem_square(tmp, ftmp);
-  felem_reduce(ftmp, tmp);  // 2^4 - 2^2
-  felem_mul(tmp, ftmp, e2);
-  felem_reduce(ftmp, tmp);  // 2^4 - 2^0
-  felem_assign(e4, ftmp);
-  felem_square(tmp, ftmp);
-  felem_reduce(ftmp, tmp);  // 2^5 - 2^1
-  felem_square(tmp, ftmp);
-  felem_reduce(ftmp, tmp);  // 2^6 - 2^2
-  felem_square(tmp, ftmp);
-  felem_reduce(ftmp, tmp);  // 2^7 - 2^3
-  felem_square(tmp, ftmp);
-  felem_reduce(ftmp, tmp);  // 2^8 - 2^4
-  felem_mul(tmp, ftmp, e4);
-  felem_reduce(ftmp, tmp);  // 2^8 - 2^0
-  felem_assign(e8, ftmp);
-  for (size_t i = 0; i < 8; i++) {
-    felem_square(tmp, ftmp);
-    felem_reduce(ftmp, tmp);
-  }  // 2^16 - 2^8
-  felem_mul(tmp, ftmp, e8);
-  felem_reduce(ftmp, tmp);  // 2^16 - 2^0
-  felem_assign(e16, ftmp);
-  for (size_t i = 0; i < 16; i++) {
-    felem_square(tmp, ftmp);
-    felem_reduce(ftmp, tmp);
-  }  // 2^32 - 2^16
-  felem_mul(tmp, ftmp, e16);
-  felem_reduce(ftmp, tmp);  // 2^32 - 2^0
-  felem_assign(e32, ftmp);
-  for (size_t i = 0; i < 32; i++) {
-    felem_square(tmp, ftmp);
-    felem_reduce(ftmp, tmp);
-  }  // 2^64 - 2^32
-  felem_assign(e64, ftmp);
-  felem_mul(tmp, ftmp, in);
-  felem_reduce(ftmp, tmp);  // 2^64 - 2^32 + 2^0
-  for (size_t i = 0; i < 192; i++) {
-    felem_square(tmp, ftmp);
-    felem_reduce(ftmp, tmp);
-  }  // 2^256 - 2^224 + 2^192
-
-  felem_mul(tmp, e64, e32);
-  felem_reduce(ftmp2, tmp);  // 2^64 - 2^0
-  for (size_t i = 0; i < 16; i++) {
-    felem_square(tmp, ftmp2);
-    felem_reduce(ftmp2, tmp);
-  }  // 2^80 - 2^16
-  felem_mul(tmp, ftmp2, e16);
-  felem_reduce(ftmp2, tmp);  // 2^80 - 2^0
-  for (size_t i = 0; i < 8; i++) {
-    felem_square(tmp, ftmp2);
-    felem_reduce(ftmp2, tmp);
-  }  // 2^88 - 2^8
-  felem_mul(tmp, ftmp2, e8);
-  felem_reduce(ftmp2, tmp);  // 2^88 - 2^0
-  for (size_t i = 0; i < 4; i++) {
-    felem_square(tmp, ftmp2);
-    felem_reduce(ftmp2, tmp);
-  }  // 2^92 - 2^4
-  felem_mul(tmp, ftmp2, e4);
-  felem_reduce(ftmp2, tmp);  // 2^92 - 2^0
-  felem_square(tmp, ftmp2);
-  felem_reduce(ftmp2, tmp);  // 2^93 - 2^1
-  felem_square(tmp, ftmp2);
-  felem_reduce(ftmp2, tmp);  // 2^94 - 2^2
-  felem_mul(tmp, ftmp2, e2);
-  felem_reduce(ftmp2, tmp);  // 2^94 - 2^0
-  felem_square(tmp, ftmp2);
-  felem_reduce(ftmp2, tmp);  // 2^95 - 2^1
-  felem_square(tmp, ftmp2);
-  felem_reduce(ftmp2, tmp);  // 2^96 - 2^2
-  felem_mul(tmp, ftmp2, in);
-  felem_reduce(ftmp2, tmp);  // 2^96 - 3
-
-  felem_mul(tmp, ftmp2, ftmp);
-  felem_reduce(out, tmp);  // 2^256 - 2^224 + 2^192 + 2^96 - 3
-}
-
-// Group operations
-// ----------------
-//
-// Building on top of the field operations we have the operations on the
-// elliptic curve group itself. Points on the curve are represented in Jacobian
-// coordinates.
-
-// point_double calculates 2*(x_in, y_in, z_in)
-//
-// The method is taken from:
-//   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
-//
-// Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
-// while x_out == y_in is not (maybe this works, but it's not tested).
-static void point_double(felem x_out, felem y_out, felem z_out,
-                         const felem x_in, const felem y_in, const felem z_in) {
-  longfelem tmp, tmp2;
-  felem delta, gamma, beta, alpha, ftmp, ftmp2;
-  smallfelem small1, small2;
-
-  felem_assign(ftmp, x_in);
-  // ftmp[i] < 2^106
-  felem_assign(ftmp2, x_in);
-  // ftmp2[i] < 2^106
-
-  // delta = z^2
-  felem_square(tmp, z_in);
-  felem_reduce(delta, tmp);
-  // delta[i] < 2^101
-
-  // gamma = y^2
-  felem_square(tmp, y_in);
-  felem_reduce(gamma, tmp);
-  // gamma[i] < 2^101
-  felem_shrink(small1, gamma);
-
-  // beta = x*gamma
-  felem_small_mul(tmp, small1, x_in);
-  felem_reduce(beta, tmp);
-  // beta[i] < 2^101
-
-  // alpha = 3*(x-delta)*(x+delta)
-  felem_diff(ftmp, delta);
-  // ftmp[i] < 2^105 + 2^106 < 2^107
-  felem_sum(ftmp2, delta);
-  // ftmp2[i] < 2^105 + 2^106 < 2^107
-  felem_scalar(ftmp2, 3);
-  // ftmp2[i] < 3 * 2^107 < 2^109
-  felem_mul(tmp, ftmp, ftmp2);
-  felem_reduce(alpha, tmp);
-  // alpha[i] < 2^101
-  felem_shrink(small2, alpha);
-
-  // x' = alpha^2 - 8*beta
-  smallfelem_square(tmp, small2);
-  felem_reduce(x_out, tmp);
-  felem_assign(ftmp, beta);
-  felem_scalar(ftmp, 8);
-  // ftmp[i] < 8 * 2^101 = 2^104
-  felem_diff(x_out, ftmp);
-  // x_out[i] < 2^105 + 2^101 < 2^106
-
-  // z' = (y + z)^2 - gamma - delta
-  felem_sum(delta, gamma);
-  // delta[i] < 2^101 + 2^101 = 2^102
-  felem_assign(ftmp, y_in);
-  felem_sum(ftmp, z_in);
-  // ftmp[i] < 2^106 + 2^106 = 2^107
-  felem_square(tmp, ftmp);
-  felem_reduce(z_out, tmp);
-  felem_diff(z_out, delta);
-  // z_out[i] < 2^105 + 2^101 < 2^106
-
-  // y' = alpha*(4*beta - x') - 8*gamma^2
-  felem_scalar(beta, 4);
-  // beta[i] < 4 * 2^101 = 2^103
-  felem_diff_zero107(beta, x_out);
-  // beta[i] < 2^107 + 2^103 < 2^108
-  felem_small_mul(tmp, small2, beta);
-  // tmp[i] < 7 * 2^64 < 2^67
-  smallfelem_square(tmp2, small1);
-  // tmp2[i] < 7 * 2^64
-  longfelem_scalar(tmp2, 8);
-  // tmp2[i] < 8 * 7 * 2^64 = 7 * 2^67
-  longfelem_diff(tmp, tmp2);
-  // tmp[i] < 2^67 + 2^70 + 2^40 < 2^71
-  felem_reduce_zero105(y_out, tmp);
-  // y_out[i] < 2^106
-}
-
-// point_double_small is the same as point_double, except that it operates on
-// smallfelems.
-static void point_double_small(smallfelem x_out, smallfelem y_out,
-                               smallfelem z_out, const smallfelem x_in,
-                               const smallfelem y_in, const smallfelem z_in) {
-  felem felem_x_out, felem_y_out, felem_z_out;
-  felem felem_x_in, felem_y_in, felem_z_in;
-
-  smallfelem_expand(felem_x_in, x_in);
-  smallfelem_expand(felem_y_in, y_in);
-  smallfelem_expand(felem_z_in, z_in);
-  point_double(felem_x_out, felem_y_out, felem_z_out, felem_x_in, felem_y_in,
-               felem_z_in);
-  felem_shrink(x_out, felem_x_out);
-  felem_shrink(y_out, felem_y_out);
-  felem_shrink(z_out, felem_z_out);
-}
-
-// p256_copy_conditional copies in to out iff mask is all ones.
-static void p256_copy_conditional(felem out, const felem in, limb mask) {
-  for (size_t i = 0; i < NLIMBS; ++i) {
-    const limb tmp = mask & (in[i] ^ out[i]);
-    out[i] ^= tmp;
-  }
-}
-
-// copy_small_conditional copies in to out iff mask is all ones.
-static void copy_small_conditional(felem out, const smallfelem in, limb mask) {
-  const uint64_t mask64 = mask;
-  for (size_t i = 0; i < NLIMBS; ++i) {
-    out[i] = ((limb)(in[i] & mask64)) | (out[i] & ~mask);
-  }
-}
-
-// point_add calcuates (x1, y1, z1) + (x2, y2, z2)
-//
-// The method is taken from:
-//   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
-// adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
-//
-// This function includes a branch for checking whether the two input points
-// are equal, (while not equal to the point at infinity). This case never
-// happens during single point multiplication, so there is no timing leak for
-// ECDH or ECDSA signing.
-static void point_add(felem x3, felem y3, felem z3, const felem x1,
-                      const felem y1, const felem z1, const int mixed,
-                      const smallfelem x2, const smallfelem y2,
-                      const smallfelem z2) {
-  felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out;
-  longfelem tmp, tmp2;
-  smallfelem small1, small2, small3, small4, small5;
-  limb x_equal, y_equal, z1_is_zero, z2_is_zero;
-
-  felem_shrink(small3, z1);
-
-  z1_is_zero = smallfelem_is_zero(small3);
-  z2_is_zero = smallfelem_is_zero(z2);
-
-  // ftmp = z1z1 = z1**2
-  smallfelem_square(tmp, small3);
-  felem_reduce(ftmp, tmp);
-  // ftmp[i] < 2^101
-  felem_shrink(small1, ftmp);
-
-  if (!mixed) {
-    // ftmp2 = z2z2 = z2**2
-    smallfelem_square(tmp, z2);
-    felem_reduce(ftmp2, tmp);
-    // ftmp2[i] < 2^101
-    felem_shrink(small2, ftmp2);
-
-    felem_shrink(small5, x1);
-
-    // u1 = ftmp3 = x1*z2z2
-    smallfelem_mul(tmp, small5, small2);
-    felem_reduce(ftmp3, tmp);
-    // ftmp3[i] < 2^101
-
-    // ftmp5 = z1 + z2
-    felem_assign(ftmp5, z1);
-    felem_small_sum(ftmp5, z2);
-    // ftmp5[i] < 2^107
-
-    // ftmp5 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2
-    felem_square(tmp, ftmp5);
-    felem_reduce(ftmp5, tmp);
-    // ftmp2 = z2z2 + z1z1
-    felem_sum(ftmp2, ftmp);
-    // ftmp2[i] < 2^101 + 2^101 = 2^102
-    felem_diff(ftmp5, ftmp2);
-    // ftmp5[i] < 2^105 + 2^101 < 2^106
-
-    // ftmp2 = z2 * z2z2
-    smallfelem_mul(tmp, small2, z2);
-    felem_reduce(ftmp2, tmp);
-
-    // s1 = ftmp2 = y1 * z2**3
-    felem_mul(tmp, y1, ftmp2);
-    felem_reduce(ftmp6, tmp);
-    // ftmp6[i] < 2^101
-  } else {
-    // We'll assume z2 = 1 (special case z2 = 0 is handled later).
-
-    // u1 = ftmp3 = x1*z2z2
-    felem_assign(ftmp3, x1);
-    // ftmp3[i] < 2^106
-
-    // ftmp5 = 2z1z2
-    felem_assign(ftmp5, z1);
-    felem_scalar(ftmp5, 2);
-    // ftmp5[i] < 2*2^106 = 2^107
-
-    // s1 = ftmp2 = y1 * z2**3
-    felem_assign(ftmp6, y1);
-    // ftmp6[i] < 2^106
-  }
-
-  // u2 = x2*z1z1
-  smallfelem_mul(tmp, x2, small1);
-  felem_reduce(ftmp4, tmp);
-
-  // h = ftmp4 = u2 - u1
-  felem_diff_zero107(ftmp4, ftmp3);
-  // ftmp4[i] < 2^107 + 2^101 < 2^108
-  felem_shrink(small4, ftmp4);
-
-  x_equal = smallfelem_is_zero(small4);
-
-  // z_out = ftmp5 * h
-  felem_small_mul(tmp, small4, ftmp5);
-  felem_reduce(z_out, tmp);
-  // z_out[i] < 2^101
-
-  // ftmp = z1 * z1z1
-  smallfelem_mul(tmp, small1, small3);
-  felem_reduce(ftmp, tmp);
-
-  // s2 = tmp = y2 * z1**3
-  felem_small_mul(tmp, y2, ftmp);
-  felem_reduce(ftmp5, tmp);
-
-  // r = ftmp5 = (s2 - s1)*2
-  felem_diff_zero107(ftmp5, ftmp6);
-  // ftmp5[i] < 2^107 + 2^107 = 2^108
-  felem_scalar(ftmp5, 2);
-  // ftmp5[i] < 2^109
-  felem_shrink(small1, ftmp5);
-  y_equal = smallfelem_is_zero(small1);
-
-  if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
-    point_double(x3, y3, z3, x1, y1, z1);
-    return;
-  }
-
-  // I = ftmp = (2h)**2
-  felem_assign(ftmp, ftmp4);
-  felem_scalar(ftmp, 2);
-  // ftmp[i] < 2*2^108 = 2^109
-  felem_square(tmp, ftmp);
-  felem_reduce(ftmp, tmp);
-
-  // J = ftmp2 = h * I
-  felem_mul(tmp, ftmp4, ftmp);
-  felem_reduce(ftmp2, tmp);
-
-  // V = ftmp4 = U1 * I
-  felem_mul(tmp, ftmp3, ftmp);
-  felem_reduce(ftmp4, tmp);
-
-  // x_out = r**2 - J - 2V
-  smallfelem_square(tmp, small1);
-  felem_reduce(x_out, tmp);
-  felem_assign(ftmp3, ftmp4);
-  felem_scalar(ftmp4, 2);
-  felem_sum(ftmp4, ftmp2);
-  // ftmp4[i] < 2*2^101 + 2^101 < 2^103
-  felem_diff(x_out, ftmp4);
-  // x_out[i] < 2^105 + 2^101
-
-  // y_out = r(V-x_out) - 2 * s1 * J
-  felem_diff_zero107(ftmp3, x_out);
-  // ftmp3[i] < 2^107 + 2^101 < 2^108
-  felem_small_mul(tmp, small1, ftmp3);
-  felem_mul(tmp2, ftmp6, ftmp2);
-  longfelem_scalar(tmp2, 2);
-  // tmp2[i] < 2*2^67 = 2^68
-  longfelem_diff(tmp, tmp2);
-  // tmp[i] < 2^67 + 2^70 + 2^40 < 2^71
-  felem_reduce_zero105(y_out, tmp);
-  // y_out[i] < 2^106
-
-  copy_small_conditional(x_out, x2, z1_is_zero);
-  p256_copy_conditional(x_out, x1, z2_is_zero);
-  copy_small_conditional(y_out, y2, z1_is_zero);
-  p256_copy_conditional(y_out, y1, z2_is_zero);
-  copy_small_conditional(z_out, z2, z1_is_zero);
-  p256_copy_conditional(z_out, z1, z2_is_zero);
-  felem_assign(x3, x_out);
-  felem_assign(y3, y_out);
-  felem_assign(z3, z_out);
-}
-
-// point_add_small is the same as point_add, except that it operates on
-// smallfelems.
-static void point_add_small(smallfelem x3, smallfelem y3, smallfelem z3,
-                            smallfelem x1, smallfelem y1, smallfelem z1,
-                            smallfelem x2, smallfelem y2, smallfelem z2) {
-  felem felem_x3, felem_y3, felem_z3;
-  felem felem_x1, felem_y1, felem_z1;
-  smallfelem_expand(felem_x1, x1);
-  smallfelem_expand(felem_y1, y1);
-  smallfelem_expand(felem_z1, z1);
-  point_add(felem_x3, felem_y3, felem_z3, felem_x1, felem_y1, felem_z1, 0, x2,
-            y2, z2);
-  felem_shrink(x3, felem_x3);
-  felem_shrink(y3, felem_y3);
-  felem_shrink(z3, felem_z3);
-}
-
-// Base point pre computation
-// --------------------------
-//
-// Two different sorts of precomputed tables are used in the following code.
-// Each contain various points on the curve, where each point is three field
-// elements (x, y, z).
-//
-// For the base point table, z is usually 1 (0 for the point at infinity).
-// This table has 2 * 16 elements, starting with the following:
-// index | bits    | point
-// ------+---------+------------------------------
-//     0 | 0 0 0 0 | 0G
-//     1 | 0 0 0 1 | 1G
-//     2 | 0 0 1 0 | 2^64G
-//     3 | 0 0 1 1 | (2^64 + 1)G
-//     4 | 0 1 0 0 | 2^128G
-//     5 | 0 1 0 1 | (2^128 + 1)G
-//     6 | 0 1 1 0 | (2^128 + 2^64)G
-//     7 | 0 1 1 1 | (2^128 + 2^64 + 1)G
-//     8 | 1 0 0 0 | 2^192G
-//     9 | 1 0 0 1 | (2^192 + 1)G
-//    10 | 1 0 1 0 | (2^192 + 2^64)G
-//    11 | 1 0 1 1 | (2^192 + 2^64 + 1)G
-//    12 | 1 1 0 0 | (2^192 + 2^128)G
-//    13 | 1 1 0 1 | (2^192 + 2^128 + 1)G
-//    14 | 1 1 1 0 | (2^192 + 2^128 + 2^64)G
-//    15 | 1 1 1 1 | (2^192 + 2^128 + 2^64 + 1)G
-// followed by a copy of this with each element multiplied by 2^32.
-//
-// The reason for this is so that we can clock bits into four different
-// locations when doing simple scalar multiplies against the base point,
-// and then another four locations using the second 16 elements.
-//
-// Tables for other points have table[i] = iG for i in 0 .. 16.
-
-// g_pre_comp is the table of precomputed base points
-static const smallfelem g_pre_comp[2][16][3] = {
-    {{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
-     {{0xf4a13945d898c296, 0x77037d812deb33a0, 0xf8bce6e563a440f2,
-       0x6b17d1f2e12c4247},
-      {0xcbb6406837bf51f5, 0x2bce33576b315ece, 0x8ee7eb4a7c0f9e16,
-       0x4fe342e2fe1a7f9b},
-      {1, 0, 0, 0}},
-     {{0x90e75cb48e14db63, 0x29493baaad651f7e, 0x8492592e326e25de,
-       0x0fa822bc2811aaa5},
-      {0xe41124545f462ee7, 0x34b1a65050fe82f5, 0x6f4ad4bcb3df188b,
-       0xbff44ae8f5dba80d},
-      {1, 0, 0, 0}},
-     {{0x93391ce2097992af, 0xe96c98fd0d35f1fa, 0xb257c0de95e02789,
-       0x300a4bbc89d6726f},
-      {0xaa54a291c08127a0, 0x5bb1eeada9d806a5, 0x7f1ddb25ff1e3c6f,
-       0x72aac7e0d09b4644},
-      {1, 0, 0, 0}},
-     {{0x57c84fc9d789bd85, 0xfc35ff7dc297eac3, 0xfb982fd588c6766e,
-       0x447d739beedb5e67},
-      {0x0c7e33c972e25b32, 0x3d349b95a7fae500, 0xe12e9d953a4aaff7,
-       0x2d4825ab834131ee},
-      {1, 0, 0, 0}},
-     {{0x13949c932a1d367f, 0xef7fbd2b1a0a11b7, 0xddc6068bb91dfc60,
-       0xef9519328a9c72ff},
-      {0x196035a77376d8a8, 0x23183b0895ca1740, 0xc1ee9807022c219c,
-       0x611e9fc37dbb2c9b},
-      {1, 0, 0, 0}},
-     {{0xcae2b1920b57f4bc, 0x2936df5ec6c9bc36, 0x7dea6482e11238bf,
-       0x550663797b51f5d8},
-      {0x44ffe216348a964c, 0x9fb3d576dbdefbe1, 0x0afa40018d9d50e5,
-       0x157164848aecb851},
-      {1, 0, 0, 0}},
-     {{0xe48ecafffc5cde01, 0x7ccd84e70d715f26, 0xa2e8f483f43e4391,
-       0xeb5d7745b21141ea},
-      {0xcac917e2731a3479, 0x85f22cfe2844b645, 0x0990e6a158006cee,
-       0xeafd72ebdbecc17b},
-      {1, 0, 0, 0}},
-     {{0x6cf20ffb313728be, 0x96439591a3c6b94a, 0x2736ff8344315fc5,
-       0xa6d39677a7849276},
-      {0xf2bab833c357f5f4, 0x824a920c2284059b, 0x66b8babd2d27ecdf,
-       0x674f84749b0b8816},
-      {1, 0, 0, 0}},
-     {{0x2df48c04677c8a3e, 0x74e02f080203a56b, 0x31855f7db8c7fedb,
-       0x4e769e7672c9ddad},
-      {0xa4c36165b824bbb0, 0xfb9ae16f3b9122a5, 0x1ec0057206947281,
-       0x42b99082de830663},
-      {1, 0, 0, 0}},
-     {{0x6ef95150dda868b9, 0xd1f89e799c0ce131, 0x7fdc1ca008a1c478,
-       0x78878ef61c6ce04d},
-      {0x9c62b9121fe0d976, 0x6ace570ebde08d4f, 0xde53142c12309def,
-       0xb6cb3f5d7b72c321},
-      {1, 0, 0, 0}},
-     {{0x7f991ed2c31a3573, 0x5b82dd5bd54fb496, 0x595c5220812ffcae,
-       0x0c88bc4d716b1287},
-      {0x3a57bf635f48aca8, 0x7c8181f4df2564f3, 0x18d1b5b39c04e6aa,
-       0xdd5ddea3f3901dc6},
-      {1, 0, 0, 0}},
-     {{0xe96a79fb3e72ad0c, 0x43a0a28c42ba792f, 0xefe0a423083e49f3,
-       0x68f344af6b317466},
-      {0xcdfe17db3fb24d4a, 0x668bfc2271f5c626, 0x604ed93c24d67ff3,
-       0x31b9c405f8540a20},
-      {1, 0, 0, 0}},
-     {{0xd36b4789a2582e7f, 0x0d1a10144ec39c28, 0x663c62c3edbad7a0,
-       0x4052bf4b6f461db9},
-      {0x235a27c3188d25eb, 0xe724f33999bfcc5b, 0x862be6bd71d70cc8,
-       0xfecf4d5190b0fc61},
-      {1, 0, 0, 0}},
-     {{0x74346c10a1d4cfac, 0xafdf5cc08526a7a4, 0x123202a8f62bff7a,
-       0x1eddbae2c802e41a},
-      {0x8fa0af2dd603f844, 0x36e06b7e4c701917, 0x0c45f45273db33a0,
-       0x43104d86560ebcfc},
-      {1, 0, 0, 0}},
-     {{0x9615b5110d1d78e5, 0x66b0de3225c4744b, 0x0a4a46fb6aaf363a,
-       0xb48e26b484f7a21c},
-      {0x06ebb0f621a01b2d, 0xc004e4048b7b0f98, 0x64131bcdfed6f668,
-       0xfac015404d4d3dab},
-      {1, 0, 0, 0}}},
-    {{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
-     {{0x3a5a9e22185a5943, 0x1ab919365c65dfb6, 0x21656b32262c71da,
-       0x7fe36b40af22af89},
-      {0xd50d152c699ca101, 0x74b3d5867b8af212, 0x9f09f40407dca6f1,
-       0xe697d45825b63624},
-      {1, 0, 0, 0}},
-     {{0xa84aa9397512218e, 0xe9a521b074ca0141, 0x57880b3a18a2e902,
-       0x4a5b506612a677a6},
-      {0x0beada7a4c4f3840, 0x626db15419e26d9d, 0xc42604fbe1627d40,
-       0xeb13461ceac089f1},
-      {1, 0, 0, 0}},
-     {{0xf9faed0927a43281, 0x5e52c4144103ecbc, 0xc342967aa815c857,
-       0x0781b8291c6a220a},
-      {0x5a8343ceeac55f80, 0x88f80eeee54a05e3, 0x97b2a14f12916434,
-       0x690cde8df0151593},
-      {1, 0, 0, 0}},
-     {{0xaee9c75df7f82f2a, 0x9e4c35874afdf43a, 0xf5622df437371326,
-       0x8a535f566ec73617},
-      {0xc5f9a0ac223094b7, 0xcde533864c8c7669, 0x37e02819085a92bf,
-       0x0455c08468b08bd7},
-      {1, 0, 0, 0}},
-     {{0x0c0a6e2c9477b5d9, 0xf9a4bf62876dc444, 0x5050a949b6cdc279,
-       0x06bada7ab77f8276},
-      {0xc8b4aed1ea48dac9, 0xdebd8a4b7ea1070f, 0x427d49101366eb70,
-       0x5b476dfd0e6cb18a},
-      {1, 0, 0, 0}},
-     {{0x7c5c3e44278c340a, 0x4d54606812d66f3b, 0x29a751b1ae23c5d8,
-       0x3e29864e8a2ec908},
-      {0x142d2a6626dbb850, 0xad1744c4765bd780, 0x1f150e68e322d1ed,
-       0x239b90ea3dc31e7e},
-      {1, 0, 0, 0}},
-     {{0x78c416527a53322a, 0x305dde6709776f8e, 0xdbcab759f8862ed4,
-       0x820f4dd949f72ff7},
-      {0x6cc544a62b5debd4, 0x75be5d937b4e8cc4, 0x1b481b1b215c14d3,
-       0x140406ec783a05ec},
-      {1, 0, 0, 0}},
-     {{0x6a703f10e895df07, 0xfd75f3fa01876bd8, 0xeb5b06e70ce08ffe,
-       0x68f6b8542783dfee},
-      {0x90c76f8a78712655, 0xcf5293d2f310bf7f, 0xfbc8044dfda45028,
-       0xcbe1feba92e40ce6},
-      {1, 0, 0, 0}},
-     {{0xe998ceea4396e4c1, 0xfc82ef0b6acea274, 0x230f729f2250e927,
-       0xd0b2f94d2f420109},
-      {0x4305adddb38d4966, 0x10b838f8624c3b45, 0x7db2636658954e7a,
-       0x971459828b0719e5},
-      {1, 0, 0, 0}},
-     {{0x4bd6b72623369fc9, 0x57f2929e53d0b876, 0xc2d5cba4f2340687,
-       0x961610004a866aba},
-      {0x49997bcd2e407a5e, 0x69ab197d92ddcb24, 0x2cf1f2438fe5131c,
-       0x7acb9fadcee75e44},
-      {1, 0, 0, 0}},
-     {{0x254e839423d2d4c0, 0xf57f0c917aea685b, 0xa60d880f6f75aaea,
-       0x24eb9acca333bf5b},
-      {0xe3de4ccb1cda5dea, 0xfeef9341c51a6b4f, 0x743125f88bac4c4d,
-       0x69f891c5acd079cc},
-      {1, 0, 0, 0}},
-     {{0xeee44b35702476b5, 0x7ed031a0e45c2258, 0xb422d1e7bd6f8514,
-       0xe51f547c5972a107},
-      {0xa25bcd6fc9cf343d, 0x8ca922ee097c184e, 0xa62f98b3a9fe9a06,
-       0x1c309a2b25bb1387},
-      {1, 0, 0, 0}},
-     {{0x9295dbeb1967c459, 0xb00148833472c98e, 0xc504977708011828,
-       0x20b87b8aa2c4e503},
-      {0x3063175de057c277, 0x1bd539338fe582dd, 0x0d11adef5f69a044,
-       0xf5c6fa49919776be},
-      {1, 0, 0, 0}},
-     {{0x8c944e760fd59e11, 0x3876cba1102fad5f, 0xa454c3fad83faa56,
-       0x1ed7d1b9332010b9},
-      {0xa1011a270024b889, 0x05e4d0dcac0cd344, 0x52b520f0eb6a2a24,
-       0x3a2b03f03217257a},
-      {1, 0, 0, 0}},
-     {{0xf20fc2afdf1d043d, 0xf330240db58d5a62, 0xfc7d229ca0058c3b,
-       0x15fee545c78dd9f6},
-      {0x501e82885bc98cda, 0x41ef80e5d046ac04, 0x557d9f49461210fb,
-       0x4ab5b6b2b8753f81},
-      {1, 0, 0, 0}}}};
-
-// select_point selects the |idx|th point from a precomputation table and
-// copies it to out.
-static void select_point(const uint64_t idx, size_t size,
-                         const smallfelem pre_comp[/*size*/][3],
-                         smallfelem out[3]) {
-  uint64_t *outlimbs = &out[0][0];
-  OPENSSL_memset(outlimbs, 0, 3 * sizeof(smallfelem));
-
-  for (size_t i = 0; i < size; i++) {
-    const uint64_t *inlimbs = (const uint64_t *)&pre_comp[i][0][0];
-    uint64_t mask = i ^ idx;
-    mask |= mask >> 4;
-    mask |= mask >> 2;
-    mask |= mask >> 1;
-    mask &= 1;
-    mask--;
-    for (size_t j = 0; j < NLIMBS * 3; j++) {
-      outlimbs[j] |= inlimbs[j] & mask;
-    }
-  }
-}
-
-// get_bit returns the |i|th bit in |in|
-static char get_bit(const felem_bytearray in, int i) {
-  if (i < 0 || i >= 256) {
-    return 0;
-  }
-  return (in[i >> 3] >> (i & 7)) & 1;
-}
-
-// Interleaved point multiplication using precomputed point multiples: The
-// small point multiples 0*P, 1*P, ..., 17*P are in p_pre_comp, the scalar
-// in p_scalar, if non-NULL. If g_scalar is non-NULL, we also add this multiple
-// of the generator, using certain (large) precomputed multiples in g_pre_comp.
-// Output point (X, Y, Z) is stored in x_out, y_out, z_out.
-static void batch_mul(felem x_out, felem y_out, felem z_out,
-                      const uint8_t *p_scalar, const uint8_t *g_scalar,
-                      const smallfelem p_pre_comp[17][3]) {
-  felem nq[3], ftmp;
-  smallfelem tmp[3];
-  uint64_t bits;
-  uint8_t sign, digit;
-
-  // set nq to the point at infinity
-  OPENSSL_memset(nq, 0, 3 * sizeof(felem));
-
-  // Loop over both scalars msb-to-lsb, interleaving additions of multiples
-  // of the generator (two in each of the last 32 rounds) and additions of p
-  // (every 5th round).
-
-  int skip = 1;  // save two point operations in the first round
-  size_t i = p_scalar != NULL ? 255 : 31;
-  for (;;) {
-    // double
-    if (!skip) {
-      point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
-    }
-
-    // add multiples of the generator
-    if (g_scalar != NULL && i <= 31) {
-      // first, look 32 bits upwards
-      bits = get_bit(g_scalar, i + 224) << 3;
-      bits |= get_bit(g_scalar, i + 160) << 2;
-      bits |= get_bit(g_scalar, i + 96) << 1;
-      bits |= get_bit(g_scalar, i + 32);
-      // select the point to add, in constant time
-      select_point(bits, 16, g_pre_comp[1], tmp);
-
-      if (!skip) {
-        point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
-                  tmp[0], tmp[1], tmp[2]);
-      } else {
-        smallfelem_expand(nq[0], tmp[0]);
-        smallfelem_expand(nq[1], tmp[1]);
-        smallfelem_expand(nq[2], tmp[2]);
-        skip = 0;
-      }
-
-      // second, look at the current position
-      bits = get_bit(g_scalar, i + 192) << 3;
-      bits |= get_bit(g_scalar, i + 128) << 2;
-      bits |= get_bit(g_scalar, i + 64) << 1;
-      bits |= get_bit(g_scalar, i);
-      // select the point to add, in constant time
-      select_point(bits, 16, g_pre_comp[0], tmp);
-      point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, tmp[0],
-                tmp[1], tmp[2]);
-    }
-
-    // do other additions every 5 doublings
-    if (p_scalar != NULL && i % 5 == 0) {
-      bits = get_bit(p_scalar, i + 4) << 5;
-      bits |= get_bit(p_scalar, i + 3) << 4;
-      bits |= get_bit(p_scalar, i + 2) << 3;
-      bits |= get_bit(p_scalar, i + 1) << 2;
-      bits |= get_bit(p_scalar, i) << 1;
-      bits |= get_bit(p_scalar, i - 1);
-      ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
-
-      // select the point to add or subtract, in constant time.
-      select_point(digit, 17, p_pre_comp, tmp);
-      smallfelem_neg(ftmp, tmp[1]);  // (X, -Y, Z) is the negative
-                                     // point
-      copy_small_conditional(ftmp, tmp[1], (((limb)sign) - 1));
-      felem_contract(tmp[1], ftmp);
-
-      if (!skip) {
-        point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */,
-                  tmp[0], tmp[1], tmp[2]);
-      } else {
-        smallfelem_expand(nq[0], tmp[0]);
-        smallfelem_expand(nq[1], tmp[1]);
-        smallfelem_expand(nq[2], tmp[2]);
-        skip = 0;
-      }
-    }
-
-    if (i == 0) {
-      break;
-    }
-    --i;
-  }
-  felem_assign(x_out, nq[0]);
-  felem_assign(y_out, nq[1]);
-  felem_assign(z_out, nq[2]);
-}
-
-// OPENSSL EC_METHOD FUNCTIONS
-
-// Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
-// (X/Z^2, Y/Z^3).
-static int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
-                                                        const EC_POINT *point,
-                                                        BIGNUM *x, BIGNUM *y,
-                                                        BN_CTX *ctx) {
-  felem z1, z2, x_in, y_in;
-  smallfelem x_out, y_out;
-  longfelem tmp;
-
-  if (EC_POINT_is_at_infinity(group, point)) {
-    OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
-    return 0;
-  }
-  if (!BN_to_felem(x_in, &point->X) ||
-      !BN_to_felem(y_in, &point->Y) ||
-      !BN_to_felem(z1, &point->Z)) {
-    return 0;
-  }
-  felem_inv(z2, z1);
-  felem_square(tmp, z2);
-  felem_reduce(z1, tmp);
-
-  if (x != NULL) {
-    felem_mul(tmp, x_in, z1);
-    felem_reduce(x_in, tmp);
-    felem_contract(x_out, x_in);
-    if (!smallfelem_to_BN(x, x_out)) {
-      OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
-      return 0;
-    }
-  }
-
-  if (y != NULL) {
-    felem_mul(tmp, z1, z2);
-    felem_reduce(z1, tmp);
-    felem_mul(tmp, y_in, z1);
-    felem_reduce(y_in, tmp);
-    felem_contract(y_out, y_in);
-    if (!smallfelem_to_BN(y, y_out)) {
-      OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
-      return 0;
-    }
-  }
-
-  return 1;
-}
-
-static int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
-                                      const EC_SCALAR *g_scalar,
-                                      const EC_POINT *p,
-                                      const EC_SCALAR *p_scalar, BN_CTX *ctx) {
-  int ret = 0;
-  BN_CTX *new_ctx = NULL;
-  BIGNUM *x, *y, *z, *tmp_scalar;
-  smallfelem p_pre_comp[17][3];
-  smallfelem x_in, y_in, z_in;
-  felem x_out, y_out, z_out;
-
-  if (ctx == NULL) {
-    ctx = new_ctx = BN_CTX_new();
-    if (ctx == NULL) {
-      return 0;
-    }
-  }
-
-  BN_CTX_start(ctx);
-  if ((x = BN_CTX_get(ctx)) == NULL ||
-      (y = BN_CTX_get(ctx)) == NULL ||
-      (z = BN_CTX_get(ctx)) == NULL ||
-      (tmp_scalar = BN_CTX_get(ctx)) == NULL) {
-    goto err;
-  }
-
-  if (p != NULL && p_scalar != NULL) {
-    // We treat NULL scalars as 0, and NULL points as points at infinity, i.e.,
-    // they contribute nothing to the linear combination.
-    OPENSSL_memset(&p_pre_comp, 0, sizeof(p_pre_comp));
-    // Precompute multiples.
-    if (!BN_to_felem(x_out, &p->X) ||
-        !BN_to_felem(y_out, &p->Y) ||
-        !BN_to_felem(z_out, &p->Z)) {
-      goto err;
-    }
-    felem_shrink(p_pre_comp[1][0], x_out);
-    felem_shrink(p_pre_comp[1][1], y_out);
-    felem_shrink(p_pre_comp[1][2], z_out);
-    for (size_t j = 2; j <= 16; ++j) {
-      if (j & 1) {
-        point_add_small(p_pre_comp[j][0], p_pre_comp[j][1],
-                        p_pre_comp[j][2], p_pre_comp[1][0],
-                        p_pre_comp[1][1], p_pre_comp[1][2],
-                        p_pre_comp[j - 1][0], p_pre_comp[j - 1][1],
-                        p_pre_comp[j - 1][2]);
-      } else {
-        point_double_small(p_pre_comp[j][0], p_pre_comp[j][1],
-                           p_pre_comp[j][2], p_pre_comp[j / 2][0],
-                           p_pre_comp[j / 2][1], p_pre_comp[j / 2][2]);
-      }
-    }
-  }
-
-  batch_mul(x_out, y_out, z_out,
-            (p != NULL && p_scalar != NULL) ? p_scalar->bytes : NULL,
-            g_scalar != NULL ? g_scalar->bytes : NULL,
-            (const smallfelem(*)[3]) & p_pre_comp);
-
-  // reduce the output to its unique minimal representation
-  felem_contract(x_in, x_out);
-  felem_contract(y_in, y_out);
-  felem_contract(z_in, z_out);
-  if (!smallfelem_to_BN(x, x_in) ||
-      !smallfelem_to_BN(y, y_in) ||
-      !smallfelem_to_BN(z, z_in)) {
-    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
-    goto err;
-  }
-  ret = ec_point_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
-
-err:
-  BN_CTX_end(ctx);
-  BN_CTX_free(new_ctx);
-  return ret;
-}
-
-DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp256_method) {
-  out->group_init = ec_GFp_simple_group_init;
-  out->group_finish = ec_GFp_simple_group_finish;
-  out->group_set_curve = ec_GFp_simple_group_set_curve;
-  out->point_get_affine_coordinates =
-      ec_GFp_nistp256_point_get_affine_coordinates;
-  out->mul = ec_GFp_nistp256_points_mul;
-  out->field_mul = ec_GFp_simple_field_mul;
-  out->field_sqr = ec_GFp_simple_field_sqr;
-  out->field_encode = NULL;
-  out->field_decode = NULL;
-};
-
-#endif  // 64_BIT && !WINDOWS
diff --git a/src/crypto/fipsmodule/ec/p256-x86_64.c b/src/crypto/fipsmodule/ec/p256-x86_64.c
index a9b603a..0e79b6d 100644
--- a/src/crypto/fipsmodule/ec/p256-x86_64.c
+++ b/src/crypto/fipsmodule/ec/p256-x86_64.c
@@ -446,6 +446,7 @@
   out->group_set_curve = ec_GFp_mont_group_set_curve;
   out->point_get_affine_coordinates = ecp_nistz256_get_affine;
   out->mul = ecp_nistz256_points_mul;
+  out->mul_public = ecp_nistz256_points_mul;
   out->field_mul = ec_GFp_mont_field_mul;
   out->field_sqr = ec_GFp_mont_field_sqr;
   out->field_encode = ec_GFp_mont_field_encode;
diff --git a/src/crypto/fipsmodule/ec/util-64.c b/src/crypto/fipsmodule/ec/util.c
similarity index 97%
rename from src/crypto/fipsmodule/ec/util-64.c
rename to src/crypto/fipsmodule/ec/util.c
index 0cb117b..7303a15 100644
--- a/src/crypto/fipsmodule/ec/util-64.c
+++ b/src/crypto/fipsmodule/ec/util.c
@@ -14,9 +14,6 @@
 
 #include <openssl/base.h>
 
-
-#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS)
-
 #include <openssl/ec.h>
 
 #include "internal.h"
@@ -105,5 +102,3 @@
   *sign = s & 1;
   *digit = d;
 }
-
-#endif  // 64_BIT && !WINDOWS
diff --git a/src/crypto/fipsmodule/ecdsa/ecdsa.c b/src/crypto/fipsmodule/ecdsa/ecdsa.c
index 6571c94..9e038de 100644
--- a/src/crypto/fipsmodule/ecdsa/ecdsa.c
+++ b/src/crypto/fipsmodule/ecdsa/ecdsa.c
@@ -275,7 +275,7 @@
     OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
     goto err;
   }
-  if (!ec_point_mul_scalar(group, point, &u1, pub_key, &u2, ctx)) {
+  if (!ec_point_mul_scalar_public(group, point, &u1, pub_key, &u2, ctx)) {
     OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
     goto err;
   }
diff --git a/src/crypto/fipsmodule/modes/asm/ghash-armv4.pl b/src/crypto/fipsmodule/modes/asm/ghash-armv4.pl
index e0b4ee0..e93e5b3 100644
--- a/src/crypto/fipsmodule/modes/asm/ghash-armv4.pl
+++ b/src/crypto/fipsmodule/modes/asm/ghash-armv4.pl
@@ -142,6 +142,11 @@
 $code=<<___;
 #include <openssl/arm_arch.h>
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions. (ARMv8 PMULL
+@ instructions are in aesv8-armx.pl.)
+.arch  armv7-a
+
 .text
 #if defined(__thumb2__) || defined(__clang__)
 .syntax	unified
diff --git a/src/crypto/fipsmodule/modes/asm/ghashv8-armx.pl b/src/crypto/fipsmodule/modes/asm/ghashv8-armx.pl
index b1b2481..9bbca10 100644
--- a/src/crypto/fipsmodule/modes/asm/ghashv8-armx.pl
+++ b/src/crypto/fipsmodule/modes/asm/ghashv8-armx.pl
@@ -66,11 +66,7 @@
 
 .text
 ___
-$code.=<<___ if ($flavour =~ /64/);
-#if !defined(__clang__) || defined(BORINGSSL_CLANG_SUPPORTS_DOT_ARCH)
-.arch  armv8-a+crypto
-#endif
-___
+$code.=".arch	armv8-a+crypto\n"	if ($flavour =~ /64/);
 $code.=<<___				if ($flavour !~ /64/);
 .fpu	neon
 .code	32
diff --git a/src/crypto/fipsmodule/rsa/rsa_impl.c b/src/crypto/fipsmodule/rsa/rsa_impl.c
index fb27320..c391228 100644
--- a/src/crypto/fipsmodule/rsa/rsa_impl.c
+++ b/src/crypto/fipsmodule/rsa/rsa_impl.c
@@ -641,6 +641,35 @@
   return ret;
 }
 
+// mod_montgomery sets |r| to |I| mod |p|. |I| must already be fully reduced
+// modulo |p| times |q|. It returns one on success and zero on error.
+static int mod_montgomery(BIGNUM *r, const BIGNUM *I, const BIGNUM *p,
+                          const BN_MONT_CTX *mont_p, const BIGNUM *q,
+                          BN_CTX *ctx) {
+  // Reduce in constant time with Montgomery reduction, which requires I <= p *
+  // R. If p and q are the same size, which is true for any RSA keys we or
+  // anyone sane generates, we have q < R and I < p * q, so this holds.
+  //
+  // If q is too big, fall back to |BN_mod|.
+  if (q->top > p->top) {
+    return BN_mod(r, I, p, ctx);
+  }
+
+  if (// Reduce mod p with Montgomery reduction. This computes I * R^-1 mod p.
+      !BN_from_montgomery(r, I, mont_p, ctx) ||
+      // Multiply by R^2 and do another Montgomery reduction to compute
+      // I * R^-1 * R^2 * R^-1 = I mod p.
+      !BN_to_montgomery(r, r, mont_p, ctx)) {
+    return 0;
+  }
+
+  // By precomputing R^3 mod p (normally |BN_MONT_CTX| only uses R^2 mod p) and
+  // adjusting the API for |BN_mod_exp_mont_consttime|, we could instead compute
+  // I * R mod p here and save a reduction per prime. But this would require
+  // changing the RSAZ code and may not be worth it.
+  return 1;
+}
+
 static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
   assert(ctx != NULL);
 
@@ -675,8 +704,12 @@
     goto err;
   }
 
+  // This is a pre-condition for |mod_montgomery|. It was already checked by the
+  // caller.
+  assert(BN_ucmp(I, rsa->n) < 0);
+
   // compute I mod q
-  if (!BN_mod(r1, I, rsa->q, ctx)) {
+  if (!mod_montgomery(r1, I, rsa->q, rsa->mont_q, rsa->p, ctx)) {
     goto err;
   }
 
@@ -686,7 +719,7 @@
   }
 
   // compute I mod p
-  if (!BN_mod(r1, I, rsa->p, ctx)) {
+  if (!mod_montgomery(r1, I, rsa->p, rsa->mont_p, rsa->q, ctx)) {
     goto err;
   }
 
@@ -695,6 +728,23 @@
     goto err;
   }
 
+  // TODO(davidben): The code below is not constant-time, even ignoring
+  // |bn_correct_top|. To fix this:
+  //
+  // 1. Canonicalize keys on p > q. (p > q for keys we generate, but not ones we
+  //    import.) We have exposed structs, but we can generalize the
+  //    |BN_MONT_CTX_set_locked| trick to do a one-time canonicalization of the
+  //    private key where we optionally swap p and q (re-computing iqmp if
+  //    necessary) and fill in mont_*. This removes the p < q case below.
+  //
+  // 2. Compute r0 - m1 (mod p) in constant-time. With (1) done, this is just a
+  //    constant-time modular subtraction. It should be doable with
+  //    |bn_sub_words| and a select on the borrow bit.
+  //
+  // 3. When computing mont_*, additionally compute iqmp_mont, iqmp in
+  //    Montgomery form. The |BN_mul| and |BN_mod| pair can then be replaced
+  //    with |BN_mod_mul_montgomery|.
+
   if (!BN_sub(r0, r0, m1)) {
     goto err;
   }
diff --git a/src/crypto/fipsmodule/sha/asm/sha256-armv4.pl b/src/crypto/fipsmodule/sha/asm/sha256-armv4.pl
index 3eea080..e5ecdfd 100644
--- a/src/crypto/fipsmodule/sha/asm/sha256-armv4.pl
+++ b/src/crypto/fipsmodule/sha/asm/sha256-armv4.pl
@@ -181,6 +181,11 @@
 # define __ARM_MAX_ARCH__ 7
 #endif
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors. It does have ARMv8-only code, but those
+@ instructions are manually-encoded. (See unsha256.)
+.arch  armv7-a
+
 .text
 #if defined(__thumb2__)
 .syntax unified
diff --git a/src/crypto/fipsmodule/sha/asm/sha512-armv4.pl b/src/crypto/fipsmodule/sha/asm/sha512-armv4.pl
index 85f403e..cc247a4 100644
--- a/src/crypto/fipsmodule/sha/asm/sha512-armv4.pl
+++ b/src/crypto/fipsmodule/sha/asm/sha512-armv4.pl
@@ -208,6 +208,10 @@
 # define VFP_ABI_POP
 #endif
 
+@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
+@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions.
+.arch  armv7-a
+
 #ifdef __ARMEL__
 # define LO 0
 # define HI 4
diff --git a/src/crypto/internal.h b/src/crypto/internal.h
index 76d39b7..5706414 100644
--- a/src/crypto/internal.h
+++ b/src/crypto/internal.h
@@ -151,9 +151,16 @@
 #endif
 
 
-#if !defined(_MSC_VER) && defined(OPENSSL_64_BIT)
+#if (!defined(_MSC_VER) || defined(__clang__)) && defined(OPENSSL_64_BIT)
+#define BORINGSSL_HAS_UINT128
 typedef __int128_t int128_t;
 typedef __uint128_t uint128_t;
+
+// clang-cl supports __uint128_t but modulus and division don't work.
+// https://crbug.com/787617.
+#if !defined(_MSC_VER) || !defined(__clang__)
+#define BORINGSSL_CAN_DIVIDE_UINT128
+#endif
 #endif
 
 #define OPENSSL_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
diff --git a/src/include/openssl/err.h b/src/include/openssl/err.h
index 920c306..a39c090 100644
--- a/src/include/openssl/err.h
+++ b/src/include/openssl/err.h
@@ -395,7 +395,7 @@
 //
 // TODO(fork): remove this function.
 OPENSSL_EXPORT char *ERR_error_string(uint32_t packed_error, char *buf);
-#define ERR_ERROR_STRING_BUF_LEN 256
+#define ERR_ERROR_STRING_BUF_LEN 120
 
 // ERR_GET_FUNC returns zero. BoringSSL errors do not report a function code.
 #define ERR_GET_FUNC(packed_error) 0
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
index c5b95e9..066390b 100644
--- a/src/include/openssl/ssl.h
+++ b/src/include/openssl/ssl.h
@@ -2988,6 +2988,13 @@
 // |SSL_ERROR_EARLY_DATA_REJECTED|.
 OPENSSL_EXPORT void SSL_reset_early_data_reject(SSL *ssl);
 
+// SSL_export_early_keying_material behaves like |SSL_export_keying_material|,
+// but it uses the early exporter. The operation will fail if |ssl| did not
+// negotiate TLS 1.3 or 0-RTT.
+OPENSSL_EXPORT int SSL_export_early_keying_material(
+    SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len,
+    const uint8_t *context, size_t context_len);
+
 
 // Alerts.
 //
@@ -4561,6 +4568,8 @@
 #define SSL_R_NO_SUPPORTED_VERSIONS_ENABLED 280
 #define SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE 281
 #define SSL_R_EMPTY_HELLO_RETRY_REQUEST 282
+#define SSL_R_EARLY_DATA_NOT_IN_USE 283
+#define SSL_R_HANDSHAKE_NOT_COMPLETE 284
 #define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000
 #define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010
 #define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020
diff --git a/src/ssl/handshake_client.cc b/src/ssl/handshake_client.cc
index b801e82..cdda459 100644
--- a/src/ssl/handshake_client.cc
+++ b/src/ssl/handshake_client.cc
@@ -464,7 +464,7 @@
     hs->session_id_len = ssl->session->session_id_length;
     OPENSSL_memcpy(hs->session_id, ssl->session->session_id,
                    hs->session_id_len);
-  } else if (ssl_is_resumption_variant(ssl->tls13_variant)) {
+  } else if (ssl_is_resumption_variant(hs->max_version, ssl->tls13_variant)) {
     hs->session_id_len = sizeof(hs->session_id);
     if (!RAND_bytes(hs->session_id, hs->session_id_len)) {
       return ssl_hs_error;
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index 4bef358..4151d2b 100644
--- a/src/ssl/internal.h
+++ b/src/ssl/internal.h
@@ -404,9 +404,10 @@
 // TLS 1.3 resumption experiment.
 bool ssl_is_resumption_experiment(uint16_t version);
 
-// ssl_is_resumption_variant returns whether the version corresponds to a
+// ssl_is_resumption_variant returns whether the variant corresponds to a
 // TLS 1.3 resumption experiment.
-bool ssl_is_resumption_variant(enum tls13_variant_t variant);
+bool ssl_is_resumption_variant(uint16_t max_version,
+                               enum tls13_variant_t variant);
 
 // ssl_is_resumption_client_ccs_experiment returns whether the version
 // corresponds to a TLS 1.3 resumption experiment that sends a client CCS.
@@ -1244,10 +1245,10 @@
 
 // tls13_export_keying_material provides an exporter interface to use the
 // |exporter_secret|.
-int tls13_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len,
-                                 const char *label, size_t label_len,
-                                 const uint8_t *context, size_t context_len,
-                                 int use_context);
+int tls13_export_keying_material(SSL *ssl, Span<uint8_t> out,
+                                 Span<const uint8_t> secret,
+                                 Span<const char> label,
+                                 Span<const uint8_t> context);
 
 // tls13_finished_mac calculates the MAC of the handshake transcript to verify
 // the integrity of the Finished message, and stores the result in |out| and
diff --git a/src/ssl/ssl_versions.cc b/src/ssl/ssl_versions.cc
index 15b0294..2406bd8 100644
--- a/src/ssl/ssl_versions.cc
+++ b/src/ssl/ssl_versions.cc
@@ -412,7 +412,11 @@
          version == TLS1_3_DRAFT22_VERSION;
 }
 
-bool ssl_is_resumption_variant(enum tls13_variant_t variant) {
+bool ssl_is_resumption_variant(uint16_t max_version,
+                               enum tls13_variant_t variant) {
+  if (max_version < TLS1_3_VERSION) {
+    return false;
+  }
   return variant == tls13_experiment || variant == tls13_experiment2 ||
          variant == tls13_experiment3 || variant == tls13_draft22;
 }
diff --git a/src/ssl/t1_enc.cc b/src/ssl/t1_enc.cc
index 2a09987..6b5447d 100644
--- a/src/ssl/t1_enc.cc
+++ b/src/ssl/t1_enc.cc
@@ -458,17 +458,28 @@
                                const uint8_t *context, size_t context_len,
                                int use_context) {
   if (!ssl->s3->have_version || ssl->version == SSL3_VERSION) {
+    OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE);
     return 0;
   }
 
-  // Exporters may not be used in the middle of a renegotiation.
-  if (SSL_in_init(ssl) && !SSL_in_false_start(ssl)) {
+  // Exporters may be used in False Start and server 0-RTT, where the handshake
+  // has progressed enough. Otherwise, they may not be used during a handshake.
+  if (SSL_in_init(ssl) &&
+      !SSL_in_false_start(ssl) &&
+      !(SSL_is_server(ssl) && SSL_in_early_data(ssl))) {
+    OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE);
     return 0;
   }
 
   if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
-    return tls13_export_keying_material(ssl, out, out_len, label, label_len,
-                                        context, context_len, use_context);
+    if (!use_context) {
+      context = nullptr;
+      context_len = 0;
+    }
+    return tls13_export_keying_material(
+        ssl, MakeSpan(out, out_len),
+        MakeConstSpan(ssl->s3->exporter_secret, ssl->s3->exporter_secret_len),
+        MakeConstSpan(label, label_len), MakeConstSpan(context, context_len));
   }
 
   size_t seed_len = 2 * SSL3_RANDOM_SIZE;
@@ -501,3 +512,27 @@
       MakeConstSpan(session->master_key, session->master_key_length),
       MakeConstSpan(label, label_len), seed, {});
 }
+
+int SSL_export_early_keying_material(
+    SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len,
+    const uint8_t *context, size_t context_len) {
+  if (!SSL_in_early_data(ssl) &&
+      (!ssl->s3->have_version ||
+       ssl_protocol_version(ssl) < TLS1_3_VERSION)) {
+    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION);
+    return 0;
+  }
+
+  // The early exporter only exists if we accepted early data or offered it as
+  // a client.
+  if (!SSL_in_early_data(ssl) && !SSL_early_data_accepted(ssl)) {
+    OPENSSL_PUT_ERROR(SSL, SSL_R_EARLY_DATA_NOT_IN_USE);
+    return 0;
+  }
+
+  return tls13_export_keying_material(
+      ssl, MakeSpan(out, out_len),
+      MakeConstSpan(ssl->s3->early_exporter_secret,
+                    ssl->s3->early_exporter_secret_len),
+      MakeConstSpan(label, label_len), MakeConstSpan(context, context_len));
+}
diff --git a/src/ssl/test/bssl_shim.cc b/src/ssl/test/bssl_shim.cc
index 1f43be6..0b4c760 100644
--- a/src/ssl/test/bssl_shim.cc
+++ b/src/ssl/test/bssl_shim.cc
@@ -2205,6 +2205,22 @@
     GetTestState(ssl)->got_new_session = false;
   }
 
+  if (config->export_early_keying_material > 0) {
+    std::vector<uint8_t> result(
+        static_cast<size_t>(config->export_early_keying_material));
+    if (!SSL_export_early_keying_material(
+            ssl, result.data(), result.size(), config->export_label.data(),
+            config->export_label.size(),
+            reinterpret_cast<const uint8_t *>(config->export_context.data()),
+            config->export_context.size())) {
+      fprintf(stderr, "failed to export keying material\n");
+      return false;
+    }
+    if (WriteAll(ssl, result.data(), result.size()) < 0) {
+      return false;
+    }
+  }
+
   if (config->export_keying_material > 0) {
     std::vector<uint8_t> result(
         static_cast<size_t>(config->export_keying_material));
diff --git a/src/ssl/test/runner/common.go b/src/ssl/test/runner/common.go
index 5343346..c6d5c65 100644
--- a/src/ssl/test/runner/common.go
+++ b/src/ssl/test/runner/common.go
@@ -1289,6 +1289,21 @@
 	// it was accepted.
 	SendEarlyDataExtension bool
 
+	// ExpectEarlyKeyingMaterial, if non-zero, causes a TLS 1.3 server to
+	// read an application data record after the ClientHello before it sends
+	// a ServerHello. The record's contents have the specified length and
+	// match the corresponding early exporter value. This is used to test
+	// the client using the early exporter in the 0-RTT state.
+	ExpectEarlyKeyingMaterial int
+
+	// ExpectEarlyKeyingLabel is the label to use with
+	// ExpectEarlyKeyingMaterial.
+	ExpectEarlyKeyingLabel string
+
+	// ExpectEarlyKeyingContext is the context string to use with
+	// ExpectEarlyKeyingMaterial
+	ExpectEarlyKeyingContext string
+
 	// ExpectEarlyData causes a TLS 1.3 server to read application
 	// data after the ClientHello (assuming the server is able to
 	// derive the key under which the data is encrypted) before it
diff --git a/src/ssl/test/runner/conn.go b/src/ssl/test/runner/conn.go
index ec320ae..c6ee443 100644
--- a/src/ssl/test/runner/conn.go
+++ b/src/ssl/test/runner/conn.go
@@ -44,6 +44,7 @@
 	didResume            bool // whether this connection was a session resumption
 	extendedMasterSecret bool // whether this session used an extended master secret
 	cipherSuite          *cipherSuite
+	earlyCipherSuite     *cipherSuite
 	ocspResponse         []byte // stapled OCSP response
 	sctList              []byte // signed certificate timestamp list
 	peerCertificates     []*x509.Certificate
@@ -63,6 +64,7 @@
 	curveID CurveID
 
 	clientRandom, serverRandom [32]byte
+	earlyExporterSecret        []byte
 	exporterSecret             []byte
 	resumptionSecret           []byte
 
@@ -1847,6 +1849,23 @@
 	return c.peerCertificates[0].VerifyHostname(host)
 }
 
+func (c *Conn) exportKeyingMaterialTLS13(length int, secret, label, context []byte) []byte {
+	cipherSuite := c.cipherSuite
+	if cipherSuite == nil {
+		cipherSuite = c.earlyCipherSuite
+	}
+	if isDraft21(c.wireVersion) {
+		hash := cipherSuite.hash()
+		exporterKeyingLabel := []byte("exporter")
+		contextHash := hash.New()
+		contextHash.Write(context)
+		exporterContext := hash.New().Sum(nil)
+		derivedSecret := hkdfExpandLabel(cipherSuite.hash(), c.wireVersion, secret, label, exporterContext, hash.Size())
+		return hkdfExpandLabel(cipherSuite.hash(), c.wireVersion, derivedSecret, exporterKeyingLabel, contextHash.Sum(nil), length)
+	}
+	return hkdfExpandLabel(cipherSuite.hash(), c.wireVersion, secret, label, context, length)
+}
+
 // ExportKeyingMaterial exports keying material from the current connection
 // state, as per RFC 5705.
 func (c *Conn) ExportKeyingMaterial(length int, label, context []byte, useContext bool) ([]byte, error) {
@@ -1857,16 +1876,7 @@
 	}
 
 	if c.vers >= VersionTLS13 {
-		if isDraft21(c.wireVersion) {
-			hash := c.cipherSuite.hash()
-			exporterKeyingLabel := []byte("exporter")
-			contextHash := hash.New()
-			contextHash.Write(context)
-			exporterContext := hash.New().Sum(nil)
-			derivedSecret := hkdfExpandLabel(c.cipherSuite.hash(), c.wireVersion, c.exporterSecret, label, exporterContext, hash.Size())
-			return hkdfExpandLabel(c.cipherSuite.hash(), c.wireVersion, derivedSecret, exporterKeyingLabel, contextHash.Sum(nil), length), nil
-		}
-		return hkdfExpandLabel(c.cipherSuite.hash(), c.wireVersion, c.exporterSecret, label, context, length), nil
+		return c.exportKeyingMaterialTLS13(length, c.exporterSecret, label, context), nil
 	}
 
 	seedLen := len(c.clientRandom) + len(c.serverRandom)
@@ -1885,6 +1895,18 @@
 	return result, nil
 }
 
+func (c *Conn) ExportEarlyKeyingMaterial(length int, label, context []byte) ([]byte, error) {
+	if c.vers < VersionTLS13 {
+		return nil, errors.New("tls: early exporters not defined before TLS 1.3")
+	}
+
+	if c.earlyExporterSecret == nil {
+		return nil, errors.New("tls: no early exporter secret")
+	}
+
+	return c.exportKeyingMaterialTLS13(length, c.earlyExporterSecret, label, context), nil
+}
+
 // noRenegotiationInfo returns true if the renegotiation info extension
 // should be supported in the current handshake.
 func (c *Conn) noRenegotiationInfo() bool {
diff --git a/src/ssl/test/runner/fuzzer_mode.json b/src/ssl/test/runner/fuzzer_mode.json
index fd029d3..89ba707 100644
--- a/src/ssl/test/runner/fuzzer_mode.json
+++ b/src/ssl/test/runner/fuzzer_mode.json
@@ -46,6 +46,7 @@
     "*-EarlyData-RejectUnfinishedWrite-Client-*": "Trial decryption does not work with the NULL cipher.",
     "EarlyData-Reject-Client-*": "Trial decryption does not work with the NULL cipher.",
     "EarlyData-RejectTicket-Client-*": "Trial decryption does not work with the NULL cipher.",
+    "CustomExtensions-Server-EarlyDataOffered": "Trial decryption does not work with the NULL cipher.",
 
     "Renegotiate-Client-BadExt*": "Fuzzer mode does not check renegotiation_info.",
 
diff --git a/src/ssl/test/runner/handshake_client.go b/src/ssl/test/runner/handshake_client.go
index 5f22ecd..55d21c9 100644
--- a/src/ssl/test/runner/handshake_client.go
+++ b/src/ssl/test/runner/handshake_client.go
@@ -414,18 +414,21 @@
 		finishedHash.addEntropy(session.masterSecret)
 		finishedHash.Write(helloBytes)
 
-		earlyLabel := earlyTrafficLabel
-		if isDraft21(session.wireVersion) {
-			earlyLabel = earlyTrafficLabelDraft21
-		}
-
 		if !c.config.Bugs.SkipChangeCipherSpec && isDraft22(session.wireVersion) {
 			c.wireVersion = session.wireVersion
 			c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
 			c.wireVersion = 0
 		}
 
-		earlyTrafficSecret := finishedHash.deriveSecret(earlyLabel)
+		var earlyTrafficSecret []byte
+		if isDraft21(session.wireVersion) {
+			earlyTrafficSecret = finishedHash.deriveSecret(earlyTrafficLabelDraft21)
+			c.earlyExporterSecret = finishedHash.deriveSecret(earlyExporterLabelDraft21)
+		} else {
+			earlyTrafficSecret = finishedHash.deriveSecret(earlyTrafficLabel)
+			c.earlyExporterSecret = finishedHash.deriveSecret(earlyExporterLabel)
+		}
+
 		c.useOutTrafficSecret(session.wireVersion, pskCipherSuite, earlyTrafficSecret)
 		for _, earlyData := range c.config.Bugs.SendEarlyData {
 			if _, err := c.writeRecord(recordTypeApplicationData, earlyData); err != nil {
diff --git a/src/ssl/test/runner/handshake_server.go b/src/ssl/test/runner/handshake_server.go
index 595f8da..9ba6c2c 100644
--- a/src/ssl/test/runner/handshake_server.go
+++ b/src/ssl/test/runner/handshake_server.go
@@ -694,22 +694,36 @@
 			}
 		}
 		if encryptedExtensions.extensions.hasEarlyData {
-			earlyLabel := earlyTrafficLabel
+			var earlyTrafficSecret []byte
 			if isDraft21(c.wireVersion) {
-				earlyLabel = earlyTrafficLabelDraft21
+				earlyTrafficSecret = hs.finishedHash.deriveSecret(earlyTrafficLabelDraft21)
+				c.earlyExporterSecret = hs.finishedHash.deriveSecret(earlyExporterLabelDraft21)
+			} else {
+				earlyTrafficSecret = hs.finishedHash.deriveSecret(earlyTrafficLabel)
+				c.earlyExporterSecret = hs.finishedHash.deriveSecret(earlyExporterLabel)
 			}
 
-			earlyTrafficSecret := hs.finishedHash.deriveSecret(earlyLabel)
 			if err := c.useInTrafficSecret(c.wireVersion, hs.suite, earlyTrafficSecret); err != nil {
 				return err
 			}
 
-			for _, expectedMsg := range config.Bugs.ExpectEarlyData {
+			c.earlyCipherSuite = hs.suite
+			expectEarlyData := config.Bugs.ExpectEarlyData
+			if n := config.Bugs.ExpectEarlyKeyingMaterial; n > 0 {
+				exporter, err := c.ExportEarlyKeyingMaterial(n, []byte(config.Bugs.ExpectEarlyKeyingLabel), []byte(config.Bugs.ExpectEarlyKeyingContext))
+				if err != nil {
+					return err
+				}
+				expectEarlyData = append([][]byte{exporter}, expectEarlyData...)
+			}
+
+			for _, expectedMsg := range expectEarlyData {
 				if err := c.readRecord(recordTypeApplicationData); err != nil {
 					return err
 				}
-				if !bytes.Equal(c.input.data[c.input.off:], expectedMsg) {
-					return errors.New("ExpectEarlyData: did not get expected message")
+				msg := c.input.data[c.input.off:]
+				if !bytes.Equal(msg, expectedMsg) {
+					return fmt.Errorf("tls: got early data record %x, wanted %x", msg, expectedMsg)
 				}
 				c.in.freeBlock(c.input)
 				c.input = nil
diff --git a/src/ssl/test/runner/prf.go b/src/ssl/test/runner/prf.go
index 6fa3c4c..54e18cb 100644
--- a/src/ssl/test/runner/prf.go
+++ b/src/ssl/test/runner/prf.go
@@ -446,6 +446,7 @@
 	clientApplicationTrafficLabel = []byte("client application traffic secret")
 	serverApplicationTrafficLabel = []byte("server application traffic secret")
 	applicationTrafficLabel       = []byte("application traffic secret")
+	earlyExporterLabel            = []byte("early exporter master secret")
 	exporterLabel                 = []byte("exporter master secret")
 	resumptionLabel               = []byte("resumption master secret")
 
@@ -457,6 +458,7 @@
 	clientApplicationTrafficLabelDraft21 = []byte("c ap traffic")
 	serverApplicationTrafficLabelDraft21 = []byte("s ap traffic")
 	applicationTrafficLabelDraft21       = []byte("traffic upd")
+	earlyExporterLabelDraft21            = []byte("e exp master")
 	exporterLabelDraft21                 = []byte("exp master")
 	resumptionLabelDraft21               = []byte("res master")
 
diff --git a/src/ssl/test/runner/runner.go b/src/ssl/test/runner/runner.go
index 362a7a5..4cfce26 100644
--- a/src/ssl/test/runner/runner.go
+++ b/src/ssl/test/runner/runner.go
@@ -431,6 +431,9 @@
 	exportLabel          string
 	exportContext        string
 	useExportContext     bool
+	// exportEarlyKeyingMaterial, if non-zero, behaves like
+	// exportKeyingMaterial, but for the early exporter.
+	exportEarlyKeyingMaterial int
 	// flags, if not empty, contains a list of command-line flags that will
 	// be passed to the shim program.
 	flags []string
@@ -694,6 +697,20 @@
 		}
 	}
 
+	if isResume && test.exportEarlyKeyingMaterial > 0 {
+		actual := make([]byte, test.exportEarlyKeyingMaterial)
+		if _, err := io.ReadFull(tlsConn, actual); err != nil {
+			return err
+		}
+		expected, err := tlsConn.ExportEarlyKeyingMaterial(test.exportEarlyKeyingMaterial, []byte(test.exportLabel), []byte(test.exportContext))
+		if err != nil {
+			return err
+		}
+		if !bytes.Equal(actual, expected) {
+			return fmt.Errorf("early keying material mismatch; got %x, wanted %x", actual, expected)
+		}
+	}
+
 	if test.exportKeyingMaterial > 0 {
 		actual := make([]byte, test.exportKeyingMaterial)
 		if _, err := io.ReadFull(tlsConn, actual); err != nil {
@@ -704,7 +721,7 @@
 			return err
 		}
 		if !bytes.Equal(actual, expected) {
-			return fmt.Errorf("keying material mismatch")
+			return fmt.Errorf("keying material mismatch; got %x, wanted %x", actual, expected)
 		}
 	}
 
@@ -1037,12 +1054,18 @@
 
 	if test.exportKeyingMaterial > 0 {
 		flags = append(flags, "-export-keying-material", strconv.Itoa(test.exportKeyingMaterial))
-		flags = append(flags, "-export-label", test.exportLabel)
-		flags = append(flags, "-export-context", test.exportContext)
 		if test.useExportContext {
 			flags = append(flags, "-use-export-context")
 		}
 	}
+	if test.exportEarlyKeyingMaterial > 0 {
+		flags = append(flags, "-on-resume-export-early-keying-material", strconv.Itoa(test.exportEarlyKeyingMaterial))
+	}
+	if test.exportKeyingMaterial > 0 || test.exportEarlyKeyingMaterial > 0 {
+		flags = append(flags, "-export-label", test.exportLabel)
+		flags = append(flags, "-export-context", test.exportContext)
+	}
+
 	if test.expectResumeRejected {
 		flags = append(flags, "-expect-session-miss")
 	}
@@ -9047,6 +9070,9 @@
 			config: Config{
 				MaxVersion: vers.version,
 			},
+			// Test the exporter in both initial and resumption
+			// handshakes.
+			resumeSession:        true,
 			tls13Variant:         vers.tls13Variant,
 			exportKeyingMaterial: 1024,
 			exportLabel:          "label",
@@ -9081,6 +9107,229 @@
 			exportContext:        "context",
 			useExportContext:     true,
 		})
+
+		if vers.version >= VersionTLS13 {
+			// Test the exporters do not work while the client is
+			// sending 0-RTT data.
+			testCases = append(testCases, testCase{
+				name: "NoEarlyKeyingMaterial-Client-InEarlyData-" + vers.name,
+				config: Config{
+					MaxVersion:       vers.version,
+					MaxEarlyDataSize: 16384,
+				},
+				resumeSession: true,
+				tls13Variant:  vers.tls13Variant,
+				flags: []string{
+					"-enable-early-data",
+					"-expect-ticket-supports-early-data",
+					"-expect-accept-early-data",
+					"-on-resume-export-keying-material", "1024",
+					"-on-resume-export-label", "label",
+					"-on-resume-export-context", "context",
+				},
+				shouldFail:    true,
+				expectedError: ":HANDSHAKE_NOT_COMPLETE:",
+			})
+
+			// Test the early exporter works while the client is
+			// sending 0-RTT data. This data arrives during the
+			// server handshake, so we test it with ProtocolBugs.
+			testCases = append(testCases, testCase{
+				name: "ExportEarlyKeyingMaterial-Client-InEarlyData-" + vers.name,
+				config: Config{
+					MaxVersion:       vers.version,
+					MaxEarlyDataSize: 16384,
+				},
+				resumeConfig: &Config{
+					MaxVersion:       vers.version,
+					MaxEarlyDataSize: 16384,
+					Bugs: ProtocolBugs{
+						ExpectEarlyKeyingMaterial: 1024,
+						ExpectEarlyKeyingLabel:    "label",
+						ExpectEarlyKeyingContext:  "context",
+					},
+				},
+				resumeSession: true,
+				tls13Variant:  vers.tls13Variant,
+				flags: []string{
+					"-enable-early-data",
+					"-expect-ticket-supports-early-data",
+					"-expect-accept-early-data",
+					"-on-resume-export-early-keying-material", "1024",
+					"-on-resume-export-label", "label",
+					"-on-resume-export-context", "context",
+				},
+			})
+
+			// Test the early exporter still works on the client
+			// after the handshake is confirmed. This arrives after
+			// the server handshake, so the normal hooks work.
+			testCases = append(testCases, testCase{
+				name: "ExportEarlyKeyingMaterial-Client-EarlyDataAccept-" + vers.name,
+				config: Config{
+					MaxVersion:       vers.version,
+					MaxEarlyDataSize: 16384,
+				},
+				resumeConfig: &Config{
+					MaxVersion:       vers.version,
+					MaxEarlyDataSize: 16384,
+				},
+				resumeSession:             true,
+				tls13Variant:              vers.tls13Variant,
+				exportEarlyKeyingMaterial: 1024,
+				exportLabel:               "label",
+				exportContext:             "context",
+				flags: []string{
+					"-enable-early-data",
+					"-expect-ticket-supports-early-data",
+					"-expect-accept-early-data",
+					// Handshake twice on the client to force
+					// handshake confirmation.
+					"-handshake-twice",
+				},
+			})
+
+			// Test the early exporter does not work on the client
+			// if 0-RTT was not offered.
+			testCases = append(testCases, testCase{
+				name: "NoExportEarlyKeyingMaterial-Client-Initial-" + vers.name,
+				config: Config{
+					MaxVersion: vers.version,
+				},
+				tls13Variant:  vers.tls13Variant,
+				flags:         []string{"-export-early-keying-material", "1024"},
+				shouldFail:    true,
+				expectedError: ":EARLY_DATA_NOT_IN_USE:",
+			})
+			testCases = append(testCases, testCase{
+				name: "NoExportEarlyKeyingMaterial-Client-Resume-" + vers.name,
+				config: Config{
+					MaxVersion: vers.version,
+				},
+				resumeSession: true,
+				tls13Variant:  vers.tls13Variant,
+				flags:         []string{"-on-resume-export-early-keying-material", "1024"},
+				shouldFail:    true,
+				expectedError: ":EARLY_DATA_NOT_IN_USE:",
+			})
+
+			// Test the early exporter does not work on the client
+			// after a 0-RTT reject.
+			testCases = append(testCases, testCase{
+				name: "NoExportEarlyKeyingMaterial-Client-EarlyDataReject-" + vers.name,
+				config: Config{
+					MaxVersion:       vers.version,
+					MaxEarlyDataSize: 16384,
+					Bugs: ProtocolBugs{
+						AlwaysRejectEarlyData: true,
+					},
+				},
+				resumeSession: true,
+				tls13Variant:  vers.tls13Variant,
+				flags: []string{
+					"-enable-early-data",
+					"-expect-ticket-supports-early-data",
+					"-expect-reject-early-data",
+					"-on-retry-export-early-keying-material", "1024",
+				},
+				shouldFail:    true,
+				expectedError: ":EARLY_DATA_NOT_IN_USE:",
+			})
+
+			// Test the normal exporter on the server in half-RTT.
+			testCases = append(testCases, testCase{
+				testType: serverTest,
+				name:     "ExportKeyingMaterial-Server-HalfRTT-" + vers.name,
+				config: Config{
+					MaxVersion: vers.version,
+					Bugs: ProtocolBugs{
+						SendEarlyData:           [][]byte{},
+						ExpectEarlyDataAccepted: true,
+					},
+				},
+				tls13Variant:         vers.tls13Variant,
+				resumeSession:        true,
+				exportKeyingMaterial: 1024,
+				exportLabel:          "label",
+				exportContext:        "context",
+				useExportContext:     true,
+				flags:                []string{"-enable-early-data"},
+			})
+
+			// Test the early exporter works on the server in half-RTT.
+			testCases = append(testCases, testCase{
+				testType: serverTest,
+				name:     "ExportEarlyKeyingMaterial-Server-HalfRTT-" + vers.name,
+				config: Config{
+					MaxVersion: vers.version,
+					Bugs: ProtocolBugs{
+						SendEarlyData:           [][]byte{},
+						ExpectEarlyDataAccepted: true,
+					},
+				},
+				tls13Variant:              vers.tls13Variant,
+				resumeSession:             true,
+				exportEarlyKeyingMaterial: 1024,
+				exportLabel:               "label",
+				exportContext:             "context",
+				flags:                     []string{"-enable-early-data"},
+			})
+
+			// Test the early exporter does not work on the server
+			// if 0-RTT was not offered.
+			testCases = append(testCases, testCase{
+				testType: serverTest,
+				name:     "NoExportEarlyKeyingMaterial-Server-Initial-" + vers.name,
+				config: Config{
+					MaxVersion: vers.version,
+				},
+				tls13Variant:  vers.tls13Variant,
+				flags:         []string{"-export-early-keying-material", "1024"},
+				shouldFail:    true,
+				expectedError: ":EARLY_DATA_NOT_IN_USE:",
+			})
+			testCases = append(testCases, testCase{
+				testType: serverTest,
+				name:     "NoExportEarlyKeyingMaterial-Server-Resume-" + vers.name,
+				config: Config{
+					MaxVersion: vers.version,
+				},
+				resumeSession: true,
+				tls13Variant:  vers.tls13Variant,
+				flags:         []string{"-on-resume-export-early-keying-material", "1024"},
+				shouldFail:    true,
+				expectedError: ":EARLY_DATA_NOT_IN_USE:",
+			})
+		} else {
+			// Test the early exporter fails before TLS 1.3.
+			testCases = append(testCases, testCase{
+				name: "NoExportEarlyKeyingMaterial-Client-" + vers.name,
+				config: Config{
+					MaxVersion: vers.version,
+				},
+				resumeSession:             true,
+				tls13Variant:              vers.tls13Variant,
+				exportEarlyKeyingMaterial: 1024,
+				exportLabel:               "label",
+				exportContext:             "context",
+				shouldFail:                true,
+				expectedError:             ":WRONG_SSL_VERSION:",
+			})
+			testCases = append(testCases, testCase{
+				testType: serverTest,
+				name:     "NoExportEarlyKeyingMaterial-Server-" + vers.name,
+				config: Config{
+					MaxVersion: vers.version,
+				},
+				resumeSession:             true,
+				tls13Variant:              vers.tls13Variant,
+				exportEarlyKeyingMaterial: 1024,
+				exportLabel:               "label",
+				exportContext:             "context",
+				shouldFail:                true,
+				expectedError:             ":WRONG_SSL_VERSION:",
+			})
+		}
 	}
 
 	testCases = append(testCases, testCase{
@@ -11149,6 +11398,20 @@
 			tls13Variant: variant,
 		})
 
+		// Test that the client omits the fake session ID when the max version is TLS 1.2 and below.
+		testCases = append(testCases, testCase{
+			testType: clientTest,
+			name:     "TLS12NoSessionID-" + name,
+			config: Config{
+				MaxVersion: VersionTLS13,
+				Bugs: ProtocolBugs{
+					ExpectNoTLS12Session: true,
+				},
+			},
+			tls13Variant: variant,
+			flags:        []string{"-max-version", strconv.Itoa(VersionTLS12)},
+		})
+
 		testCases = append(testCases, testCase{
 			testType: clientTest,
 			name:     "EarlyData-Client-" + name,
diff --git a/src/ssl/test/test_config.cc b/src/ssl/test/test_config.cc
index efe5acb..579cf89 100644
--- a/src/ssl/test/test_config.cc
+++ b/src/ssl/test/test_config.cc
@@ -177,6 +177,8 @@
   { "-max-version", &TestConfig::max_version },
   { "-expect-version", &TestConfig::expect_version },
   { "-mtu", &TestConfig::mtu },
+  { "-export-early-keying-material",
+    &TestConfig::export_early_keying_material },
   { "-export-keying-material", &TestConfig::export_keying_material },
   { "-expect-total-renegotiations", &TestConfig::expect_total_renegotiations },
   { "-expect-peer-signature-algorithm",
diff --git a/src/ssl/test/test_config.h b/src/ssl/test/test_config.h
index 783471a..49b86ed 100644
--- a/src/ssl/test/test_config.h
+++ b/src/ssl/test/test_config.h
@@ -79,6 +79,7 @@
   bool fail_cert_callback = false;
   std::string cipher;
   bool handshake_never_done = false;
+  int export_early_keying_material = 0;
   int export_keying_material = 0;
   std::string export_label;
   std::string export_context;
diff --git a/src/ssl/tls13_enc.cc b/src/ssl/tls13_enc.cc
index 14f4a78..9dcd071 100644
--- a/src/ssl/tls13_enc.cc
+++ b/src/ssl/tls13_enc.cc
@@ -68,7 +68,7 @@
 
 static int hkdf_expand_label(uint8_t *out, uint16_t version,
                              const EVP_MD *digest, const uint8_t *secret,
-                             size_t secret_len, const uint8_t *label,
+                             size_t secret_len, const char *label,
                              size_t label_len, const uint8_t *hash,
                              size_t hash_len, size_t len) {
   const char *kTLS13LabelVersion =
@@ -84,7 +84,7 @@
       !CBB_add_u8_length_prefixed(cbb.get(), &child) ||
       !CBB_add_bytes(&child, (const uint8_t *)kTLS13LabelVersion,
                      strlen(kTLS13LabelVersion)) ||
-      !CBB_add_bytes(&child, label, label_len) ||
+      !CBB_add_bytes(&child, (const uint8_t *)label, label_len) ||
       !CBB_add_u8_length_prefixed(cbb.get(), &child) ||
       !CBB_add_bytes(&child, hash, hash_len) ||
       !CBB_finish(cbb.get(), &hkdf_label, &hkdf_label_len)) {
@@ -113,8 +113,7 @@
     }
 
     if (!hkdf_expand_label(hs->secret, ssl->version, hs->transcript.Digest(),
-                           hs->secret, hs->hash_len,
-                           (const uint8_t *)kTLS13LabelDerived,
+                           hs->secret, hs->hash_len, kTLS13LabelDerived,
                            strlen(kTLS13LabelDerived), derive_context,
                            derive_context_len, hs->hash_len)) {
       return 0;
@@ -129,7 +128,7 @@
 // with the given label and the current base secret and most recently-saved
 // handshake context. It returns one on success and zero on error.
 static int derive_secret(SSL_HANDSHAKE *hs, uint8_t *out, size_t len,
-                         const uint8_t *label, size_t label_len) {
+                         const char *label, size_t label_len) {
   uint8_t context_hash[EVP_MAX_MD_SIZE];
   size_t context_hash_len;
   if (!hs->transcript.GetHash(context_hash, &context_hash_len)) {
@@ -167,8 +166,7 @@
   size_t key_len = EVP_AEAD_key_length(aead);
   uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
   if (!hkdf_expand_label(key, session->ssl_version, digest, traffic_secret,
-                         traffic_secret_len, (const uint8_t *)"key", 3, NULL, 0,
-                         key_len)) {
+                         traffic_secret_len, "key", 3, NULL, 0, key_len)) {
     return 0;
   }
 
@@ -176,8 +174,7 @@
   size_t iv_len = EVP_AEAD_nonce_length(aead);
   uint8_t iv[EVP_AEAD_MAX_NONCE_LENGTH];
   if (!hkdf_expand_label(iv, session->ssl_version, digest, traffic_secret,
-                         traffic_secret_len, (const uint8_t *)"iv", 2, NULL, 0,
-                         iv_len)) {
+                         traffic_secret_len, "iv", 2, NULL, 0, iv_len)) {
     return 0;
   }
 
@@ -246,14 +243,16 @@
   const char *early_exporter_label = ssl_is_draft21(version)
                                          ? kTLS13Draft21LabelEarlyExporter
                                          : kTLS13LabelEarlyExporter;
-  return derive_secret(hs, hs->early_traffic_secret, hs->hash_len,
-                       (const uint8_t *)early_traffic_label,
-                       strlen(early_traffic_label)) &&
-         ssl_log_secret(ssl, "CLIENT_EARLY_TRAFFIC_SECRET",
-                        hs->early_traffic_secret, hs->hash_len) &&
-         derive_secret(hs, ssl->s3->early_exporter_secret, hs->hash_len,
-                       (const uint8_t *)early_exporter_label,
-                       strlen(early_exporter_label));
+  if (!derive_secret(hs, hs->early_traffic_secret, hs->hash_len,
+                     early_traffic_label, strlen(early_traffic_label)) ||
+      !ssl_log_secret(ssl, "CLIENT_EARLY_TRAFFIC_SECRET",
+                      hs->early_traffic_secret, hs->hash_len) ||
+      !derive_secret(hs, ssl->s3->early_exporter_secret, hs->hash_len,
+                     early_exporter_label, strlen(early_exporter_label))) {
+    return 0;
+  }
+  ssl->s3->early_exporter_secret_len = hs->hash_len;
+  return 1;
 }
 
 int tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs) {
@@ -265,11 +264,11 @@
                                  ? kTLS13Draft21LabelServerHandshakeTraffic
                                  : kTLS13LabelServerHandshakeTraffic;
   return derive_secret(hs, hs->client_handshake_secret, hs->hash_len,
-                       (const uint8_t *)client_label, strlen(client_label)) &&
+                       client_label, strlen(client_label)) &&
          ssl_log_secret(ssl, "CLIENT_HANDSHAKE_TRAFFIC_SECRET",
                         hs->client_handshake_secret, hs->hash_len) &&
          derive_secret(hs, hs->server_handshake_secret, hs->hash_len,
-                       (const uint8_t *)server_label, strlen(server_label)) &&
+                       server_label, strlen(server_label)) &&
          ssl_log_secret(ssl, "SERVER_HANDSHAKE_TRAFFIC_SECRET",
                         hs->server_handshake_secret, hs->hash_len);
 }
@@ -287,16 +286,15 @@
                                    ? kTLS13Draft21LabelExporter
                                    : kTLS13LabelExporter;
   return derive_secret(hs, hs->client_traffic_secret_0, hs->hash_len,
-                       (const uint8_t *)client_label, strlen(client_label)) &&
+                       client_label, strlen(client_label)) &&
          ssl_log_secret(ssl, "CLIENT_TRAFFIC_SECRET_0",
                         hs->client_traffic_secret_0, hs->hash_len) &&
          derive_secret(hs, hs->server_traffic_secret_0, hs->hash_len,
-                       (const uint8_t *)server_label, strlen(server_label)) &&
+                       server_label, strlen(server_label)) &&
          ssl_log_secret(ssl, "SERVER_TRAFFIC_SECRET_0",
                         hs->server_traffic_secret_0, hs->hash_len) &&
          derive_secret(hs, ssl->s3->exporter_secret, hs->hash_len,
-                       (const uint8_t *)exporter_label,
-                       strlen(exporter_label)) &&
+                       exporter_label, strlen(exporter_label)) &&
          ssl_log_secret(ssl, "EXPORTER_SECRET", ssl->s3->exporter_secret,
                         hs->hash_len);
 }
@@ -322,8 +320,8 @@
 
   const EVP_MD *digest = ssl_session_get_digest(SSL_get_session(ssl));
   if (!hkdf_expand_label(secret, ssl->version, digest, secret, secret_len,
-                         (const uint8_t *)traffic_label, strlen(traffic_label),
-                         NULL, 0, secret_len)) {
+                         traffic_label, strlen(traffic_label), NULL, 0,
+                         secret_len)) {
     return 0;
   }
 
@@ -342,9 +340,9 @@
                                      ? kTLS13Draft21LabelResumption
                                      : kTLS13LabelResumption;
   hs->new_session->master_key_length = hs->hash_len;
-  return derive_secret(
-      hs, hs->new_session->master_key, hs->new_session->master_key_length,
-      (const uint8_t *)resumption_label, strlen(resumption_label));
+  return derive_secret(hs, hs->new_session->master_key,
+                       hs->new_session->master_key_length, resumption_label,
+                       strlen(resumption_label));
 }
 
 static const char kTLS13LabelFinished[] = "finished";
@@ -358,8 +356,8 @@
   uint8_t key[EVP_MAX_MD_SIZE];
   unsigned len;
   if (!hkdf_expand_label(key, version, digest, secret, hash_len,
-                         (const uint8_t *)kTLS13LabelFinished,
-                         strlen(kTLS13LabelFinished), NULL, 0, hash_len) ||
+                         kTLS13LabelFinished, strlen(kTLS13LabelFinished), NULL,
+                         0, hash_len) ||
       HMAC(digest, key, hash_len, context, context_len, out, &len) == NULL) {
     return 0;
   }
@@ -397,30 +395,29 @@
   const EVP_MD *digest = ssl_session_get_digest(session);
   return hkdf_expand_label(session->master_key, session->ssl_version, digest,
                            session->master_key, session->master_key_length,
-                           (const uint8_t *)kTLS13LabelResumptionPSK,
+                           kTLS13LabelResumptionPSK,
                            strlen(kTLS13LabelResumptionPSK), nonce.data(),
                            nonce.size(), session->master_key_length);
 }
 
 static const char kTLS13LabelExportKeying[] = "exporter";
 
-int tls13_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len,
-                                 const char *label, size_t label_len,
-                                 const uint8_t *context_in,
-                                 size_t context_in_len, int use_context) {
-  const uint8_t *context = NULL;
-  size_t context_len = 0;
-  if (use_context) {
-    context = context_in;
-    context_len = context_in_len;
+int tls13_export_keying_material(SSL *ssl, Span<uint8_t> out,
+                                 Span<const uint8_t> secret,
+                                 Span<const char> label,
+                                 Span<const uint8_t> context) {
+  if (secret.empty()) {
+    assert(0);
+    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+    return 0;
   }
 
-  if (!ssl_is_draft21(ssl->version)) {
+  uint16_t version = SSL_get_session(ssl)->ssl_version;
+  if (!ssl_is_draft21(version)) {
     const EVP_MD *digest = ssl_session_get_digest(SSL_get_session(ssl));
-    return hkdf_expand_label(
-        out, ssl->version, digest, ssl->s3->exporter_secret,
-        ssl->s3->exporter_secret_len, (const uint8_t *)label, label_len,
-        context, context_len, out_len);
+    return hkdf_expand_label(out.data(), version, digest, secret.data(),
+                             secret.size(), label.data(), label.size(),
+                             context.data(), context.size(), out.size());
   }
 
   const EVP_MD *digest = ssl_session_get_digest(SSL_get_session(ssl));
@@ -431,18 +428,18 @@
   unsigned hash_len;
   unsigned export_context_len;
   unsigned derived_secret_len = EVP_MD_size(digest);
-  if (!EVP_Digest(context, context_len, hash, &hash_len, digest, NULL) ||
-      !EVP_Digest(NULL, 0, export_context, &export_context_len, digest, NULL)) {
-    return 0;
-  }
-  return hkdf_expand_label(
-             derived_secret, ssl->version, digest, ssl->s3->exporter_secret,
-             ssl->s3->exporter_secret_len, (const uint8_t *)label, label_len,
-             export_context, export_context_len, derived_secret_len) &&
-         hkdf_expand_label(
-             out, ssl->version, digest, derived_secret, derived_secret_len,
-             (const uint8_t *)kTLS13LabelExportKeying,
-             strlen(kTLS13LabelExportKeying), hash, hash_len, out_len);
+  return EVP_Digest(context.data(), context.size(), hash, &hash_len, digest,
+                    nullptr) &&
+         EVP_Digest(nullptr, 0, export_context, &export_context_len, digest,
+                    nullptr) &&
+         hkdf_expand_label(derived_secret, version, digest, secret.data(),
+                           secret.size(), label.data(), label.size(),
+                           export_context, export_context_len,
+                           derived_secret_len) &&
+         hkdf_expand_label(out.data(), version, digest, derived_secret,
+                           derived_secret_len, kTLS13LabelExportKeying,
+                           strlen(kTLS13LabelExportKeying), hash, hash_len,
+                           out.size());
 }
 
 static const char kTLS13LabelPSKBinder[] = "resumption psk binder key";
@@ -471,8 +468,8 @@
   uint8_t binder_key[EVP_MAX_MD_SIZE] = {0};
   size_t len;
   if (!hkdf_expand_label(binder_key, version, digest, early_secret, hash_len,
-                         (const uint8_t *)binder_label, strlen(binder_label),
-                         binder_context, binder_context_len, hash_len) ||
+                         binder_label, strlen(binder_label), binder_context,
+                         binder_context_len, hash_len) ||
       !tls13_verify_data(digest, version, out, &len, binder_key, hash_len,
                          context, context_len)) {
     return 0;
diff --git a/src/third_party/fiat/p256.c b/src/third_party/fiat/p256.c
new file mode 100644
index 0000000..25ef383
--- /dev/null
+++ b/src/third_party/fiat/p256.c
@@ -0,0 +1,1725 @@
+// The MIT License (MIT)
+//
+// Copyright (c) 2015-2016 the fiat-crypto authors (see the AUTHORS file).
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+// The field arithmetic code is generated by Fiat
+// (https://github.com/mit-plv/fiat-crypto), which is MIT licensed.
+//
+// An implementation of the NIST P-256 elliptic curve point multiplication.
+// 256-bit Montgomery form, generated using fiat-crypto, for 64 and 32-bit.
+// Field operations with inputs in [0,p) return outputs in [0,p).
+
+#include <openssl/base.h>
+
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+
+#include <string.h>
+
+#include "../../crypto/fipsmodule/delocate.h"
+#include "../../crypto/fipsmodule/ec/internal.h"
+#include "../../crypto/internal.h"
+
+
+// MSVC does not implement uint128_t, and crashes with intrinsics
+#if defined(BORINGSSL_HAS_UINT128)
+#define BORINGSSL_NISTP256_64BIT 1
+#endif
+
+// "intrinsics"
+
+#if defined(BORINGSSL_NISTP256_64BIT)
+
+static uint64_t mulx_u64(uint64_t a, uint64_t b, uint64_t *high) {
+  uint128_t x = (uint128_t)a * b;
+  *high = (uint64_t) (x >> 64);
+  return (uint64_t) x;
+}
+
+static uint64_t addcarryx_u64(uint8_t c, uint64_t a, uint64_t b, uint64_t *low) {
+  uint128_t x = (uint128_t)a + b + c;
+  *low = (uint64_t) x;
+  return (uint64_t) (x>>64);
+}
+
+static uint64_t subborrow_u64(uint8_t c, uint64_t a, uint64_t b, uint64_t *low) {
+  uint128_t t = ((uint128_t) b + c);
+  uint128_t x = a-t;
+  *low = (uint64_t) x;
+  return (uint8_t) (x>>127);
+}
+
+static uint64_t cmovznz_u64(uint64_t t, uint64_t z, uint64_t nz) {
+  t = -!!t; // all set if nonzero, 0 if 0
+  return (t&nz) | ((~t)&z);
+}
+
+#else
+
+static uint32_t mulx_u32(uint32_t a, uint32_t b, uint32_t *high) {
+  uint64_t x = (uint64_t)a * b;
+  *high = (uint32_t) (x >> 32);
+  return (uint32_t) x;
+}
+
+static uint32_t addcarryx_u32(uint8_t c, uint32_t a, uint32_t b, uint32_t *low) {
+  uint64_t x = (uint64_t)a + b + c;
+  *low = (uint32_t) x;
+  return (uint32_t) (x>>32);
+}
+
+static uint32_t subborrow_u32(uint8_t c, uint32_t a, uint32_t b, uint32_t *low) {
+  uint64_t t = ((uint64_t) b + c);
+  uint64_t x = a-t;
+  *low = (uint32_t) x;
+  return (uint8_t) (x>>63);
+}
+
+static uint32_t cmovznz_u32(uint32_t t, uint32_t z, uint32_t nz) {
+  t = -!!t; // all set if nonzero, 0 if 0
+  return (t&nz) | ((~t)&z);
+}
+
+#endif
+
+// fiat-crypto generated code
+
+#if defined(BORINGSSL_NISTP256_64BIT)
+
+static void fe_add(uint64_t out[4], const uint64_t in1[4], const uint64_t in2[4]) {
+  { const uint64_t x8 = in1[3];
+  { const uint64_t x9 = in1[2];
+  { const uint64_t x7 = in1[1];
+  { const uint64_t x5 = in1[0];
+  { const uint64_t x14 = in2[3];
+  { const uint64_t x15 = in2[2];
+  { const uint64_t x13 = in2[1];
+  { const uint64_t x11 = in2[0];
+  { uint64_t x17; uint8_t x18 = addcarryx_u64(0x0, x5, x11, &x17);
+  { uint64_t x20; uint8_t x21 = addcarryx_u64(x18, x7, x13, &x20);
+  { uint64_t x23; uint8_t x24 = addcarryx_u64(x21, x9, x15, &x23);
+  { uint64_t x26; uint8_t x27 = addcarryx_u64(x24, x8, x14, &x26);
+  { uint64_t x29; uint8_t x30 = subborrow_u64(0x0, x17, 0xffffffffffffffffL, &x29);
+  { uint64_t x32; uint8_t x33 = subborrow_u64(x30, x20, 0xffffffff, &x32);
+  { uint64_t x35; uint8_t x36 = subborrow_u64(x33, x23, 0x0, &x35);
+  { uint64_t x38; uint8_t x39 = subborrow_u64(x36, x26, 0xffffffff00000001L, &x38);
+  { uint64_t _1; uint8_t x42 = subborrow_u64(x39, x27, 0x0, &_1);
+  { uint64_t x43 = cmovznz_u64(x42, x38, x26);
+  { uint64_t x44 = cmovznz_u64(x42, x35, x23);
+  { uint64_t x45 = cmovznz_u64(x42, x32, x20);
+  { uint64_t x46 = cmovznz_u64(x42, x29, x17);
+  out[0] = x46;
+  out[1] = x45;
+  out[2] = x44;
+  out[3] = x43;
+  }}}}}}}}}}}}}}}}}}}}}
+}
+
+// fe_op sets out = -in
+static void fe_opp(uint64_t out[4], const uint64_t in1[4]) {
+  const uint64_t x5 = in1[3];
+  const uint64_t x6 = in1[2];
+  const uint64_t x4 = in1[1];
+  const uint64_t x2 = in1[0];
+  uint64_t x8; uint8_t x9 = subborrow_u64(0x0, 0x0, x2, &x8);
+  uint64_t x11; uint8_t x12 = subborrow_u64(x9, 0x0, x4, &x11);
+  uint64_t x14; uint8_t x15 = subborrow_u64(x12, 0x0, x6, &x14);
+  uint64_t x17; uint8_t x18 = subborrow_u64(x15, 0x0, x5, &x17);
+  uint64_t x19 = (uint64_t)cmovznz_u64(x18, 0x0, 0xffffffffffffffffL);
+  uint64_t x20 = (x19 & 0xffffffffffffffffL);
+  uint64_t x22; uint8_t x23 = addcarryx_u64(0x0, x8, x20, &x22);
+  uint64_t x24 = (x19 & 0xffffffff);
+  uint64_t x26; uint8_t x27 = addcarryx_u64(x23, x11, x24, &x26);
+  uint64_t x29; uint8_t x30 = addcarryx_u64(x27, x14, 0x0, &x29);
+  uint64_t x31 = (x19 & 0xffffffff00000001L);
+  uint64_t x33; addcarryx_u64(x30, x17, x31, &x33);
+  out[0] = x22;
+  out[1] = x26;
+  out[2] = x29;
+  out[3] = x33;
+}
+
+static void fe_mul(uint64_t out[4], const uint64_t in1[4], const uint64_t in2[4]) {
+  const uint64_t x8 = in1[3];
+  const uint64_t x9 = in1[2];
+  const uint64_t x7 = in1[1];
+  const uint64_t x5 = in1[0];
+  const uint64_t x14 = in2[3];
+  const uint64_t x15 = in2[2];
+  const uint64_t x13 = in2[1];
+  const uint64_t x11 = in2[0];
+  uint64_t x18;  uint64_t x17 = mulx_u64(x5, x11, &x18);
+  uint64_t x21;  uint64_t x20 = mulx_u64(x5, x13, &x21);
+  uint64_t x24;  uint64_t x23 = mulx_u64(x5, x15, &x24);
+  uint64_t x27;  uint64_t x26 = mulx_u64(x5, x14, &x27);
+  uint64_t x29; uint8_t x30 = addcarryx_u64(0x0, x18, x20, &x29);
+  uint64_t x32; uint8_t x33 = addcarryx_u64(x30, x21, x23, &x32);
+  uint64_t x35; uint8_t x36 = addcarryx_u64(x33, x24, x26, &x35);
+  uint64_t x38; addcarryx_u64(0x0, x36, x27, &x38);
+  uint64_t x42;  uint64_t x41 = mulx_u64(x17, 0xffffffffffffffffL, &x42);
+  uint64_t x45;  uint64_t x44 = mulx_u64(x17, 0xffffffff, &x45);
+  uint64_t x48;  uint64_t x47 = mulx_u64(x17, 0xffffffff00000001L, &x48);
+  uint64_t x50; uint8_t x51 = addcarryx_u64(0x0, x42, x44, &x50);
+  uint64_t x53; uint8_t x54 = addcarryx_u64(x51, x45, 0x0, &x53);
+  uint64_t x56; uint8_t x57 = addcarryx_u64(x54, 0x0, x47, &x56);
+  uint64_t x59; addcarryx_u64(0x0, x57, x48, &x59);
+  uint64_t _2; uint8_t x63 = addcarryx_u64(0x0, x17, x41, &_2);
+  uint64_t x65; uint8_t x66 = addcarryx_u64(x63, x29, x50, &x65);
+  uint64_t x68; uint8_t x69 = addcarryx_u64(x66, x32, x53, &x68);
+  uint64_t x71; uint8_t x72 = addcarryx_u64(x69, x35, x56, &x71);
+  uint64_t x74; uint8_t x75 = addcarryx_u64(x72, x38, x59, &x74);
+  uint64_t x78;  uint64_t x77 = mulx_u64(x7, x11, &x78);
+  uint64_t x81;  uint64_t x80 = mulx_u64(x7, x13, &x81);
+  uint64_t x84;  uint64_t x83 = mulx_u64(x7, x15, &x84);
+  uint64_t x87;  uint64_t x86 = mulx_u64(x7, x14, &x87);
+  uint64_t x89; uint8_t x90 = addcarryx_u64(0x0, x78, x80, &x89);
+  uint64_t x92; uint8_t x93 = addcarryx_u64(x90, x81, x83, &x92);
+  uint64_t x95; uint8_t x96 = addcarryx_u64(x93, x84, x86, &x95);
+  uint64_t x98; addcarryx_u64(0x0, x96, x87, &x98);
+  uint64_t x101; uint8_t x102 = addcarryx_u64(0x0, x65, x77, &x101);
+  uint64_t x104; uint8_t x105 = addcarryx_u64(x102, x68, x89, &x104);
+  uint64_t x107; uint8_t x108 = addcarryx_u64(x105, x71, x92, &x107);
+  uint64_t x110; uint8_t x111 = addcarryx_u64(x108, x74, x95, &x110);
+  uint64_t x113; uint8_t x114 = addcarryx_u64(x111, x75, x98, &x113);
+  uint64_t x117;  uint64_t x116 = mulx_u64(x101, 0xffffffffffffffffL, &x117);
+  uint64_t x120;  uint64_t x119 = mulx_u64(x101, 0xffffffff, &x120);
+  uint64_t x123;  uint64_t x122 = mulx_u64(x101, 0xffffffff00000001L, &x123);
+  uint64_t x125; uint8_t x126 = addcarryx_u64(0x0, x117, x119, &x125);
+  uint64_t x128; uint8_t x129 = addcarryx_u64(x126, x120, 0x0, &x128);
+  uint64_t x131; uint8_t x132 = addcarryx_u64(x129, 0x0, x122, &x131);
+  uint64_t x134; addcarryx_u64(0x0, x132, x123, &x134);
+  uint64_t _3; uint8_t x138 = addcarryx_u64(0x0, x101, x116, &_3);
+  uint64_t x140; uint8_t x141 = addcarryx_u64(x138, x104, x125, &x140);
+  uint64_t x143; uint8_t x144 = addcarryx_u64(x141, x107, x128, &x143);
+  uint64_t x146; uint8_t x147 = addcarryx_u64(x144, x110, x131, &x146);
+  uint64_t x149; uint8_t x150 = addcarryx_u64(x147, x113, x134, &x149);
+  uint8_t x151 = (x150 + x114);
+  uint64_t x154;  uint64_t x153 = mulx_u64(x9, x11, &x154);
+  uint64_t x157;  uint64_t x156 = mulx_u64(x9, x13, &x157);
+  uint64_t x160;  uint64_t x159 = mulx_u64(x9, x15, &x160);
+  uint64_t x163;  uint64_t x162 = mulx_u64(x9, x14, &x163);
+  uint64_t x165; uint8_t x166 = addcarryx_u64(0x0, x154, x156, &x165);
+  uint64_t x168; uint8_t x169 = addcarryx_u64(x166, x157, x159, &x168);
+  uint64_t x171; uint8_t x172 = addcarryx_u64(x169, x160, x162, &x171);
+  uint64_t x174; addcarryx_u64(0x0, x172, x163, &x174);
+  uint64_t x177; uint8_t x178 = addcarryx_u64(0x0, x140, x153, &x177);
+  uint64_t x180; uint8_t x181 = addcarryx_u64(x178, x143, x165, &x180);
+  uint64_t x183; uint8_t x184 = addcarryx_u64(x181, x146, x168, &x183);
+  uint64_t x186; uint8_t x187 = addcarryx_u64(x184, x149, x171, &x186);
+  uint64_t x189; uint8_t x190 = addcarryx_u64(x187, x151, x174, &x189);
+  uint64_t x193;  uint64_t x192 = mulx_u64(x177, 0xffffffffffffffffL, &x193);
+  uint64_t x196;  uint64_t x195 = mulx_u64(x177, 0xffffffff, &x196);
+  uint64_t x199;  uint64_t x198 = mulx_u64(x177, 0xffffffff00000001L, &x199);
+  uint64_t x201; uint8_t x202 = addcarryx_u64(0x0, x193, x195, &x201);
+  uint64_t x204; uint8_t x205 = addcarryx_u64(x202, x196, 0x0, &x204);
+  uint64_t x207; uint8_t x208 = addcarryx_u64(x205, 0x0, x198, &x207);
+  uint64_t x210; addcarryx_u64(0x0, x208, x199, &x210);
+  uint64_t _4; uint8_t x214 = addcarryx_u64(0x0, x177, x192, &_4);
+  uint64_t x216; uint8_t x217 = addcarryx_u64(x214, x180, x201, &x216);
+  uint64_t x219; uint8_t x220 = addcarryx_u64(x217, x183, x204, &x219);
+  uint64_t x222; uint8_t x223 = addcarryx_u64(x220, x186, x207, &x222);
+  uint64_t x225; uint8_t x226 = addcarryx_u64(x223, x189, x210, &x225);
+  uint8_t x227 = (x226 + x190);
+  uint64_t x230;  uint64_t x229 = mulx_u64(x8, x11, &x230);
+  uint64_t x233;  uint64_t x232 = mulx_u64(x8, x13, &x233);
+  uint64_t x236;  uint64_t x235 = mulx_u64(x8, x15, &x236);
+  uint64_t x239;  uint64_t x238 = mulx_u64(x8, x14, &x239);
+  uint64_t x241; uint8_t x242 = addcarryx_u64(0x0, x230, x232, &x241);
+  uint64_t x244; uint8_t x245 = addcarryx_u64(x242, x233, x235, &x244);
+  uint64_t x247; uint8_t x248 = addcarryx_u64(x245, x236, x238, &x247);
+  uint64_t x250; addcarryx_u64(0x0, x248, x239, &x250);
+  uint64_t x253; uint8_t x254 = addcarryx_u64(0x0, x216, x229, &x253);
+  uint64_t x256; uint8_t x257 = addcarryx_u64(x254, x219, x241, &x256);
+  uint64_t x259; uint8_t x260 = addcarryx_u64(x257, x222, x244, &x259);
+  uint64_t x262; uint8_t x263 = addcarryx_u64(x260, x225, x247, &x262);
+  uint64_t x265; uint8_t x266 = addcarryx_u64(x263, x227, x250, &x265);
+  uint64_t x269;  uint64_t x268 = mulx_u64(x253, 0xffffffffffffffffL, &x269);
+  uint64_t x272;  uint64_t x271 = mulx_u64(x253, 0xffffffff, &x272);
+  uint64_t x275;  uint64_t x274 = mulx_u64(x253, 0xffffffff00000001L, &x275);
+  uint64_t x277; uint8_t x278 = addcarryx_u64(0x0, x269, x271, &x277);
+  uint64_t x280; uint8_t x281 = addcarryx_u64(x278, x272, 0x0, &x280);
+  uint64_t x283; uint8_t x284 = addcarryx_u64(x281, 0x0, x274, &x283);
+  uint64_t x286; addcarryx_u64(0x0, x284, x275, &x286);
+  uint64_t _5; uint8_t x290 = addcarryx_u64(0x0, x253, x268, &_5);
+  uint64_t x292; uint8_t x293 = addcarryx_u64(x290, x256, x277, &x292);
+  uint64_t x295; uint8_t x296 = addcarryx_u64(x293, x259, x280, &x295);
+  uint64_t x298; uint8_t x299 = addcarryx_u64(x296, x262, x283, &x298);
+  uint64_t x301; uint8_t x302 = addcarryx_u64(x299, x265, x286, &x301);
+  uint8_t x303 = (x302 + x266);
+  uint64_t x305; uint8_t x306 = subborrow_u64(0x0, x292, 0xffffffffffffffffL, &x305);
+  uint64_t x308; uint8_t x309 = subborrow_u64(x306, x295, 0xffffffff, &x308);
+  uint64_t x311; uint8_t x312 = subborrow_u64(x309, x298, 0x0, &x311);
+  uint64_t x314; uint8_t x315 = subborrow_u64(x312, x301, 0xffffffff00000001L, &x314);
+  uint64_t _6; uint8_t x318 = subborrow_u64(x315, x303, 0x0, &_6);
+  uint64_t x319 = cmovznz_u64(x318, x314, x301);
+  uint64_t x320 = cmovznz_u64(x318, x311, x298);
+  uint64_t x321 = cmovznz_u64(x318, x308, x295);
+  uint64_t x322 = cmovznz_u64(x318, x305, x292);
+  out[0] = x322;
+  out[1] = x321;
+  out[2] = x320;
+  out[3] = x319;
+}
+
+static void fe_sub(uint64_t out[4], const uint64_t in1[4], const uint64_t in2[4]) {
+  const uint64_t x8 = in1[3];
+  const uint64_t x9 = in1[2];
+  const uint64_t x7 = in1[1];
+  const uint64_t x5 = in1[0];
+  const uint64_t x14 = in2[3];
+  const uint64_t x15 = in2[2];
+  const uint64_t x13 = in2[1];
+  const uint64_t x11 = in2[0];
+  uint64_t x17; uint8_t x18 = subborrow_u64(0x0, x5, x11, &x17);
+  uint64_t x20; uint8_t x21 = subborrow_u64(x18, x7, x13, &x20);
+  uint64_t x23; uint8_t x24 = subborrow_u64(x21, x9, x15, &x23);
+  uint64_t x26; uint8_t x27 = subborrow_u64(x24, x8, x14, &x26);
+  uint64_t x28 = (uint64_t)cmovznz_u64(x27, 0x0, 0xffffffffffffffffL);
+  uint64_t x29 = (x28 & 0xffffffffffffffffL);
+  uint64_t x31; uint8_t x32 = addcarryx_u64(0x0, x17, x29, &x31);
+  uint64_t x33 = (x28 & 0xffffffff);
+  uint64_t x35; uint8_t x36 = addcarryx_u64(x32, x20, x33, &x35);
+  uint64_t x38; uint8_t x39 = addcarryx_u64(x36, x23, 0x0, &x38);
+  uint64_t x40 = (x28 & 0xffffffff00000001L);
+  uint64_t x42; addcarryx_u64(x39, x26, x40, &x42);
+  out[0] = x31;
+  out[1] = x35;
+  out[2] = x38;
+  out[3] = x42;
+}
+
+#else // 64BIT, else 32BIT
+
+static void fe_add(uint32_t out[8], const uint32_t in1[8], const uint32_t in2[8]) {
+  const uint32_t x16 = in1[7];
+  const uint32_t x17 = in1[6];
+  const uint32_t x15 = in1[5];
+  const uint32_t x13 = in1[4];
+  const uint32_t x11 = in1[3];
+  const uint32_t x9 = in1[2];
+  const uint32_t x7 = in1[1];
+  const uint32_t x5 = in1[0];
+  const uint32_t x30 = in2[7];
+  const uint32_t x31 = in2[6];
+  const uint32_t x29 = in2[5];
+  const uint32_t x27 = in2[4];
+  const uint32_t x25 = in2[3];
+  const uint32_t x23 = in2[2];
+  const uint32_t x21 = in2[1];
+  const uint32_t x19 = in2[0];
+  uint32_t x33; uint8_t x34 = addcarryx_u32(0x0, x5, x19, &x33);
+  uint32_t x36; uint8_t x37 = addcarryx_u32(x34, x7, x21, &x36);
+  uint32_t x39; uint8_t x40 = addcarryx_u32(x37, x9, x23, &x39);
+  uint32_t x42; uint8_t x43 = addcarryx_u32(x40, x11, x25, &x42);
+  uint32_t x45; uint8_t x46 = addcarryx_u32(x43, x13, x27, &x45);
+  uint32_t x48; uint8_t x49 = addcarryx_u32(x46, x15, x29, &x48);
+  uint32_t x51; uint8_t x52 = addcarryx_u32(x49, x17, x31, &x51);
+  uint32_t x54; uint8_t x55 = addcarryx_u32(x52, x16, x30, &x54);
+  uint32_t x57; uint8_t x58 = subborrow_u32(0x0, x33, 0xffffffff, &x57);
+  uint32_t x60; uint8_t x61 = subborrow_u32(x58, x36, 0xffffffff, &x60);
+  uint32_t x63; uint8_t x64 = subborrow_u32(x61, x39, 0xffffffff, &x63);
+  uint32_t x66; uint8_t x67 = subborrow_u32(x64, x42, 0x0, &x66);
+  uint32_t x69; uint8_t x70 = subborrow_u32(x67, x45, 0x0, &x69);
+  uint32_t x72; uint8_t x73 = subborrow_u32(x70, x48, 0x0, &x72);
+  uint32_t x75; uint8_t x76 = subborrow_u32(x73, x51, 0x1, &x75);
+  uint32_t x78; uint8_t x79 = subborrow_u32(x76, x54, 0xffffffff, &x78);
+  uint32_t _; uint8_t x82 = subborrow_u32(x79, x55, 0x0, &_);
+  uint32_t x83 = cmovznz_u32(x82, x78, x54);
+  uint32_t x84 = cmovznz_u32(x82, x75, x51);
+  uint32_t x85 = cmovznz_u32(x82, x72, x48);
+  uint32_t x86 = cmovznz_u32(x82, x69, x45);
+  uint32_t x87 = cmovznz_u32(x82, x66, x42);
+  uint32_t x88 = cmovznz_u32(x82, x63, x39);
+  uint32_t x89 = cmovznz_u32(x82, x60, x36);
+  uint32_t x90 = cmovznz_u32(x82, x57, x33);
+  out[0] = x90;
+  out[1] = x89;
+  out[2] = x88;
+  out[3] = x87;
+  out[4] = x86;
+  out[5] = x85;
+  out[6] = x84;
+  out[7] = x83;
+}
+
+static void fe_mul(uint32_t out[8], const uint32_t in1[8], const uint32_t in2[8]) {
+  const uint32_t x16 = in1[7];
+  const uint32_t x17 = in1[6];
+  const uint32_t x15 = in1[5];
+  const uint32_t x13 = in1[4];
+  const uint32_t x11 = in1[3];
+  const uint32_t x9 = in1[2];
+  const uint32_t x7 = in1[1];
+  const uint32_t x5 = in1[0];
+  const uint32_t x30 = in2[7];
+  const uint32_t x31 = in2[6];
+  const uint32_t x29 = in2[5];
+  const uint32_t x27 = in2[4];
+  const uint32_t x25 = in2[3];
+  const uint32_t x23 = in2[2];
+  const uint32_t x21 = in2[1];
+  const uint32_t x19 = in2[0];
+  uint32_t x34;  uint32_t x33 = mulx_u32(x5, x19, &x34);
+  uint32_t x37;  uint32_t x36 = mulx_u32(x5, x21, &x37);
+  uint32_t x40;  uint32_t x39 = mulx_u32(x5, x23, &x40);
+  uint32_t x43;  uint32_t x42 = mulx_u32(x5, x25, &x43);
+  uint32_t x46;  uint32_t x45 = mulx_u32(x5, x27, &x46);
+  uint32_t x49;  uint32_t x48 = mulx_u32(x5, x29, &x49);
+  uint32_t x52;  uint32_t x51 = mulx_u32(x5, x31, &x52);
+  uint32_t x55;  uint32_t x54 = mulx_u32(x5, x30, &x55);
+  uint32_t x57; uint8_t x58 = addcarryx_u32(0x0, x34, x36, &x57);
+  uint32_t x60; uint8_t x61 = addcarryx_u32(x58, x37, x39, &x60);
+  uint32_t x63; uint8_t x64 = addcarryx_u32(x61, x40, x42, &x63);
+  uint32_t x66; uint8_t x67 = addcarryx_u32(x64, x43, x45, &x66);
+  uint32_t x69; uint8_t x70 = addcarryx_u32(x67, x46, x48, &x69);
+  uint32_t x72; uint8_t x73 = addcarryx_u32(x70, x49, x51, &x72);
+  uint32_t x75; uint8_t x76 = addcarryx_u32(x73, x52, x54, &x75);
+  uint32_t x78; addcarryx_u32(0x0, x76, x55, &x78);
+  uint32_t x82;  uint32_t x81 = mulx_u32(x33, 0xffffffff, &x82);
+  uint32_t x85;  uint32_t x84 = mulx_u32(x33, 0xffffffff, &x85);
+  uint32_t x88;  uint32_t x87 = mulx_u32(x33, 0xffffffff, &x88);
+  uint32_t x91;  uint32_t x90 = mulx_u32(x33, 0xffffffff, &x91);
+  uint32_t x93; uint8_t x94 = addcarryx_u32(0x0, x82, x84, &x93);
+  uint32_t x96; uint8_t x97 = addcarryx_u32(x94, x85, x87, &x96);
+  uint32_t x99; uint8_t x100 = addcarryx_u32(x97, x88, 0x0, &x99);
+  uint8_t x101 = (0x0 + 0x0);
+  uint32_t _1; uint8_t x104 = addcarryx_u32(0x0, x33, x81, &_1);
+  uint32_t x106; uint8_t x107 = addcarryx_u32(x104, x57, x93, &x106);
+  uint32_t x109; uint8_t x110 = addcarryx_u32(x107, x60, x96, &x109);
+  uint32_t x112; uint8_t x113 = addcarryx_u32(x110, x63, x99, &x112);
+  uint32_t x115; uint8_t x116 = addcarryx_u32(x113, x66, x100, &x115);
+  uint32_t x118; uint8_t x119 = addcarryx_u32(x116, x69, x101, &x118);
+  uint32_t x121; uint8_t x122 = addcarryx_u32(x119, x72, x33, &x121);
+  uint32_t x124; uint8_t x125 = addcarryx_u32(x122, x75, x90, &x124);
+  uint32_t x127; uint8_t x128 = addcarryx_u32(x125, x78, x91, &x127);
+  uint8_t x129 = (x128 + 0x0);
+  uint32_t x132;  uint32_t x131 = mulx_u32(x7, x19, &x132);
+  uint32_t x135;  uint32_t x134 = mulx_u32(x7, x21, &x135);
+  uint32_t x138;  uint32_t x137 = mulx_u32(x7, x23, &x138);
+  uint32_t x141;  uint32_t x140 = mulx_u32(x7, x25, &x141);
+  uint32_t x144;  uint32_t x143 = mulx_u32(x7, x27, &x144);
+  uint32_t x147;  uint32_t x146 = mulx_u32(x7, x29, &x147);
+  uint32_t x150;  uint32_t x149 = mulx_u32(x7, x31, &x150);
+  uint32_t x153;  uint32_t x152 = mulx_u32(x7, x30, &x153);
+  uint32_t x155; uint8_t x156 = addcarryx_u32(0x0, x132, x134, &x155);
+  uint32_t x158; uint8_t x159 = addcarryx_u32(x156, x135, x137, &x158);
+  uint32_t x161; uint8_t x162 = addcarryx_u32(x159, x138, x140, &x161);
+  uint32_t x164; uint8_t x165 = addcarryx_u32(x162, x141, x143, &x164);
+  uint32_t x167; uint8_t x168 = addcarryx_u32(x165, x144, x146, &x167);
+  uint32_t x170; uint8_t x171 = addcarryx_u32(x168, x147, x149, &x170);
+  uint32_t x173; uint8_t x174 = addcarryx_u32(x171, x150, x152, &x173);
+  uint32_t x176; addcarryx_u32(0x0, x174, x153, &x176);
+  uint32_t x179; uint8_t x180 = addcarryx_u32(0x0, x106, x131, &x179);
+  uint32_t x182; uint8_t x183 = addcarryx_u32(x180, x109, x155, &x182);
+  uint32_t x185; uint8_t x186 = addcarryx_u32(x183, x112, x158, &x185);
+  uint32_t x188; uint8_t x189 = addcarryx_u32(x186, x115, x161, &x188);
+  uint32_t x191; uint8_t x192 = addcarryx_u32(x189, x118, x164, &x191);
+  uint32_t x194; uint8_t x195 = addcarryx_u32(x192, x121, x167, &x194);
+  uint32_t x197; uint8_t x198 = addcarryx_u32(x195, x124, x170, &x197);
+  uint32_t x200; uint8_t x201 = addcarryx_u32(x198, x127, x173, &x200);
+  uint32_t x203; uint8_t x204 = addcarryx_u32(x201, x129, x176, &x203);
+  uint32_t x207;  uint32_t x206 = mulx_u32(x179, 0xffffffff, &x207);
+  uint32_t x210;  uint32_t x209 = mulx_u32(x179, 0xffffffff, &x210);
+  uint32_t x213;  uint32_t x212 = mulx_u32(x179, 0xffffffff, &x213);
+  uint32_t x216;  uint32_t x215 = mulx_u32(x179, 0xffffffff, &x216);
+  uint32_t x218; uint8_t x219 = addcarryx_u32(0x0, x207, x209, &x218);
+  uint32_t x221; uint8_t x222 = addcarryx_u32(x219, x210, x212, &x221);
+  uint32_t x224; uint8_t x225 = addcarryx_u32(x222, x213, 0x0, &x224);
+  uint8_t x226 = (0x0 + 0x0);
+  uint32_t _2; uint8_t x229 = addcarryx_u32(0x0, x179, x206, &_2);
+  uint32_t x231; uint8_t x232 = addcarryx_u32(x229, x182, x218, &x231);
+  uint32_t x234; uint8_t x235 = addcarryx_u32(x232, x185, x221, &x234);
+  uint32_t x237; uint8_t x238 = addcarryx_u32(x235, x188, x224, &x237);
+  uint32_t x240; uint8_t x241 = addcarryx_u32(x238, x191, x225, &x240);
+  uint32_t x243; uint8_t x244 = addcarryx_u32(x241, x194, x226, &x243);
+  uint32_t x246; uint8_t x247 = addcarryx_u32(x244, x197, x179, &x246);
+  uint32_t x249; uint8_t x250 = addcarryx_u32(x247, x200, x215, &x249);
+  uint32_t x252; uint8_t x253 = addcarryx_u32(x250, x203, x216, &x252);
+  uint8_t x254 = (x253 + x204);
+  uint32_t x257;  uint32_t x256 = mulx_u32(x9, x19, &x257);
+  uint32_t x260;  uint32_t x259 = mulx_u32(x9, x21, &x260);
+  uint32_t x263;  uint32_t x262 = mulx_u32(x9, x23, &x263);
+  uint32_t x266;  uint32_t x265 = mulx_u32(x9, x25, &x266);
+  uint32_t x269;  uint32_t x268 = mulx_u32(x9, x27, &x269);
+  uint32_t x272;  uint32_t x271 = mulx_u32(x9, x29, &x272);
+  uint32_t x275;  uint32_t x274 = mulx_u32(x9, x31, &x275);
+  uint32_t x278;  uint32_t x277 = mulx_u32(x9, x30, &x278);
+  uint32_t x280; uint8_t x281 = addcarryx_u32(0x0, x257, x259, &x280);
+  uint32_t x283; uint8_t x284 = addcarryx_u32(x281, x260, x262, &x283);
+  uint32_t x286; uint8_t x287 = addcarryx_u32(x284, x263, x265, &x286);
+  uint32_t x289; uint8_t x290 = addcarryx_u32(x287, x266, x268, &x289);
+  uint32_t x292; uint8_t x293 = addcarryx_u32(x290, x269, x271, &x292);
+  uint32_t x295; uint8_t x296 = addcarryx_u32(x293, x272, x274, &x295);
+  uint32_t x298; uint8_t x299 = addcarryx_u32(x296, x275, x277, &x298);
+  uint32_t x301; addcarryx_u32(0x0, x299, x278, &x301);
+  uint32_t x304; uint8_t x305 = addcarryx_u32(0x0, x231, x256, &x304);
+  uint32_t x307; uint8_t x308 = addcarryx_u32(x305, x234, x280, &x307);
+  uint32_t x310; uint8_t x311 = addcarryx_u32(x308, x237, x283, &x310);
+  uint32_t x313; uint8_t x314 = addcarryx_u32(x311, x240, x286, &x313);
+  uint32_t x316; uint8_t x317 = addcarryx_u32(x314, x243, x289, &x316);
+  uint32_t x319; uint8_t x320 = addcarryx_u32(x317, x246, x292, &x319);
+  uint32_t x322; uint8_t x323 = addcarryx_u32(x320, x249, x295, &x322);
+  uint32_t x325; uint8_t x326 = addcarryx_u32(x323, x252, x298, &x325);
+  uint32_t x328; uint8_t x329 = addcarryx_u32(x326, x254, x301, &x328);
+  uint32_t x332;  uint32_t x331 = mulx_u32(x304, 0xffffffff, &x332);
+  uint32_t x335;  uint32_t x334 = mulx_u32(x304, 0xffffffff, &x335);
+  uint32_t x338;  uint32_t x337 = mulx_u32(x304, 0xffffffff, &x338);
+  uint32_t x341;  uint32_t x340 = mulx_u32(x304, 0xffffffff, &x341);
+  uint32_t x343; uint8_t x344 = addcarryx_u32(0x0, x332, x334, &x343);
+  uint32_t x346; uint8_t x347 = addcarryx_u32(x344, x335, x337, &x346);
+  uint32_t x349; uint8_t x350 = addcarryx_u32(x347, x338, 0x0, &x349);
+  uint8_t x351 = (0x0 + 0x0);
+  uint32_t _3; uint8_t x354 = addcarryx_u32(0x0, x304, x331, &_3);
+  uint32_t x356; uint8_t x357 = addcarryx_u32(x354, x307, x343, &x356);
+  uint32_t x359; uint8_t x360 = addcarryx_u32(x357, x310, x346, &x359);
+  uint32_t x362; uint8_t x363 = addcarryx_u32(x360, x313, x349, &x362);
+  uint32_t x365; uint8_t x366 = addcarryx_u32(x363, x316, x350, &x365);
+  uint32_t x368; uint8_t x369 = addcarryx_u32(x366, x319, x351, &x368);
+  uint32_t x371; uint8_t x372 = addcarryx_u32(x369, x322, x304, &x371);
+  uint32_t x374; uint8_t x375 = addcarryx_u32(x372, x325, x340, &x374);
+  uint32_t x377; uint8_t x378 = addcarryx_u32(x375, x328, x341, &x377);
+  uint8_t x379 = (x378 + x329);
+  uint32_t x382;  uint32_t x381 = mulx_u32(x11, x19, &x382);
+  uint32_t x385;  uint32_t x384 = mulx_u32(x11, x21, &x385);
+  uint32_t x388;  uint32_t x387 = mulx_u32(x11, x23, &x388);
+  uint32_t x391;  uint32_t x390 = mulx_u32(x11, x25, &x391);
+  uint32_t x394;  uint32_t x393 = mulx_u32(x11, x27, &x394);
+  uint32_t x397;  uint32_t x396 = mulx_u32(x11, x29, &x397);
+  uint32_t x400;  uint32_t x399 = mulx_u32(x11, x31, &x400);
+  uint32_t x403;  uint32_t x402 = mulx_u32(x11, x30, &x403);
+  uint32_t x405; uint8_t x406 = addcarryx_u32(0x0, x382, x384, &x405);
+  uint32_t x408; uint8_t x409 = addcarryx_u32(x406, x385, x387, &x408);
+  uint32_t x411; uint8_t x412 = addcarryx_u32(x409, x388, x390, &x411);
+  uint32_t x414; uint8_t x415 = addcarryx_u32(x412, x391, x393, &x414);
+  uint32_t x417; uint8_t x418 = addcarryx_u32(x415, x394, x396, &x417);
+  uint32_t x420; uint8_t x421 = addcarryx_u32(x418, x397, x399, &x420);
+  uint32_t x423; uint8_t x424 = addcarryx_u32(x421, x400, x402, &x423);
+  uint32_t x426; addcarryx_u32(0x0, x424, x403, &x426);
+  uint32_t x429; uint8_t x430 = addcarryx_u32(0x0, x356, x381, &x429);
+  uint32_t x432; uint8_t x433 = addcarryx_u32(x430, x359, x405, &x432);
+  uint32_t x435; uint8_t x436 = addcarryx_u32(x433, x362, x408, &x435);
+  uint32_t x438; uint8_t x439 = addcarryx_u32(x436, x365, x411, &x438);
+  uint32_t x441; uint8_t x442 = addcarryx_u32(x439, x368, x414, &x441);
+  uint32_t x444; uint8_t x445 = addcarryx_u32(x442, x371, x417, &x444);
+  uint32_t x447; uint8_t x448 = addcarryx_u32(x445, x374, x420, &x447);
+  uint32_t x450; uint8_t x451 = addcarryx_u32(x448, x377, x423, &x450);
+  uint32_t x453; uint8_t x454 = addcarryx_u32(x451, x379, x426, &x453);
+  uint32_t x457;  uint32_t x456 = mulx_u32(x429, 0xffffffff, &x457);
+  uint32_t x460;  uint32_t x459 = mulx_u32(x429, 0xffffffff, &x460);
+  uint32_t x463;  uint32_t x462 = mulx_u32(x429, 0xffffffff, &x463);
+  uint32_t x466;  uint32_t x465 = mulx_u32(x429, 0xffffffff, &x466);
+  uint32_t x468; uint8_t x469 = addcarryx_u32(0x0, x457, x459, &x468);
+  uint32_t x471; uint8_t x472 = addcarryx_u32(x469, x460, x462, &x471);
+  uint32_t x474; uint8_t x475 = addcarryx_u32(x472, x463, 0x0, &x474);
+  uint8_t x476 = (0x0 + 0x0);
+  uint32_t _4; uint8_t x479 = addcarryx_u32(0x0, x429, x456, &_4);
+  uint32_t x481; uint8_t x482 = addcarryx_u32(x479, x432, x468, &x481);
+  uint32_t x484; uint8_t x485 = addcarryx_u32(x482, x435, x471, &x484);
+  uint32_t x487; uint8_t x488 = addcarryx_u32(x485, x438, x474, &x487);
+  uint32_t x490; uint8_t x491 = addcarryx_u32(x488, x441, x475, &x490);
+  uint32_t x493; uint8_t x494 = addcarryx_u32(x491, x444, x476, &x493);
+  uint32_t x496; uint8_t x497 = addcarryx_u32(x494, x447, x429, &x496);
+  uint32_t x499; uint8_t x500 = addcarryx_u32(x497, x450, x465, &x499);
+  uint32_t x502; uint8_t x503 = addcarryx_u32(x500, x453, x466, &x502);
+  uint8_t x504 = (x503 + x454);
+  uint32_t x507;  uint32_t x506 = mulx_u32(x13, x19, &x507);
+  uint32_t x510;  uint32_t x509 = mulx_u32(x13, x21, &x510);
+  uint32_t x513;  uint32_t x512 = mulx_u32(x13, x23, &x513);
+  uint32_t x516;  uint32_t x515 = mulx_u32(x13, x25, &x516);
+  uint32_t x519;  uint32_t x518 = mulx_u32(x13, x27, &x519);
+  uint32_t x522;  uint32_t x521 = mulx_u32(x13, x29, &x522);
+  uint32_t x525;  uint32_t x524 = mulx_u32(x13, x31, &x525);
+  uint32_t x528;  uint32_t x527 = mulx_u32(x13, x30, &x528);
+  uint32_t x530; uint8_t x531 = addcarryx_u32(0x0, x507, x509, &x530);
+  uint32_t x533; uint8_t x534 = addcarryx_u32(x531, x510, x512, &x533);
+  uint32_t x536; uint8_t x537 = addcarryx_u32(x534, x513, x515, &x536);
+  uint32_t x539; uint8_t x540 = addcarryx_u32(x537, x516, x518, &x539);
+  uint32_t x542; uint8_t x543 = addcarryx_u32(x540, x519, x521, &x542);
+  uint32_t x545; uint8_t x546 = addcarryx_u32(x543, x522, x524, &x545);
+  uint32_t x548; uint8_t x549 = addcarryx_u32(x546, x525, x527, &x548);
+  uint32_t x551; addcarryx_u32(0x0, x549, x528, &x551);
+  uint32_t x554; uint8_t x555 = addcarryx_u32(0x0, x481, x506, &x554);
+  uint32_t x557; uint8_t x558 = addcarryx_u32(x555, x484, x530, &x557);
+  uint32_t x560; uint8_t x561 = addcarryx_u32(x558, x487, x533, &x560);
+  uint32_t x563; uint8_t x564 = addcarryx_u32(x561, x490, x536, &x563);
+  uint32_t x566; uint8_t x567 = addcarryx_u32(x564, x493, x539, &x566);
+  uint32_t x569; uint8_t x570 = addcarryx_u32(x567, x496, x542, &x569);
+  uint32_t x572; uint8_t x573 = addcarryx_u32(x570, x499, x545, &x572);
+  uint32_t x575; uint8_t x576 = addcarryx_u32(x573, x502, x548, &x575);
+  uint32_t x578; uint8_t x579 = addcarryx_u32(x576, x504, x551, &x578);
+  uint32_t x582;  uint32_t x581 = mulx_u32(x554, 0xffffffff, &x582);
+  uint32_t x585;  uint32_t x584 = mulx_u32(x554, 0xffffffff, &x585);
+  uint32_t x588;  uint32_t x587 = mulx_u32(x554, 0xffffffff, &x588);
+  uint32_t x591;  uint32_t x590 = mulx_u32(x554, 0xffffffff, &x591);
+  uint32_t x593; uint8_t x594 = addcarryx_u32(0x0, x582, x584, &x593);
+  uint32_t x596; uint8_t x597 = addcarryx_u32(x594, x585, x587, &x596);
+  uint32_t x599; uint8_t x600 = addcarryx_u32(x597, x588, 0x0, &x599);
+  uint8_t x601 = (0x0 + 0x0);
+  uint32_t _5; uint8_t x604 = addcarryx_u32(0x0, x554, x581, &_5);
+  uint32_t x606; uint8_t x607 = addcarryx_u32(x604, x557, x593, &x606);
+  uint32_t x609; uint8_t x610 = addcarryx_u32(x607, x560, x596, &x609);
+  uint32_t x612; uint8_t x613 = addcarryx_u32(x610, x563, x599, &x612);
+  uint32_t x615; uint8_t x616 = addcarryx_u32(x613, x566, x600, &x615);
+  uint32_t x618; uint8_t x619 = addcarryx_u32(x616, x569, x601, &x618);
+  uint32_t x621; uint8_t x622 = addcarryx_u32(x619, x572, x554, &x621);
+  uint32_t x624; uint8_t x625 = addcarryx_u32(x622, x575, x590, &x624);
+  uint32_t x627; uint8_t x628 = addcarryx_u32(x625, x578, x591, &x627);
+  uint8_t x629 = (x628 + x579);
+  uint32_t x632;  uint32_t x631 = mulx_u32(x15, x19, &x632);
+  uint32_t x635;  uint32_t x634 = mulx_u32(x15, x21, &x635);
+  uint32_t x638;  uint32_t x637 = mulx_u32(x15, x23, &x638);
+  uint32_t x641;  uint32_t x640 = mulx_u32(x15, x25, &x641);
+  uint32_t x644;  uint32_t x643 = mulx_u32(x15, x27, &x644);
+  uint32_t x647;  uint32_t x646 = mulx_u32(x15, x29, &x647);
+  uint32_t x650;  uint32_t x649 = mulx_u32(x15, x31, &x650);
+  uint32_t x653;  uint32_t x652 = mulx_u32(x15, x30, &x653);
+  uint32_t x655; uint8_t x656 = addcarryx_u32(0x0, x632, x634, &x655);
+  uint32_t x658; uint8_t x659 = addcarryx_u32(x656, x635, x637, &x658);
+  uint32_t x661; uint8_t x662 = addcarryx_u32(x659, x638, x640, &x661);
+  uint32_t x664; uint8_t x665 = addcarryx_u32(x662, x641, x643, &x664);
+  uint32_t x667; uint8_t x668 = addcarryx_u32(x665, x644, x646, &x667);
+  uint32_t x670; uint8_t x671 = addcarryx_u32(x668, x647, x649, &x670);
+  uint32_t x673; uint8_t x674 = addcarryx_u32(x671, x650, x652, &x673);
+  uint32_t x676; addcarryx_u32(0x0, x674, x653, &x676);
+  uint32_t x679; uint8_t x680 = addcarryx_u32(0x0, x606, x631, &x679);
+  uint32_t x682; uint8_t x683 = addcarryx_u32(x680, x609, x655, &x682);
+  uint32_t x685; uint8_t x686 = addcarryx_u32(x683, x612, x658, &x685);
+  uint32_t x688; uint8_t x689 = addcarryx_u32(x686, x615, x661, &x688);
+  uint32_t x691; uint8_t x692 = addcarryx_u32(x689, x618, x664, &x691);
+  uint32_t x694; uint8_t x695 = addcarryx_u32(x692, x621, x667, &x694);
+  uint32_t x697; uint8_t x698 = addcarryx_u32(x695, x624, x670, &x697);
+  uint32_t x700; uint8_t x701 = addcarryx_u32(x698, x627, x673, &x700);
+  uint32_t x703; uint8_t x704 = addcarryx_u32(x701, x629, x676, &x703);
+  uint32_t x707;  uint32_t x706 = mulx_u32(x679, 0xffffffff, &x707);
+  uint32_t x710;  uint32_t x709 = mulx_u32(x679, 0xffffffff, &x710);
+  uint32_t x713;  uint32_t x712 = mulx_u32(x679, 0xffffffff, &x713);
+  uint32_t x716;  uint32_t x715 = mulx_u32(x679, 0xffffffff, &x716);
+  uint32_t x718; uint8_t x719 = addcarryx_u32(0x0, x707, x709, &x718);
+  uint32_t x721; uint8_t x722 = addcarryx_u32(x719, x710, x712, &x721);
+  uint32_t x724; uint8_t x725 = addcarryx_u32(x722, x713, 0x0, &x724);
+  uint8_t x726 = (0x0 + 0x0);
+  uint32_t _6; uint8_t x729 = addcarryx_u32(0x0, x679, x706, &_6);
+  uint32_t x731; uint8_t x732 = addcarryx_u32(x729, x682, x718, &x731);
+  uint32_t x734; uint8_t x735 = addcarryx_u32(x732, x685, x721, &x734);
+  uint32_t x737; uint8_t x738 = addcarryx_u32(x735, x688, x724, &x737);
+  uint32_t x740; uint8_t x741 = addcarryx_u32(x738, x691, x725, &x740);
+  uint32_t x743; uint8_t x744 = addcarryx_u32(x741, x694, x726, &x743);
+  uint32_t x746; uint8_t x747 = addcarryx_u32(x744, x697, x679, &x746);
+  uint32_t x749; uint8_t x750 = addcarryx_u32(x747, x700, x715, &x749);
+  uint32_t x752; uint8_t x753 = addcarryx_u32(x750, x703, x716, &x752);
+  uint8_t x754 = (x753 + x704);
+  uint32_t x757;  uint32_t x756 = mulx_u32(x17, x19, &x757);
+  uint32_t x760;  uint32_t x759 = mulx_u32(x17, x21, &x760);
+  uint32_t x763;  uint32_t x762 = mulx_u32(x17, x23, &x763);
+  uint32_t x766;  uint32_t x765 = mulx_u32(x17, x25, &x766);
+  uint32_t x769;  uint32_t x768 = mulx_u32(x17, x27, &x769);
+  uint32_t x772;  uint32_t x771 = mulx_u32(x17, x29, &x772);
+  uint32_t x775;  uint32_t x774 = mulx_u32(x17, x31, &x775);
+  uint32_t x778;  uint32_t x777 = mulx_u32(x17, x30, &x778);
+  uint32_t x780; uint8_t x781 = addcarryx_u32(0x0, x757, x759, &x780);
+  uint32_t x783; uint8_t x784 = addcarryx_u32(x781, x760, x762, &x783);
+  uint32_t x786; uint8_t x787 = addcarryx_u32(x784, x763, x765, &x786);
+  uint32_t x789; uint8_t x790 = addcarryx_u32(x787, x766, x768, &x789);
+  uint32_t x792; uint8_t x793 = addcarryx_u32(x790, x769, x771, &x792);
+  uint32_t x795; uint8_t x796 = addcarryx_u32(x793, x772, x774, &x795);
+  uint32_t x798; uint8_t x799 = addcarryx_u32(x796, x775, x777, &x798);
+  uint32_t x801; addcarryx_u32(0x0, x799, x778, &x801);
+  uint32_t x804; uint8_t x805 = addcarryx_u32(0x0, x731, x756, &x804);
+  uint32_t x807; uint8_t x808 = addcarryx_u32(x805, x734, x780, &x807);
+  uint32_t x810; uint8_t x811 = addcarryx_u32(x808, x737, x783, &x810);
+  uint32_t x813; uint8_t x814 = addcarryx_u32(x811, x740, x786, &x813);
+  uint32_t x816; uint8_t x817 = addcarryx_u32(x814, x743, x789, &x816);
+  uint32_t x819; uint8_t x820 = addcarryx_u32(x817, x746, x792, &x819);
+  uint32_t x822; uint8_t x823 = addcarryx_u32(x820, x749, x795, &x822);
+  uint32_t x825; uint8_t x826 = addcarryx_u32(x823, x752, x798, &x825);
+  uint32_t x828; uint8_t x829 = addcarryx_u32(x826, x754, x801, &x828);
+  uint32_t x832;  uint32_t x831 = mulx_u32(x804, 0xffffffff, &x832);
+  uint32_t x835;  uint32_t x834 = mulx_u32(x804, 0xffffffff, &x835);
+  uint32_t x838;  uint32_t x837 = mulx_u32(x804, 0xffffffff, &x838);
+  uint32_t x841;  uint32_t x840 = mulx_u32(x804, 0xffffffff, &x841);
+  uint32_t x843; uint8_t x844 = addcarryx_u32(0x0, x832, x834, &x843);
+  uint32_t x846; uint8_t x847 = addcarryx_u32(x844, x835, x837, &x846);
+  uint32_t x849; uint8_t x850 = addcarryx_u32(x847, x838, 0x0, &x849);
+  uint8_t x851 = (0x0 + 0x0);
+  uint32_t _7; uint8_t x854 = addcarryx_u32(0x0, x804, x831, &_7);
+  uint32_t x856; uint8_t x857 = addcarryx_u32(x854, x807, x843, &x856);
+  uint32_t x859; uint8_t x860 = addcarryx_u32(x857, x810, x846, &x859);
+  uint32_t x862; uint8_t x863 = addcarryx_u32(x860, x813, x849, &x862);
+  uint32_t x865; uint8_t x866 = addcarryx_u32(x863, x816, x850, &x865);
+  uint32_t x868; uint8_t x869 = addcarryx_u32(x866, x819, x851, &x868);
+  uint32_t x871; uint8_t x872 = addcarryx_u32(x869, x822, x804, &x871);
+  uint32_t x874; uint8_t x875 = addcarryx_u32(x872, x825, x840, &x874);
+  uint32_t x877; uint8_t x878 = addcarryx_u32(x875, x828, x841, &x877);
+  uint8_t x879 = (x878 + x829);
+  uint32_t x882;  uint32_t x881 = mulx_u32(x16, x19, &x882);
+  uint32_t x885;  uint32_t x884 = mulx_u32(x16, x21, &x885);
+  uint32_t x888;  uint32_t x887 = mulx_u32(x16, x23, &x888);
+  uint32_t x891;  uint32_t x890 = mulx_u32(x16, x25, &x891);
+  uint32_t x894;  uint32_t x893 = mulx_u32(x16, x27, &x894);
+  uint32_t x897;  uint32_t x896 = mulx_u32(x16, x29, &x897);
+  uint32_t x900;  uint32_t x899 = mulx_u32(x16, x31, &x900);
+  uint32_t x903;  uint32_t x902 = mulx_u32(x16, x30, &x903);
+  uint32_t x905; uint8_t x906 = addcarryx_u32(0x0, x882, x884, &x905);
+  uint32_t x908; uint8_t x909 = addcarryx_u32(x906, x885, x887, &x908);
+  uint32_t x911; uint8_t x912 = addcarryx_u32(x909, x888, x890, &x911);
+  uint32_t x914; uint8_t x915 = addcarryx_u32(x912, x891, x893, &x914);
+  uint32_t x917; uint8_t x918 = addcarryx_u32(x915, x894, x896, &x917);
+  uint32_t x920; uint8_t x921 = addcarryx_u32(x918, x897, x899, &x920);
+  uint32_t x923; uint8_t x924 = addcarryx_u32(x921, x900, x902, &x923);
+  uint32_t x926; addcarryx_u32(0x0, x924, x903, &x926);
+  uint32_t x929; uint8_t x930 = addcarryx_u32(0x0, x856, x881, &x929);
+  uint32_t x932; uint8_t x933 = addcarryx_u32(x930, x859, x905, &x932);
+  uint32_t x935; uint8_t x936 = addcarryx_u32(x933, x862, x908, &x935);
+  uint32_t x938; uint8_t x939 = addcarryx_u32(x936, x865, x911, &x938);
+  uint32_t x941; uint8_t x942 = addcarryx_u32(x939, x868, x914, &x941);
+  uint32_t x944; uint8_t x945 = addcarryx_u32(x942, x871, x917, &x944);
+  uint32_t x947; uint8_t x948 = addcarryx_u32(x945, x874, x920, &x947);
+  uint32_t x950; uint8_t x951 = addcarryx_u32(x948, x877, x923, &x950);
+  uint32_t x953; uint8_t x954 = addcarryx_u32(x951, x879, x926, &x953);
+  uint32_t x957;  uint32_t x956 = mulx_u32(x929, 0xffffffff, &x957);
+  uint32_t x960;  uint32_t x959 = mulx_u32(x929, 0xffffffff, &x960);
+  uint32_t x963;  uint32_t x962 = mulx_u32(x929, 0xffffffff, &x963);
+  uint32_t x966;  uint32_t x965 = mulx_u32(x929, 0xffffffff, &x966);
+  uint32_t x968; uint8_t x969 = addcarryx_u32(0x0, x957, x959, &x968);
+  uint32_t x971; uint8_t x972 = addcarryx_u32(x969, x960, x962, &x971);
+  uint32_t x974; uint8_t x975 = addcarryx_u32(x972, x963, 0x0, &x974);
+  uint8_t x976 = (0x0 + 0x0);
+  uint32_t _8; uint8_t x979 = addcarryx_u32(0x0, x929, x956, &_8);
+  uint32_t x981; uint8_t x982 = addcarryx_u32(x979, x932, x968, &x981);
+  uint32_t x984; uint8_t x985 = addcarryx_u32(x982, x935, x971, &x984);
+  uint32_t x987; uint8_t x988 = addcarryx_u32(x985, x938, x974, &x987);
+  uint32_t x990; uint8_t x991 = addcarryx_u32(x988, x941, x975, &x990);
+  uint32_t x993; uint8_t x994 = addcarryx_u32(x991, x944, x976, &x993);
+  uint32_t x996; uint8_t x997 = addcarryx_u32(x994, x947, x929, &x996);
+  uint32_t x999; uint8_t x1000 = addcarryx_u32(x997, x950, x965, &x999);
+  uint32_t x1002; uint8_t x1003 = addcarryx_u32(x1000, x953, x966, &x1002);
+  uint8_t x1004 = (x1003 + x954);
+  uint32_t x1006; uint8_t x1007 = subborrow_u32(0x0, x981, 0xffffffff, &x1006);
+  uint32_t x1009; uint8_t x1010 = subborrow_u32(x1007, x984, 0xffffffff, &x1009);
+  uint32_t x1012; uint8_t x1013 = subborrow_u32(x1010, x987, 0xffffffff, &x1012);
+  uint32_t x1015; uint8_t x1016 = subborrow_u32(x1013, x990, 0x0, &x1015);
+  uint32_t x1018; uint8_t x1019 = subborrow_u32(x1016, x993, 0x0, &x1018);
+  uint32_t x1021; uint8_t x1022 = subborrow_u32(x1019, x996, 0x0, &x1021);
+  uint32_t x1024; uint8_t x1025 = subborrow_u32(x1022, x999, 0x1, &x1024);
+  uint32_t x1027; uint8_t x1028 = subborrow_u32(x1025, x1002, 0xffffffff, &x1027);
+  uint32_t _9; uint8_t x1031 = subborrow_u32(x1028, x1004, 0x0, &_9);
+  uint32_t x1032 = cmovznz_u32(x1031, x1027, x1002);
+  uint32_t x1033 = cmovznz_u32(x1031, x1024, x999);
+  uint32_t x1034 = cmovznz_u32(x1031, x1021, x996);
+  uint32_t x1035 = cmovznz_u32(x1031, x1018, x993);
+  uint32_t x1036 = cmovznz_u32(x1031, x1015, x990);
+  uint32_t x1037 = cmovznz_u32(x1031, x1012, x987);
+  uint32_t x1038 = cmovznz_u32(x1031, x1009, x984);
+  uint32_t x1039 = cmovznz_u32(x1031, x1006, x981);
+  out[0] = x1039;
+  out[1] = x1038;
+  out[2] = x1037;
+  out[3] = x1036;
+  out[4] = x1035;
+  out[5] = x1034;
+  out[6] = x1033;
+  out[7] = x1032;
+}
+
+// NOTE: the following functions are generated from fiat-crypto, from the same
+// template as their 64-bit counterparts above, but the correctness proof of
+// the template was not composed with the correctness proof of the
+// specialization pipeline. This is because Coq unexplainedly loops on trying
+// to synthesize opp and sub using the normal pipeline.
+
+static void fe_sub(uint32_t out[8], const uint32_t in1[8], const uint32_t in2[8]) {
+  const uint32_t x14 = in1[7];
+  const uint32_t x15 = in1[6];
+  const uint32_t x13 = in1[5];
+  const uint32_t x11 = in1[4];
+  const uint32_t x9 = in1[3];
+  const uint32_t x7 = in1[2];
+  const uint32_t x5 = in1[1];
+  const uint32_t x3 = in1[0];
+  const uint32_t x28 = in2[7];
+  const uint32_t x29 = in2[6];
+  const uint32_t x27 = in2[5];
+  const uint32_t x25 = in2[4];
+  const uint32_t x23 = in2[3];
+  const uint32_t x21 = in2[2];
+  const uint32_t x19 = in2[1];
+  const uint32_t x17 = in2[0];
+  uint32_t x31; uint8_t x32 = subborrow_u32(0x0, x3, x17, &x31);
+  uint32_t x34; uint8_t x35 = subborrow_u32(x32, x5, x19, &x34);
+  uint32_t x37; uint8_t x38 = subborrow_u32(x35, x7, x21, &x37);
+  uint32_t x40; uint8_t x41 = subborrow_u32(x38, x9, x23, &x40);
+  uint32_t x43; uint8_t x44 = subborrow_u32(x41, x11, x25, &x43);
+  uint32_t x46; uint8_t x47 = subborrow_u32(x44, x13, x27, &x46);
+  uint32_t x49; uint8_t x50 = subborrow_u32(x47, x15, x29, &x49);
+  uint32_t x52; uint8_t x53 = subborrow_u32(x50, x14, x28, &x52);
+  uint32_t x54 = cmovznz_u32(x53, 0x0, 0xffffffff);
+  uint32_t x56; uint8_t x57 = addcarryx_u32(0x0, x31, (x54 & 0xffffffff), &x56);
+  uint32_t x59; uint8_t x60 = addcarryx_u32(x57, x34, (x54 & 0xffffffff), &x59);
+  uint32_t x62; uint8_t x63 = addcarryx_u32(x60, x37, (x54 & 0xffffffff), &x62);
+  uint32_t x65; uint8_t x66 = addcarryx_u32(x63, x40, 0x0, &x65);
+  uint32_t x68; uint8_t x69 = addcarryx_u32(x66, x43, 0x0, &x68);
+  uint32_t x71; uint8_t x72 = addcarryx_u32(x69, x46, 0x0, &x71);
+  uint32_t x74; uint8_t x75 = addcarryx_u32(x72, x49, ((uint8_t)x54 & 0x1), &x74);
+  uint32_t x77; addcarryx_u32(x75, x52, (x54 & 0xffffffff), &x77);
+  out[0] = x56;
+  out[1] = x59;
+  out[2] = x62;
+  out[3] = x65;
+  out[4] = x68;
+  out[5] = x71;
+  out[6] = x74;
+  out[7] = x77;
+}
+
+// fe_op sets out = -in
+static void fe_opp(uint32_t out[8], const uint32_t in1[8]) {
+  const uint32_t x12 = in1[7];
+  const uint32_t x13 = in1[6];
+  const uint32_t x11 = in1[5];
+  const uint32_t x9 = in1[4];
+  const uint32_t x7 = in1[3];
+  const uint32_t x5 = in1[2];
+  const uint32_t x3 = in1[1];
+  const uint32_t x1 = in1[0];
+  uint32_t x15; uint8_t x16 = subborrow_u32(0x0, 0x0, x1, &x15);
+  uint32_t x18; uint8_t x19 = subborrow_u32(x16, 0x0, x3, &x18);
+  uint32_t x21; uint8_t x22 = subborrow_u32(x19, 0x0, x5, &x21);
+  uint32_t x24; uint8_t x25 = subborrow_u32(x22, 0x0, x7, &x24);
+  uint32_t x27; uint8_t x28 = subborrow_u32(x25, 0x0, x9, &x27);
+  uint32_t x30; uint8_t x31 = subborrow_u32(x28, 0x0, x11, &x30);
+  uint32_t x33; uint8_t x34 = subborrow_u32(x31, 0x0, x13, &x33);
+  uint32_t x36; uint8_t x37 = subborrow_u32(x34, 0x0, x12, &x36);
+  uint32_t x38 = cmovznz_u32(x37, 0x0, 0xffffffff);
+  uint32_t x40; uint8_t x41 = addcarryx_u32(0x0, x15, (x38 & 0xffffffff), &x40);
+  uint32_t x43; uint8_t x44 = addcarryx_u32(x41, x18, (x38 & 0xffffffff), &x43);
+  uint32_t x46; uint8_t x47 = addcarryx_u32(x44, x21, (x38 & 0xffffffff), &x46);
+  uint32_t x49; uint8_t x50 = addcarryx_u32(x47, x24, 0x0, &x49);
+  uint32_t x52; uint8_t x53 = addcarryx_u32(x50, x27, 0x0, &x52);
+  uint32_t x55; uint8_t x56 = addcarryx_u32(x53, x30, 0x0, &x55);
+  uint32_t x58; uint8_t x59 = addcarryx_u32(x56, x33, ((uint8_t)x38 & 0x1), &x58);
+  uint32_t x61; addcarryx_u32(x59, x36, (x38 & 0xffffffff), &x61);
+  out[0] = x40;
+  out[1] = x43;
+  out[2] = x46;
+  out[3] = x49;
+  out[4] = x52;
+  out[5] = x55;
+  out[6] = x58;
+  out[7] = x61;
+}
+
+#endif
+
+// utility functions, handwritten
+
+#define NBYTES 32
+
+#if defined(BORINGSSL_NISTP256_64BIT)
+
+#define NLIMBS 4
+typedef uint64_t limb_t;
+#define cmovznz_limb cmovznz_u64
+typedef uint64_t fe[NLIMBS];
+#else // 64BIT; else 32BIT
+
+#define NLIMBS 8
+typedef uint32_t limb_t;
+#define cmovznz_limb cmovznz_u32
+typedef uint32_t fe[NLIMBS];
+
+#endif // 64BIT
+
+static limb_t fe_nz(const limb_t in1[NLIMBS]) {
+  limb_t ret = 0;
+  for (int i = 0; i < NLIMBS; i++) {
+    ret |= in1[i];
+  }
+  return ret;
+}
+
+static void fe_copy(limb_t out[NLIMBS], const limb_t in1[NLIMBS]) {
+  for (int i = 0; i < NLIMBS; i++) {
+    out[i] = in1[i];
+  }
+}
+
+static void fe_cmovznz(limb_t out[NLIMBS], limb_t t, const limb_t z[NLIMBS],
+                       const limb_t nz[NLIMBS]) {
+  for (int i = 0; i < NLIMBS; i++) {
+    out[i] = cmovznz_limb(t, z[i], nz[i]);
+  }
+}
+
+static void fe_sqr(fe out, const fe in) {
+  fe_mul(out, in, in);
+}
+
+static void fe_tobytes(uint8_t out[NBYTES], const fe in) {
+  for (int i = 0; i<NBYTES; i++) {
+    out[i] = (uint8_t)(in[i/sizeof(in[0])] >> (8*(i%sizeof(in[0]))));
+  }
+}
+
+static void fe_frombytes(fe out, const uint8_t in[NBYTES]) {
+  for (int i = 0; i<NLIMBS; i++) {
+    out[i] = 0;
+  }
+  for (int i = 0; i<NBYTES; i++) {
+    out[i/sizeof(out[0])] |= ((limb_t)in[i]) << (8*(i%sizeof(out[0])));
+  }
+}
+
+static void fe_from_montgomery(fe x) {
+  static const limb_t kOne[NLIMBS] = {1, 0};
+  fe_mul(x, x, kOne);
+}
+
+// BN_* compatability wrappers
+
+static int BN_to_fe(fe out, const BIGNUM *bn) {
+  uint8_t tmp[NBYTES];
+  if (!BN_bn2le_padded(tmp, NBYTES, bn)) {
+    return 0;
+  }
+  fe_frombytes(out, tmp);
+  return 1;
+}
+
+static BIGNUM *fe_to_BN(BIGNUM *out, const fe in) {
+  uint8_t tmp[NBYTES];
+  fe_tobytes(tmp, in);
+  return BN_le2bn(tmp, NBYTES, out);
+}
+
+// fe_inv calculates |out| = |in|^{-1}
+//
+// Based on Fermat's Little Theorem:
+//   a^p = a (mod p)
+//   a^{p-1} = 1 (mod p)
+//   a^{p-2} = a^{-1} (mod p)
+static void fe_inv(fe out, const fe in) {
+  fe ftmp, ftmp2;
+  // each e_I will hold |in|^{2^I - 1}
+  fe e2, e4, e8, e16, e32, e64;
+
+  fe_sqr(ftmp, in);  // 2^1
+  fe_mul(ftmp, in, ftmp);  // 2^2 - 2^0
+  fe_copy(e2, ftmp);
+  fe_sqr(ftmp, ftmp);  // 2^3 - 2^1
+  fe_sqr(ftmp, ftmp);  // 2^4 - 2^2
+  fe_mul(ftmp, ftmp, e2);  // 2^4 - 2^0
+  fe_copy(e4, ftmp);
+  fe_sqr(ftmp, ftmp);  // 2^5 - 2^1
+  fe_sqr(ftmp, ftmp);  // 2^6 - 2^2
+  fe_sqr(ftmp, ftmp);  // 2^7 - 2^3
+  fe_sqr(ftmp, ftmp);  // 2^8 - 2^4
+  fe_mul(ftmp, ftmp, e4);  // 2^8 - 2^0
+  fe_copy(e8, ftmp);
+  for (size_t i = 0; i < 8; i++) {
+    fe_sqr(ftmp, ftmp);
+  }  // 2^16 - 2^8
+  fe_mul(ftmp, ftmp, e8);  // 2^16 - 2^0
+  fe_copy(e16, ftmp);
+  for (size_t i = 0; i < 16; i++) {
+    fe_sqr(ftmp, ftmp);
+  }  // 2^32 - 2^16
+  fe_mul(ftmp, ftmp, e16);  // 2^32 - 2^0
+  fe_copy(e32, ftmp);
+  for (size_t i = 0; i < 32; i++) {
+    fe_sqr(ftmp, ftmp);
+  }  // 2^64 - 2^32
+  fe_copy(e64, ftmp);
+  fe_mul(ftmp, ftmp, in);  // 2^64 - 2^32 + 2^0
+  for (size_t i = 0; i < 192; i++) {
+    fe_sqr(ftmp, ftmp);
+  }  // 2^256 - 2^224 + 2^192
+
+  fe_mul(ftmp2, e64, e32);  // 2^64 - 2^0
+  for (size_t i = 0; i < 16; i++) {
+    fe_sqr(ftmp2, ftmp2);
+  }  // 2^80 - 2^16
+  fe_mul(ftmp2, ftmp2, e16);  // 2^80 - 2^0
+  for (size_t i = 0; i < 8; i++) {
+    fe_sqr(ftmp2, ftmp2);
+  }  // 2^88 - 2^8
+  fe_mul(ftmp2, ftmp2, e8);  // 2^88 - 2^0
+  for (size_t i = 0; i < 4; i++) {
+    fe_sqr(ftmp2, ftmp2);
+  }  // 2^92 - 2^4
+  fe_mul(ftmp2, ftmp2, e4);  // 2^92 - 2^0
+  fe_sqr(ftmp2, ftmp2);  // 2^93 - 2^1
+  fe_sqr(ftmp2, ftmp2);  // 2^94 - 2^2
+  fe_mul(ftmp2, ftmp2, e2);  // 2^94 - 2^0
+  fe_sqr(ftmp2, ftmp2);  // 2^95 - 2^1
+  fe_sqr(ftmp2, ftmp2);  // 2^96 - 2^2
+  fe_mul(ftmp2, ftmp2, in);  // 2^96 - 3
+
+  fe_mul(out, ftmp2, ftmp);  // 2^256 - 2^224 + 2^192 + 2^96 - 3
+}
+
+// Group operations
+// ----------------
+//
+// Building on top of the field operations we have the operations on the
+// elliptic curve group itself. Points on the curve are represented in Jacobian
+// coordinates.
+
+// point_double calculates 2*(x_in, y_in, z_in)
+//
+// The method is taken from:
+//   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
+//
+// Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
+// while x_out == y_in is not (maybe this works, but it's not tested).
+static void point_double(fe x_out, fe y_out, fe z_out,
+                         const fe x_in, const fe y_in, const fe z_in) {
+  fe delta, gamma, beta, ftmp, ftmp2, tmptmp, alpha, fourbeta;
+  // delta = z^2
+  fe_sqr(delta, z_in);
+  // gamma = y^2
+  fe_sqr(gamma, y_in);
+  // beta = x*gamma
+  fe_mul(beta, x_in, gamma);
+
+  // alpha = 3*(x-delta)*(x+delta)
+  fe_sub(ftmp, x_in, delta);
+  fe_add(ftmp2, x_in, delta);
+
+  fe_add(tmptmp, ftmp2, ftmp2);
+  fe_add(ftmp2, ftmp2, tmptmp);
+  fe_mul(alpha, ftmp, ftmp2);
+
+  // x' = alpha^2 - 8*beta
+  fe_sqr(x_out, alpha);
+  fe_add(fourbeta, beta, beta);
+  fe_add(fourbeta, fourbeta, fourbeta);
+  fe_add(tmptmp, fourbeta, fourbeta);
+  fe_sub(x_out, x_out, tmptmp);
+
+  // z' = (y + z)^2 - gamma - delta
+  fe_add(delta, gamma, delta);
+  fe_add(ftmp, y_in, z_in);
+  fe_sqr(z_out, ftmp);
+  fe_sub(z_out, z_out, delta);
+
+  // y' = alpha*(4*beta - x') - 8*gamma^2
+  fe_sub(y_out, fourbeta, x_out);
+  fe_add(gamma, gamma, gamma);
+  fe_sqr(gamma, gamma);
+  fe_mul(y_out, alpha, y_out);
+  fe_add(gamma, gamma, gamma);
+  fe_sub(y_out, y_out, gamma);
+}
+
+// point_add calcuates (x1, y1, z1) + (x2, y2, z2)
+//
+// The method is taken from:
+//   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
+// adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
+//
+// This function includes a branch for checking whether the two input points
+// are equal, (while not equal to the point at infinity). This case never
+// happens during single point multiplication, so there is no timing leak for
+// ECDH or ECDSA signing.
+static void point_add(fe x3, fe y3, fe z3, const fe x1,
+                      const fe y1, const fe z1, const int mixed,
+                      const fe x2, const fe y2, const fe z2) {
+  fe x_out, y_out, z_out;
+  limb_t z1nz = fe_nz(z1);
+  limb_t z2nz = fe_nz(z2);
+
+  // z1z1 = z1z1 = z1**2
+  fe z1z1; fe_sqr(z1z1, z1);
+
+  fe u1, s1, two_z1z2;
+  if (!mixed) {
+    // ftmp2 = z2z2 = z2**2
+    fe z2z2; fe_sqr(z2z2, z2);
+
+    // u1 = ftmp3 = x1*z2z2
+    fe_mul(u1, x1, z2z2);
+
+    // two_z1z2 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2
+    fe_add(two_z1z2, z1, z2);
+    fe_sqr(two_z1z2, two_z1z2);
+    fe_sub(two_z1z2, two_z1z2, z1z1);
+    fe_sub(two_z1z2, two_z1z2, z2z2);
+
+    // s1 = ftmp2 = y1 * z2**3
+    fe_mul(s1, z2, z2z2);
+    fe_mul(s1, s1, y1);
+  } else {
+    // We'll assume z2 = 1 (special case z2 = 0 is handled later).
+
+    // u1 = ftmp3 = x1*z2z2
+    fe_copy(u1, x1);
+    // two_z1z2 = 2z1z2
+    fe_add(two_z1z2, z1, z1);
+    // s1 = ftmp2 = y1 * z2**3
+    fe_copy(s1, y1);
+  }
+
+  // u2 = x2*z1z1
+  fe u2; fe_mul(u2, x2, z1z1);
+
+  // h = ftmp4 = u2 - u1
+  fe h; fe_sub(h, u2, u1);
+
+  limb_t xneq = fe_nz(h);
+
+  // z_out = two_z1z2 * h
+  fe_mul(z_out, h, two_z1z2);
+
+  // z1z1z1 = z1 * z1z1
+  fe z1z1z1; fe_mul(z1z1z1, z1, z1z1);
+
+  // s2 = tmp = y2 * z1**3
+  fe s2; fe_mul(s2, y2, z1z1z1);
+
+  // r = (s2 - s1)*2
+  fe r;
+  fe_sub(r, s2, s1);
+  fe_add(r, r, r);
+
+  limb_t yneq = fe_nz(r);
+
+  if (!xneq && !yneq && z1nz && z2nz) {
+    point_double(x_out, y_out, z_out, x1, y1, z1);
+    return;
+  }
+
+  // I = (2h)**2
+  fe i;
+  fe_add(i, h, h);
+  fe_sqr(i, i);
+
+  // J = ftmp2 = h * I
+  fe j; fe_mul(j, h, i);
+
+  // V = ftmp4 = U1 * I
+  fe v; fe_mul(v, u1, i);
+
+  // x_out = r**2 - J - 2V
+  fe_sqr(x_out, r);
+  fe_sub(x_out, x_out, j);
+  fe_sub(x_out, x_out, v);
+  fe_sub(x_out, x_out, v);
+
+  // y_out = r(V-x_out) - 2 * s1 * J
+  fe_sub(y_out, v, x_out);
+  fe_mul(y_out, y_out, r);
+  fe s1j;
+  fe_mul(s1j, s1, j);
+  fe_sub(y_out, y_out, s1j);
+  fe_sub(y_out, y_out, s1j);
+
+  fe_cmovznz(x_out, z1nz, x2, x_out);
+  fe_cmovznz(x3, z2nz, x1, x_out);
+  fe_cmovznz(y_out, z1nz, y2, y_out);
+  fe_cmovznz(y3, z2nz, y1, y_out);
+  fe_cmovznz(z_out, z1nz, z2, z_out);
+  fe_cmovznz(z3, z2nz, z1, z_out);
+}
+
+// Base point pre computation
+// --------------------------
+//
+// Two different sorts of precomputed tables are used in the following code.
+// Each contain various points on the curve, where each point is three field
+// elements (x, y, z).
+//
+// For the base point table, z is usually 1 (0 for the point at infinity).
+// This table has 2 * 16 elements, starting with the following:
+// index | bits    | point
+// ------+---------+------------------------------
+//     0 | 0 0 0 0 | 0G
+//     1 | 0 0 0 1 | 1G
+//     2 | 0 0 1 0 | 2^64G
+//     3 | 0 0 1 1 | (2^64 + 1)G
+//     4 | 0 1 0 0 | 2^128G
+//     5 | 0 1 0 1 | (2^128 + 1)G
+//     6 | 0 1 1 0 | (2^128 + 2^64)G
+//     7 | 0 1 1 1 | (2^128 + 2^64 + 1)G
+//     8 | 1 0 0 0 | 2^192G
+//     9 | 1 0 0 1 | (2^192 + 1)G
+//    10 | 1 0 1 0 | (2^192 + 2^64)G
+//    11 | 1 0 1 1 | (2^192 + 2^64 + 1)G
+//    12 | 1 1 0 0 | (2^192 + 2^128)G
+//    13 | 1 1 0 1 | (2^192 + 2^128 + 1)G
+//    14 | 1 1 1 0 | (2^192 + 2^128 + 2^64)G
+//    15 | 1 1 1 1 | (2^192 + 2^128 + 2^64 + 1)G
+// followed by a copy of this with each element multiplied by 2^32.
+//
+// The reason for this is so that we can clock bits into four different
+// locations when doing simple scalar multiplies against the base point,
+// and then another four locations using the second 16 elements.
+//
+// Tables for other points have table[i] = iG for i in 0 .. 16.
+
+// g_pre_comp is the table of precomputed base points
+#if defined(BORINGSSL_NISTP256_64BIT)
+static const fe g_pre_comp[2][16][3] = {
+    {{{0x0, 0x0, 0x0, 0x0}, {0x0, 0x0, 0x0, 0x0}, {0x0, 0x0, 0x0, 0x0}},
+     {{0x79e730d418a9143c, 0x75ba95fc5fedb601, 0x79fb732b77622510,
+       0x18905f76a53755c6},
+      {0xddf25357ce95560a, 0x8b4ab8e4ba19e45c, 0xd2e88688dd21f325,
+       0x8571ff1825885d85},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0x4f922fc516a0d2bb, 0xd5cc16c1a623499, 0x9241cf3a57c62c8b,
+       0x2f5e6961fd1b667f},
+      {0x5c15c70bf5a01797, 0x3d20b44d60956192, 0x4911b37071fdb52,
+       0xf648f9168d6f0f7b},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0x9e566847e137bbbc, 0xe434469e8a6a0bec, 0xb1c4276179d73463,
+       0x5abe0285133d0015},
+      {0x92aa837cc04c7dab, 0x573d9f4c43260c07, 0xc93156278e6cc37,
+       0x94bb725b6b6f7383},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0x62a8c244bfe20925, 0x91c19ac38fdce867, 0x5a96a5d5dd387063,
+       0x61d587d421d324f6},
+      {0xe87673a2a37173ea, 0x2384800853778b65, 0x10f8441e05bab43e,
+       0xfa11fe124621efbe},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0x1c891f2b2cb19ffd, 0x1ba8d5bb1923c23, 0xb6d03d678ac5ca8e,
+       0x586eb04c1f13bedc},
+      {0xc35c6e527e8ed09, 0x1e81a33c1819ede2, 0x278fd6c056c652fa,
+       0x19d5ac0870864f11},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0x62577734d2b533d5, 0x673b8af6a1bdddc0, 0x577e7c9aa79ec293,
+       0xbb6de651c3b266b1},
+      {0xe7e9303ab65259b3, 0xd6a0afd3d03a7480, 0xc5ac83d19b3cfc27,
+       0x60b4619a5d18b99b},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0xbd6a38e11ae5aa1c, 0xb8b7652b49e73658, 0xb130014ee5f87ed,
+       0x9d0f27b2aeebffcd},
+      {0xca9246317a730a55, 0x9c955b2fddbbc83a, 0x7c1dfe0ac019a71,
+       0x244a566d356ec48d},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0x56f8410ef4f8b16a, 0x97241afec47b266a, 0xa406b8e6d9c87c1,
+       0x803f3e02cd42ab1b},
+      {0x7f0309a804dbec69, 0xa83b85f73bbad05f, 0xc6097273ad8e197f,
+       0xc097440e5067adc1},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0x846a56f2c379ab34, 0xa8ee068b841df8d1, 0x20314459176c68ef,
+       0xf1af32d5915f1f30},
+      {0x99c375315d75bd50, 0x837cffbaf72f67bc, 0x613a41848d7723f,
+       0x23d0f130e2d41c8b},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0xed93e225d5be5a2b, 0x6fe799835934f3c6, 0x4314092622626ffc,
+       0x50bbb4d97990216a},
+      {0x378191c6e57ec63e, 0x65422c40181dcdb2, 0x41a8099b0236e0f6,
+       0x2b10011801fe49c3},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0xfc68b5c59b391593, 0xc385f5a2598270fc, 0x7144f3aad19adcbb,
+       0xdd55899983fbae0c},
+      {0x93b88b8e74b82ff4, 0xd2e03c4071e734c9, 0x9a7a9eaf43c0322a,
+       0xe6e4c551149d6041},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0x5fe14bfe80ec21fe, 0xf6ce116ac255be82, 0x98bc5a072f4a5d67,
+       0xfad27148db7e63af},
+      {0x90c0b6ac29ab05b3, 0x37a9a83c4e251ae6, 0xa7dc875c2aade7d,
+       0x77387de39f0e1a84},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0x1e9ecc49a56c0dd7, 0xa5cffcd846086c74, 0x8f7a1408f505aece,
+       0xb37b85c0bef0c47e},
+      {0x3596b6e4cc0e6a8f, 0xfd6d4bbf6b388f23, 0xaba453fac39cef4e,
+       0x9c135ac8f9f628d5},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0xa1c729495c8f8be, 0x2961c4803bf362bf, 0x9e418403df63d4ac,
+       0xc109f9cb91ece900},
+      {0xc2d095d058945705, 0xb9083d96ddeb85c0, 0x84692b8d7a40449b,
+       0x9bc3344f2eee1ee1},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0xd5ae35642913074, 0x55491b2748a542b1, 0x469ca665b310732a,
+       0x29591d525f1a4cc1},
+      {0xe76f5b6bb84f983f, 0xbe7eef419f5f84e1, 0x1200d49680baa189,
+       0x6376551f18ef332c},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}},
+    {{{0x0, 0x0, 0x0, 0x0}, {0x0, 0x0, 0x0, 0x0}, {0x0, 0x0, 0x0, 0x0}},
+     {{0x202886024147519a, 0xd0981eac26b372f0, 0xa9d4a7caa785ebc8,
+       0xd953c50ddbdf58e9},
+      {0x9d6361ccfd590f8f, 0x72e9626b44e6c917, 0x7fd9611022eb64cf,
+       0x863ebb7e9eb288f3},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0x4fe7ee31b0e63d34, 0xf4600572a9e54fab, 0xc0493334d5e7b5a4,
+       0x8589fb9206d54831},
+      {0xaa70f5cc6583553a, 0x879094ae25649e5, 0xcc90450710044652,
+       0xebb0696d02541c4f},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0xabbaa0c03b89da99, 0xa6f2d79eb8284022, 0x27847862b81c05e8,
+       0x337a4b5905e54d63},
+      {0x3c67500d21f7794a, 0x207005b77d6d7f61, 0xa5a378104cfd6e8,
+       0xd65e0d5f4c2fbd6},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0xd433e50f6d3549cf, 0x6f33696ffacd665e, 0x695bfdacce11fcb4,
+       0x810ee252af7c9860},
+      {0x65450fe17159bb2c, 0xf7dfbebe758b357b, 0x2b057e74d69fea72,
+       0xd485717a92731745},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0xce1f69bbe83f7669, 0x9f8ae8272877d6b, 0x9548ae543244278d,
+       0x207755dee3c2c19c},
+      {0x87bd61d96fef1945, 0x18813cefb12d28c3, 0x9fbcd1d672df64aa,
+       0x48dc5ee57154b00d},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0xef0f469ef49a3154, 0x3e85a5956e2b2e9a, 0x45aaec1eaa924a9c,
+       0xaa12dfc8a09e4719},
+      {0x26f272274df69f1d, 0xe0e4c82ca2ff5e73, 0xb9d8ce73b7a9dd44,
+       0x6c036e73e48ca901},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0xe1e421e1a47153f0, 0xb86c3b79920418c9, 0x93bdce87705d7672,
+       0xf25ae793cab79a77},
+      {0x1f3194a36d869d0c, 0x9d55c8824986c264, 0x49fb5ea3096e945e,
+       0x39b8e65313db0a3e},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0xe3417bc035d0b34a, 0x440b386b8327c0a7, 0x8fb7262dac0362d1,
+       0x2c41114ce0cdf943},
+      {0x2ba5cef1ad95a0b1, 0xc09b37a867d54362, 0x26d6cdd201e486c9,
+       0x20477abf42ff9297},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0xf121b41bc0a67d2, 0x62d4760a444d248a, 0xe044f1d659b4737,
+       0x8fde365250bb4a8},
+      {0xaceec3da848bf287, 0xc2a62182d3369d6e, 0x3582dfdc92449482,
+       0x2f7e2fd2565d6cd7},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0xa0122b5178a876b, 0x51ff96ff085104b4, 0x50b31ab14f29f76,
+       0x84abb28b5f87d4e6},
+      {0xd5ed439f8270790a, 0x2d6cb59d85e3f46b, 0x75f55c1b6c1e2212,
+       0xe5436f6717655640},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0xc2965ecc9aeb596d, 0x1ea03e7023c92b4, 0x4704b4b62e013961,
+       0xca8fd3f905ea367},
+      {0x92523a42551b2b61, 0x1eb7a89c390fcd06, 0xe7f1d2be0392a63e,
+       0x96dca2644ddb0c33},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0x231c210e15339848, 0xe87a28e870778c8d, 0x9d1de6616956e170,
+       0x4ac3c9382bb09c0b},
+      {0x19be05516998987d, 0x8b2376c4ae09f4d6, 0x1de0b7651a3f933d,
+       0x380d94c7e39705f4},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0x3685954b8c31c31d, 0x68533d005bf21a0c, 0xbd7626e75c79ec9,
+       0xca17754742c69d54},
+      {0xcc6edafff6d2dbb2, 0xfd0d8cbd174a9d18, 0x875e8793aa4578e8,
+       0xa976a7139cab2ce6},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0xce37ab11b43ea1db, 0xa7ff1a95259d292, 0x851b02218f84f186,
+       0xa7222beadefaad13},
+      {0xa2ac78ec2b0a9144, 0x5a024051f2fa59c5, 0x91d1eca56147ce38,
+       0xbe94d523bc2ac690},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}},
+     {{0x2d8daefd79ec1a0f, 0x3bbcd6fdceb39c97, 0xf5575ffc58f61a95,
+       0xdbd986c4adf7b420},
+      {0x81aa881415f39eb7, 0x6ee2fcf5b98d976c, 0x5465475dcf2f717d,
+       0x8e24d3c46860bbd0},
+      {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}}};
+#else
+static const fe g_pre_comp[2][16][3] = {
+    {{{0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0},
+      {0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0},
+      {0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0}},
+     {{0x18a9143c,0x79e730d4, 0x5fedb601,0x75ba95fc, 0x77622510,0x79fb732b,
+       0xa53755c6,0x18905f76},
+      {0xce95560a,0xddf25357, 0xba19e45c,0x8b4ab8e4, 0xdd21f325,0xd2e88688,
+       0x25885d85,0x8571ff18},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0x16a0d2bb,0x4f922fc5, 0x1a623499,0xd5cc16c, 0x57c62c8b,0x9241cf3a,
+       0xfd1b667f,0x2f5e6961},
+      {0xf5a01797,0x5c15c70b, 0x60956192,0x3d20b44d, 0x71fdb52,0x4911b37,
+       0x8d6f0f7b,0xf648f916},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0xe137bbbc,0x9e566847, 0x8a6a0bec,0xe434469e, 0x79d73463,0xb1c42761,
+       0x133d0015,0x5abe0285},
+      {0xc04c7dab,0x92aa837c, 0x43260c07,0x573d9f4c, 0x78e6cc37,0xc931562,
+       0x6b6f7383,0x94bb725b},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0xbfe20925,0x62a8c244, 0x8fdce867,0x91c19ac3, 0xdd387063,0x5a96a5d5,
+       0x21d324f6,0x61d587d4},
+      {0xa37173ea,0xe87673a2, 0x53778b65,0x23848008, 0x5bab43e,0x10f8441e,
+       0x4621efbe,0xfa11fe12},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0x2cb19ffd,0x1c891f2b, 0xb1923c23,0x1ba8d5b, 0x8ac5ca8e,0xb6d03d67,
+       0x1f13bedc,0x586eb04c},
+      {0x27e8ed09,0xc35c6e5, 0x1819ede2,0x1e81a33c, 0x56c652fa,0x278fd6c0,
+       0x70864f11,0x19d5ac08},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0xd2b533d5,0x62577734, 0xa1bdddc0,0x673b8af6, 0xa79ec293,0x577e7c9a,
+       0xc3b266b1,0xbb6de651},
+      {0xb65259b3,0xe7e9303a, 0xd03a7480,0xd6a0afd3, 0x9b3cfc27,0xc5ac83d1,
+       0x5d18b99b,0x60b4619a},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0x1ae5aa1c,0xbd6a38e1, 0x49e73658,0xb8b7652b, 0xee5f87ed,0xb130014,
+       0xaeebffcd,0x9d0f27b2},
+      {0x7a730a55,0xca924631, 0xddbbc83a,0x9c955b2f, 0xac019a71,0x7c1dfe0,
+       0x356ec48d,0x244a566d},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0xf4f8b16a,0x56f8410e, 0xc47b266a,0x97241afe, 0x6d9c87c1,0xa406b8e,
+       0xcd42ab1b,0x803f3e02},
+      {0x4dbec69,0x7f0309a8, 0x3bbad05f,0xa83b85f7, 0xad8e197f,0xc6097273,
+       0x5067adc1,0xc097440e},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0xc379ab34,0x846a56f2, 0x841df8d1,0xa8ee068b, 0x176c68ef,0x20314459,
+       0x915f1f30,0xf1af32d5},
+      {0x5d75bd50,0x99c37531, 0xf72f67bc,0x837cffba, 0x48d7723f,0x613a418,
+       0xe2d41c8b,0x23d0f130},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0xd5be5a2b,0xed93e225, 0x5934f3c6,0x6fe79983, 0x22626ffc,0x43140926,
+       0x7990216a,0x50bbb4d9},
+      {0xe57ec63e,0x378191c6, 0x181dcdb2,0x65422c40, 0x236e0f6,0x41a8099b,
+       0x1fe49c3,0x2b100118},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0x9b391593,0xfc68b5c5, 0x598270fc,0xc385f5a2, 0xd19adcbb,0x7144f3aa,
+       0x83fbae0c,0xdd558999},
+      {0x74b82ff4,0x93b88b8e, 0x71e734c9,0xd2e03c40, 0x43c0322a,0x9a7a9eaf,
+       0x149d6041,0xe6e4c551},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0x80ec21fe,0x5fe14bfe, 0xc255be82,0xf6ce116a, 0x2f4a5d67,0x98bc5a07,
+       0xdb7e63af,0xfad27148},
+      {0x29ab05b3,0x90c0b6ac, 0x4e251ae6,0x37a9a83c, 0xc2aade7d,0xa7dc875,
+       0x9f0e1a84,0x77387de3},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0xa56c0dd7,0x1e9ecc49, 0x46086c74,0xa5cffcd8, 0xf505aece,0x8f7a1408,
+       0xbef0c47e,0xb37b85c0},
+      {0xcc0e6a8f,0x3596b6e4, 0x6b388f23,0xfd6d4bbf, 0xc39cef4e,0xaba453fa,
+       0xf9f628d5,0x9c135ac8},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0x95c8f8be,0xa1c7294, 0x3bf362bf,0x2961c480, 0xdf63d4ac,0x9e418403,
+       0x91ece900,0xc109f9cb},
+      {0x58945705,0xc2d095d0, 0xddeb85c0,0xb9083d96, 0x7a40449b,0x84692b8d,
+       0x2eee1ee1,0x9bc3344f},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0x42913074,0xd5ae356, 0x48a542b1,0x55491b27, 0xb310732a,0x469ca665,
+       0x5f1a4cc1,0x29591d52},
+      {0xb84f983f,0xe76f5b6b, 0x9f5f84e1,0xbe7eef41, 0x80baa189,0x1200d496,
+       0x18ef332c,0x6376551f},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}},
+    {{{0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0},
+      {0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0},
+      {0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0}},
+     {{0x4147519a,0x20288602, 0x26b372f0,0xd0981eac, 0xa785ebc8,0xa9d4a7ca,
+       0xdbdf58e9,0xd953c50d},
+      {0xfd590f8f,0x9d6361cc, 0x44e6c917,0x72e9626b, 0x22eb64cf,0x7fd96110,
+       0x9eb288f3,0x863ebb7e},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0xb0e63d34,0x4fe7ee31, 0xa9e54fab,0xf4600572, 0xd5e7b5a4,0xc0493334,
+       0x6d54831,0x8589fb92},
+      {0x6583553a,0xaa70f5cc, 0xe25649e5,0x879094a, 0x10044652,0xcc904507,
+       0x2541c4f,0xebb0696d},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0x3b89da99,0xabbaa0c0, 0xb8284022,0xa6f2d79e, 0xb81c05e8,0x27847862,
+       0x5e54d63,0x337a4b59},
+      {0x21f7794a,0x3c67500d, 0x7d6d7f61,0x207005b7, 0x4cfd6e8,0xa5a3781,
+       0xf4c2fbd6,0xd65e0d5},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0x6d3549cf,0xd433e50f, 0xfacd665e,0x6f33696f, 0xce11fcb4,0x695bfdac,
+       0xaf7c9860,0x810ee252},
+      {0x7159bb2c,0x65450fe1, 0x758b357b,0xf7dfbebe, 0xd69fea72,0x2b057e74,
+       0x92731745,0xd485717a},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0xe83f7669,0xce1f69bb, 0x72877d6b,0x9f8ae82, 0x3244278d,0x9548ae54,
+       0xe3c2c19c,0x207755de},
+      {0x6fef1945,0x87bd61d9, 0xb12d28c3,0x18813cef, 0x72df64aa,0x9fbcd1d6,
+       0x7154b00d,0x48dc5ee5},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0xf49a3154,0xef0f469e, 0x6e2b2e9a,0x3e85a595, 0xaa924a9c,0x45aaec1e,
+       0xa09e4719,0xaa12dfc8},
+      {0x4df69f1d,0x26f27227, 0xa2ff5e73,0xe0e4c82c, 0xb7a9dd44,0xb9d8ce73,
+       0xe48ca901,0x6c036e73},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0xa47153f0,0xe1e421e1, 0x920418c9,0xb86c3b79, 0x705d7672,0x93bdce87,
+       0xcab79a77,0xf25ae793},
+      {0x6d869d0c,0x1f3194a3, 0x4986c264,0x9d55c882, 0x96e945e,0x49fb5ea3,
+       0x13db0a3e,0x39b8e653},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0x35d0b34a,0xe3417bc0, 0x8327c0a7,0x440b386b, 0xac0362d1,0x8fb7262d,
+       0xe0cdf943,0x2c41114c},
+      {0xad95a0b1,0x2ba5cef1, 0x67d54362,0xc09b37a8, 0x1e486c9,0x26d6cdd2,
+       0x42ff9297,0x20477abf},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0xbc0a67d2,0xf121b41, 0x444d248a,0x62d4760a, 0x659b4737,0xe044f1d,
+       0x250bb4a8,0x8fde365},
+      {0x848bf287,0xaceec3da, 0xd3369d6e,0xc2a62182, 0x92449482,0x3582dfdc,
+       0x565d6cd7,0x2f7e2fd2},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0x178a876b,0xa0122b5, 0x85104b4,0x51ff96ff, 0x14f29f76,0x50b31ab,
+       0x5f87d4e6,0x84abb28b},
+      {0x8270790a,0xd5ed439f, 0x85e3f46b,0x2d6cb59d, 0x6c1e2212,0x75f55c1b,
+       0x17655640,0xe5436f67},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0x9aeb596d,0xc2965ecc, 0x23c92b4,0x1ea03e7, 0x2e013961,0x4704b4b6,
+       0x905ea367,0xca8fd3f},
+      {0x551b2b61,0x92523a42, 0x390fcd06,0x1eb7a89c, 0x392a63e,0xe7f1d2be,
+       0x4ddb0c33,0x96dca264},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0x15339848,0x231c210e, 0x70778c8d,0xe87a28e8, 0x6956e170,0x9d1de661,
+       0x2bb09c0b,0x4ac3c938},
+      {0x6998987d,0x19be0551, 0xae09f4d6,0x8b2376c4, 0x1a3f933d,0x1de0b765,
+       0xe39705f4,0x380d94c7},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0x8c31c31d,0x3685954b, 0x5bf21a0c,0x68533d00, 0x75c79ec9,0xbd7626e,
+       0x42c69d54,0xca177547},
+      {0xf6d2dbb2,0xcc6edaff, 0x174a9d18,0xfd0d8cbd, 0xaa4578e8,0x875e8793,
+       0x9cab2ce6,0xa976a713},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0xb43ea1db,0xce37ab11, 0x5259d292,0xa7ff1a9, 0x8f84f186,0x851b0221,
+       0xdefaad13,0xa7222bea},
+      {0x2b0a9144,0xa2ac78ec, 0xf2fa59c5,0x5a024051, 0x6147ce38,0x91d1eca5,
+       0xbc2ac690,0xbe94d523},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}},
+     {{0x79ec1a0f,0x2d8daefd, 0xceb39c97,0x3bbcd6fd, 0x58f61a95,0xf5575ffc,
+       0xadf7b420,0xdbd986c4},
+      {0x15f39eb7,0x81aa8814, 0xb98d976c,0x6ee2fcf5, 0xcf2f717d,0x5465475d,
+       0x6860bbd0,0x8e24d3c4},
+      {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}}};
+#endif
+
+// select_point selects the |idx|th point from a precomputation table and
+// copies it to out.
+static void select_point(const limb_t idx, size_t size,
+                         const fe pre_comp[/*size*/][3],
+                         fe out[3]) {
+  OPENSSL_memset(out, 0, sizeof(fe) * 3);
+  for (size_t i = 0; i < size; i++) {
+    limb_t mismatch = i ^ idx;
+    fe_cmovznz(out[0], mismatch, pre_comp[i][0], out[0]);
+    fe_cmovznz(out[1], mismatch, pre_comp[i][1], out[1]);
+    fe_cmovznz(out[2], mismatch, pre_comp[i][2], out[2]);
+  }
+}
+
+// get_bit returns the |i|th bit in |in|
+static char get_bit(const uint8_t *in, int i) {
+  if (i < 0 || i >= 256) {
+    return 0;
+  }
+  return (in[i >> 3] >> (i & 7)) & 1;
+}
+
+// Interleaved point multiplication using precomputed point multiples: The
+// small point multiples 0*P, 1*P, ..., 17*P are in p_pre_comp, the scalar
+// in p_scalar, if non-NULL. If g_scalar is non-NULL, we also add this multiple
+// of the generator, using certain (large) precomputed multiples in g_pre_comp.
+// Output point (X, Y, Z) is stored in x_out, y_out, z_out.
+static void batch_mul(fe x_out, fe y_out, fe z_out,
+                      const uint8_t *p_scalar, const uint8_t *g_scalar,
+                      const fe p_pre_comp[17][3]) {
+  // set nq to the point at infinity
+  fe nq[3] = {{0},{0},{0}}, ftmp, tmp[3];
+  uint64_t bits;
+  uint8_t sign, digit;
+
+  // Loop over both scalars msb-to-lsb, interleaving additions of multiples
+  // of the generator (two in each of the last 32 rounds) and additions of p
+  // (every 5th round).
+
+  int skip = 1;  // save two point operations in the first round
+  size_t i = p_scalar != NULL ? 255 : 31;
+  for (;;) {
+    // double
+    if (!skip) {
+      point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
+    }
+
+    // add multiples of the generator
+    if (g_scalar != NULL && i <= 31) {
+      // first, look 32 bits upwards
+      bits = get_bit(g_scalar, i + 224) << 3;
+      bits |= get_bit(g_scalar, i + 160) << 2;
+      bits |= get_bit(g_scalar, i + 96) << 1;
+      bits |= get_bit(g_scalar, i + 32);
+      // select the point to add, in constant time
+      select_point(bits, 16, g_pre_comp[1], tmp);
+
+      if (!skip) {
+        point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
+                  tmp[0], tmp[1], tmp[2]);
+      } else {
+        fe_copy(nq[0], tmp[0]);
+        fe_copy(nq[1], tmp[1]);
+        fe_copy(nq[2], tmp[2]);
+        skip = 0;
+      }
+
+      // second, look at the current position
+      bits = get_bit(g_scalar, i + 192) << 3;
+      bits |= get_bit(g_scalar, i + 128) << 2;
+      bits |= get_bit(g_scalar, i + 64) << 1;
+      bits |= get_bit(g_scalar, i);
+      // select the point to add, in constant time
+      select_point(bits, 16, g_pre_comp[0], tmp);
+      point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, tmp[0],
+                tmp[1], tmp[2]);
+    }
+
+    // do other additions every 5 doublings
+    if (p_scalar != NULL && i % 5 == 0) {
+      bits = get_bit(p_scalar, i + 4) << 5;
+      bits |= get_bit(p_scalar, i + 3) << 4;
+      bits |= get_bit(p_scalar, i + 2) << 3;
+      bits |= get_bit(p_scalar, i + 1) << 2;
+      bits |= get_bit(p_scalar, i) << 1;
+      bits |= get_bit(p_scalar, i - 1);
+      ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+
+      // select the point to add or subtract, in constant time.
+      select_point(digit, 17, p_pre_comp, tmp);
+      fe_opp(ftmp, tmp[1]);  // (X, -Y, Z) is the negative point.
+      fe_cmovznz(tmp[1], sign, tmp[1], ftmp);
+
+      if (!skip) {
+        point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */,
+                  tmp[0], tmp[1], tmp[2]);
+      } else {
+        fe_copy(nq[0], tmp[0]);
+        fe_copy(nq[1], tmp[1]);
+        fe_copy(nq[2], tmp[2]);
+        skip = 0;
+      }
+    }
+
+    if (i == 0) {
+      break;
+    }
+    --i;
+  }
+  fe_copy(x_out, nq[0]);
+  fe_copy(y_out, nq[1]);
+  fe_copy(z_out, nq[2]);
+}
+
+// OPENSSL EC_METHOD FUNCTIONS
+
+// Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
+// (X/Z^2, Y/Z^3).
+static int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
+                                                        const EC_POINT *point,
+                                                        BIGNUM *x_out,
+                                                        BIGNUM *y_out,
+                                                        BN_CTX *ctx) {
+  fe x, y, z1, z2;
+
+  if (EC_POINT_is_at_infinity(group, point)) {
+    OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
+    return 0;
+  }
+  if (!BN_to_fe(x, &point->X) ||
+      !BN_to_fe(y, &point->Y) ||
+      !BN_to_fe(z1, &point->Z)) {
+    return 0;
+  }
+
+  fe_inv(z2, z1);
+  fe_sqr(z1, z2);
+
+  if (x_out != NULL) {
+    fe_mul(x, x, z1);
+    fe_from_montgomery(x);
+    if (!fe_to_BN(x_out, x)) {
+      OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+      return 0;
+    }
+  }
+
+  if (y_out != NULL) {
+    fe_mul(z1, z1, z2);
+    fe_mul(y, y, z1);
+    fe_from_montgomery(y);
+    if (!fe_to_BN(y_out, y)) {
+      OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+      return 0;
+    }
+  }
+
+  return 1;
+}
+
+static int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
+                                      const EC_SCALAR *g_scalar,
+                                      const EC_POINT *p,
+                                      const EC_SCALAR *p_scalar,
+                                      BN_CTX *unused_ctx) {
+  fe p_pre_comp[17][3];
+  fe x_out, y_out, z_out;
+
+  if (p != NULL && p_scalar != NULL) {
+    // We treat NULL scalars as 0, and NULL points as points at infinity, i.e.,
+    // they contribute nothing to the linear combination.
+    OPENSSL_memset(&p_pre_comp, 0, sizeof(p_pre_comp));
+    // Precompute multiples.
+    if (!BN_to_fe(p_pre_comp[1][0], &p->X) ||
+        !BN_to_fe(p_pre_comp[1][1], &p->Y) ||
+        !BN_to_fe(p_pre_comp[1][2], &p->Z)) {
+      return 0;
+    }
+    for (size_t j = 2; j <= 16; ++j) {
+      if (j & 1) {
+        point_add(p_pre_comp[j][0], p_pre_comp[j][1],
+                  p_pre_comp[j][2], p_pre_comp[1][0],
+                  p_pre_comp[1][1], p_pre_comp[1][2],
+                  0,
+                  p_pre_comp[j - 1][0], p_pre_comp[j - 1][1],
+                  p_pre_comp[j - 1][2]);
+      } else {
+        point_double(p_pre_comp[j][0], p_pre_comp[j][1],
+                     p_pre_comp[j][2], p_pre_comp[j / 2][0],
+                     p_pre_comp[j / 2][1], p_pre_comp[j / 2][2]);
+      }
+    }
+  }
+
+  batch_mul(x_out, y_out, z_out,
+            (p != NULL && p_scalar != NULL) ? p_scalar->bytes : NULL,
+            g_scalar != NULL ? g_scalar->bytes : NULL,
+            (const fe (*) [3])p_pre_comp);
+
+  if (!fe_to_BN(&r->X, x_out) ||
+      !fe_to_BN(&r->Y, y_out) ||
+      !fe_to_BN(&r->Z, z_out)) {
+    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
+    return 0;
+  }
+  return 1;
+}
+
+DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp256_method) {
+  out->group_init = ec_GFp_mont_group_init;
+  out->group_finish = ec_GFp_mont_group_finish;
+  out->group_set_curve = ec_GFp_mont_group_set_curve;
+  out->point_get_affine_coordinates =
+    ec_GFp_nistp256_point_get_affine_coordinates;
+  out->mul = ec_GFp_nistp256_points_mul;
+// The variable-time wNAF point multiplication uses fewer field operations than
+// the constant-time implementation here, but the 64-bit field arithmetic in
+// this file is much faster than the generic BIGNUM-based field arithmetic used
+// by wNAF. For 32-bit, the wNAF code is overall ~60% faster on non-precomputed
+// points, so we use it for public inputs.
+#if defined(BORINGSSL_NISTP256_64BIT)
+  out->mul_public = ec_GFp_nistp256_points_mul;
+#else
+  out->mul_public = ec_wNAF_mul;
+#endif
+  out->field_mul = ec_GFp_mont_field_mul;
+  out->field_sqr = ec_GFp_mont_field_sqr;
+  out->field_encode = ec_GFp_mont_field_encode;
+  out->field_decode = ec_GFp_mont_field_decode;
+};
+
+#undef BORINGSSL_NISTP256_64BIT
diff --git a/src/util/bot/UPDATING b/src/util/bot/UPDATING
index a9915ab..7162f94 100644
--- a/src/util/bot/UPDATING
+++ b/src/util/bot/UPDATING
@@ -28,12 +28,12 @@
         ./bootstrap --prefix=$PWD/cmake-linux64 && make && make install
         tar -czf cmake-linux64.tar.gz cmake-linux64/
 
-    The current revision was built against cmake-3.5.0.tar.gz.
+    The current revision was built against cmake-3.10.0.tar.gz.
 
 cmake-mac.tar.gz: Follow the same instructions as above on a Mac, but replace
     cmake-linux64 with cmake-mac.
 
-    The current revision was built against cmake-3.5.0.tar.gz.
+    The current revision was built against cmake-3.10.0.tar.gz.
 
 cmake-win32.zip: Update to the latest prebuilt release of CMake, found at
     https://cmake.org/download/. Use the file labeled "Windows ZIP". The
@@ -41,6 +41,10 @@
 
     The current revision is cmake-3.5.0-win32-x86.zip.
 
+    TODO(davidben): The update to CMake 3.10 on Windows was rolled back due to a
+    CMake bug. Update to 3.10.1 when that is released.
+    https://github.com/Kitware/CMake/commit/f969f1a9ce1d0045b9d056fd08c4683c34c420fa
+
 perl-win32.zip: Update to the latest 32-bit prebuilt "Portable" edition of
     Strawberry Perl, found at http://strawberryperl.com/releases.html. The
     download will be named strawberry-perl-VERSION-32bit-portable.zip.
diff --git a/src/util/bot/cmake-linux64.tar.gz.sha1 b/src/util/bot/cmake-linux64.tar.gz.sha1
index 404570f..52e17f0 100644
--- a/src/util/bot/cmake-linux64.tar.gz.sha1
+++ b/src/util/bot/cmake-linux64.tar.gz.sha1
@@ -1 +1 @@
-6ea4ad07a4bab113ea74c45fafb14b8d0b0feab5
\ No newline at end of file
+e32e920dc95a0ac58fe78f666d2ce69222b23edb
\ No newline at end of file
diff --git a/src/util/bot/cmake-mac.tar.gz.sha1 b/src/util/bot/cmake-mac.tar.gz.sha1
index 19c9b61..cf90503 100644
--- a/src/util/bot/cmake-mac.tar.gz.sha1
+++ b/src/util/bot/cmake-mac.tar.gz.sha1
@@ -1 +1 @@
-f3166dab96234c9516ece56dc2851bf4c8e70fe8
\ No newline at end of file
+20ee0e2d2e11e2ea34caf78197e4784a4fc95181
\ No newline at end of file
diff --git a/src/util/generate_build_files.py b/src/util/generate_build_files.py
index 4b4a899..a4af666 100644
--- a/src/util/generate_build_files.py
+++ b/src/util/generate_build_files.py
@@ -594,6 +594,12 @@
   tool_c_files = FindCFiles(os.path.join('src', 'tool'), NoTests)
   tool_h_files = FindHeaderFiles(os.path.join('src', 'tool'), AllFiles)
 
+  # third_party/fiat/p256.c lives in third_party/fiat, but it is a FIPS
+  # fragment, not a normal source file.
+  p256 = os.path.join('src', 'third_party', 'fiat', 'p256.c')
+  fips_fragments.append(p256)
+  crypto_c_files.remove(p256)
+
   # Generate err_data.c
   with open('err_data.c', 'w+') as err_data:
     subprocess.check_call(['go', 'run', 'err_data_generate.go'],