Drop CECPQ2b code.

The experiment which motivated CECPQ2b has concluded (although the
results haven't been published yet) and the SIKE code is causing some
issues for gRPC in gprc/grpc#20100. Also, this is code size that takes
up space in Android etc.

Change-Id: I43b0b8c420f236c0fe9b40bf2517d2fde98495d5
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/38384
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/LICENSE b/LICENSE
index 2f4dfcd..49c41fa 100644
--- a/LICENSE
+++ b/LICENSE
@@ -181,29 +181,6 @@
 SOFTWARE.
 
 
-The code in third_party/sike also carries the MIT license:
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-
-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
-
-
 Licenses for support code
 -------------------------
 
diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt
index f3e2ca4..427bc64 100644
--- a/crypto/CMakeLists.txt
+++ b/crypto/CMakeLists.txt
@@ -115,7 +115,6 @@
 
     chacha/chacha-armv8.${ASM_EXT}
     test/trampoline-armv8.${ASM_EXT}
-    third_party/sike/asm/fp-armv8.${ASM_EXT}
   )
 endif()
 
@@ -137,7 +136,6 @@
     cipher_extra/chacha20_poly1305_x86_64.${ASM_EXT}
     hrss/asm/poly_rq_mul.S
     test/trampoline-x86_64.${ASM_EXT}
-    third_party/sike/asm/fp-x86_64.${ASM_EXT}
   )
 endif()
 
@@ -147,8 +145,6 @@
 perlasm(chacha/chacha-x86_64.${ASM_EXT} chacha/asm/chacha-x86_64.pl)
 perlasm(cipher_extra/aes128gcmsiv-x86_64.${ASM_EXT} cipher_extra/asm/aes128gcmsiv-x86_64.pl)
 perlasm(cipher_extra/chacha20_poly1305_x86_64.${ASM_EXT} cipher_extra/asm/chacha20_poly1305_x86_64.pl)
-perlasm(third_party/sike/asm/fp-x86_64.${ASM_EXT} ../third_party/sike/asm/fp-x86_64.pl)
-perlasm(third_party/sike/asm/fp-armv8.${ASM_EXT} ../third_party/sike/asm/fp-armv8.pl)
 perlasm(test/trampoline-armv4.${ASM_EXT} test/asm/trampoline-armv4.pl)
 perlasm(test/trampoline-armv8.${ASM_EXT} test/asm/trampoline-armv8.pl)
 perlasm(test/trampoline-x86.${ASM_EXT} test/asm/trampoline-x86.pl)
@@ -412,11 +408,6 @@
   x509v3/v3_sxnet.c
   x509v3/v3_utl.c
   ../third_party/fiat/curve25519.c
-  ../third_party/sike/fpx.c
-  ../third_party/sike/isogeny.c
-  ../third_party/sike/curve_params.c
-  ../third_party/sike/sike.c
-  ../third_party/sike/asm/fp_generic.c
 
   $<TARGET_OBJECTS:fipsmodule>
 
@@ -537,7 +528,6 @@
   x509/x509_time_test.cc
   x509v3/tab_test.cc
   x509v3/v3name_test.cc
-  ../third_party/sike/sike_test.cc
 
   $<TARGET_OBJECTS:crypto_test_data>
   $<TARGET_OBJECTS:boringssl_gtest_main>
diff --git a/crypto/obj/obj_dat.h b/crypto/obj/obj_dat.h
index 1a9bf15..0313a08 100644
--- a/crypto/obj/obj_dat.h
+++ b/crypto/obj/obj_dat.h
@@ -57,7 +57,7 @@
 /* This file is generated by crypto/obj/objects.go. */
 
 
-#define NUM_NID 961
+#define NUM_NID 960
 
 static const uint8_t kObjectData[] = {
     /* NID_rsadsi */
@@ -8756,7 +8756,6 @@
     {"KxANY", "kx-any", NID_kx_any, 0, NULL, 0},
     {"AuthANY", "auth-any", NID_auth_any, 0, NULL, 0},
     {"CECPQ2", "CECPQ2", NID_CECPQ2, 0, NULL, 0},
-    {"CECPQ2b", "CECPQ2b", NID_CECPQ2b, 0, NULL, 0},
 };
 
 static const unsigned kNIDsInShortNameOrder[] = {
@@ -8819,7 +8818,6 @@
     109 /* CAST5-ECB */,
     111 /* CAST5-OFB */,
     959 /* CECPQ2 */,
-    960 /* CECPQ2b */,
     894 /* CMAC */,
     13 /* CN */,
     141 /* CRLReason */,
@@ -9725,7 +9723,6 @@
     179 /* CA Issuers */,
     785 /* CA Repository */,
     959 /* CECPQ2 */,
-    960 /* CECPQ2b */,
     131 /* Code Signing */,
     783 /* Diffie-Hellman based MAC */,
     382 /* Directory */,
diff --git a/crypto/obj/obj_mac.num b/crypto/obj/obj_mac.num
index f2d4e8c..5fa839d 100644
--- a/crypto/obj/obj_mac.num
+++ b/crypto/obj/obj_mac.num
@@ -948,4 +948,3 @@
 kx_any		957
 auth_any		958
 CECPQ2		959
-CECPQ2b		960
diff --git a/crypto/obj/objects.txt b/crypto/obj/objects.txt
index 6e7ecf0..6dbb7ad 100644
--- a/crypto/obj/objects.txt
+++ b/crypto/obj/objects.txt
@@ -1337,9 +1337,6 @@
 # NID for CECPQ2 (no corresponding OID).
  : CECPQ2
 
-# NID for CECPQ2 (no corresponding OID).
- : CECPQ2b
-
 # See RFC 8410.
 1 3 101 112 : ED25519
 
diff --git a/include/openssl/nid.h b/include/openssl/nid.h
index cea975a..270d443 100644
--- a/include/openssl/nid.h
+++ b/include/openssl/nid.h
@@ -4237,9 +4237,6 @@
 #define SN_CECPQ2 "CECPQ2"
 #define NID_CECPQ2 959
 
-#define SN_CECPQ2b "CECPQ2b"
-#define NID_CECPQ2b 960
-
 
 #if defined(__cplusplus)
 } /* extern C */
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index f12cacc..48a381b 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -2231,7 +2231,6 @@
 #define SSL_CURVE_SECP521R1 25
 #define SSL_CURVE_X25519 29
 #define SSL_CURVE_CECPQ2 16696
-#define SSL_CURVE_CECPQ2b 65074
 
 // SSL_get_curve_id returns the ID of the curve used by |ssl|'s most recently
 // completed handshake or 0 if not applicable.
diff --git a/ssl/s3_both.cc b/ssl/s3_both.cc
index 58f0f8a..1ec596a 100644
--- a/ssl/s3_both.cc
+++ b/ssl/s3_both.cc
@@ -660,8 +660,7 @@
  public:
   CipherScorer(uint16_t group_id)
       : aes_is_fine_(EVP_has_aes_hardware()),
-        security_128_is_fine_(group_id != SSL_CURVE_CECPQ2 &&
-                              group_id != SSL_CURVE_CECPQ2b) {}
+        security_128_is_fine_(group_id != SSL_CURVE_CECPQ2) {}
 
   typedef std::tuple<bool, bool, bool> Score;
 
diff --git a/ssl/ssl_key_share.cc b/ssl/ssl_key_share.cc
index 826fb1a..6cac3cf 100644
--- a/ssl/ssl_key_share.cc
+++ b/ssl/ssl_key_share.cc
@@ -31,7 +31,6 @@
 
 #include "internal.h"
 #include "../crypto/internal.h"
-#include "../third_party/sike/sike.h"
 
 BSSL_NAMESPACE_BEGIN
 
@@ -300,87 +299,6 @@
   HRSS_private_key hrss_private_key_;
 };
 
-class CECPQ2bKeyShare : public SSLKeyShare {
- public:
-  uint16_t GroupID() const override { return SSL_CURVE_CECPQ2b; }
-
-  bool Offer(CBB *out) override {
-    uint8_t public_x25519[32] = {0};
-    X25519_keypair(public_x25519, private_x25519_);
-    if (!SIKE_keypair(private_sike_, public_sike_)) {
-      return false;
-    }
-
-    return CBB_add_bytes(out, public_x25519, sizeof(public_x25519)) &&
-           CBB_add_bytes(out, public_sike_, sizeof(public_sike_));
-  }
-
-  bool Accept(CBB *out_public_key, Array<uint8_t> *out_secret,
-              uint8_t *out_alert, Span<const uint8_t> peer_key) override {
-    uint8_t public_x25519[32];
-    uint8_t private_x25519[32];
-    uint8_t sike_ciphertext[SIKE_CT_BYTESZ] = {0};
-
-    *out_alert = SSL_AD_INTERNAL_ERROR;
-
-    if (peer_key.size() != sizeof(public_x25519) + SIKE_PUB_BYTESZ) {
-      *out_alert = SSL_AD_DECODE_ERROR;
-      OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT);
-      return false;
-    }
-
-    Array<uint8_t> secret;
-    if (!secret.Init(sizeof(private_x25519_) + SIKE_SS_BYTESZ)) {
-      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
-      return false;
-    }
-
-    X25519_keypair(public_x25519, private_x25519);
-    if (!X25519(secret.data(), private_x25519, peer_key.data())) {
-      *out_alert = SSL_AD_DECODE_ERROR;
-      OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT);
-      return false;
-    }
-
-    SIKE_encaps(secret.data() + sizeof(private_x25519_), sike_ciphertext,
-                peer_key.data() + sizeof(public_x25519));
-    *out_secret = std::move(secret);
-
-    return CBB_add_bytes(out_public_key, public_x25519,
-                         sizeof(public_x25519)) &&
-           CBB_add_bytes(out_public_key, sike_ciphertext,
-                         sizeof(sike_ciphertext));
-  }
-
-  bool Finish(Array<uint8_t> *out_secret, uint8_t *out_alert,
-              Span<const uint8_t> peer_key) override {
-    *out_alert = SSL_AD_INTERNAL_ERROR;
-
-    Array<uint8_t> secret;
-    if (!secret.Init(sizeof(private_x25519_) + SIKE_SS_BYTESZ)) {
-      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
-      return false;
-    }
-
-    if (peer_key.size() != 32 + SIKE_CT_BYTESZ ||
-        !X25519(secret.data(), private_x25519_, peer_key.data())) {
-      *out_alert = SSL_AD_DECODE_ERROR;
-      OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT);
-      return false;
-    }
-
-    SIKE_decaps(secret.data() + sizeof(private_x25519_), peer_key.data() + 32,
-                public_sike_, private_sike_);
-    *out_secret = std::move(secret);
-    return true;
-  }
-
- private:
-  uint8_t private_x25519_[32];
-  uint8_t private_sike_[SIKE_PRV_BYTESZ];
-  uint8_t public_sike_[SIKE_PUB_BYTESZ];
-};
-
 CONSTEXPR_ARRAY NamedGroup kNamedGroups[] = {
     {NID_secp224r1, SSL_CURVE_SECP224R1, "P-224", "secp224r1"},
     {NID_X9_62_prime256v1, SSL_CURVE_SECP256R1, "P-256", "prime256v1"},
@@ -388,7 +306,6 @@
     {NID_secp521r1, SSL_CURVE_SECP521R1, "P-521", "secp521r1"},
     {NID_X25519, SSL_CURVE_X25519, "X25519", "x25519"},
     {NID_CECPQ2, SSL_CURVE_CECPQ2, "CECPQ2", "CECPQ2"},
-    {NID_CECPQ2b, SSL_CURVE_CECPQ2b, "CECPQ2b", "CECPQ2b"},
 };
 
 }  // namespace
@@ -415,8 +332,6 @@
       return UniquePtr<SSLKeyShare>(New<X25519KeyShare>());
     case SSL_CURVE_CECPQ2:
       return UniquePtr<SSLKeyShare>(New<CECPQ2KeyShare>());
-    case SSL_CURVE_CECPQ2b:
-      return UniquePtr<SSLKeyShare>(New<CECPQ2bKeyShare>());
     default:
       return nullptr;
   }
diff --git a/ssl/t1_lib.cc b/ssl/t1_lib.cc
index cc29a83..e5a33dd 100644
--- a/ssl/t1_lib.cc
+++ b/ssl/t1_lib.cc
@@ -200,7 +200,7 @@
 }
 
 static bool is_post_quantum_group(uint16_t id) {
-  return id == SSL_CURVE_CECPQ2 || id == SSL_CURVE_CECPQ2b;
+  return id == SSL_CURVE_CECPQ2;
 }
 
 bool ssl_client_hello_init(const SSL *ssl, SSL_CLIENT_HELLO *out,
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index d1cf757..a4f787a 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -151,7 +151,6 @@
 	CurveP521    CurveID = 25
 	CurveX25519  CurveID = 29
 	CurveCECPQ2  CurveID = 16696
-	CurveCECPQ2b CurveID = 65074
 )
 
 // TLS Elliptic Curve Point Formats
@@ -1732,7 +1731,7 @@
 	return ret
 }
 
-var defaultCurvePreferences = []CurveID{CurveCECPQ2b, CurveCECPQ2, CurveX25519, CurveP256, CurveP384, CurveP521}
+var defaultCurvePreferences = []CurveID{CurveCECPQ2, CurveX25519, CurveP256, CurveP384, CurveP521}
 
 func (c *Config) curvePreferences() []CurveID {
 	if c == nil || len(c.CurvePreferences) == 0 {
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go
index 44b817e..2427856 100644
--- a/ssl/test/runner/handshake_server.go
+++ b/ssl/test/runner/handshake_server.go
@@ -210,7 +210,7 @@
 	if config.Bugs.FailIfCECPQ2Offered {
 		for _, offeredCurve := range hs.clientHello.supportedCurves {
 			if isPqGroup(offeredCurve) {
-				return errors.New("tls: CECPQ2 or CECPQ2b was offered")
+				return errors.New("tls: CECPQ2 was offered")
 			}
 		}
 	}
@@ -1227,7 +1227,7 @@
 Curves:
 	for _, curve := range hs.clientHello.supportedCurves {
 		if isPqGroup(curve) && c.vers < VersionTLS13 {
-			// CECPQ2 and CECPQ2b is TLS 1.3-only.
+			// CECPQ2 is TLS 1.3-only.
 			continue
 		}
 
diff --git a/ssl/test/runner/key_agreement.go b/ssl/test/runner/key_agreement.go
index 56cfec8..266163e 100644
--- a/ssl/test/runner/key_agreement.go
+++ b/ssl/test/runner/key_agreement.go
@@ -19,7 +19,6 @@
 
 	"boringssl.googlesource.com/boringssl/ssl/test/runner/curve25519"
 	"boringssl.googlesource.com/boringssl/ssl/test/runner/hrss"
-	"boringssl.googlesource.com/boringssl/ssl/test/runner/sike"
 )
 
 type keyType int
@@ -434,98 +433,6 @@
 	return preMasterSecret, nil
 }
 
-// cecpq2BCurve implements CECPQ2b, which is SIKE combined with X25519.
-type cecpq2BCurve struct {
-	// Both public key and shared secret size
-	x25519PrivateKey [32]byte
-	sikePrivateKey   *sike.PrivateKey
-}
-
-func (e *cecpq2BCurve) offer(rand io.Reader) (publicKey []byte, err error) {
-	if _, err = io.ReadFull(rand, e.x25519PrivateKey[:]); err != nil {
-		return nil, err
-	}
-
-	var x25519Public [32]byte
-	curve25519.ScalarBaseMult(&x25519Public, &e.x25519PrivateKey)
-
-	e.sikePrivateKey = sike.NewPrivateKey(sike.KeyVariant_SIKE)
-	if err = e.sikePrivateKey.Generate(rand); err != nil {
-		return nil, err
-	}
-
-	sikePublic := e.sikePrivateKey.GeneratePublicKey().Export()
-	var ret []byte
-	ret = append(ret, x25519Public[:]...)
-	ret = append(ret, sikePublic...)
-	return ret, nil
-}
-
-func (e *cecpq2BCurve) accept(rand io.Reader, peerKey []byte) (publicKey []byte, preMasterSecret []byte, err error) {
-	if len(peerKey) != 32+sike.Params.PublicKeySize {
-		return nil, nil, errors.New("tls: bad length CECPQ2b offer")
-	}
-
-	if _, err = io.ReadFull(rand, e.x25519PrivateKey[:]); err != nil {
-		return nil, nil, err
-	}
-
-	var x25519Shared, x25519PeerKey, x25519Public [32]byte
-	copy(x25519PeerKey[:], peerKey)
-	curve25519.ScalarBaseMult(&x25519Public, &e.x25519PrivateKey)
-	curve25519.ScalarMult(&x25519Shared, &e.x25519PrivateKey, &x25519PeerKey)
-
-	// Per RFC 7748, reject the all-zero value in constant time.
-	var zeros [32]byte
-	if subtle.ConstantTimeCompare(zeros[:], x25519Shared[:]) == 1 {
-		return nil, nil, errors.New("tls: X25519 value with wrong order")
-	}
-
-	var sikePubKey = sike.NewPublicKey(sike.KeyVariant_SIKE)
-	if err = sikePubKey.Import(peerKey[32:]); err != nil {
-		// should never happen as size was already checked
-		return nil, nil, errors.New("tls: implementation error")
-	}
-	sikeCiphertext, sikeShared, err := sike.Encapsulate(rand, sikePubKey)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	publicKey = append(publicKey, x25519Public[:]...)
-	publicKey = append(publicKey, sikeCiphertext...)
-	preMasterSecret = append(preMasterSecret, x25519Shared[:]...)
-	preMasterSecret = append(preMasterSecret, sikeShared...)
-
-	return publicKey, preMasterSecret, nil
-}
-
-func (e *cecpq2BCurve) finish(peerKey []byte) (preMasterSecret []byte, err error) {
-	if len(peerKey) != 32+(sike.Params.PublicKeySize+sike.Params.MsgLen) {
-		return nil, errors.New("tls: bad length CECPQ2b reply")
-	}
-
-	var x25519Shared, x25519PeerKey [32]byte
-	copy(x25519PeerKey[:], peerKey)
-	curve25519.ScalarMult(&x25519Shared, &e.x25519PrivateKey, &x25519PeerKey)
-
-	// Per RFC 7748, reject the all-zero value in constant time.
-	var zeros [32]byte
-	if subtle.ConstantTimeCompare(zeros[:], x25519Shared[:]) == 1 {
-		return nil, errors.New("tls: X25519 value with wrong order")
-	}
-
-	var sikePubKey = e.sikePrivateKey.GeneratePublicKey()
-	sikeShared, err := sike.Decapsulate(e.sikePrivateKey, sikePubKey, peerKey[32:])
-	if err != nil {
-		return nil, errors.New("tls: invalid SIKE ciphertext")
-	}
-
-	preMasterSecret = append(preMasterSecret, x25519Shared[:]...)
-	preMasterSecret = append(preMasterSecret, sikeShared...)
-
-	return preMasterSecret, nil
-}
-
 func curveForCurveID(id CurveID, config *Config) (ecdhCurve, bool) {
 	switch id {
 	case CurveP224:
@@ -540,8 +447,6 @@
 		return &x25519ECDHCurve{setHighBit: config.Bugs.SetX25519HighBit}, true
 	case CurveCECPQ2:
 		return &cecpq2Curve{}, true
-	case CurveCECPQ2b:
-		return &cecpq2BCurve{}, true
 	default:
 		return nil, false
 	}
@@ -690,7 +595,7 @@
 NextCandidate:
 	for _, candidate := range preferredCurves {
 		if isPqGroup(candidate) && version < VersionTLS13 {
-			// CECPQ2 and CECPQ2b is TLS 1.3-only.
+			// CECPQ2 is TLS 1.3-only.
 			continue
 		}
 
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 758566a..18b01aa 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -10449,13 +10449,12 @@
 	{"P-521", CurveP521},
 	{"X25519", CurveX25519},
 	{"CECPQ2", CurveCECPQ2},
-	{"CECPQ2b", CurveCECPQ2b},
 }
 
 const bogusCurve = 0x1234
 
 func isPqGroup(r CurveID) bool {
-	return r == CurveCECPQ2 || r == CurveCECPQ2b
+	return r == CurveCECPQ2
 }
 
 func addCurveTests() {
@@ -10928,21 +10927,6 @@
 		},
 	})
 
-	// CECPQ2b should not be offered by a TLS < 1.3 client.
-	testCases = append(testCases, testCase{
-		name: "CECPQ2bNotInTLS12",
-		config: Config{
-			Bugs: ProtocolBugs{
-				FailIfCECPQ2Offered: true,
-			},
-		},
-		flags: []string{
-			"-max-version", strconv.Itoa(VersionTLS12),
-			"-curves", strconv.Itoa(int(CurveCECPQ2b)),
-			"-curves", strconv.Itoa(int(CurveX25519)),
-		},
-	})
-
 	// CECPQ2 should not crash a TLS < 1.3 client if the server mistakenly
 	// selects it.
 	testCases = append(testCases, testCase{
@@ -10961,24 +10945,6 @@
 		expectedError: ":WRONG_CURVE:",
 	})
 
-	// CECPQ2b should not crash a TLS < 1.3 client if the server mistakenly
-	// selects it.
-	testCases = append(testCases, testCase{
-		name: "CECPQ2bNotAcceptedByTLS12Client",
-		config: Config{
-			Bugs: ProtocolBugs{
-				SendCurve: CurveCECPQ2b,
-			},
-		},
-		flags: []string{
-			"-max-version", strconv.Itoa(VersionTLS12),
-			"-curves", strconv.Itoa(int(CurveCECPQ2b)),
-			"-curves", strconv.Itoa(int(CurveX25519)),
-		},
-		shouldFail:    true,
-		expectedError: ":WRONG_CURVE:",
-	})
-
 	// CECPQ2 should not be offered by default as a client.
 	testCases = append(testCases, testCase{
 		name: "CECPQ2NotEnabledByDefaultInClients",
@@ -10990,17 +10956,6 @@
 		},
 	})
 
-	// CECPQ2b should not be offered by default as a client.
-	testCases = append(testCases, testCase{
-		name: "CECPQ2bNotEnabledByDefaultInClients",
-		config: Config{
-			MinVersion: VersionTLS13,
-			Bugs: ProtocolBugs{
-				FailIfCECPQ2Offered: true,
-			},
-		},
-	})
-
 	// If CECPQ2 is offered, both X25519 and CECPQ2 should have a key-share.
 	testCases = append(testCases, testCase{
 		name: "NotJustCECPQ2KeyShare",
@@ -11033,38 +10988,6 @@
 		},
 	})
 
-	// If CECPQ2b is offered, both X25519 and CECPQ2b should have a key-share.
-	testCases = append(testCases, testCase{
-		name: "NotJustCECPQ2bKeyShare",
-		config: Config{
-			MinVersion: VersionTLS13,
-			Bugs: ProtocolBugs{
-				ExpectedKeyShares: []CurveID{CurveCECPQ2b, CurveX25519},
-			},
-		},
-		flags: []string{
-			"-curves", strconv.Itoa(int(CurveCECPQ2b)),
-			"-curves", strconv.Itoa(int(CurveX25519)),
-			"-expect-curve-id", strconv.Itoa(int(CurveCECPQ2b)),
-		},
-	})
-
-	// ... but only if CECPQ2b is listed first.
-	testCases = append(testCases, testCase{
-		name: "CECPQ2bKeyShareNotIncludedSecond",
-		config: Config{
-			MinVersion: VersionTLS13,
-			Bugs: ProtocolBugs{
-				ExpectedKeyShares: []CurveID{CurveX25519},
-			},
-		},
-		flags: []string{
-			"-curves", strconv.Itoa(int(CurveX25519)),
-			"-curves", strconv.Itoa(int(CurveCECPQ2b)),
-			"-expect-curve-id", strconv.Itoa(int(CurveX25519)),
-		},
-	})
-
 	// If CECPQ2 is the only configured curve, the key share is sent.
 	testCases = append(testCases, testCase{
 		name: "JustConfiguringCECPQ2Works",
@@ -11080,21 +11003,6 @@
 		},
 	})
 
-	// If CECPQ2b is the only configured curve, the key share is sent.
-	testCases = append(testCases, testCase{
-		name: "JustConfiguringCECPQ2bWorks",
-		config: Config{
-			MinVersion: VersionTLS13,
-			Bugs: ProtocolBugs{
-				ExpectedKeyShares: []CurveID{CurveCECPQ2b},
-			},
-		},
-		flags: []string{
-			"-curves", strconv.Itoa(int(CurveCECPQ2b)),
-			"-expect-curve-id", strconv.Itoa(int(CurveCECPQ2b)),
-		},
-	})
-
 	// As a server, CECPQ2 is not yet supported by default.
 	testCases = append(testCases, testCase{
 		testType: serverTest,
@@ -11109,21 +11017,6 @@
 			"-expect-curve-id", strconv.Itoa(int(CurveX25519)),
 		},
 	})
-
-	// As a server, CECPQ2b is not yet supported by default.
-	testCases = append(testCases, testCase{
-		testType: serverTest,
-		name:     "CECPQ2bNotEnabledByDefaultForAServer",
-		config: Config{
-			MinVersion:       VersionTLS13,
-			CurvePreferences: []CurveID{CurveCECPQ2b, CurveX25519},
-			DefaultCurves:    []CurveID{CurveCECPQ2b},
-		},
-		flags: []string{
-			"-server-preference",
-			"-expect-curve-id", strconv.Itoa(int(CurveX25519)),
-		},
-	})
 }
 
 func addTLS13RecordTests() {
@@ -14049,21 +13942,6 @@
 		},
 	})
 
-	// CECPQ2b prefers 256-bit ciphers but will use AES-128 if there's nothing else.
-	testCases = append(testCases, testCase{
-		testType: serverTest,
-		name:     "TLS13-CipherPreference-CECPQ2b-AES128Only",
-		config: Config{
-			MaxVersion: VersionTLS13,
-			CipherSuites: []uint16{
-				TLS_AES_128_GCM_SHA256,
-			},
-		},
-		flags: []string{
-			"-curves", strconv.Itoa(int(CurveCECPQ2b)),
-		},
-	})
-
 	// When a 256-bit cipher is offered, even if not in first place, it should be
 	// picked.
 	testCases = append(testCases, testCase{
@@ -14098,40 +13976,6 @@
 		expectedCipher: TLS_AES_128_GCM_SHA256,
 	})
 
-	// When a 256-bit cipher is offered, even if not in first place, it should be
-	// picked.
-	testCases = append(testCases, testCase{
-		testType: serverTest,
-		name:     "TLS13-CipherPreference-CECPQ2b-AES256Preferred",
-		config: Config{
-			MaxVersion: VersionTLS13,
-			CipherSuites: []uint16{
-				TLS_AES_128_GCM_SHA256,
-				TLS_AES_256_GCM_SHA384,
-			},
-		},
-		flags: []string{
-			"-curves", strconv.Itoa(int(CurveCECPQ2b)),
-		},
-		expectedCipher: TLS_AES_256_GCM_SHA384,
-	})
-	// ... but when CECPQ2b isn't being used, the client's preference controls.
-	testCases = append(testCases, testCase{
-		testType: serverTest,
-		name:     "TLS13-CipherPreference-CECPQ2b-AES128PreferredOtherwise",
-		config: Config{
-			MaxVersion: VersionTLS13,
-			CipherSuites: []uint16{
-				TLS_AES_128_GCM_SHA256,
-				TLS_AES_256_GCM_SHA384,
-			},
-		},
-		flags: []string{
-			"-curves", strconv.Itoa(int(CurveX25519)),
-		},
-		expectedCipher: TLS_AES_128_GCM_SHA256,
-	})
-
 	// Test that CECPQ2 continues to honor AES vs ChaCha20 logic.
 	testCases = append(testCases, testCase{
 		testType: serverTest,
@@ -14167,42 +14011,6 @@
 			"-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
 		},
 	})
-
-	// Test that CECPQ2b continues to honor AES vs ChaCha20 logic.
-	testCases = append(testCases, testCase{
-		testType: serverTest,
-		name:     "TLS13-CipherPreference-CECPQ2b-AES128-ChaCha20-AES256",
-		config: Config{
-			MaxVersion: VersionTLS13,
-			CipherSuites: []uint16{
-				TLS_AES_128_GCM_SHA256,
-				TLS_CHACHA20_POLY1305_SHA256,
-				TLS_AES_256_GCM_SHA384,
-			},
-		},
-		flags: []string{
-			"-curves", strconv.Itoa(int(CurveCECPQ2b)),
-			"-expect-cipher-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
-			"-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
-		},
-	})
-	testCases = append(testCases, testCase{
-		testType: serverTest,
-		name:     "TLS13-CipherPreference-CECPQ2b-AES128-AES256-ChaCha20",
-		config: Config{
-			MaxVersion: VersionTLS13,
-			CipherSuites: []uint16{
-				TLS_AES_128_GCM_SHA256,
-				TLS_AES_256_GCM_SHA384,
-				TLS_CHACHA20_POLY1305_SHA256,
-			},
-		},
-		flags: []string{
-			"-curves", strconv.Itoa(int(CurveCECPQ2b)),
-			"-expect-cipher-aes", strconv.Itoa(int(TLS_AES_256_GCM_SHA384)),
-			"-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
-		},
-	})
 }
 
 func addPeekTests() {
diff --git a/ssl/test/runner/sike/arith.go b/ssl/test/runner/sike/arith.go
deleted file mode 100644
index 10a2ca6..0000000
--- a/ssl/test/runner/sike/arith.go
+++ /dev/null
@@ -1,374 +0,0 @@
-// Copyright (c) 2019, Cloudflare 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.
-
-package sike
-
-import (
-	"math/bits"
-)
-
-// Compute z = x + y (mod 2*p).
-func fpAddRdc(z, x, y *Fp) {
-	var carry uint64
-
-	// z=x+y % p
-	for i := 0; i < FP_WORDS; i++ {
-		z[i], carry = bits.Add64(x[i], y[i], carry)
-	}
-
-	// z = z - pX2
-	carry = 0
-	for i := 0; i < FP_WORDS; i++ {
-		z[i], carry = bits.Sub64(z[i], pX2[i], carry)
-	}
-
-	// if z<0 add pX2 back
-	mask := uint64(0 - carry)
-	carry = 0
-	for i := 0; i < FP_WORDS; i++ {
-		z[i], carry = bits.Add64(z[i], pX2[i]&mask, carry)
-	}
-}
-
-// Compute z = x - y (mod 2*p).
-func fpSubRdc(z, x, y *Fp) {
-	var borrow uint64
-
-	// z = z - pX2
-	for i := 0; i < FP_WORDS; i++ {
-		z[i], borrow = bits.Sub64(x[i], y[i], borrow)
-	}
-
-	// if z<0 add pX2 back
-	mask := uint64(0 - borrow)
-	borrow = 0
-	for i := 0; i < FP_WORDS; i++ {
-		z[i], borrow = bits.Add64(z[i], pX2[i]&mask, borrow)
-	}
-}
-
-// Reduce a field element in [0, 2*p) to one in [0,p).
-func fpRdcP(x *Fp) {
-	var borrow, mask uint64
-	for i := 0; i < FP_WORDS; i++ {
-		x[i], borrow = bits.Sub64(x[i], p[i], borrow)
-	}
-
-	// Sets all bits if borrow = 1
-	mask = 0 - borrow
-	borrow = 0
-	for i := 0; i < FP_WORDS; i++ {
-		x[i], borrow = bits.Add64(x[i], p[i]&mask, borrow)
-	}
-}
-
-// Implementation doesn't actually depend on a prime field.
-func fpSwapCond(x, y *Fp, mask uint8) {
-	if mask != 0 {
-		var tmp Fp
-		copy(tmp[:], y[:])
-		copy(y[:], x[:])
-		copy(x[:], tmp[:])
-	}
-}
-
-// Compute z = x * y.
-func fpMul(z *FpX2, x, y *Fp) {
-	var carry, t, u, v uint64
-	var hi, lo uint64
-
-	for i := uint64(0); i < FP_WORDS; i++ {
-		for j := uint64(0); j <= i; j++ {
-			hi, lo = bits.Mul64(x[j], y[i-j])
-			v, carry = bits.Add64(lo, v, 0)
-			u, carry = bits.Add64(hi, u, carry)
-			t += carry
-		}
-		z[i] = v
-		v = u
-		u = t
-		t = 0
-	}
-
-	for i := FP_WORDS; i < (2*FP_WORDS)-1; i++ {
-		for j := i - FP_WORDS + 1; j < FP_WORDS; j++ {
-			hi, lo = bits.Mul64(x[j], y[i-j])
-			v, carry = bits.Add64(lo, v, 0)
-			u, carry = bits.Add64(hi, u, carry)
-			t += carry
-		}
-		z[i] = v
-		v = u
-		u = t
-		t = 0
-	}
-	z[2*FP_WORDS-1] = v
-}
-
-// Perform Montgomery reduction: set z = x R^{-1} (mod 2*p)
-// with R=2^512. Destroys the input value.
-func fpMontRdc(z *Fp, x *FpX2) {
-	var carry, t, u, v uint64
-	var hi, lo uint64
-	var count int
-
-	count = 3 // number of 0 digits in the least significat part of p + 1
-
-	for i := 0; i < FP_WORDS; i++ {
-		for j := 0; j < i; j++ {
-			if j < (i - count + 1) {
-				hi, lo = bits.Mul64(z[j], p1[i-j])
-				v, carry = bits.Add64(lo, v, 0)
-				u, carry = bits.Add64(hi, u, carry)
-				t += carry
-			}
-		}
-		v, carry = bits.Add64(v, x[i], 0)
-		u, carry = bits.Add64(u, 0, carry)
-		t += carry
-
-		z[i] = v
-		v = u
-		u = t
-		t = 0
-	}
-
-	for i := FP_WORDS; i < 2*FP_WORDS-1; i++ {
-		if count > 0 {
-			count--
-		}
-		for j := i - FP_WORDS + 1; j < FP_WORDS; j++ {
-			if j < (FP_WORDS - count) {
-				hi, lo = bits.Mul64(z[j], p1[i-j])
-				v, carry = bits.Add64(lo, v, 0)
-				u, carry = bits.Add64(hi, u, carry)
-				t += carry
-			}
-		}
-		v, carry = bits.Add64(v, x[i], 0)
-		u, carry = bits.Add64(u, 0, carry)
-
-		t += carry
-		z[i-FP_WORDS] = v
-		v = u
-		u = t
-		t = 0
-	}
-	v, carry = bits.Add64(v, x[2*FP_WORDS-1], 0)
-	z[FP_WORDS-1] = v
-}
-
-// Compute z = x + y, without reducing mod p.
-func fp2Add(z, x, y *FpX2) {
-	var carry uint64
-	for i := 0; i < 2*FP_WORDS; i++ {
-		z[i], carry = bits.Add64(x[i], y[i], carry)
-	}
-}
-
-// Compute z = x - y, without reducing mod p.
-func fp2Sub(z, x, y *FpX2) {
-	var borrow, mask uint64
-	for i := 0; i < 2*FP_WORDS; i++ {
-		z[i], borrow = bits.Sub64(x[i], y[i], borrow)
-	}
-
-	// Sets all bits if borrow = 1
-	mask = 0 - borrow
-	borrow = 0
-	for i := FP_WORDS; i < 2*FP_WORDS; i++ {
-		z[i], borrow = bits.Add64(z[i], p[i-FP_WORDS]&mask, borrow)
-	}
-}
-
-// Montgomery multiplication. Input values must be already
-// in Montgomery domain.
-func fpMulRdc(dest, lhs, rhs *Fp) {
-	a := lhs // = a*R
-	b := rhs // = b*R
-
-	var ab FpX2
-	fpMul(&ab, a, b)     // = a*b*R*R
-	fpMontRdc(dest, &ab) // = a*b*R mod p
-}
-
-// Set dest = x^((p-3)/4).  If x is square, this is 1/sqrt(x).
-// Uses variation of sliding-window algorithm from with window size
-// of 5 and least to most significant bit sliding (left-to-right)
-// See HAC 14.85 for general description.
-//
-// Allowed to overlap x with dest.
-// All values in Montgomery domains
-// Set dest = x^(2^k), for k >= 1, by repeated squarings.
-func p34(dest, x *Fp) {
-	var lookup [16]Fp
-
-	// This performs sum(powStrategy) + 1 squarings and len(lookup) + len(mulStrategy)
-	// multiplications.
-	powStrategy := []uint8{
-		0x03, 0x0A, 0x07, 0x05, 0x06, 0x05, 0x03, 0x08, 0x04, 0x07,
-		0x05, 0x06, 0x04, 0x05, 0x09, 0x06, 0x03, 0x0B, 0x05, 0x05,
-		0x02, 0x08, 0x04, 0x07, 0x07, 0x08, 0x05, 0x06, 0x04, 0x08,
-		0x05, 0x02, 0x0A, 0x06, 0x05, 0x04, 0x08, 0x05, 0x05, 0x05,
-		0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-		0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-		0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-		0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x01}
-	mulStrategy := []uint8{
-		0x02, 0x0F, 0x09, 0x08, 0x0E, 0x0C, 0x02, 0x08, 0x05, 0x0F,
-		0x08, 0x0F, 0x06, 0x06, 0x03, 0x02, 0x00, 0x0A, 0x09, 0x0D,
-		0x01, 0x0C, 0x03, 0x07, 0x01, 0x0A, 0x08, 0x0B, 0x02, 0x0F,
-		0x0E, 0x01, 0x0B, 0x0C, 0x0E, 0x03, 0x0B, 0x0F, 0x0F, 0x0F,
-		0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
-		0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
-		0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
-		0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00}
-	initialMul := uint8(8)
-
-	// Precompute lookup table of odd multiples of x for window
-	// size k=5.
-	var xx Fp
-	fpMulRdc(&xx, x, x)
-	lookup[0] = *x
-	for i := 1; i < 16; i++ {
-		fpMulRdc(&lookup[i], &lookup[i-1], &xx)
-	}
-
-	// Now lookup = {x, x^3, x^5, ... }
-	// so that lookup[i] = x^{2*i + 1}
-	// so that lookup[k/2] = x^k, for odd k
-	*dest = lookup[initialMul]
-	for i := uint8(0); i < uint8(len(powStrategy)); i++ {
-		fpMulRdc(dest, dest, dest)
-		for j := uint8(1); j < powStrategy[i]; j++ {
-			fpMulRdc(dest, dest, dest)
-		}
-		fpMulRdc(dest, dest, &lookup[mulStrategy[i]])
-	}
-}
-
-func add(dest, lhs, rhs *Fp2) {
-	fpAddRdc(&dest.A, &lhs.A, &rhs.A)
-	fpAddRdc(&dest.B, &lhs.B, &rhs.B)
-}
-
-func sub(dest, lhs, rhs *Fp2) {
-	fpSubRdc(&dest.A, &lhs.A, &rhs.A)
-	fpSubRdc(&dest.B, &lhs.B, &rhs.B)
-}
-
-func mul(dest, lhs, rhs *Fp2) {
-	// Let (a,b,c,d) = (lhs.a,lhs.b,rhs.a,rhs.b).
-	a := &lhs.A
-	b := &lhs.B
-	c := &rhs.A
-	d := &rhs.B
-
-	// We want to compute
-	//
-	// (a + bi)*(c + di) = (a*c - b*d) + (a*d + b*c)i
-	//
-	// Use Karatsuba's trick: note that
-	//
-	// (b - a)*(c - d) = (b*c + a*d) - a*c - b*d
-	//
-	// so (a*d + b*c) = (b-a)*(c-d) + a*c + b*d.
-
-	var ac, bd FpX2
-	fpMul(&ac, a, c) // = a*c*R*R
-	fpMul(&bd, b, d) // = b*d*R*R
-
-	var b_minus_a, c_minus_d Fp
-	fpSubRdc(&b_minus_a, b, a) // = (b-a)*R
-	fpSubRdc(&c_minus_d, c, d) // = (c-d)*R
-
-	var ad_plus_bc FpX2
-	fpMul(&ad_plus_bc, &b_minus_a, &c_minus_d) // = (b-a)*(c-d)*R*R
-	fp2Add(&ad_plus_bc, &ad_plus_bc, &ac)      // = ((b-a)*(c-d) + a*c)*R*R
-	fp2Add(&ad_plus_bc, &ad_plus_bc, &bd)      // = ((b-a)*(c-d) + a*c + b*d)*R*R
-
-	fpMontRdc(&dest.B, &ad_plus_bc) // = (a*d + b*c)*R mod p
-
-	var ac_minus_bd FpX2
-	fp2Sub(&ac_minus_bd, &ac, &bd)   // = (a*c - b*d)*R*R
-	fpMontRdc(&dest.A, &ac_minus_bd) // = (a*c - b*d)*R mod p
-}
-
-func inv(dest, x *Fp2) {
-	var a2PlusB2 Fp
-	var asq, bsq FpX2
-	var ac FpX2
-	var minusB Fp
-	var minusBC FpX2
-
-	a := &x.A
-	b := &x.B
-
-	// We want to compute
-	//
-	//    1          1     (a - bi)	    (a - bi)
-	// -------- = -------- -------- = -----------
-	// (a + bi)   (a + bi) (a - bi)   (a^2 + b^2)
-	//
-	// Letting c = 1/(a^2 + b^2), this is
-	//
-	// 1/(a+bi) = a*c - b*ci.
-
-	fpMul(&asq, a, a)          // = a*a*R*R
-	fpMul(&bsq, b, b)          // = b*b*R*R
-	fp2Add(&asq, &asq, &bsq)   // = (a^2 + b^2)*R*R
-	fpMontRdc(&a2PlusB2, &asq) // = (a^2 + b^2)*R mod p
-	// Now a2PlusB2 = a^2 + b^2
-
-	inv := a2PlusB2
-	fpMulRdc(&inv, &a2PlusB2, &a2PlusB2)
-	p34(&inv, &inv)
-	fpMulRdc(&inv, &inv, &inv)
-	fpMulRdc(&inv, &inv, &a2PlusB2)
-
-	fpMul(&ac, a, &inv)
-	fpMontRdc(&dest.A, &ac)
-
-	fpSubRdc(&minusB, &minusB, b)
-	fpMul(&minusBC, &minusB, &inv)
-	fpMontRdc(&dest.B, &minusBC)
-}
-
-func sqr(dest, x *Fp2) {
-	var a2, aPlusB, aMinusB Fp
-	var a2MinB2, ab2 FpX2
-
-	a := &x.A
-	b := &x.B
-
-	// (a + bi)*(a + bi) = (a^2 - b^2) + 2abi.
-	fpAddRdc(&a2, a, a)                // = a*R + a*R = 2*a*R
-	fpAddRdc(&aPlusB, a, b)            // = a*R + b*R = (a+b)*R
-	fpSubRdc(&aMinusB, a, b)           // = a*R - b*R = (a-b)*R
-	fpMul(&a2MinB2, &aPlusB, &aMinusB) // = (a+b)*(a-b)*R*R = (a^2 - b^2)*R*R
-	fpMul(&ab2, &a2, b)                // = 2*a*b*R*R
-	fpMontRdc(&dest.A, &a2MinB2)       // = (a^2 - b^2)*R mod p
-	fpMontRdc(&dest.B, &ab2)           // = 2*a*b*R mod p
-}
-
-// In case choice == 1, performs following swap in constant time:
-// 	xPx <-> xQx
-//	xPz <-> xQz
-// Otherwise returns xPx, xPz, xQx, xQz unchanged
-func condSwap(xPx, xPz, xQx, xQz *Fp2, choice uint8) {
-	fpSwapCond(&xPx.A, &xQx.A, choice)
-	fpSwapCond(&xPx.B, &xQx.B, choice)
-	fpSwapCond(&xPz.A, &xQz.A, choice)
-	fpSwapCond(&xPz.B, &xQz.B, choice)
-}
diff --git a/ssl/test/runner/sike/consts.go b/ssl/test/runner/sike/consts.go
deleted file mode 100644
index 9d68a4f..0000000
--- a/ssl/test/runner/sike/consts.go
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright (c) 2019, Cloudflare 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.
-
-package sike
-
-// I keep it bool in order to be able to apply logical NOT
-type KeyVariant uint
-
-// Representation of an element of the base field F_p.
-//
-// No particular meaning is assigned to the representation -- it could represent
-// an element in Montgomery form, or not.  Tracking the meaning of the field
-// element is left to higher types.
-type Fp [FP_WORDS]uint64
-
-// Represents an intermediate product of two elements of the base field F_p.
-type FpX2 [2 * FP_WORDS]uint64
-
-// Represents an element of the extended field Fp^2 = Fp(x+i)
-type Fp2 struct {
-	A Fp
-	B Fp
-}
-
-type DomainParams struct {
-	// P, Q and R=P-Q base points
-	Affine_P, Affine_Q, Affine_R Fp2
-	// Size of a compuatation strategy for x-torsion group
-	IsogenyStrategy []uint32
-	// Max size of secret key for x-torsion group
-	SecretBitLen uint
-	// Max size of secret key for x-torsion group
-	SecretByteLen uint
-}
-
-type SidhParams struct {
-	Id uint8
-	// Bytelen of P
-	Bytelen int
-	// The public key size, in bytes.
-	PublicKeySize int
-	// The shared secret size, in bytes.
-	SharedSecretSize int
-	// Defines A,C constant for starting curve Cy^2 = x^3 + Ax^2 + x
-	InitCurve ProjectiveCurveParameters
-	// 2- and 3-torsion group parameter definitions
-	A, B DomainParams
-	// Precomputed 1/2 in the Fp2 in Montgomery domain
-	HalfFp2 Fp2
-	// Precomputed identity element in the Fp2 in Montgomery domain
-	OneFp2 Fp2
-	// Length of SIKE secret message. Must be one of {24,32,40},
-	// depending on size of prime field used (see [SIKE], 1.4 and 5.1)
-	MsgLen int
-	// Length of SIKE ephemeral KEM key (see [SIKE], 1.4 and 5.1)
-	KemSize int
-	// Size of a ciphertext returned by encapsulation in bytes
-	CiphertextSize int
-}
-
-// Stores curve projective parameters equivalent to A/C. Meaning of the
-// values depends on the context. When working with isogenies over
-// subgroup that are powers of:
-// * three then  (A:C) ~ (A+2C:A-2C)
-// * four then   (A:C) ~ (A+2C:  4C)
-// See Appendix A of SIKE for more details
-type CurveCoefficientsEquiv struct {
-	A Fp2
-	C Fp2
-}
-
-// A point on the projective line P^1(F_{p^2}).
-//
-// This represents a point on the Kummer line of a Montgomery curve.  The
-// curve is specified by a ProjectiveCurveParameters struct.
-type ProjectivePoint struct {
-	X Fp2
-	Z Fp2
-}
-
-// Base type for public and private key. Used mainly to carry domain
-// parameters.
-type key struct {
-	// Domain parameters of the algorithm to be used with a key
-	params *SidhParams
-	// Flag indicates whether corresponds to 2-, 3-torsion group or SIKE
-	keyVariant KeyVariant
-}
-
-// Defines operations on private key
-type PrivateKey struct {
-	key
-	// Secret key
-	Scalar []byte
-	// Used only by KEM
-	S []byte
-}
-
-// Defines operations on public key
-type PublicKey struct {
-	key
-	affine_xP   Fp2
-	affine_xQ   Fp2
-	affine_xQmP Fp2
-}
-
-// A point on the projective line P^1(F_{p^2}).
-//
-// This is used to work projectively with the curve coefficients.
-type ProjectiveCurveParameters struct {
-	A Fp2
-	C Fp2
-}
-
-const (
-	// First 2 bits identify SIDH variant third bit indicates
-	// whether key is a SIKE variant (set) or SIDH (not set)
-
-	// 001 - SIDH: corresponds to 2-torsion group
-	KeyVariant_SIDH_A KeyVariant = 1 << 0
-	// 010 - SIDH: corresponds to 3-torsion group
-	KeyVariant_SIDH_B = 1 << 1
-	// 110 - SIKE
-	KeyVariant_SIKE = 1<<2 | KeyVariant_SIDH_B
-	// Number of uint64 limbs used to store field element
-	FP_WORDS = 7
-)
-
-// Used internally by this package
-// -------------------------------
-
-var (
-	p = Fp{
-		0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFDC1767AE2FFFFFF,
-		0x7BC65C783158AEA3, 0x6CFC5FD681C52056, 0x2341F27177344,
-	}
-
-	// 2*p434
-	pX2 = Fp{
-		0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFB82ECF5C5FFFFFF,
-		0xF78CB8F062B15D47, 0xD9F8BFAD038A40AC, 0x4683E4E2EE688,
-	}
-
-	// p434 + 1
-	p1 = Fp{
-		0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFDC1767AE3000000,
-		0x7BC65C783158AEA3, 0x6CFC5FD681C52056, 0x0002341F27177344,
-	}
-
-	// R^2=(2^448)^2 mod p
-	R2 = Fp{
-		0x28E55B65DCD69B30, 0xACEC7367768798C2, 0xAB27973F8311688D, 0x175CC6AF8D6C7C0B,
-		0xABCD92BF2DDE347E, 0x69E16A61C7686D9A, 0x000025A89BCDD12A,
-	}
-
-	// 1/2 * R mod p
-	half = Fp2{
-		A: Fp{
-			0x0000000000003A16, 0x0000000000000000, 0x0000000000000000, 0x5C87FA027E000000,
-			0x6C00D27DAACFD66A, 0x74992A2A2FBBA086, 0x0000767753DE976D},
-	}
-
-	// 1*R mod p
-	one = Fp2{
-		A: Fp{
-			0x000000000000742C, 0x0000000000000000, 0x0000000000000000, 0xB90FF404FC000000,
-			0xD801A4FB559FACD4, 0xE93254545F77410C, 0x0000ECEEA7BD2EDA},
-	}
-
-	// 6*R mod p
-	six = Fp2{
-		A: Fp{
-			0x000000000002B90A, 0x0000000000000000, 0x0000000000000000, 0x5ADCCB2822000000,
-			0x187D24F39F0CAFB4, 0x9D353A4D394145A0, 0x00012559A0403298},
-	}
-
-	Params SidhParams
-)
-
-func init() {
-	Params = SidhParams{
-		// SIDH public key byte size.
-		PublicKeySize: 330,
-		// SIDH shared secret byte size.
-		SharedSecretSize: 110,
-		InitCurve: ProjectiveCurveParameters{
-			A: six,
-			C: one,
-		},
-		A: DomainParams{
-			// The x-coordinate of PA
-			Affine_P: Fp2{
-				A: Fp{
-					0x05ADF455C5C345BF, 0x91935C5CC767AC2B, 0xAFE4E879951F0257, 0x70E792DC89FA27B1,
-					0xF797F526BB48C8CD, 0x2181DB6131AF621F, 0x00000A1C08B1ECC4,
-				},
-				B: Fp{
-					0x74840EB87CDA7788, 0x2971AA0ECF9F9D0B, 0xCB5732BDF41715D5, 0x8CD8E51F7AACFFAA,
-					0xA7F424730D7E419F, 0xD671EB919A179E8C, 0x0000FFA26C5A924A,
-				},
-			},
-			// The x-coordinate of QA
-			Affine_Q: Fp2{
-				A: Fp{
-					0xFEC6E64588B7273B, 0xD2A626D74CBBF1C6, 0xF8F58F07A78098C7, 0xE23941F470841B03,
-					0x1B63EDA2045538DD, 0x735CFEB0FFD49215, 0x0001C4CB77542876,
-				},
-				B: Fp{
-					0xADB0F733C17FFDD6, 0x6AFFBD037DA0A050, 0x680EC43DB144E02F, 0x1E2E5D5FF524E374,
-					0xE2DDA115260E2995, 0xA6E4B552E2EDE508, 0x00018ECCDDF4B53E,
-				},
-			},
-			// The x-coordinate of RA = PA-QA
-			Affine_R: Fp2{
-				A: Fp{
-					0x01BA4DB518CD6C7D, 0x2CB0251FE3CC0611, 0x259B0C6949A9121B, 0x60E17AC16D2F82AD,
-					0x3AA41F1CE175D92D, 0x413FBE6A9B9BC4F3, 0x00022A81D8D55643,
-				},
-				B: Fp{
-					0xB8ADBC70FC82E54A, 0xEF9CDDB0D5FADDED, 0x5820C734C80096A0, 0x7799994BAA96E0E4,
-					0x044961599E379AF8, 0xDB2B94FBF09F27E2, 0x0000B87FC716C0C6,
-				},
-			},
-			// Max size of secret key for 2-torsion group, corresponds to 2^e2 - 1
-			SecretBitLen: 216,
-			// SecretBitLen in bytes.
-			SecretByteLen: 27,
-			// 2-torsion group computation strategy
-			IsogenyStrategy: []uint32{
-				0x30, 0x1C, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01,
-				0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x08, 0x04,
-				0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01,
-				0x02, 0x01, 0x01, 0x0D, 0x07, 0x04, 0x02, 0x01, 0x01, 0x02,
-				0x01, 0x01, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x05, 0x04,
-				0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
-				0x15, 0x0C, 0x07, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01,
-				0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x05, 0x03, 0x02, 0x01,
-				0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x09, 0x05, 0x03,
-				0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x04,
-				0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01},
-		},
-		B: DomainParams{
-			// The x-coordinate of PB
-			Affine_P: Fp2{
-				A: Fp{
-					0x6E5497556EDD48A3, 0x2A61B501546F1C05, 0xEB919446D049887D, 0x5864A4A69D450C4F,
-					0xB883F276A6490D2B, 0x22CC287022D5F5B9, 0x0001BED4772E551F,
-				},
-				B: Fp{
-					0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
-					0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
-				},
-			},
-			// The x-coordinate of QB
-			Affine_Q: Fp2{
-				A: Fp{
-					0xFAE2A3F93D8B6B8E, 0x494871F51700FE1C, 0xEF1A94228413C27C, 0x498FF4A4AF60BD62,
-					0xB00AD2A708267E8A, 0xF4328294E017837F, 0x000034080181D8AE,
-				},
-				B: Fp{
-					0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
-					0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
-				},
-			},
-			// The x-coordinate of RB = PB - QB
-			Affine_R: Fp2{
-				A: Fp{
-					0x283B34FAFEFDC8E4, 0x9208F44977C3E647, 0x7DEAE962816F4E9A, 0x68A2BA8AA262EC9D,
-					0x8176F112EA43F45B, 0x02106D022634F504, 0x00007E8A50F02E37,
-				},
-				B: Fp{
-					0xB378B7C1DA22CCB1, 0x6D089C99AD1D9230, 0xEBE15711813E2369, 0x2B35A68239D48A53,
-					0x445F6FD138407C93, 0xBEF93B29A3F6B54B, 0x000173FA910377D3,
-				},
-			},
-			// Size of secret key for 3-torsion group, corresponds to log_2(3^e3) - 1.
-			SecretBitLen: 217,
-			// SecretBitLen in bytes.
-			SecretByteLen: 28,
-			// 3-torsion group computation strategy
-			IsogenyStrategy: []uint32{
-				0x42, 0x21, 0x11, 0x09, 0x05, 0x03, 0x02, 0x01, 0x01, 0x01,
-				0x01, 0x02, 0x01, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x01,
-				0x02, 0x01, 0x01, 0x08, 0x04, 0x02, 0x01, 0x01, 0x01, 0x02,
-				0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x10,
-				0x08, 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04,
-				0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x08, 0x04, 0x02, 0x01,
-				0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01,
-				0x01, 0x20, 0x10, 0x08, 0x04, 0x03, 0x01, 0x01, 0x01, 0x01,
-				0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01,
-				0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02,
-				0x01, 0x01, 0x02, 0x01, 0x01, 0x10, 0x08, 0x04, 0x02, 0x01,
-				0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01,
-				0x01, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04,
-				0x02, 0x01, 0x01, 0x02, 0x01, 0x01},
-		},
-		OneFp2:  one,
-		HalfFp2: half,
-		MsgLen:  16,
-		// SIKEp434 provides 128 bit of classical security ([SIKE], 5.1)
-		KemSize: 16,
-		// ceil(434+7/8)
-		Bytelen:        55,
-		CiphertextSize: 16 + 330,
-	}
-}
diff --git a/ssl/test/runner/sike/curve.go b/ssl/test/runner/sike/curve.go
deleted file mode 100644
index 8172546..0000000
--- a/ssl/test/runner/sike/curve.go
+++ /dev/null
@@ -1,422 +0,0 @@
-// Copyright (c) 2019, Cloudflare 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.
-
-package sike
-
-// Interface for working with isogenies.
-type isogeny interface {
-	// Given a torsion point on a curve computes isogenous curve.
-	// Returns curve coefficients (A:C), so that E_(A/C) = E_(A/C)/<P>,
-	// where P is a provided projective point. Sets also isogeny constants
-	// that are needed for isogeny evaluation.
-	GenerateCurve(*ProjectivePoint) CurveCoefficientsEquiv
-	// Evaluates isogeny at caller provided point. Requires isogeny curve constants
-	// to be earlier computed by GenerateCurve.
-	EvaluatePoint(*ProjectivePoint) ProjectivePoint
-}
-
-// Stores isogeny 3 curve constants
-type isogeny3 struct {
-	K1 Fp2
-	K2 Fp2
-}
-
-// Stores isogeny 4 curve constants
-type isogeny4 struct {
-	isogeny3
-	K3 Fp2
-}
-
-// Constructs isogeny3 objects
-func NewIsogeny3() isogeny {
-	return &isogeny3{}
-}
-
-// Constructs isogeny4 objects
-func NewIsogeny4() isogeny {
-	return &isogeny4{}
-}
-
-// Helper function for RightToLeftLadder(). Returns A+2C / 4.
-func calcAplus2Over4(cparams *ProjectiveCurveParameters) (ret Fp2) {
-	var tmp Fp2
-
-	// 2C
-	add(&tmp, &cparams.C, &cparams.C)
-	// A+2C
-	add(&ret, &cparams.A, &tmp)
-	// 1/4C
-	add(&tmp, &tmp, &tmp)
-	inv(&tmp, &tmp)
-	// A+2C/4C
-	mul(&ret, &ret, &tmp)
-	return
-}
-
-// Converts values in x.A and x.B to Montgomery domain
-// x.A = x.A * R mod p
-// x.B = x.B * R mod p
-// Performs v = v*R^2*R^(-1) mod p, for both x.A and x.B
-func toMontDomain(x *Fp2) {
-	var aRR FpX2
-
-	// convert to montgomery domain
-	fpMul(&aRR, &x.A, &R2) // = a*R*R
-	fpMontRdc(&x.A, &aRR)  // = a*R mod p
-	fpMul(&aRR, &x.B, &R2)
-	fpMontRdc(&x.B, &aRR)
-}
-
-// Converts values in x.A and x.B from Montgomery domain
-// a = x.A mod p
-// b = x.B mod p
-//
-// After returning from the call x is not modified.
-func fromMontDomain(x *Fp2, out *Fp2) {
-	var aR FpX2
-
-	// convert from montgomery domain
-	copy(aR[:], x.A[:])
-	fpMontRdc(&out.A, &aR) // = a mod p in [0, 2p)
-	fpRdcP(&out.A)         // = a mod p in [0, p)
-	for i := range aR {
-		aR[i] = 0
-	}
-	copy(aR[:], x.B[:])
-	fpMontRdc(&out.B, &aR)
-	fpRdcP(&out.B)
-}
-
-// Computes j-invariant for a curve y2=x3+A/Cx+x with A,C in F_(p^2). Result
-// is returned in 'j'. Implementation corresponds to Algorithm 9 from SIKE.
-func Jinvariant(cparams *ProjectiveCurveParameters, j *Fp2) {
-	var t0, t1 Fp2
-
-	sqr(j, &cparams.A)   // j  = A^2
-	sqr(&t1, &cparams.C) // t1 = C^2
-	add(&t0, &t1, &t1)   // t0 = t1 + t1
-	sub(&t0, j, &t0)     // t0 = j - t0
-	sub(&t0, &t0, &t1)   // t0 = t0 - t1
-	sub(j, &t0, &t1)     // t0 = t0 - t1
-	sqr(&t1, &t1)        // t1 = t1^2
-	mul(j, j, &t1)       // j = j * t1
-	add(&t0, &t0, &t0)   // t0 = t0 + t0
-	add(&t0, &t0, &t0)   // t0 = t0 + t0
-	sqr(&t1, &t0)        // t1 = t0^2
-	mul(&t0, &t0, &t1)   // t0 = t0 * t1
-	add(&t0, &t0, &t0)   // t0 = t0 + t0
-	add(&t0, &t0, &t0)   // t0 = t0 + t0
-	inv(j, j)            // j  = 1/j
-	mul(j, &t0, j)       // j  = t0 * j
-}
-
-// Given affine points x(P), x(Q) and x(Q-P) in a extension field F_{p^2}, function
-// recorvers projective coordinate A of a curve. This is Algorithm 10 from SIKE.
-func RecoverCoordinateA(curve *ProjectiveCurveParameters, xp, xq, xr *Fp2) {
-	var t0, t1 Fp2
-
-	add(&t1, xp, xq)                        // t1 = Xp + Xq
-	mul(&t0, xp, xq)                        // t0 = Xp * Xq
-	mul(&curve.A, xr, &t1)                  // A  = X(q-p) * t1
-	add(&curve.A, &curve.A, &t0)            // A  = A + t0
-	mul(&t0, &t0, xr)                       // t0 = t0 * X(q-p)
-	sub(&curve.A, &curve.A, &Params.OneFp2) // A  = A - 1
-	add(&t0, &t0, &t0)                      // t0 = t0 + t0
-	add(&t1, &t1, xr)                       // t1 = t1 + X(q-p)
-	add(&t0, &t0, &t0)                      // t0 = t0 + t0
-	sqr(&curve.A, &curve.A)                 // A  = A^2
-	inv(&t0, &t0)                           // t0 = 1/t0
-	mul(&curve.A, &curve.A, &t0)            // A  = A * t0
-	sub(&curve.A, &curve.A, &t1)            // A  = A - t1
-}
-
-// Computes equivalence (A:C) ~ (A+2C : A-2C)
-func CalcCurveParamsEquiv3(cparams *ProjectiveCurveParameters) CurveCoefficientsEquiv {
-	var coef CurveCoefficientsEquiv
-	var c2 Fp2
-
-	add(&c2, &cparams.C, &cparams.C)
-	// A24p = A+2*C
-	add(&coef.A, &cparams.A, &c2)
-	// A24m = A-2*C
-	sub(&coef.C, &cparams.A, &c2)
-	return coef
-}
-
-// Computes equivalence (A:C) ~ (A+2C : 4C)
-func CalcCurveParamsEquiv4(cparams *ProjectiveCurveParameters) CurveCoefficientsEquiv {
-	var coefEq CurveCoefficientsEquiv
-
-	add(&coefEq.C, &cparams.C, &cparams.C)
-	// A24p = A+2C
-	add(&coefEq.A, &cparams.A, &coefEq.C)
-	// C24 = 4*C
-	add(&coefEq.C, &coefEq.C, &coefEq.C)
-	return coefEq
-}
-
-// Recovers (A:C) curve parameters from projectively equivalent (A+2C:A-2C).
-func RecoverCurveCoefficients3(cparams *ProjectiveCurveParameters, coefEq *CurveCoefficientsEquiv) {
-	add(&cparams.A, &coefEq.A, &coefEq.C)
-	// cparams.A = 2*(A+2C+A-2C) = 4A
-	add(&cparams.A, &cparams.A, &cparams.A)
-	// cparams.C = (A+2C-A+2C) = 4C
-	sub(&cparams.C, &coefEq.A, &coefEq.C)
-	return
-}
-
-// Recovers (A:C) curve parameters from projectively equivalent (A+2C:4C).
-func RecoverCurveCoefficients4(cparams *ProjectiveCurveParameters, coefEq *CurveCoefficientsEquiv) {
-	// cparams.C = (4C)*1/2=2C
-	mul(&cparams.C, &coefEq.C, &Params.HalfFp2)
-	// cparams.A = A+2C - 2C = A
-	sub(&cparams.A, &coefEq.A, &cparams.C)
-	// cparams.C = 2C * 1/2 = C
-	mul(&cparams.C, &cparams.C, &Params.HalfFp2)
-	return
-}
-
-// Combined coordinate doubling and differential addition. Takes projective points
-// P,Q,Q-P and (A+2C)/4C curve E coefficient. Returns 2*P and P+Q calculated on E.
-// Function is used only by RightToLeftLadder. Corresponds to Algorithm 5 of SIKE
-func xDbladd(P, Q, QmP *ProjectivePoint, a24 *Fp2) (dblP, PaQ ProjectivePoint) {
-	var t0, t1, t2 Fp2
-	xQmP, zQmP := &QmP.X, &QmP.Z
-	xPaQ, zPaQ := &PaQ.X, &PaQ.Z
-	x2P, z2P := &dblP.X, &dblP.Z
-	xP, zP := &P.X, &P.Z
-	xQ, zQ := &Q.X, &Q.Z
-
-	add(&t0, xP, zP)      // t0   = Xp+Zp
-	sub(&t1, xP, zP)      // t1   = Xp-Zp
-	sqr(x2P, &t0)         // 2P.X = t0^2
-	sub(&t2, xQ, zQ)      // t2   = Xq-Zq
-	add(xPaQ, xQ, zQ)     // Xp+q = Xq+Zq
-	mul(&t0, &t0, &t2)    // t0   = t0 * t2
-	mul(z2P, &t1, &t1)    // 2P.Z = t1 * t1
-	mul(&t1, &t1, xPaQ)   // t1   = t1 * Xp+q
-	sub(&t2, x2P, z2P)    // t2   = 2P.X - 2P.Z
-	mul(x2P, x2P, z2P)    // 2P.X = 2P.X * 2P.Z
-	mul(xPaQ, a24, &t2)   // Xp+q = A24 * t2
-	sub(zPaQ, &t0, &t1)   // Zp+q = t0 - t1
-	add(z2P, xPaQ, z2P)   // 2P.Z = Xp+q + 2P.Z
-	add(xPaQ, &t0, &t1)   // Xp+q = t0 + t1
-	mul(z2P, z2P, &t2)    // 2P.Z = 2P.Z * t2
-	sqr(zPaQ, zPaQ)       // Zp+q = Zp+q ^ 2
-	sqr(xPaQ, xPaQ)       // Xp+q = Xp+q ^ 2
-	mul(zPaQ, xQmP, zPaQ) // Zp+q = Xq-p * Zp+q
-	mul(xPaQ, zQmP, xPaQ) // Xp+q = Zq-p * Xp+q
-	return
-}
-
-// Given the curve parameters, xP = x(P), computes xP = x([2^k]P)
-// Safe to overlap xP, x2P.
-func Pow2k(xP *ProjectivePoint, params *CurveCoefficientsEquiv, k uint32) {
-	var t0, t1 Fp2
-
-	x, z := &xP.X, &xP.Z
-	for i := uint32(0); i < k; i++ {
-		sub(&t0, x, z)           // t0  = Xp - Zp
-		add(&t1, x, z)           // t1  = Xp + Zp
-		sqr(&t0, &t0)            // t0  = t0 ^ 2
-		sqr(&t1, &t1)            // t1  = t1 ^ 2
-		mul(z, &params.C, &t0)   // Z2p = C24 * t0
-		mul(x, z, &t1)           // X2p = Z2p * t1
-		sub(&t1, &t1, &t0)       // t1  = t1 - t0
-		mul(&t0, &params.A, &t1) // t0  = A24+ * t1
-		add(z, z, &t0)           // Z2p = Z2p + t0
-		mul(z, z, &t1)           // Zp  = Z2p * t1
-	}
-}
-
-// Given the curve parameters, xP = x(P), and k >= 0, compute xP = x([3^k]P).
-//
-// Safe to overlap xP, xR.
-func Pow3k(xP *ProjectivePoint, params *CurveCoefficientsEquiv, k uint32) {
-	var t0, t1, t2, t3, t4, t5, t6 Fp2
-
-	x, z := &xP.X, &xP.Z
-	for i := uint32(0); i < k; i++ {
-		sub(&t0, x, z)           // t0  = Xp - Zp
-		sqr(&t2, &t0)            // t2  = t0^2
-		add(&t1, x, z)           // t1  = Xp + Zp
-		sqr(&t3, &t1)            // t3  = t1^2
-		add(&t4, &t1, &t0)       // t4  = t1 + t0
-		sub(&t0, &t1, &t0)       // t0  = t1 - t0
-		sqr(&t1, &t4)            // t1  = t4^2
-		sub(&t1, &t1, &t3)       // t1  = t1 - t3
-		sub(&t1, &t1, &t2)       // t1  = t1 - t2
-		mul(&t5, &t3, &params.A) // t5  = t3 * A24+
-		mul(&t3, &t3, &t5)       // t3  = t5 * t3
-		mul(&t6, &t2, &params.C) // t6  = t2 * A24-
-		mul(&t2, &t2, &t6)       // t2  = t2 * t6
-		sub(&t3, &t2, &t3)       // t3  = t2 - t3
-		sub(&t2, &t5, &t6)       // t2  = t5 - t6
-		mul(&t1, &t2, &t1)       // t1  = t2 * t1
-		add(&t2, &t3, &t1)       // t2  = t3 + t1
-		sqr(&t2, &t2)            // t2  = t2^2
-		mul(x, &t2, &t4)         // X3p = t2 * t4
-		sub(&t1, &t3, &t1)       // t1  = t3 - t1
-		sqr(&t1, &t1)            // t1  = t1^2
-		mul(z, &t1, &t0)         // Z3p = t1 * t0
-	}
-}
-
-// Set (y1, y2, y3)  = (1/x1, 1/x2, 1/x3).
-//
-// All xi, yi must be distinct.
-func Fp2Batch3Inv(x1, x2, x3, y1, y2, y3 *Fp2) {
-	var x1x2, t Fp2
-
-	mul(&x1x2, x1, x2) // x1*x2
-	mul(&t, &x1x2, x3) // 1/(x1*x2*x3)
-	inv(&t, &t)
-	mul(y1, &t, x2) // 1/x1
-	mul(y1, y1, x3)
-	mul(y2, &t, x1) // 1/x2
-	mul(y2, y2, x3)
-	mul(y3, &t, &x1x2) // 1/x3
-}
-
-// ScalarMul3Pt is a right-to-left point multiplication that given the
-// x-coordinate of P, Q and P-Q calculates the x-coordinate of R=Q+[scalar]P.
-// nbits must be smaller or equal to len(scalar).
-func ScalarMul3Pt(cparams *ProjectiveCurveParameters, P, Q, PmQ *ProjectivePoint, nbits uint, scalar []uint8) ProjectivePoint {
-	var R0, R2, R1 ProjectivePoint
-	aPlus2Over4 := calcAplus2Over4(cparams)
-	R1 = *P
-	R2 = *PmQ
-	R0 = *Q
-
-	// Iterate over the bits of the scalar, bottom to top
-	prevBit := uint8(0)
-	for i := uint(0); i < nbits; i++ {
-		bit := (scalar[i>>3] >> (i & 7) & 1)
-		swap := prevBit ^ bit
-		prevBit = bit
-		condSwap(&R1.X, &R1.Z, &R2.X, &R2.Z, swap)
-		R0, R2 = xDbladd(&R0, &R2, &R1, &aPlus2Over4)
-	}
-	condSwap(&R1.X, &R1.Z, &R2.X, &R2.Z, prevBit)
-	return R1
-}
-
-// Given a three-torsion point p = x(PB) on the curve E_(A:C), construct the
-// three-isogeny phi : E_(A:C) -> E_(A:C)/<P_3> = E_(A':C').
-//
-// Input: (XP_3: ZP_3), where P_3 has exact order 3 on E_A/C
-// Output: * Curve coordinates (A' + 2C', A' - 2C') corresponding to E_A'/C' = A_E/C/<P3>
-//         * isogeny phi with constants in F_p^2
-func (phi *isogeny3) GenerateCurve(p *ProjectivePoint) CurveCoefficientsEquiv {
-	var t0, t1, t2, t3, t4 Fp2
-	var coefEq CurveCoefficientsEquiv
-	var K1, K2 = &phi.K1, &phi.K2
-
-	sub(K1, &p.X, &p.Z)            // K1 = XP3 - ZP3
-	sqr(&t0, K1)                   // t0 = K1^2
-	add(K2, &p.X, &p.Z)            // K2 = XP3 + ZP3
-	sqr(&t1, K2)                   // t1 = K2^2
-	add(&t2, &t0, &t1)             // t2 = t0 + t1
-	add(&t3, K1, K2)               // t3 = K1 + K2
-	sqr(&t3, &t3)                  // t3 = t3^2
-	sub(&t3, &t3, &t2)             // t3 = t3 - t2
-	add(&t2, &t1, &t3)             // t2 = t1 + t3
-	add(&t3, &t3, &t0)             // t3 = t3 + t0
-	add(&t4, &t3, &t0)             // t4 = t3 + t0
-	add(&t4, &t4, &t4)             // t4 = t4 + t4
-	add(&t4, &t1, &t4)             // t4 = t1 + t4
-	mul(&coefEq.C, &t2, &t4)       // A24m = t2 * t4
-	add(&t4, &t1, &t2)             // t4 = t1 + t2
-	add(&t4, &t4, &t4)             // t4 = t4 + t4
-	add(&t4, &t0, &t4)             // t4 = t0 + t4
-	mul(&t4, &t3, &t4)             // t4 = t3 * t4
-	sub(&t0, &t4, &coefEq.C)       // t0 = t4 - A24m
-	add(&coefEq.A, &coefEq.C, &t0) // A24p = A24m + t0
-	return coefEq
-}
-
-// Given a 3-isogeny phi and a point pB = x(PB), compute x(QB), the x-coordinate
-// of the image QB = phi(PB) of PB under phi : E_(A:C) -> E_(A':C').
-//
-// The output xQ = x(Q) is then a point on the curve E_(A':C'); the curve
-// parameters are returned by the GenerateCurve function used to construct phi.
-func (phi *isogeny3) EvaluatePoint(p *ProjectivePoint) ProjectivePoint {
-	var t0, t1, t2 Fp2
-	var q ProjectivePoint
-	var K1, K2 = &phi.K1, &phi.K2
-	var px, pz = &p.X, &p.Z
-
-	add(&t0, px, pz)   // t0 = XQ + ZQ
-	sub(&t1, px, pz)   // t1 = XQ - ZQ
-	mul(&t0, K1, &t0)  // t2 = K1 * t0
-	mul(&t1, K2, &t1)  // t1 = K2 * t1
-	add(&t2, &t0, &t1) // t2 = t0 + t1
-	sub(&t0, &t1, &t0) // t0 = t1 - t0
-	sqr(&t2, &t2)      // t2 = t2 ^ 2
-	sqr(&t0, &t0)      // t0 = t0 ^ 2
-	mul(&q.X, px, &t2) // XQ'= XQ * t2
-	mul(&q.Z, pz, &t0) // ZQ'= ZQ * t0
-	return q
-}
-
-// Given a four-torsion point p = x(PB) on the curve E_(A:C), construct the
-// four-isogeny phi : E_(A:C) -> E_(A:C)/<P_4> = E_(A':C').
-//
-// Input: (XP_4: ZP_4), where P_4 has exact order 4 on E_A/C
-// Output: * Curve coordinates (A' + 2C', 4C') corresponding to E_A'/C' = A_E/C/<P4>
-//         * isogeny phi with constants in F_p^2
-func (phi *isogeny4) GenerateCurve(p *ProjectivePoint) CurveCoefficientsEquiv {
-	var coefEq CurveCoefficientsEquiv
-	var xp4, zp4 = &p.X, &p.Z
-	var K1, K2, K3 = &phi.K1, &phi.K2, &phi.K3
-
-	sub(K2, xp4, zp4)
-	add(K3, xp4, zp4)
-	sqr(K1, zp4)
-	add(K1, K1, K1)
-	sqr(&coefEq.C, K1)
-	add(K1, K1, K1)
-	sqr(&coefEq.A, xp4)
-	add(&coefEq.A, &coefEq.A, &coefEq.A)
-	sqr(&coefEq.A, &coefEq.A)
-	return coefEq
-}
-
-// Given a 4-isogeny phi and a point xP = x(P), compute x(Q), the x-coordinate
-// of the image Q = phi(P) of P under phi : E_(A:C) -> E_(A':C').
-//
-// Input: isogeny returned by GenerateCurve and point q=(Qx,Qz) from E0_A/C
-// Output: Corresponding point q from E1_A'/C', where E1 is 4-isogenous to E0
-func (phi *isogeny4) EvaluatePoint(p *ProjectivePoint) ProjectivePoint {
-	var t0, t1 Fp2
-	var q = *p
-	var xq, zq = &q.X, &q.Z
-	var K1, K2, K3 = &phi.K1, &phi.K2, &phi.K3
-
-	add(&t0, xq, zq)
-	sub(&t1, xq, zq)
-	mul(xq, &t0, K2)
-	mul(zq, &t1, K3)
-	mul(&t0, &t0, &t1)
-	mul(&t0, &t0, K1)
-	add(&t1, xq, zq)
-	sub(zq, xq, zq)
-	sqr(&t1, &t1)
-	sqr(zq, zq)
-	add(xq, &t0, &t1)
-	sub(&t0, zq, &t0)
-	mul(xq, xq, &t1)
-	mul(zq, zq, &t0)
-	return q
-}
diff --git a/ssl/test/runner/sike/sike.go b/ssl/test/runner/sike/sike.go
deleted file mode 100644
index dcd6cfc..0000000
--- a/ssl/test/runner/sike/sike.go
+++ /dev/null
@@ -1,683 +0,0 @@
-// Copyright (c) 2019, Cloudflare 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.
-
-package sike
-
-import (
-	"crypto/sha256"
-	"crypto/subtle"
-	"errors"
-	"io"
-)
-
-// Zeroize Fp2
-func zeroize(fp *Fp2) {
-	// Zeroizing in 2 separated loops tells compiler to
-	// use fast runtime.memclr()
-	for i := range fp.A {
-		fp.A[i] = 0
-	}
-	for i := range fp.B {
-		fp.B[i] = 0
-	}
-}
-
-// Convert the input to wire format.
-//
-// The output byte slice must be at least 2*bytelen(p) bytes long.
-func convFp2ToBytes(output []byte, fp2 *Fp2) {
-	if len(output) < 2*Params.Bytelen {
-		panic("output byte slice too short")
-	}
-	var a Fp2
-	fromMontDomain(fp2, &a)
-
-	// convert to bytes in little endian form
-	for i := 0; i < Params.Bytelen; i++ {
-		// set i = j*8 + k
-		tmp := i / 8
-		k := uint64(i % 8)
-		output[i] = byte(a.A[tmp] >> (8 * k))
-		output[i+Params.Bytelen] = byte(a.B[tmp] >> (8 * k))
-	}
-}
-
-// Read 2*bytelen(p) bytes into the given ExtensionFieldElement.
-//
-// It is an error to call this function if the input byte slice is less than 2*bytelen(p) bytes long.
-func convBytesToFp2(fp2 *Fp2, input []byte) {
-	if len(input) < 2*Params.Bytelen {
-		panic("input byte slice too short")
-	}
-
-	for i := 0; i < Params.Bytelen; i++ {
-		j := i / 8
-		k := uint64(i % 8)
-		fp2.A[j] |= uint64(input[i]) << (8 * k)
-		fp2.B[j] |= uint64(input[i+Params.Bytelen]) << (8 * k)
-	}
-	toMontDomain(fp2)
-}
-
-// -----------------------------------------------------------------------------
-// Functions for traversing isogeny trees acoording to strategy. Key type 'A' is
-//
-
-// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed
-// for public key generation.
-func traverseTreePublicKeyA(curve *ProjectiveCurveParameters, xR, phiP, phiQ, phiR *ProjectivePoint, pub *PublicKey) {
-	var points = make([]ProjectivePoint, 0, 8)
-	var indices = make([]int, 0, 8)
-	var i, sidx int
-
-	cparam := CalcCurveParamsEquiv4(curve)
-	phi := NewIsogeny4()
-	strat := pub.params.A.IsogenyStrategy
-	stratSz := len(strat)
-
-	for j := 1; j <= stratSz; j++ {
-		for i <= stratSz-j {
-			points = append(points, *xR)
-			indices = append(indices, i)
-
-			k := strat[sidx]
-			sidx++
-			Pow2k(xR, &cparam, 2*k)
-			i += int(k)
-		}
-
-		cparam = phi.GenerateCurve(xR)
-		for k := 0; k < len(points); k++ {
-			points[k] = phi.EvaluatePoint(&points[k])
-		}
-
-		*phiP = phi.EvaluatePoint(phiP)
-		*phiQ = phi.EvaluatePoint(phiQ)
-		*phiR = phi.EvaluatePoint(phiR)
-
-		// pop xR from points
-		*xR, points = points[len(points)-1], points[:len(points)-1]
-		i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1]
-	}
-}
-
-// Traverses isogeny tree in order to compute xR needed
-// for public key generation.
-func traverseTreeSharedKeyA(curve *ProjectiveCurveParameters, xR *ProjectivePoint, pub *PublicKey) {
-	var points = make([]ProjectivePoint, 0, 8)
-	var indices = make([]int, 0, 8)
-	var i, sidx int
-
-	cparam := CalcCurveParamsEquiv4(curve)
-	phi := NewIsogeny4()
-	strat := pub.params.A.IsogenyStrategy
-	stratSz := len(strat)
-
-	for j := 1; j <= stratSz; j++ {
-		for i <= stratSz-j {
-			points = append(points, *xR)
-			indices = append(indices, i)
-
-			k := strat[sidx]
-			sidx++
-			Pow2k(xR, &cparam, 2*k)
-			i += int(k)
-		}
-
-		cparam = phi.GenerateCurve(xR)
-		for k := 0; k < len(points); k++ {
-			points[k] = phi.EvaluatePoint(&points[k])
-		}
-
-		// pop xR from points
-		*xR, points = points[len(points)-1], points[:len(points)-1]
-		i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1]
-	}
-}
-
-// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed
-// for public key generation.
-func traverseTreePublicKeyB(curve *ProjectiveCurveParameters, xR, phiP, phiQ, phiR *ProjectivePoint, pub *PublicKey) {
-	var points = make([]ProjectivePoint, 0, 8)
-	var indices = make([]int, 0, 8)
-	var i, sidx int
-
-	cparam := CalcCurveParamsEquiv3(curve)
-	phi := NewIsogeny3()
-	strat := pub.params.B.IsogenyStrategy
-	stratSz := len(strat)
-
-	for j := 1; j <= stratSz; j++ {
-		for i <= stratSz-j {
-			points = append(points, *xR)
-			indices = append(indices, i)
-
-			k := strat[sidx]
-			sidx++
-			Pow3k(xR, &cparam, k)
-			i += int(k)
-		}
-
-		cparam = phi.GenerateCurve(xR)
-		for k := 0; k < len(points); k++ {
-			points[k] = phi.EvaluatePoint(&points[k])
-		}
-
-		*phiP = phi.EvaluatePoint(phiP)
-		*phiQ = phi.EvaluatePoint(phiQ)
-		*phiR = phi.EvaluatePoint(phiR)
-
-		// pop xR from points
-		*xR, points = points[len(points)-1], points[:len(points)-1]
-		i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1]
-	}
-}
-
-// Traverses isogeny tree in order to compute xR, xP, xQ and xQmP needed
-// for public key generation.
-func traverseTreeSharedKeyB(curve *ProjectiveCurveParameters, xR *ProjectivePoint, pub *PublicKey) {
-	var points = make([]ProjectivePoint, 0, 8)
-	var indices = make([]int, 0, 8)
-	var i, sidx int
-
-	cparam := CalcCurveParamsEquiv3(curve)
-	phi := NewIsogeny3()
-	strat := pub.params.B.IsogenyStrategy
-	stratSz := len(strat)
-
-	for j := 1; j <= stratSz; j++ {
-		for i <= stratSz-j {
-			points = append(points, *xR)
-			indices = append(indices, i)
-
-			k := strat[sidx]
-			sidx++
-			Pow3k(xR, &cparam, k)
-			i += int(k)
-		}
-
-		cparam = phi.GenerateCurve(xR)
-		for k := 0; k < len(points); k++ {
-			points[k] = phi.EvaluatePoint(&points[k])
-		}
-
-		// pop xR from points
-		*xR, points = points[len(points)-1], points[:len(points)-1]
-		i, indices = int(indices[len(indices)-1]), indices[:len(indices)-1]
-	}
-}
-
-// Generate a public key in the 2-torsion group
-func publicKeyGenA(prv *PrivateKey) (pub *PublicKey) {
-	var xPA, xQA, xRA ProjectivePoint
-	var xPB, xQB, xRB, xK ProjectivePoint
-	var invZP, invZQ, invZR Fp2
-
-	pub = NewPublicKey(KeyVariant_SIDH_A)
-	var phi = NewIsogeny4()
-
-	// Load points for A
-	xPA = ProjectivePoint{X: prv.params.A.Affine_P, Z: prv.params.OneFp2}
-	xQA = ProjectivePoint{X: prv.params.A.Affine_Q, Z: prv.params.OneFp2}
-	xRA = ProjectivePoint{X: prv.params.A.Affine_R, Z: prv.params.OneFp2}
-
-	// Load points for B
-	xRB = ProjectivePoint{X: prv.params.B.Affine_R, Z: prv.params.OneFp2}
-	xQB = ProjectivePoint{X: prv.params.B.Affine_Q, Z: prv.params.OneFp2}
-	xPB = ProjectivePoint{X: prv.params.B.Affine_P, Z: prv.params.OneFp2}
-
-	// Find isogeny kernel
-	xK = ScalarMul3Pt(&pub.params.InitCurve, &xPA, &xQA, &xRA, prv.params.A.SecretBitLen, prv.Scalar)
-	traverseTreePublicKeyA(&pub.params.InitCurve, &xK, &xPB, &xQB, &xRB, pub)
-
-	// Secret isogeny
-	phi.GenerateCurve(&xK)
-	xPA = phi.EvaluatePoint(&xPB)
-	xQA = phi.EvaluatePoint(&xQB)
-	xRA = phi.EvaluatePoint(&xRB)
-	Fp2Batch3Inv(&xPA.Z, &xQA.Z, &xRA.Z, &invZP, &invZQ, &invZR)
-
-	mul(&pub.affine_xP, &xPA.X, &invZP)
-	mul(&pub.affine_xQ, &xQA.X, &invZQ)
-	mul(&pub.affine_xQmP, &xRA.X, &invZR)
-	return
-}
-
-// Generate a public key in the 3-torsion group
-func publicKeyGenB(prv *PrivateKey) (pub *PublicKey) {
-	var xPB, xQB, xRB, xK ProjectivePoint
-	var xPA, xQA, xRA ProjectivePoint
-	var invZP, invZQ, invZR Fp2
-
-	pub = NewPublicKey(prv.keyVariant)
-	var phi = NewIsogeny3()
-
-	// Load points for B
-	xRB = ProjectivePoint{X: prv.params.B.Affine_R, Z: prv.params.OneFp2}
-	xQB = ProjectivePoint{X: prv.params.B.Affine_Q, Z: prv.params.OneFp2}
-	xPB = ProjectivePoint{X: prv.params.B.Affine_P, Z: prv.params.OneFp2}
-
-	// Load points for A
-	xPA = ProjectivePoint{X: prv.params.A.Affine_P, Z: prv.params.OneFp2}
-	xQA = ProjectivePoint{X: prv.params.A.Affine_Q, Z: prv.params.OneFp2}
-	xRA = ProjectivePoint{X: prv.params.A.Affine_R, Z: prv.params.OneFp2}
-
-	xK = ScalarMul3Pt(&pub.params.InitCurve, &xPB, &xQB, &xRB, prv.params.B.SecretBitLen, prv.Scalar)
-	traverseTreePublicKeyB(&pub.params.InitCurve, &xK, &xPA, &xQA, &xRA, pub)
-
-	phi.GenerateCurve(&xK)
-	xPB = phi.EvaluatePoint(&xPA)
-	xQB = phi.EvaluatePoint(&xQA)
-	xRB = phi.EvaluatePoint(&xRA)
-	Fp2Batch3Inv(&xPB.Z, &xQB.Z, &xRB.Z, &invZP, &invZQ, &invZR)
-
-	mul(&pub.affine_xP, &xPB.X, &invZP)
-	mul(&pub.affine_xQ, &xQB.X, &invZQ)
-	mul(&pub.affine_xQmP, &xRB.X, &invZR)
-	return
-}
-
-// -----------------------------------------------------------------------------
-// Key agreement functions
-//
-
-// Establishing shared keys in in 2-torsion group
-func deriveSecretA(prv *PrivateKey, pub *PublicKey) []byte {
-	var sharedSecret = make([]byte, pub.params.SharedSecretSize)
-	var xP, xQ, xQmP ProjectivePoint
-	var xK ProjectivePoint
-	var cparam ProjectiveCurveParameters
-	var phi = NewIsogeny4()
-	var jInv Fp2
-
-	// Recover curve coefficients
-	RecoverCoordinateA(&cparam, &pub.affine_xP, &pub.affine_xQ, &pub.affine_xQmP)
-	// C=1
-	cparam.C = Params.OneFp2
-
-	// Find kernel of the morphism
-	xP = ProjectivePoint{X: pub.affine_xP, Z: pub.params.OneFp2}
-	xQ = ProjectivePoint{X: pub.affine_xQ, Z: pub.params.OneFp2}
-	xQmP = ProjectivePoint{X: pub.affine_xQmP, Z: pub.params.OneFp2}
-	xK = ScalarMul3Pt(&cparam, &xP, &xQ, &xQmP, pub.params.A.SecretBitLen, prv.Scalar)
-
-	// Traverse isogeny tree
-	traverseTreeSharedKeyA(&cparam, &xK, pub)
-
-	// Calculate j-invariant on isogeneus curve
-	c := phi.GenerateCurve(&xK)
-	RecoverCurveCoefficients4(&cparam, &c)
-	Jinvariant(&cparam, &jInv)
-	convFp2ToBytes(sharedSecret, &jInv)
-	return sharedSecret
-}
-
-// Establishing shared keys in in 3-torsion group
-func deriveSecretB(prv *PrivateKey, pub *PublicKey) []byte {
-	var sharedSecret = make([]byte, pub.params.SharedSecretSize)
-	var xP, xQ, xQmP ProjectivePoint
-	var xK ProjectivePoint
-	var cparam ProjectiveCurveParameters
-	var phi = NewIsogeny3()
-	var jInv Fp2
-
-	// Recover curve A coefficient
-	RecoverCoordinateA(&cparam, &pub.affine_xP, &pub.affine_xQ, &pub.affine_xQmP)
-	// C=1
-	cparam.C = Params.OneFp2
-
-	// Find kernel of the morphism
-	xP = ProjectivePoint{X: pub.affine_xP, Z: pub.params.OneFp2}
-	xQ = ProjectivePoint{X: pub.affine_xQ, Z: pub.params.OneFp2}
-	xQmP = ProjectivePoint{X: pub.affine_xQmP, Z: pub.params.OneFp2}
-	xK = ScalarMul3Pt(&cparam, &xP, &xQ, &xQmP, pub.params.B.SecretBitLen, prv.Scalar)
-
-	// Traverse isogeny tree
-	traverseTreeSharedKeyB(&cparam, &xK, pub)
-
-	// Calculate j-invariant on isogeneus curve
-	c := phi.GenerateCurve(&xK)
-	RecoverCurveCoefficients3(&cparam, &c)
-	Jinvariant(&cparam, &jInv)
-	convFp2ToBytes(sharedSecret, &jInv)
-	return sharedSecret
-}
-
-func encrypt(skA *PrivateKey, pkA, pkB *PublicKey, ptext []byte) ([]byte, error) {
-	if pkB.keyVariant != KeyVariant_SIKE {
-		return nil, errors.New("wrong key type")
-	}
-
-	j, err := DeriveSecret(skA, pkB)
-	if err != nil {
-		return nil, err
-	}
-
-	if len(ptext) != pkA.params.KemSize {
-		panic("Implementation error")
-	}
-
-	digest := sha256.Sum256(j)
-	// Uses truncated digest (first 16-bytes)
-	for i, _ := range ptext {
-		digest[i] ^= ptext[i]
-	}
-
-	ret := make([]byte, pkA.Size()+len(ptext))
-	copy(ret, pkA.Export())
-	copy(ret[pkA.Size():], digest[:pkA.params.KemSize])
-	return ret, nil
-}
-
-// NewPrivateKey initializes private key.
-// Usage of this function guarantees that the object is correctly initialized.
-func NewPrivateKey(v KeyVariant) *PrivateKey {
-	prv := &PrivateKey{key: key{params: &Params, keyVariant: v}}
-	if (v & KeyVariant_SIDH_A) == KeyVariant_SIDH_A {
-		prv.Scalar = make([]byte, prv.params.A.SecretByteLen)
-	} else {
-		prv.Scalar = make([]byte, prv.params.B.SecretByteLen)
-	}
-	if v == KeyVariant_SIKE {
-		prv.S = make([]byte, prv.params.MsgLen)
-	}
-	return prv
-}
-
-// NewPublicKey initializes public key.
-// Usage of this function guarantees that the object is correctly initialized.
-func NewPublicKey(v KeyVariant) *PublicKey {
-	return &PublicKey{key: key{params: &Params, keyVariant: v}}
-}
-
-// Import clears content of the public key currently stored in the structure
-// and imports key stored in the byte string. Returns error in case byte string
-// size is wrong. Doesn't perform any validation.
-func (pub *PublicKey) Import(input []byte) error {
-	if len(input) != pub.Size() {
-		return errors.New("sidh: input to short")
-	}
-	ssSz := pub.params.SharedSecretSize
-	convBytesToFp2(&pub.affine_xP, input[0:ssSz])
-	convBytesToFp2(&pub.affine_xQ, input[ssSz:2*ssSz])
-	convBytesToFp2(&pub.affine_xQmP, input[2*ssSz:3*ssSz])
-	return nil
-}
-
-// Exports currently stored key. In case structure hasn't been filled with key data
-// returned byte string is filled with zeros.
-func (pub *PublicKey) Export() []byte {
-	output := make([]byte, pub.params.PublicKeySize)
-	ssSz := pub.params.SharedSecretSize
-	convFp2ToBytes(output[0:ssSz], &pub.affine_xP)
-	convFp2ToBytes(output[ssSz:2*ssSz], &pub.affine_xQ)
-	convFp2ToBytes(output[2*ssSz:3*ssSz], &pub.affine_xQmP)
-	return output
-}
-
-// Size returns size of the public key in bytes
-func (pub *PublicKey) Size() int {
-	return pub.params.PublicKeySize
-}
-
-// Exports currently stored key. In case structure hasn't been filled with key data
-// returned byte string is filled with zeros.
-func (prv *PrivateKey) Export() []byte {
-	ret := make([]byte, len(prv.Scalar)+len(prv.S))
-	copy(ret, prv.S)
-	copy(ret[len(prv.S):], prv.Scalar)
-	return ret
-}
-
-// Size returns size of the private key in bytes
-func (prv *PrivateKey) Size() int {
-	tmp := len(prv.Scalar)
-	if prv.keyVariant == KeyVariant_SIKE {
-		tmp += int(prv.params.MsgLen)
-	}
-	return tmp
-}
-
-// Import clears content of the private key currently stored in the structure
-// and imports key from octet string. In case of SIKE, the random value 'S'
-// must be prepended to the value of actual private key (see SIKE spec for details).
-// Function doesn't import public key value to PrivateKey object.
-func (prv *PrivateKey) Import(input []byte) error {
-	if len(input) != prv.Size() {
-		return errors.New("sidh: input to short")
-	}
-	copy(prv.S, input[:len(prv.S)])
-	copy(prv.Scalar, input[len(prv.S):])
-	return nil
-}
-
-// Generates random private key for SIDH or SIKE. Generated value is
-// formed as little-endian integer from key-space <2^(e2-1)..2^e2 - 1>
-// for KeyVariant_A or <2^(s-1)..2^s - 1>, where s = floor(log_2(3^e3)),
-// for KeyVariant_B.
-//
-// Returns error in case user provided RNG fails.
-func (prv *PrivateKey) Generate(rand io.Reader) error {
-	var err error
-	var dp *DomainParams
-
-	if (prv.keyVariant & KeyVariant_SIDH_A) == KeyVariant_SIDH_A {
-		dp = &prv.params.A
-	} else {
-		dp = &prv.params.B
-	}
-
-	if prv.keyVariant == KeyVariant_SIKE {
-		_, err = io.ReadFull(rand, prv.S)
-	}
-
-	// Private key generation takes advantage of the fact that keyspace for secret
-	// key is (0, 2^x - 1), for some possitivite value of 'x' (see SIKE, 1.3.8).
-	// It means that all bytes in the secret key, but the last one, can take any
-	// value between <0x00,0xFF>. Similarily for the last byte, but generation
-	// needs to chop off some bits, to make sure generated value is an element of
-	// a key-space.
-	_, err = io.ReadFull(rand, prv.Scalar)
-	if err != nil {
-		return err
-	}
-	prv.Scalar[len(prv.Scalar)-1] &= (1 << (dp.SecretBitLen % 8)) - 1
-	// Make sure scalar is SecretBitLen long. SIKE spec says that key
-	// space starts from 0, but I'm not confortable with having low
-	// value scalars used for private keys. It is still secrure as per
-	// table 5.1 in [SIKE].
-	prv.Scalar[len(prv.Scalar)-1] |= 1 << ((dp.SecretBitLen % 8) - 1)
-	return err
-}
-
-// Generates public key.
-//
-// Constant time.
-func (prv *PrivateKey) GeneratePublicKey() *PublicKey {
-	if (prv.keyVariant & KeyVariant_SIDH_A) == KeyVariant_SIDH_A {
-		return publicKeyGenA(prv)
-	}
-	return publicKeyGenB(prv)
-}
-
-// Computes a shared secret which is a j-invariant. Function requires that pub has
-// different KeyVariant than prv. Length of returned output is 2*ceil(log_2 P)/8),
-// where P is a prime defining finite field.
-//
-// It's important to notice that each keypair must not be used more than once
-// to calculate shared secret.
-//
-// Function may return error. This happens only in case provided input is invalid.
-// Constant time for properly initialized private and public key.
-func DeriveSecret(prv *PrivateKey, pub *PublicKey) ([]byte, error) {
-
-	if (pub == nil) || (prv == nil) {
-		return nil, errors.New("sidh: invalid arguments")
-	}
-
-	if (pub.keyVariant == prv.keyVariant) || (pub.params.Id != prv.params.Id) {
-		return nil, errors.New("sidh: public and private are incompatbile")
-	}
-
-	if (prv.keyVariant & KeyVariant_SIDH_A) == KeyVariant_SIDH_A {
-		return deriveSecretA(prv, pub), nil
-	} else {
-		return deriveSecretB(prv, pub), nil
-	}
-}
-
-// Uses SIKE public key to encrypt plaintext. Requires cryptographically secure PRNG
-// Returns ciphertext in case encryption succeeds. Returns error in case PRNG fails
-// or wrongly formatted input was provided.
-func Encrypt(rng io.Reader, pub *PublicKey, ptext []byte) ([]byte, error) {
-	var ptextLen = len(ptext)
-	// c1 must be security level + 64 bits (see [SIKE] 1.4 and 4.3.3)
-	if ptextLen != pub.params.KemSize {
-		return nil, errors.New("Unsupported message length")
-	}
-
-	skA := NewPrivateKey(KeyVariant_SIDH_A)
-	err := skA.Generate(rng)
-	if err != nil {
-		return nil, err
-	}
-
-	pkA := skA.GeneratePublicKey()
-	return encrypt(skA, pkA, pub, ptext)
-}
-
-// Uses SIKE private key to decrypt ciphertext. Returns plaintext in case
-// decryption succeeds or error in case unexptected input was provided.
-// Constant time
-func Decrypt(prv *PrivateKey, ctext []byte) ([]byte, error) {
-	var c1_len int
-	n := make([]byte, prv.params.KemSize)
-	pk_len := prv.params.PublicKeySize
-
-	if prv.keyVariant != KeyVariant_SIKE {
-		return nil, errors.New("wrong key type")
-	}
-
-	// ctext is a concatenation of (pubkey_A || c1=ciphertext)
-	// it must be security level + 64 bits (see [SIKE] 1.4 and 4.3.3)
-	c1_len = len(ctext) - pk_len
-	if c1_len != int(prv.params.KemSize) {
-		return nil, errors.New("wrong size of cipher text")
-	}
-
-	c0 := NewPublicKey(KeyVariant_SIDH_A)
-	err := c0.Import(ctext[:pk_len])
-	if err != nil {
-		return nil, err
-	}
-	j, err := DeriveSecret(prv, c0)
-	if err != nil {
-		return nil, err
-	}
-
-	digest := sha256.Sum256(j)
-	copy(n, digest[:])
-
-	for i, _ := range n {
-		n[i] ^= ctext[pk_len+i]
-	}
-	return n[:c1_len], nil
-}
-
-// Encapsulation receives the public key and generates SIKE ciphertext and shared secret.
-// The generated ciphertext is used for authentication.
-// The rng must be cryptographically secure PRNG.
-// Error is returned in case PRNG fails or wrongly formatted input was provided.
-func Encapsulate(rng io.Reader, pub *PublicKey) (ctext []byte, secret []byte, err error) {
-	// Buffer for random, secret message
-	ptext := make([]byte, pub.params.MsgLen)
-	// SHA256 hash context object
-	d := sha256.New()
-
-	// Generate ephemeral value
-	_, err = io.ReadFull(rng, ptext)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	// Implementation uses first 28-bytes of secret
-	d.Write(ptext)
-	d.Write(pub.Export())
-	digest := d.Sum(nil)
-	// r = G(ptext||pub)
-	r := digest[:pub.params.A.SecretByteLen]
-
-	// (c0 || c1) = Enc(pkA, ptext; r)
-	skA := NewPrivateKey(KeyVariant_SIDH_A)
-	err = skA.Import(r)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	pkA := skA.GeneratePublicKey()
-	ctext, err = encrypt(skA, pkA, pub, ptext)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	// K = H(ptext||(c0||c1))
-	d.Reset()
-	d.Write(ptext)
-	d.Write(ctext)
-	digest = d.Sum(digest[:0])
-	return ctext, digest[:pub.params.KemSize], nil
-}
-
-// Decapsulate given the keypair and ciphertext as inputs, Decapsulate outputs a shared
-// secret if plaintext verifies correctly, otherwise function outputs random value.
-// Decapsulation may fail in case input is wrongly formatted.
-// Constant time for properly initialized input.
-func Decapsulate(prv *PrivateKey, pub *PublicKey, ctext []byte) ([]byte, error) {
-	var skA = NewPrivateKey(KeyVariant_SIDH_A)
-	// SHA256 hash context object
-	d := sha256.New()
-
-	m, err := Decrypt(prv, ctext)
-	if err != nil {
-		return nil, err
-	}
-
-	// r' = G(m'||pub)
-	d.Write(m)
-	d.Write(pub.Export())
-	digest := d.Sum(nil)
-	// Never fails
-	skA.Import(digest[:pub.params.A.SecretByteLen])
-
-	// Never fails
-	pkA := skA.GeneratePublicKey()
-	c0 := pkA.Export()
-
-	d.Reset()
-	if subtle.ConstantTimeCompare(c0, ctext[:len(c0)]) == 1 {
-		d.Write(m)
-	} else {
-		// S is chosen at random when generating a key and is unknown to the other party. It
-		// may seem weird, but it's correct. It is important that S is unpredictable
-		// to other party. Without this check, it is possible to recover a secret, by
-		// providing series of invalid ciphertexts. It is also important that in case
-		//
-		// See more details in "On the security of supersingular isogeny cryptosystems"
-		// (S. Galbraith, et al., 2016, ePrint #859).
-		d.Write(prv.S)
-	}
-	d.Write(ctext)
-	digest = d.Sum(digest[:0])
-	return digest[:pub.params.KemSize], nil
-}
diff --git a/ssl/test/runner/sike/sike_test.go b/ssl/test/runner/sike/sike_test.go
deleted file mode 100644
index 2e146bc..0000000
--- a/ssl/test/runner/sike/sike_test.go
+++ /dev/null
@@ -1,698 +0,0 @@
-// Copyright (c) 2019, Cloudflare 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.
-
-package sike
-
-import (
-	"bufio"
-	"bytes"
-	"crypto/rand"
-	"encoding/hex"
-	"math/big"
-	"strings"
-	"testing"
-)
-
-var tdata = struct {
-	name     string
-	PrB_sidh string
-	PkB_sidh string
-	PrA_sidh string
-	PkA_sidh string
-	PkB_sike string
-	PrB_sike string
-}{
-	name:     "P-434",
-	PrA_sidh: "3A727E04EA9B7E2A766A6F846489E7E7B915263BCEED308BB10FC9",
-	PkA_sidh: "9E668D1E6750ED4B91EE052C32839CA9DD2E56D52BC24DECC950AA" +
-		"AD24CEED3F9049C77FE80F0B9B01E7F8DAD7833EEC2286544D6380" +
-		"009C379CDD3E7517CEF5E20EB01F8231D52FC30DC61D2F63FB357F" +
-		"85DC6396E8A95DB9740BD3A972C8DB7901B31F074CD3E45345CA78" +
-		"F900817130E688A29A7CF0073B5C00FF2C65FBE776918EF9BD8E75" +
-		"B29EF7FAB791969B60B0C5B37A8992EDEF95FA7BAC40A95DAFE02E" +
-		"237301FEE9A7A43FD0B73477E8035DD12B73FAFEF18D39904DDE36" +
-		"53A754F36BE1888F6607C6A7951349A414352CF31A29F2C40302DB" +
-		"406C48018C905EB9DC46AFBF42A9187A9BB9E51B587622A2862DC7" +
-		"D5CC598BF38ED6320FB51D8697AD3D7A72ABCC32A393F0133DA8DF" +
-		"5E253D9E00B760B2DF342FCE974DCFE946CFE4727783531882800F" +
-		"9E5DD594D6D5A6275EEFEF9713ED838F4A06BB34D7B8D46E0B385A" +
-		"AEA1C7963601",
-	PrB_sidh: "E37BFE55B43B32448F375903D8D226EC94ADBFEA1D2B3536EB987001",
-	PkB_sidh: "C9F73E4497AAA3FDF9EB688135866A8A83934BA10E273B8CC3808C" +
-		"F0C1F5FAB3E9BB295885881B73DEBC875670C0F51C4BB40DF5FEDE" +
-		"01B8AF32D1BF10508B8C17B2734EB93B2B7F5D84A4A0F2F816E9E2" +
-		"C32AC253C0B6025B124D05A87A9E2A8567930F44BAA14219B941B6" +
-		"B400B4AED1D796DA12A5A9F0B8F3F5EE9DD43F64CB24A3B1719DF2" +
-		"78ADF56B5F3395187829DA2319DEABF6BBD6EDA244DE2B62CC5AC2" +
-		"50C1009DD1CD4712B0B37406612AD002B5E51A62B51AC9C0374D14" +
-		"3ABBBD58275FAFC4A5E959C54838C2D6D9FB43B7B2609061267B6A" +
-		"2E6C6D01D295C4223E0D3D7A4CDCFB28A7818A737935279751A6DD" +
-		"8290FD498D1F6AD5F4FFF6BDFA536713F509DCE8047252F1E7D0DD" +
-		"9FCC414C0070B5DCCE3665A21A032D7FBE749181032183AFAD240B" +
-		"7E671E87FBBEC3A8CA4C11AA7A9A23AC69AE2ACF54B664DECD2775" +
-		"3D63508F1B02",
-	PrB_sike: "4B622DE1350119C45A9F2E2EF3DC5DF56A27FCDFCDDAF58CD69B90" +
-		"3752D68C200934E160B234E49EDE247601",
-	PkB_sike: "1BD0A2E81307B6F96461317DDF535ACC0E59C742627BAE60D27605" +
-		"E10FAF722D22A73E184CB572A12E79DCD58C6B54FB01442114CBE9" +
-		"010B6CAEC25D04C16C5E42540C1524C545B8C67614ED4183C9FA5B" +
-		"D0BE45A7F89FBC770EE8E7E5E391C7EE6F35F74C29E6D9E35B1663" +
-		"DA01E48E9DEB2347512D366FDE505161677055E3EF23054D276E81" +
-		"7E2C57025DA1C10D2461F68617F2D11256EEE4E2D7DBDF6C8E34F3" +
-		"A0FD00C625428CB41857002159DAB94267ABE42D630C6AAA91AF83" +
-		"7C7A6740754EA6634C45454C51B0BB4D44C3CCCCE4B32C00901CF6" +
-		"9C008D013348379B2F9837F428A01B6173584691F2A6F3A3C4CF48" +
-		"7D20D261B36C8CDB1BC158E2A5162A9DA4F7A97AA0879B9897E2B6" +
-		"891B672201F9AEFBF799C27B2587120AC586A511360926FB7DA8EB" +
-		"F5CB5272F396AE06608422BE9792E2CE9BEF21BF55B7EFF8DC7EC8" +
-		"C99910D3F800",
-}
-
-/* -------------------------------------------------------------------------
-   Helpers
-   -------------------------------------------------------------------------*/
-// Fail if err !=nil. Display msg as an error message
-func checkErr(t testing.TB, err error, msg string) {
-	t.Helper()
-	if err != nil {
-		t.Error(msg)
-	}
-}
-
-// Utility used for running same test with all registered prime fields
-type MultiIdTestingFunc func(testing.TB)
-
-// Converts string to private key
-func convToPrv(s string, v KeyVariant) *PrivateKey {
-	key := NewPrivateKey(v)
-	hex, e := hex.DecodeString(s)
-	if e != nil {
-		panic("non-hex number provided")
-	}
-	e = key.Import(hex)
-	if e != nil {
-		panic("Can't import private key")
-	}
-	return key
-}
-
-// Converts string to public key
-func convToPub(s string, v KeyVariant) *PublicKey {
-	key := NewPublicKey(v)
-	hex, e := hex.DecodeString(s)
-	if e != nil {
-		panic("non-hex number provided")
-	}
-	e = key.Import(hex)
-	if e != nil {
-		panic("Can't import public key")
-	}
-	return key
-}
-
-/* -------------------------------------------------------------------------
-   Unit tests
-   -------------------------------------------------------------------------*/
-func TestKeygen(t *testing.T) {
-	alicePrivate := convToPrv(tdata.PrA_sidh, KeyVariant_SIDH_A)
-	bobPrivate := convToPrv(tdata.PrB_sidh, KeyVariant_SIDH_B)
-	expPubA := convToPub(tdata.PkA_sidh, KeyVariant_SIDH_A)
-	expPubB := convToPub(tdata.PkB_sidh, KeyVariant_SIDH_B)
-
-	pubA := alicePrivate.GeneratePublicKey()
-	pubB := bobPrivate.GeneratePublicKey()
-
-	if !bytes.Equal(pubA.Export(), expPubA.Export()) {
-		t.Fatalf("unexpected value of public key A")
-	}
-	if !bytes.Equal(pubB.Export(), expPubB.Export()) {
-		t.Fatalf("unexpected value of public key B")
-	}
-}
-
-func TestImportExport(t *testing.T) {
-	var err error
-	a := NewPublicKey(KeyVariant_SIDH_A)
-	b := NewPublicKey(KeyVariant_SIDH_B)
-
-	// Import keys
-	a_hex, err := hex.DecodeString(tdata.PkA_sidh)
-	checkErr(t, err, "invalid hex-number provided")
-
-	err = a.Import(a_hex)
-	checkErr(t, err, "import failed")
-
-	b_hex, err := hex.DecodeString(tdata.PkB_sike)
-	checkErr(t, err, "invalid hex-number provided")
-
-	err = b.Import(b_hex)
-	checkErr(t, err, "import failed")
-
-	// Export and check if same
-	if !bytes.Equal(b.Export(), b_hex) || !bytes.Equal(a.Export(), a_hex) {
-		t.Fatalf("export/import failed")
-	}
-
-	if (len(b.Export()) != b.Size()) || (len(a.Export()) != a.Size()) {
-		t.Fatalf("wrong size of exported keys")
-	}
-}
-
-func testPrivateKeyBelowMax(t testing.TB) {
-	for variant, keySz := range map[KeyVariant]*DomainParams{
-		KeyVariant_SIDH_A: &Params.A,
-		KeyVariant_SIDH_B: &Params.B} {
-
-		func(v KeyVariant, dp *DomainParams) {
-			var blen = int(dp.SecretByteLen)
-			var prv = NewPrivateKey(v)
-
-			// Calculate either (2^e2 - 1) or (2^s - 1); where s=ceil(log_2(3^e3)))
-			maxSecertVal := big.NewInt(int64(dp.SecretBitLen))
-			maxSecertVal.Exp(big.NewInt(int64(2)), maxSecertVal, nil)
-			maxSecertVal.Sub(maxSecertVal, big.NewInt(1))
-
-			// Do same test 1000 times
-			for i := 0; i < 1000; i++ {
-				err := prv.Generate(rand.Reader)
-				checkErr(t, err, "Private key generation")
-
-				// Convert to big-endian, as that's what expected by (*Int)SetBytes()
-				secretBytes := prv.Export()
-				for i := 0; i < int(blen/2); i++ {
-					tmp := secretBytes[i] ^ secretBytes[blen-i-1]
-					secretBytes[i] = tmp ^ secretBytes[i]
-					secretBytes[blen-i-1] = tmp ^ secretBytes[blen-i-1]
-				}
-				prvBig := new(big.Int).SetBytes(secretBytes)
-				// Check if generated key is bigger than acceptable
-				if prvBig.Cmp(maxSecertVal) == 1 {
-					t.Error("Generated private key is wrong")
-				}
-			}
-		}(variant, keySz)
-	}
-}
-
-func testKeyAgreement(t *testing.T, pkA, prA, pkB, prB string) {
-	var e error
-
-	// KeyPairs
-	alicePublic := convToPub(pkA, KeyVariant_SIDH_A)
-	bobPublic := convToPub(pkB, KeyVariant_SIDH_B)
-	alicePrivate := convToPrv(prA, KeyVariant_SIDH_A)
-	bobPrivate := convToPrv(prB, KeyVariant_SIDH_B)
-
-	// Do actual test
-	s1, e := DeriveSecret(bobPrivate, alicePublic)
-	checkErr(t, e, "derivation s1")
-	s2, e := DeriveSecret(alicePrivate, bobPublic)
-	checkErr(t, e, "derivation s1")
-
-	if !bytes.Equal(s1[:], s2[:]) {
-		t.Fatalf("two shared keys: %d, %d do not match", s1, s2)
-	}
-
-	// Negative case
-	dec, e := hex.DecodeString(tdata.PkA_sidh)
-	if e != nil {
-		t.FailNow()
-	}
-	dec[0] = ^dec[0]
-	e = alicePublic.Import(dec)
-	if e != nil {
-		t.FailNow()
-	}
-
-	s1, e = DeriveSecret(bobPrivate, alicePublic)
-	checkErr(t, e, "derivation of s1 failed")
-	s2, e = DeriveSecret(alicePrivate, bobPublic)
-	checkErr(t, e, "derivation of s2 failed")
-
-	if bytes.Equal(s1[:], s2[:]) {
-		t.Fatalf("The two shared keys: %d, %d match", s1, s2)
-	}
-}
-
-func TestDerivationRoundTrip(t *testing.T) {
-	var err error
-
-	prvA := NewPrivateKey(KeyVariant_SIDH_A)
-	prvB := NewPrivateKey(KeyVariant_SIDH_B)
-
-	// Generate private keys
-	err = prvA.Generate(rand.Reader)
-	checkErr(t, err, "key generation failed")
-	err = prvB.Generate(rand.Reader)
-	checkErr(t, err, "key generation failed")
-
-	// Generate public keys
-	pubA := prvA.GeneratePublicKey()
-	pubB := prvB.GeneratePublicKey()
-
-	// Derive shared secret
-	s1, err := DeriveSecret(prvB, pubA)
-	checkErr(t, err, "")
-
-	s2, err := DeriveSecret(prvA, pubB)
-	checkErr(t, err, "")
-
-	if !bytes.Equal(s1[:], s2[:]) {
-		t.Fatalf("Two shared keys: \n%X, \n%X do not match", s1, s2)
-	}
-}
-
-// Encrypt, Decrypt, check if input/output plaintext is the same
-func testPKERoundTrip(t testing.TB, id uint8) {
-	// Message to be encrypted
-	var msg = make([]byte, Params.MsgLen)
-	for i, _ := range msg {
-		msg[i] = byte(i)
-	}
-
-	// Import keys
-	pkB := NewPublicKey(KeyVariant_SIKE)
-	skB := NewPrivateKey(KeyVariant_SIKE)
-	pk_hex, err := hex.DecodeString(tdata.PkB_sike)
-	if err != nil {
-		t.Fatal(err)
-	}
-	sk_hex, err := hex.DecodeString(tdata.PrB_sike)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if pkB.Import(pk_hex) != nil || skB.Import(sk_hex) != nil {
-		t.Error("Import")
-	}
-
-	ct, err := Encrypt(rand.Reader, pkB, msg[:])
-	if err != nil {
-		t.Fatal(err)
-	}
-	pt, err := Decrypt(skB, ct)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !bytes.Equal(pt[:], msg[:]) {
-		t.Errorf("Decryption failed \n got : %X\n exp : %X", pt, msg)
-	}
-}
-
-// Generate key and check if can encrypt
-func TestPKEKeyGeneration(t *testing.T) {
-	// Message to be encrypted
-	var msg = make([]byte, Params.MsgLen)
-	var err error
-	for i, _ := range msg {
-		msg[i] = byte(i)
-	}
-
-	sk := NewPrivateKey(KeyVariant_SIKE)
-	err = sk.Generate(rand.Reader)
-	checkErr(t, err, "PEK key generation")
-	pk := sk.GeneratePublicKey()
-
-	// Try to encrypt
-	ct, err := Encrypt(rand.Reader, pk, msg[:])
-	checkErr(t, err, "PEK encryption")
-	pt, err := Decrypt(sk, ct)
-	checkErr(t, err, "PEK key decryption")
-
-	if !bytes.Equal(pt[:], msg[:]) {
-		t.Fatalf("Decryption failed \n got : %X\n exp : %X", pt, msg)
-	}
-}
-
-func TestNegativePKE(t *testing.T) {
-	var msg [40]byte
-	var err error
-
-	// Generate key
-	sk := NewPrivateKey(KeyVariant_SIKE)
-	err = sk.Generate(rand.Reader)
-	checkErr(t, err, "key generation")
-
-	pk := sk.GeneratePublicKey()
-
-	// bytelen(msg) - 1
-	ct, err := Encrypt(rand.Reader, pk, msg[:Params.KemSize+8-1])
-	if err == nil {
-		t.Fatal("Error hasn't been returned")
-	}
-	if ct != nil {
-		t.Fatal("Ciphertext must be nil")
-	}
-
-	// KemSize - 1
-	pt, err := Decrypt(sk, msg[:Params.KemSize+8-1])
-	if err == nil {
-		t.Fatal("Error hasn't been returned")
-	}
-	if pt != nil {
-		t.Fatal("Ciphertext must be nil")
-	}
-}
-
-func testKEMRoundTrip(t *testing.T, pkB, skB []byte) {
-	// Import keys
-	pk := NewPublicKey(KeyVariant_SIKE)
-	sk := NewPrivateKey(KeyVariant_SIKE)
-	if pk.Import(pkB) != nil || sk.Import(skB) != nil {
-		t.Error("Import failed")
-	}
-
-	ct, ss_e, err := Encapsulate(rand.Reader, pk)
-	if err != nil {
-		t.Error("Encapsulate failed")
-	}
-
-	ss_d, err := Decapsulate(sk, pk, ct)
-	if err != nil {
-		t.Error("Decapsulate failed")
-	}
-	if !bytes.Equal(ss_e, ss_d) {
-		t.Error("Shared secrets from decapsulation and encapsulation differ")
-	}
-}
-
-func TestKEMRoundTrip(t *testing.T) {
-	pk, err := hex.DecodeString(tdata.PkB_sike)
-	checkErr(t, err, "public key B not a number")
-	sk, err := hex.DecodeString(tdata.PrB_sike)
-	checkErr(t, err, "private key B not a number")
-	testKEMRoundTrip(t, pk, sk)
-}
-
-func TestKEMKeyGeneration(t *testing.T) {
-	// Generate key
-	sk := NewPrivateKey(KeyVariant_SIKE)
-	checkErr(t, sk.Generate(rand.Reader), "error: key generation")
-	pk := sk.GeneratePublicKey()
-
-	// calculated shared secret
-	ct, ss_e, err := Encapsulate(rand.Reader, pk)
-
-	checkErr(t, err, "encapsulation failed")
-	ss_d, err := Decapsulate(sk, pk, ct)
-	checkErr(t, err, "decapsulation failed")
-
-	if !bytes.Equal(ss_e, ss_d) {
-		t.Fatalf("KEM failed \n encapsulated: %X\n decapsulated: %X", ss_d, ss_e)
-	}
-}
-
-func TestNegativeKEM(t *testing.T) {
-	sk := NewPrivateKey(KeyVariant_SIKE)
-	checkErr(t, sk.Generate(rand.Reader), "error: key generation")
-	pk := sk.GeneratePublicKey()
-
-	ct, ss_e, err := Encapsulate(rand.Reader, pk)
-	checkErr(t, err, "pre-requisite for a test failed")
-
-	ct[0] = ct[0] - 1
-	ss_d, err := Decapsulate(sk, pk, ct)
-	checkErr(t, err, "decapsulation returns error when invalid ciphertext provided")
-
-	if bytes.Equal(ss_e, ss_d) {
-		// no idea how this could ever happen, but it would be very bad
-		t.Error("critical error")
-	}
-
-	// Try encapsulating with SIDH key
-	pkSidh := NewPublicKey(KeyVariant_SIDH_B)
-	prSidh := NewPrivateKey(KeyVariant_SIDH_B)
-	_, _, err = Encapsulate(rand.Reader, pkSidh)
-	if err == nil {
-		t.Error("encapsulation accepts SIDH public key")
-	}
-	// Try decapsulating with SIDH key
-	_, err = Decapsulate(prSidh, pk, ct)
-	if err == nil {
-		t.Error("decapsulation accepts SIDH private key key")
-	}
-}
-
-// In case invalid ciphertext is provided, SIKE's decapsulation must
-// return same (but unpredictable) result for a given key.
-func TestNegativeKEMSameWrongResult(t *testing.T) {
-	sk := NewPrivateKey(KeyVariant_SIKE)
-	checkErr(t, sk.Generate(rand.Reader), "error: key generation")
-	pk := sk.GeneratePublicKey()
-
-	ct, encSs, err := Encapsulate(rand.Reader, pk)
-	checkErr(t, err, "pre-requisite for a test failed")
-
-	// make ciphertext wrong
-	ct[0] = ct[0] - 1
-	decSs1, err := Decapsulate(sk, pk, ct)
-	checkErr(t, err, "pre-requisite for a test failed")
-
-	// second decapsulation must be done with same, but imported private key
-	expSk := sk.Export()
-
-	// creat new private key
-	sk = NewPrivateKey(KeyVariant_SIKE)
-	err = sk.Import(expSk)
-	checkErr(t, err, "import failed")
-
-	// try decapsulating again. ss2 must be same as ss1 and different than
-	// original plaintext
-	decSs2, err := Decapsulate(sk, pk, ct)
-	checkErr(t, err, "pre-requisite for a test failed")
-
-	if !bytes.Equal(decSs1, decSs2) {
-		t.Error("decapsulation is insecure")
-	}
-
-	if bytes.Equal(encSs, decSs1) || bytes.Equal(encSs, decSs2) {
-		// this test requires that decapsulation returns wrong result
-		t.Errorf("test implementation error")
-	}
-}
-
-func readAndCheckLine(r *bufio.Reader) []byte {
-	// Read next line from buffer
-	line, isPrefix, err := r.ReadLine()
-	if err != nil || isPrefix {
-		panic("Wrong format of input file")
-	}
-
-	// Function expects that line is in format "KEY = HEX_VALUE". Get
-	// value, which should be a hex string
-	hexst := strings.Split(string(line), "=")[1]
-	hexst = strings.TrimSpace(hexst)
-	// Convert value to byte string
-	ret, err := hex.DecodeString(hexst)
-	if err != nil {
-		panic("Wrong format of input file")
-	}
-	return ret
-}
-
-func testKeygenSIKE(pk, sk []byte, id uint8) bool {
-	// Import provided private key
-	var prvKey = NewPrivateKey(KeyVariant_SIKE)
-	if prvKey.Import(sk) != nil {
-		panic("sike test: can't load KAT")
-	}
-
-	// Generate public key
-	pubKey := prvKey.GeneratePublicKey()
-	return bytes.Equal(pubKey.Export(), pk)
-}
-
-func testDecapsulation(pk, sk, ct, ssExpected []byte, id uint8) bool {
-	var pubKey = NewPublicKey(KeyVariant_SIKE)
-	var prvKey = NewPrivateKey(KeyVariant_SIKE)
-	if pubKey.Import(pk) != nil || prvKey.Import(sk) != nil {
-		panic("sike test: can't load KAT")
-	}
-
-	ssGot, err := Decapsulate(prvKey, pubKey, ct)
-	if err != nil {
-		panic("sike test: can't perform degcapsulation KAT")
-	}
-
-	return bytes.Equal(ssGot, ssExpected)
-}
-
-func TestKeyAgreement(t *testing.T) {
-	testKeyAgreement(t, tdata.PkA_sidh, tdata.PrA_sidh, tdata.PkB_sidh, tdata.PrB_sidh)
-}
-
-// Same values as in sike_test.cc
-func TestDecapsulation(t *testing.T) {
-	var sk = [16 + 28]byte{
-		0x04, 0x5E, 0x01, 0x42, 0xB8, 0x2F, 0xE1, 0x9A, 0x38, 0x25,
-		0x92, 0xE7, 0xDC, 0xBA, 0xF7, 0x1B, 0xB1, 0xFD, 0x34, 0x42,
-		0xDB, 0x02, 0xBC, 0x9D, 0x4C, 0xD0, 0x72, 0x34, 0x4D, 0xBD,
-		0x06, 0xDF, 0x1C, 0x7D, 0x0A, 0x88, 0xB2, 0x50, 0xC4, 0xF6,
-		0xAE, 0xE8, 0x25, 0x01,
-	}
-
-	var pk = [330]byte{
-		0x6D, 0x8D, 0xF5, 0x7B, 0xCD, 0x47, 0xCA, 0xCB, 0x7A, 0x38,
-		0xB7, 0xA6, 0x90, 0xB7, 0x37, 0x03, 0xD4, 0x6F, 0x27, 0x73,
-		0x74, 0x17, 0x5A, 0xA4, 0x0D, 0xC6, 0x81, 0xAD, 0xDB, 0xF7,
-		0x18, 0xB2, 0x3C, 0x30, 0xCF, 0xAA, 0x08, 0x11, 0x91, 0xCC,
-		0x27, 0x4E, 0xF1, 0xA6, 0xB7, 0xDA, 0xD2, 0xCF, 0x99, 0x7F,
-		0xF7, 0xE1, 0xD0, 0xCE, 0x00, 0xD2, 0x4B, 0xA4, 0x33, 0xB4,
-		0x87, 0x01, 0x3F, 0x02, 0xF7, 0xF9, 0xDE, 0xC3, 0x60, 0x62,
-		0xDA, 0x3F, 0x74, 0xA9, 0x44, 0xBE, 0x19, 0xD5, 0x03, 0x2A,
-		0x79, 0x8C, 0xA7, 0xFF, 0xEA, 0xB3, 0xBB, 0xB5, 0xD4, 0x1D,
-		0x8F, 0x92, 0xCE, 0x62, 0x6E, 0x99, 0x24, 0xD7, 0x57, 0xFA,
-		0xCD, 0xB6, 0xE2, 0x8E, 0xFD, 0x22, 0x0E, 0x31, 0x21, 0x01,
-		0x8D, 0x79, 0xF8, 0x3E, 0x27, 0xEC, 0x43, 0x40, 0xDB, 0x82,
-		0xE5, 0xEB, 0x6C, 0x97, 0x66, 0x29, 0x15, 0x68, 0xB7, 0x4D,
-		0x84, 0xD1, 0x8A, 0x0B, 0x12, 0x36, 0x2C, 0x0C, 0x0A, 0x6E,
-		0x4E, 0xDE, 0xA5, 0x8A, 0xDE, 0x77, 0xDD, 0x70, 0x49, 0x73,
-		0xAC, 0x27, 0x6D, 0x8D, 0x25, 0x9A, 0xE4, 0x25, 0xE8, 0x95,
-		0x8F, 0xFE, 0x90, 0x3B, 0x00, 0x69, 0x20, 0xE8, 0x7C, 0xA5,
-		0xF5, 0x79, 0xC0, 0x61, 0x51, 0x91, 0x35, 0x25, 0x3F, 0x17,
-		0x2F, 0x70, 0x73, 0xF0, 0x89, 0xB5, 0xC8, 0x25, 0xB8, 0xE5,
-		0x7E, 0x34, 0xDD, 0x11, 0xE5, 0xD6, 0xC3, 0xD5, 0x29, 0x89,
-		0xC6, 0x2C, 0x99, 0x53, 0x1D, 0x2C, 0x77, 0xB0, 0xB6, 0xA1,
-		0xBD, 0x79, 0xFB, 0x4A, 0xC2, 0x48, 0x4C, 0x62, 0x51, 0x00,
-		0xE3, 0x91, 0x2A, 0xCB, 0x84, 0x03, 0x5D, 0x2D, 0xC8, 0x33,
-		0xE9, 0x14, 0xBF, 0x74, 0x21, 0xBC, 0xF4, 0x76, 0xE5, 0x42,
-		0xB8, 0xBD, 0xE2, 0xE7, 0x20, 0x95, 0x54, 0xF2, 0xED, 0xC0,
-		0x79, 0x38, 0x1E, 0xD2, 0xEA, 0x1A, 0x63, 0x85, 0xE7, 0x3A,
-		0xDA, 0xAD, 0xAB, 0x1B, 0x1E, 0x19, 0x9E, 0x73, 0xD0, 0x10,
-		0x2E, 0x38, 0xAC, 0x8B, 0x00, 0x6A, 0x30, 0x2C, 0x3D, 0x70,
-		0x8E, 0x39, 0x6D, 0xC0, 0x12, 0x61, 0x7D, 0x2A, 0x0A, 0x04,
-		0x95, 0x8E, 0x09, 0x3C, 0x7B, 0xEC, 0x2E, 0xBC, 0xE8, 0xE8,
-		0xE8, 0x37, 0x29, 0xC4, 0x7E, 0x76, 0x48, 0xB9, 0x3B, 0x72,
-		0xE5, 0x99, 0x9B, 0xF9, 0xE3, 0x99, 0x72, 0x3F, 0x35, 0x29,
-		0x85, 0xE0, 0xC8, 0xBF, 0xB1, 0x6B, 0xB1, 0x6E, 0x72, 0x00,
-	}
-
-	var ct = [330 + 16]byte{
-		0xFF, 0xEB, 0xEF, 0x4A, 0xC0, 0x57, 0x0F, 0x26, 0xAC, 0x76,
-		0xA8, 0xB0, 0xA3, 0x5D, 0x9C, 0xD9, 0x25, 0xD1, 0x7F, 0x92,
-		0x5D, 0xF4, 0x23, 0x34, 0xC3, 0x03, 0x10, 0xE1, 0xB0, 0x24,
-		0x9B, 0x44, 0x58, 0x26, 0x13, 0x56, 0x83, 0x43, 0x72, 0x69,
-		0x28, 0x0D, 0x55, 0x07, 0x1F, 0xDB, 0xC0, 0x23, 0x34, 0x83,
-		0x1A, 0x09, 0x9B, 0x80, 0x00, 0x64, 0x56, 0xDC, 0x79, 0x7A,
-		0xD2, 0xCE, 0x23, 0xC9, 0x72, 0x27, 0xFC, 0x8D, 0xAB, 0xBF,
-		0xD3, 0x17, 0xF6, 0x91, 0x7B, 0x15, 0x93, 0x83, 0x8A, 0x4F,
-		0x6C, 0xCA, 0x4A, 0x94, 0xDA, 0xC7, 0x9D, 0xB6, 0xD6, 0xBA,
-		0xBD, 0x81, 0x9A, 0x78, 0xE5, 0xE5, 0xBE, 0x17, 0xBC, 0xCB,
-		0xC8, 0x23, 0x80, 0x5F, 0x75, 0xF8, 0xDB, 0x51, 0x55, 0x00,
-		0x25, 0x33, 0x52, 0x64, 0xB2, 0xD6, 0xD8, 0x9A, 0x2A, 0x9E,
-		0x29, 0x99, 0x13, 0x33, 0xE2, 0xA7, 0x98, 0xAC, 0xD7, 0x79,
-		0x5C, 0x2F, 0xBA, 0x07, 0xC3, 0x03, 0x37, 0xD6, 0xE6, 0xB5,
-		0xA1, 0xF5, 0x29, 0xB6, 0xF6, 0xC0, 0x5C, 0x44, 0x68, 0x2B,
-		0x0B, 0xF5, 0x00, 0x01, 0x44, 0xD5, 0xCC, 0x23, 0xB5, 0x27,
-		0x4F, 0xCA, 0xB4, 0x05, 0x01, 0xF9, 0xD4, 0x41, 0xE0, 0xE1,
-		0x1E, 0xCF, 0xA9, 0xBC, 0x79, 0xD7, 0xD5, 0xF5, 0x3C, 0xE6,
-		0x93, 0xF4, 0x6C, 0x84, 0x5A, 0x2C, 0x4B, 0xE4, 0x91, 0xB2,
-		0xB2, 0xB8, 0xAD, 0x74, 0x9A, 0x69, 0x79, 0x4C, 0x84, 0xB7,
-		0xBF, 0xF1, 0x68, 0x4B, 0xAE, 0x0F, 0x7F, 0x45, 0x3B, 0x18,
-		0x3F, 0xFA, 0x00, 0x48, 0xE0, 0x3A, 0xE2, 0xC0, 0xAE, 0x00,
-		0xCE, 0x90, 0x28, 0xA4, 0x1B, 0xBE, 0xCA, 0x0C, 0x21, 0x29,
-		0x64, 0x30, 0x5E, 0x35, 0xAD, 0xFD, 0x83, 0x47, 0x40, 0x6D,
-		0x15, 0x56, 0xFC, 0xF8, 0x5F, 0xAB, 0x81, 0xFE, 0x6B, 0xE9,
-		0x6B, 0xED, 0x27, 0x35, 0x7C, 0xD8, 0x2C, 0xD4, 0xF2, 0x11,
-		0xE6, 0xAF, 0xDF, 0xB8, 0x91, 0x96, 0xEB, 0xF7, 0x4C, 0x8D,
-		0x70, 0x77, 0x90, 0x81, 0x00, 0x09, 0x19, 0x27, 0x8A, 0x9E,
-		0xB6, 0x1A, 0xE9, 0xAC, 0x6C, 0xC9, 0xF8, 0xEA, 0xA2, 0x34,
-		0xB8, 0xAC, 0xB3, 0xB3, 0x68, 0xA1, 0xB7, 0x29, 0x55, 0xCA,
-		0x40, 0x23, 0x92, 0x5C, 0x0C, 0x79, 0x6B, 0xD6, 0x9F, 0x5B,
-		0xD2, 0xE6, 0xAE, 0x04, 0xCB, 0xEC, 0xC7, 0x88, 0x18, 0xDB,
-		0x7A, 0xE6, 0xD6, 0xC9, 0x39, 0xFD, 0x93, 0x9B, 0xC8, 0x01,
-		0x6F, 0x3E, 0x6C, 0x90, 0x3E, 0x73, 0x76, 0x99, 0x7C, 0x48,
-		0xDA, 0x68, 0x48, 0x80, 0x2B, 0x63,
-	}
-	var ssExp = [16]byte{
-		0xA1, 0xF9, 0x5A, 0x67, 0xB9, 0x3D, 0x1E, 0x72, 0xE8, 0xC5,
-		0x71, 0xF1, 0x4C, 0xB2, 0xAA, 0x6D,
-	}
-
-	var prvObj = NewPrivateKey(KeyVariant_SIKE)
-	var pubObj = NewPublicKey(KeyVariant_SIKE)
-
-	if pubObj.Import(pk[:]) != nil || prvObj.Import(sk[:]) != nil {
-		t.Error("Can't import one of the keys")
-	}
-
-	res, _ := Decapsulate(prvObj, pubObj, ct[:])
-	if !bytes.Equal(ssExp[:], res) {
-		t.Error("Wrong decapsulation result")
-	}
-}
-
-/* -------------------------------------------------------------------------
-   Benchmarking
-   -------------------------------------------------------------------------*/
-
-func BenchmarkSidhKeyAgreement(b *testing.B) {
-	// KeyPairs
-	alicePublic := convToPub(tdata.PkA_sidh, KeyVariant_SIDH_A)
-	alicePrivate := convToPrv(tdata.PrA_sidh, KeyVariant_SIDH_A)
-	bobPublic := convToPub(tdata.PkB_sidh, KeyVariant_SIDH_B)
-	bobPrivate := convToPrv(tdata.PrB_sidh, KeyVariant_SIDH_B)
-
-	for i := 0; i < b.N; i++ {
-		// Derive shared secret
-		DeriveSecret(bobPrivate, alicePublic)
-		DeriveSecret(alicePrivate, bobPublic)
-	}
-}
-
-func BenchmarkAliceKeyGenPrv(b *testing.B) {
-	prv := NewPrivateKey(KeyVariant_SIDH_A)
-	for n := 0; n < b.N; n++ {
-		prv.Generate(rand.Reader)
-	}
-}
-
-func BenchmarkBobKeyGenPrv(b *testing.B) {
-	prv := NewPrivateKey(KeyVariant_SIDH_B)
-	for n := 0; n < b.N; n++ {
-		prv.Generate(rand.Reader)
-	}
-}
-
-func BenchmarkAliceKeyGenPub(b *testing.B) {
-	prv := NewPrivateKey(KeyVariant_SIDH_A)
-	prv.Generate(rand.Reader)
-	for n := 0; n < b.N; n++ {
-		prv.GeneratePublicKey()
-	}
-}
-
-func BenchmarkBobKeyGenPub(b *testing.B) {
-	prv := NewPrivateKey(KeyVariant_SIDH_B)
-	prv.Generate(rand.Reader)
-	for n := 0; n < b.N; n++ {
-		prv.GeneratePublicKey()
-	}
-}
-
-func BenchmarkSharedSecretAlice(b *testing.B) {
-	aPr := convToPrv(tdata.PrA_sidh, KeyVariant_SIDH_A)
-	bPk := convToPub(tdata.PkB_sike, KeyVariant_SIDH_B)
-	for n := 0; n < b.N; n++ {
-		DeriveSecret(aPr, bPk)
-	}
-}
-
-func BenchmarkSharedSecretBob(b *testing.B) {
-	// m_B = 3*randint(0,3^238)
-	aPk := convToPub(tdata.PkA_sidh, KeyVariant_SIDH_A)
-	bPr := convToPrv(tdata.PrB_sidh, KeyVariant_SIDH_B)
-	for n := 0; n < b.N; n++ {
-		DeriveSecret(bPr, aPk)
-	}
-}
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index 8d8a068..6313673 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -1611,9 +1611,6 @@
         case SSL_CURVE_CECPQ2:
           nids.push_back(NID_CECPQ2);
           break;
-        case SSL_CURVE_CECPQ2b:
-          nids.push_back(NID_CECPQ2b);
-          break;
       }
       if (!SSL_set1_curves(ssl.get(), &nids[0], nids.size())) {
         return nullptr;
@@ -1622,8 +1619,8 @@
   }
   if (enable_all_curves) {
     static const int kAllCurves[] = {
-        NID_secp224r1, NID_X9_62_prime256v1, NID_secp384r1, NID_secp521r1,
-        NID_X25519,    NID_CECPQ2,           NID_CECPQ2b,
+        NID_secp224r1, NID_X9_62_prime256v1, NID_secp384r1,
+        NID_secp521r1, NID_X25519,           NID_CECPQ2,
     };
     if (!SSL_set1_curves(ssl.get(), kAllCurves,
                          OPENSSL_ARRAY_SIZE(kAllCurves))) {
diff --git a/third_party/sike/LICENSE b/third_party/sike/LICENSE
deleted file mode 100644
index 5cf7c8d..0000000
--- a/third_party/sike/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-
-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
diff --git a/third_party/sike/asm/fp-armv8.pl b/third_party/sike/asm/fp-armv8.pl
deleted file mode 100644
index ce19d80..0000000
--- a/third_party/sike/asm/fp-armv8.pl
+++ /dev/null
@@ -1,915 +0,0 @@
-#! /usr/bin/env perl
-#
-# April 2019
-#
-# Abstract: field arithmetic in aarch64 assembly for SIDH/p434
-
-$flavour = shift;
-$output  = shift;
-if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-( $xlate="${dir}../../../crypto/perlasm/arm-xlate.pl" and -f $xlate) or
-die "can't locate arm-xlate.pl";
-
-open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-*STDOUT=*OUT;
-
-$PREFIX="sike";
-
-$code.=<<___;
-.section  .rodata
-
-# p434 x 2
-.Lp434x2:
-    .quad  0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF
-    .quad  0xFB82ECF5C5FFFFFF, 0xF78CB8F062B15D47
-    .quad  0xD9F8BFAD038A40AC, 0x0004683E4E2EE688
-
-# p434 + 1
-.Lp434p1:
-    .quad  0xFDC1767AE3000000, 0x7BC65C783158AEA3
-    .quad  0x6CFC5FD681C52056, 0x0002341F27177344
-
-.text
-___
-
-# Computes C0-C2 = A0 * (B0-B1)
-# Inputs remain intact
-sub mul64x128 {
-    my ($A0,$B0,$B1,$C0,$C1,$C2,$T0,$T1)=@_;
-    my $body=<<___;
-        mul     $T1, $A0, $B0
-        umulh   $B0, $A0, $B0
-        adds    $C0, $C0, $C2
-        adc     $C1, $C1, xzr
-
-        mul     $T0, $A0, $B1
-        umulh   $B1, $A0, $B1
-        adds    $C0, $C0, $T1
-        adcs    $C1, $C1, $B0
-        adc     $C2, xzr, xzr
-
-        adds    $C1, $C1, $T0
-        adc     $C2, $C2, $B1
-___
-    return $body;
-}
-
-# Computes C0-C4 = A0 * (B0-B3)
-# Inputs remain intact
-sub mul64x256 {
-    my ($A0,$B0,$B1,$B2,$B3,$C0,$C1,$C2,$C3,$C4,$T0,$T1,$T2)=@_;
-    my $body=<<___;
-        mul     $C0, $A0, $B0    // C0
-        umulh   $T0, $A0, $B0
-
-        mul     $C1, $A0, $B1
-        umulh   $T1, $A0, $B1
-        adds    $C1, $C1, $T0    // C1
-        adc     $T0, xzr, xzr
-
-        mul     $C2, $A0, $B2
-        umulh   $T2, $A0, $B2
-        adds    $T1, $T0, $T1
-        adcs    $C2, $C2, $T1    // C2
-        adc     $T0, xzr, xzr
-
-        mul     $C3, $A0, $B3
-        umulh   $C4, $A0, $B3
-        adds    $T2, $T0, $T2
-        adcs    $C3, $C3, $T2    // C3
-        adc     $C4, $C4, xzr    // C4
-___
-    return $body;
-}
-
-# Computes C0-C4 = (A0-A1) * (B0-B3)
-# Inputs remain intact
-sub mul128x256 {
-    my ($A0,$A1,$B0,$B1,$B2,$B3,$C0,$C1,$C2,$C3,$C4,$C5,$T0,$T1,$T2,$T3)=@_;
-    my $body=<<___;
-        mul     $C0, $A0, $B0  // C0
-        umulh   $C3, $A0, $B0
-
-        mul     $C1, $A0, $B1
-        umulh   $C2, $A0, $B1
-
-        mul     $T0, $A1, $B0
-        umulh   $T1, $A1, $B0
-        adds    $C1, $C1, $C3
-        adc     $C2, $C2, xzr
-
-        mul     $T2, $A0, $B2
-        umulh   $T3, $A0, $B2
-        adds    $C1, $C1, $T0  // C1
-        adcs    $C2, $C2, $T1
-        adc     $C3, xzr, xzr
-
-        mul     $T0, $A1, $B1
-        umulh   $T1, $A1, $B1
-        adds    $C2, $C2, $T2
-        adcs    $C3, $C3, $T3
-        adc     $C4, xzr, xzr
-
-        mul     $T2, $A0, $B3
-        umulh   $T3, $A0, $B3
-        adds    $C2, $C2, $T0  // C2
-        adcs    $C3, $C3, $T1
-        adc     $C4, $C4, xzr
-
-        mul     $T0, $A1, $B2
-        umulh   $T1, $A1, $B2
-        adds    $C3, $C3, $T2
-        adcs    $C4, $C4, $T3
-        adc     $C5, xzr, xzr
-
-        mul     $T2, $A1, $B3
-        umulh   $T3, $A1, $B3
-        adds    $C3, $C3, $T0  // C3
-        adcs    $C4, $C4, $T1
-        adc     $C5, $C5, xzr
-        adds    $C4, $C4, $T2  // C4
-        adc     $C5, $C5, $T3  // C5
-
-___
-    return $body;
-}
-
-# Computes C0-C5 = (A0-A2) * (B0-B2)
-# Inputs remain intact
-sub mul192 {
-    my ($A0,$A1,$A2,$B0,$B1,$B2,$C0,$C1,$C2,$C3,$C4,$C5,$T0,$T1,$T2,$T3)=@_;
-    my $body=<<___;
-
-        // A0 * B0
-        mul     $C0, $A0, $B0  // C0
-        umulh   $C3, $A0, $B0
-
-        // A0 * B1
-        mul     $C1, $A0, $B1
-        umulh   $C2, $A0, $B1
-
-        // A1 * B0
-        mul     $T0, $A1, $B0
-        umulh   $T1, $A1, $B0
-        adds    $C1, $C1, $C3
-        adc     $C2, $C2, xzr
-
-        // A0 * B2
-        mul     $T2, $A0, $B2
-        umulh   $T3, $A0, $B2
-        adds    $C1, $C1, $T0  // C1
-        adcs    $C2, $C2, $T1
-        adc     $C3, xzr, xzr
-
-        // A2 * B0
-        mul     $T0, $A2, $B0
-        umulh   $C4, $A2, $B0
-        adds    $C2, $C2, $T2
-        adcs    $C3, $C3, $C4
-        adc     $C4, xzr, xzr
-
-        // A1 * B1
-        mul     $T2, $A1, $B1
-        umulh   $T1, $A1, $B1
-        adds    $C2, $C2, $T0
-        adcs    $C3, $C3, $T3
-        adc     $C4, $C4, xzr
-
-        // A1 * B2
-        mul     $T0, $A1, $B2
-        umulh   $T3, $A1, $B2
-        adds    $C2, $C2, $T2 // C2
-        adcs    $C3, $C3, $T1
-        adc     $C4, $C4, xzr
-
-        // A2 * B1
-        mul     $T2, $A2, $B1
-        umulh   $T1, $A2, $B1
-        adds    $C3, $C3, $T0
-        adcs    $C4, $C4, $T3
-        adc     $C5, xzr, xzr
-
-        // A2 * B2
-        mul     $T0, $A2, $B2
-        umulh   $T3, $A2, $B2
-        adds    $C3, $C3, $T2 // C3
-        adcs    $C4, $C4, $T1
-        adc     $C5, $C5, xzr
-
-        adds    $C4, $C4, $T0 // C4
-        adc     $C5, $C5, $T3 // C5
-___
-    return $body;
-}
-sub mul256_karatsuba {
-    my ($M,$A0,$A1,$A2,$A3,$B0,$B1,$B2,$B3,$C0,$C1,$C2,$C3,$C4,$C5,$C6,$C7,$T0,$T1)=@_;
-    # (AH+AL) x (BH+BL), low part
-    my $mul_low=&mul64x128($A1, $C6, $T1, $C3, $C4, $C5, $C7, $A0);
-    # AL x BL
-    my $mul_albl=&mul64x128($A1, $B0, $B1, $C1, $T1, $C7, $C6, $A0);
-    # AH x BH
-    my $mul_ahbh=&mul64x128($A3, $B2, $B3, $A1, $C6, $B0, $B1, $A2);
-    my $body=<<___;
-        // A0-A1 <- AH + AL, T0 <- mask
-        adds    $A0, $A0, $A2
-        adcs    $A1, $A1, $A3
-        adc     $T0, xzr, xzr
-
-        // C6, T1 <- BH + BL, C7 <- mask
-        adds    $C6, $B0, $B2
-        adcs    $T1, $B1, $B3
-        adc     $C7, xzr, xzr
-
-        // C0-C1 <- masked (BH + BL)
-        sub     $C2, xzr, $T0
-        sub     $C3, xzr, $C7
-        and     $C0, $C6, $C2
-        and     $C1, $T1, $C2
-
-        // C4-C5 <- masked (AH + AL), T0 <- combined carry
-        and     $C4, $A0, $C3
-        and     $C5, $A1, $C3
-        mul     $C2, $A0, $C6
-        mul     $C3, $A0, $T1
-        and     $T0, $T0, $C7
-
-        // C0-C1, T0 <- (AH+AL) x (BH+BL), part 1
-        adds    $C0, $C4, $C0
-        umulh   $C4, $A0, $T1
-        adcs    $C1, $C5, $C1
-        umulh   $C5, $A0, $C6
-        adc     $T0, $T0, xzr
-
-        // C2-C5 <- (AH+AL) x (BH+BL), low part
-        $mul_low
-        ldp     $A0, $A1, [$M,#0]
-
-        // C2-C5, T0 <- (AH+AL) x (BH+BL), final part
-        adds    $C4, $C0, $C4
-        umulh   $C7, $A0, $B0
-        umulh   $T1, $A0, $B1
-        adcs    $C5, $C1, $C5
-        mul     $C0, $A0, $B0
-        mul     $C1, $A0, $B1
-        adc     $T0, $T0, xzr
-
-        // C0-C1, T1, C7 <- AL x BL
-        $mul_albl
-
-        // C2-C5, T0 <- (AH+AL) x (BH+BL) - ALxBL
-        mul     $A0, $A2, $B2
-        umulh   $B0, $A2, $B2
-        subs    $C2, $C2, $C0
-        sbcs    $C3, $C3, $C1
-        sbcs    $C4, $C4, $T1
-        mul     $A1, $A2, $B3
-        umulh   $C6, $A2, $B3
-        sbcs    $C5, $C5, $C7
-        sbc     $T0, $T0, xzr
-
-        // A0, A1, C6, B0 <- AH x BH
-        $mul_ahbh
-
-        // C2-C5, T0 <- (AH+AL) x (BH+BL) - ALxBL - AHxBH
-        subs    $C2, $C2, $A0
-        sbcs    $C3, $C3, $A1
-        sbcs    $C4, $C4, $C6
-        sbcs    $C5, $C5, $B0
-        sbc     $T0, $T0, xzr
-
-        adds    $C2, $C2, $T1
-        adcs    $C3, $C3, $C7
-        adcs    $C4, $C4, $A0
-        adcs    $C5, $C5, $A1
-        adcs    $C6, $T0, $C6
-        adc     $C7, $B0, xzr
-___
-    return $body;
-}
-
-# 512-bit integer multiplication using Karatsuba (two levels),
-# Comba (lower level).
-# Operation: c [x2] = a [x0] * b [x1]
-sub mul {
-    # (AH+AL) x (BH+BL), low part
-    my $mul_kc_low=&mul256_karatsuba(
-        "x2",                                           # M0
-        "x3","x4","x5","x6",                            # A0-A3
-        "x10","x11","x12","x13",                        # B0-B3
-        "x8","x9","x19","x20","x21","x22","x23","x24",  # C0-C7
-        "x25","x26");                                   # TMP
-    # AL x BL
-    my $mul_albl=&mul256_karatsuba(
-        "x0",                                           # M0f
-        "x3","x4","x5","x6",                            # A0-A3
-        "x10","x11","x12","x13",                        # B0-B3
-        "x21","x22","x23","x24","x25","x26","x27","x28",# C0-C7
-        "x8","x9");                                     # TMP
-    # AH x BH
-    my $mul_ahbh=&mul192(
-        "x3","x4","x5",                                 # A0-A2
-        "x10","x11","x12",                              # B0-B2
-        "x21","x22","x23","x24","x25","x26",            # C0-C5
-        "x8","x9","x27","x28");                         # TMP
-
-    my $body=<<___;
-        .global ${PREFIX}_mpmul
-        .align 4
-        ${PREFIX}_mpmul:
-        stp     x29, x30, [sp,#-96]!
-        add     x29, sp, #0
-        stp     x19, x20, [sp,#16]
-        stp     x21, x22, [sp,#32]
-        stp     x23, x24, [sp,#48]
-        stp     x25, x26, [sp,#64]
-        stp     x27, x28, [sp,#80]
-
-        ldp      x3,  x4, [x0]
-        ldp      x5,  x6, [x0,#16]
-        ldp      x7,  x8, [x0,#32]
-        ldr      x9,      [x0,#48]
-        ldp     x10, x11, [x1,#0]
-        ldp     x12, x13, [x1,#16]
-        ldp     x14, x15, [x1,#32]
-        ldr     x16,      [x1,#48]
-
-        // x3-x7 <- AH + AL, x7 <- carry
-        adds    x3, x3, x7
-        adcs    x4, x4, x8
-        adcs    x5, x5, x9
-        adcs    x6, x6, xzr
-        adc     x7, xzr, xzr
-
-        // x10-x13 <- BH + BL, x8 <- carry
-        adds    x10, x10, x14
-        adcs    x11, x11, x15
-        adcs    x12, x12, x16
-        adcs    x13, x13, xzr
-        adc     x8, xzr, xzr
-
-        // x9 <- combined carry
-        and      x9, x7, x8
-        // x7-x8 <- mask
-        sub      x7, xzr, x7
-        sub      x8, xzr, x8
-
-        // x15-x19 <- masked (BH + BL)
-        and     x14, x10, x7
-        and     x15, x11, x7
-        and     x16, x12, x7
-        and     x17, x13, x7
-
-        // x20-x23 <- masked (AH + AL)
-        and     x20, x3, x8
-        and     x21, x4, x8
-        and     x22, x5, x8
-        and     x23, x6, x8
-
-        // x15-x19, x7 <- masked (AH+AL) + masked (BH+BL), step 1
-        adds    x14, x14, x20
-        adcs    x15, x15, x21
-        adcs    x16, x16, x22
-        adcs    x17, x17, x23
-        adc     x7, x9, xzr
-
-        // x8-x9,x19,x20-x24 <- (AH+AL) x (BH+BL), low part
-        stp     x3, x4, [x2,#0]
-        $mul_kc_low
-
-        // x15-x19, x7 <- (AH+AL) x (BH+BL), final step
-        adds    x14, x14, x21
-        adcs    x15, x15, x22
-        adcs    x16, x16, x23
-        adcs    x17, x17, x24
-        adc     x7, x7, xzr
-
-        // Load AL
-        ldp     x3, x4, [x0]
-        ldp     x5, x6, [x0,#16]
-        // Load BL
-        ldp     x10, x11, [x1,#0]
-        ldp     x12, x13, [x1,#16]
-
-        // Temporarily store x8 in x2
-        stp     x8, x9, [x2,#0]
-        // x21-x28 <- AL x BL
-        $mul_albl
-        // Restore x8
-        ldp     x8, x9, [x2,#0]
-
-        // x8-x10,x20,x15-x17,x19 <- maskd (AH+AL) x (BH+BL) - ALxBL
-        subs    x8, x8, x21
-        sbcs    x9, x9, x22
-        sbcs    x19, x19, x23
-        sbcs    x20, x20, x24
-        sbcs    x14, x14, x25
-        sbcs    x15, x15, x26
-        sbcs    x16, x16, x27
-        sbcs    x17, x17, x28
-        sbc     x7, x7, xzr
-
-        // Store ALxBL, low
-        stp     x21, x22, [x2]
-        stp     x23, x24, [x2,#16]
-
-        // Load AH
-        ldp     x3, x4, [x0,#32]
-        ldr     x5,     [x0,#48]
-        // Load BH
-        ldp     x10, x11, [x1,#32]
-        ldr     x12,      [x1,#48]
-
-        adds     x8,  x8, x25
-        adcs     x9,  x9, x26
-        adcs    x19, x19, x27
-        adcs    x20, x20, x28
-        adc     x1, xzr, xzr
-
-        add     x0, x0, #32
-        // Temporarily store x8,x9 in x2
-        stp     x8,x9, [x2,#32]
-        // x21-x28 <- AH x BH
-        $mul_ahbh
-        // Restore x8,x9
-        ldp     x8,x9, [x2,#32]
-
-        neg     x1, x1
-
-        // x8-x9,x19,x20,x14-x17 <- (AH+AL) x (BH+BL) - ALxBL - AHxBH
-        subs    x8, x8, x21
-        sbcs    x9, x9, x22
-        sbcs    x19, x19, x23
-        sbcs    x20, x20, x24
-        sbcs    x14, x14, x25
-        sbcs    x15, x15, x26
-        sbcs    x16, x16, xzr
-        sbcs    x17, x17, xzr
-        sbc     x7, x7, xzr
-
-        // Store (AH+AL) x (BH+BL) - ALxBL - AHxBH, low
-        stp      x8,  x9, [x2,#32]
-        stp     x19, x20, [x2,#48]
-
-        adds     x1,  x1, #1
-        adcs    x14, x14, x21
-        adcs    x15, x15, x22
-        adcs    x16, x16, x23
-        adcs    x17, x17, x24
-        adcs    x25,  x7, x25
-        adc     x26, x26, xzr
-
-        stp     x14, x15, [x2,#64]
-        stp     x16, x17, [x2,#80]
-        stp     x25, x26, [x2,#96]
-
-        ldp     x19, x20, [x29,#16]
-        ldp     x21, x22, [x29,#32]
-        ldp     x23, x24, [x29,#48]
-        ldp     x25, x26, [x29,#64]
-        ldp     x27, x28, [x29,#80]
-        ldp     x29, x30, [sp],#96
-        ret
-___
-    return $body;
-}
-$code.=&mul();
-
-#  Montgomery reduction
-#  Based on method described in Faz-Hernandez et al. https://eprint.iacr.org/2017/1015
-#  Operation: mc [x1] = ma [x0]
-#  NOTE: ma=mc is not allowed
-sub rdc {
-    my $mul01=&mul128x256(
-        "x2","x3",                     # A0-A1
-        "x23","x24","x25","x26",       # B0-B3
-        "x4","x5","x6","x7","x8","x9", # C0-C5
-        "x10","x11","x27","x28");      # TMP
-    my $mul23=&mul128x256(
-        "x2","x10",                    # A0-A1
-        "x23","x24","x25","x26",       # B0-B3
-        "x4","x5","x6","x7","x8","x9", # C0-C5
-        "x0","x3","x27","x28");        # TMP
-    my $mul45=&mul128x256(
-        "x11","x12",                   # A0-A1
-        "x23","x24","x25","x26",       # B0-B3
-        "x4","x5","x6","x7","x8","x9", # C0-C5
-        "x10","x3","x27","x28");       # TMP
-    my $mul67=&mul64x256(
-        "x13",                         # A0
-        "x23","x24","x25","x26",       # B0-B3
-        "x4","x5","x6","x7","x8",      # C0-C4
-        "x10","x27","x28");            # TMP
-    my $body=<<___;
-    .global ${PREFIX}_fprdc
-    .align 4
-    ${PREFIX}_fprdc:
-        stp     x29, x30, [sp, #-96]!
-        add     x29, sp, xzr
-        stp     x19, x20, [sp,#16]
-        stp     x21, x22, [sp,#32]
-        stp     x23, x24, [sp,#48]
-        stp     x25, x26, [sp,#64]
-        stp     x27, x28, [sp,#80]
-
-        ldp     x2, x3, [x0,#0]       // a[0-1]
-
-        // Load the prime constant
-        adrp    x26, :pg_hi21:.Lp434p1
-        add     x26, x26, :lo12:.Lp434p1
-        ldp     x23, x24, [x26, #0x0]
-        ldp     x25, x26, [x26,#0x10]
-
-        // a[0-1] * p434+1
-        $mul01
-
-        ldp     x10, x11, [x0, #0x18]
-        ldp     x12, x13, [x0, #0x28]
-        ldp     x14, x15, [x0, #0x38]
-        ldp     x16, x17, [x0, #0x48]
-        ldp     x19, x20, [x0, #0x58]
-        ldr     x21,      [x0, #0x68]
-
-        adds     x10, x10, x4
-        adcs     x11, x11, x5
-        adcs     x12, x12, x6
-        adcs     x13, x13, x7
-        adcs     x14, x14, x8
-        adcs     x15, x15, x9
-        adcs     x22, x16, xzr
-        adcs     x17, x17, xzr
-        adcs     x19, x19, xzr
-        adcs     x20, x20, xzr
-        adc      x21, x21, xzr
-
-        ldr      x2,  [x0,#0x10]       // a[2]
-        // a[2-3] * p434+1
-        $mul23
-
-        adds    x12, x12, x4
-        adcs    x13, x13, x5
-        adcs    x14, x14, x6
-        adcs    x15, x15, x7
-        adcs    x16, x22, x8
-        adcs    x17, x17, x9
-        adcs    x22, x19, xzr
-        adcs    x20, x20, xzr
-        adc     x21, x21, xzr
-
-        $mul45
-        adds    x14, x14, x4
-        adcs    x15, x15, x5
-        adcs    x16, x16, x6
-        adcs    x17, x17, x7
-        adcs    x19, x22, x8
-        adcs    x20, x20, x9
-        adc     x22, x21, xzr
-
-        stp     x14, x15, [x1, #0x0]     // C0, C1
-
-        $mul67
-        adds    x16, x16, x4
-        adcs    x17, x17, x5
-        adcs    x19, x19, x6
-        adcs    x20, x20, x7
-        adc     x21, x22, x8
-
-        str     x16,       [x1, #0x10]
-        stp     x17, x19,  [x1, #0x18]
-        stp     x20, x21,  [x1, #0x28]
-
-        ldp     x19, x20, [x29,#16]
-        ldp     x21, x22, [x29,#32]
-        ldp     x23, x24, [x29,#48]
-        ldp     x25, x26, [x29,#64]
-        ldp     x27, x28, [x29,#80]
-        ldp     x29, x30, [sp],#96
-        ret
-___
-}
-$code.=&rdc();
-
-#  Field addition
-#  Operation: c [x2] = a [x0] + b [x1]
-$code.=<<___;
-    .global ${PREFIX}_fpadd
-    .align 4
-    ${PREFIX}_fpadd:
-        stp     x29,x30, [sp,#-16]!
-        add     x29, sp, #0
-
-        ldp     x3, x4,   [x0,#0]
-        ldp     x5, x6,   [x0,#16]
-        ldp     x7, x8,   [x0,#32]
-        ldr     x9,       [x0,#48]
-        ldp     x11, x12, [x1,#0]
-        ldp     x13, x14, [x1,#16]
-        ldp     x15, x16, [x1,#32]
-        ldr     x17,      [x1,#48]
-
-        // Add a + b
-        adds    x3, x3, x11
-        adcs    x4, x4, x12
-        adcs    x5, x5, x13
-        adcs    x6, x6, x14
-        adcs    x7, x7, x15
-        adcs    x8, x8, x16
-        adc     x9, x9, x17
-
-        //  Subtract 2xp434
-        adrp    x17, :pg_hi21:.Lp434x2
-        add     x17, x17, :lo12:.Lp434x2
-        ldp     x11, x12, [x17, #0]
-        ldp     x13, x14, [x17, #16]
-        ldp     x15, x16, [x17, #32]
-        subs    x3, x3, x11
-        sbcs    x4, x4, x12
-        sbcs    x5, x5, x12
-        sbcs    x6, x6, x13
-        sbcs    x7, x7, x14
-        sbcs    x8, x8, x15
-        sbcs    x9, x9, x16
-        sbc     x0, xzr, xzr    // x0 can be reused now
-
-        // Add 2xp434 anded with the mask in x0
-        and     x11, x11, x0
-        and     x12, x12, x0
-        and     x13, x13, x0
-        and     x14, x14, x0
-        and     x15, x15, x0
-        and     x16, x16, x0
-
-        adds    x3, x3, x11
-        adcs    x4, x4, x12
-        adcs    x5, x5, x12
-        adcs    x6, x6, x13
-        adcs    x7, x7, x14
-        adcs    x8, x8, x15
-        adc     x9, x9, x16
-
-        stp     x3, x4,  [x2,#0]
-        stp     x5, x6,  [x2,#16]
-        stp     x7, x8,  [x2,#32]
-        str     x9,      [x2,#48]
-
-        ldp     x29, x30, [sp],#16
-        ret
-___
-
-#  Field subtraction
-#  Operation: c [x2] = a [x0] - b [x1]
-$code.=<<___;
-    .global ${PREFIX}_fpsub
-    .align 4
-    ${PREFIX}_fpsub:
-        stp     x29, x30, [sp,#-16]!
-        add     x29, sp, #0
-
-        ldp     x3, x4,   [x0,#0]
-        ldp     x5, x6,   [x0,#16]
-        ldp     x7, x8,   [x0,#32]
-        ldr     x9,       [x0,#48]
-        ldp     x11, x12, [x1,#0]
-        ldp     x13, x14, [x1,#16]
-        ldp     x15, x16, [x1,#32]
-        ldr     x17,      [x1,#48]
-
-        // Subtract a - b
-        subs    x3, x3, x11
-        sbcs    x4, x4, x12
-        sbcs    x5, x5, x13
-        sbcs    x6, x6, x14
-        sbcs    x7, x7, x15
-        sbcs    x8, x8, x16
-        sbcs    x9, x9, x17
-        sbc     x0, xzr, xzr
-
-        // Add 2xp434 anded with the mask in x0
-        adrp    x17, :pg_hi21:.Lp434x2
-        add     x17, x17, :lo12:.Lp434x2
-
-        // First half
-        ldp     x11, x12, [x17, #0]
-        ldp     x13, x14, [x17, #16]
-        ldp     x15, x16, [x17, #32]
-
-        // Add 2xp434 anded with the mask in x0
-        and     x11, x11, x0
-        and     x12, x12, x0
-        and     x13, x13, x0
-        and     x14, x14, x0
-        and     x15, x15, x0
-        and     x16, x16, x0
-
-        adds    x3, x3, x11
-        adcs    x4, x4, x12
-        adcs    x5, x5, x12
-        adcs    x6, x6, x13
-        adcs    x7, x7, x14
-        adcs    x8, x8, x15
-        adc     x9, x9, x16
-
-        stp     x3, x4,  [x2,#0]
-        stp     x5, x6,  [x2,#16]
-        stp     x7, x8,  [x2,#32]
-        str     x9,      [x2,#48]
-
-        ldp     x29, x30, [sp],#16
-        ret
-___
-
-# 434-bit multiprecision addition
-# Operation: c [x2] = a [x0] + b [x1]
-$code.=<<___;
-    .global ${PREFIX}_mpadd_asm
-    .align 4
-    ${PREFIX}_mpadd_asm:
-        stp     x29, x30, [sp,#-16]!
-        add     x29, sp, #0
-
-        ldp     x3, x4,   [x0,#0]
-        ldp     x5, x6,   [x0,#16]
-        ldp     x7, x8,   [x0,#32]
-        ldr     x9,       [x0,#48]
-        ldp     x11, x12, [x1,#0]
-        ldp     x13, x14, [x1,#16]
-        ldp     x15, x16, [x1,#32]
-        ldr     x17,      [x1,#48]
-
-        adds    x3, x3, x11
-        adcs    x4, x4, x12
-        adcs    x5, x5, x13
-        adcs    x6, x6, x14
-        adcs    x7, x7, x15
-        adcs    x8, x8, x16
-        adc     x9, x9, x17
-
-        stp     x3, x4,   [x2,#0]
-        stp     x5, x6,   [x2,#16]
-        stp     x7, x8,   [x2,#32]
-        str     x9,       [x2,#48]
-
-        ldp     x29, x30, [sp],#16
-        ret
-___
-
-# 2x434-bit multiprecision subtraction
-# Operation: c [x2] = a [x0] - b [x1].
-# Returns borrow mask
-$code.=<<___;
-    .global ${PREFIX}_mpsubx2_asm
-    .align 4
-    ${PREFIX}_mpsubx2_asm:
-        stp     x29, x30, [sp,#-16]!
-        add     x29, sp, #0
-
-        ldp     x3, x4,   [x0,#0]
-        ldp     x5, x6,   [x0,#16]
-        ldp     x11, x12, [x1,#0]
-        ldp     x13, x14, [x1,#16]
-        subs    x3, x3, x11
-        sbcs    x4, x4, x12
-        sbcs    x5, x5, x13
-        sbcs    x6, x6, x14
-        ldp     x7, x8,   [x0,#32]
-        ldp     x9, x10,  [x0,#48]
-        ldp     x11, x12, [x1,#32]
-        ldp     x13, x14, [x1,#48]
-        sbcs    x7, x7, x11
-        sbcs    x8, x8, x12
-        sbcs    x9, x9, x13
-        sbcs    x10, x10, x14
-
-        stp     x3, x4,   [x2,#0]
-        stp     x5, x6,   [x2,#16]
-        stp     x7, x8,   [x2,#32]
-        stp     x9, x10,  [x2,#48]
-
-        ldp     x3, x4,   [x0,#64]
-        ldp     x5, x6,   [x0,#80]
-        ldp     x11, x12, [x1,#64]
-        ldp     x13, x14, [x1,#80]
-        sbcs    x3, x3, x11
-        sbcs    x4, x4, x12
-        sbcs    x5, x5, x13
-        sbcs    x6, x6, x14
-        ldp     x7, x8,   [x0,#96]
-        ldp     x11, x12, [x1,#96]
-        sbcs    x7, x7, x11
-        sbcs    x8, x8, x12
-        sbc     x0, xzr, xzr
-
-        stp     x3, x4,   [x2,#64]
-        stp     x5, x6,   [x2,#80]
-        stp     x7, x8,   [x2,#96]
-
-        ldp     x29, x30, [sp],#16
-        ret
-___
-
-
-# Double 2x434-bit multiprecision subtraction
-# Operation: c [x2] = c [x2] - a [x0] - b [x1]
-$code.=<<___;
-    .global ${PREFIX}_mpdblsubx2_asm
-    .align 4
-    ${PREFIX}_mpdblsubx2_asm:
-        stp     x29, x30, [sp, #-16]!
-        add     x29, sp, #0
-
-        ldp     x3, x4,   [x2, #0]
-        ldp     x5, x6,   [x2,#16]
-        ldp     x7, x8,   [x2,#32]
-
-        ldp     x11, x12, [x0, #0]
-        ldp     x13, x14, [x0,#16]
-        ldp     x15, x16, [x0,#32]
-
-        subs    x3, x3, x11
-        sbcs    x4, x4, x12
-        sbcs    x5, x5, x13
-        sbcs    x6, x6, x14
-        sbcs    x7, x7, x15
-        sbcs    x8, x8, x16
-
-        // x9 stores carry
-        adc     x9, xzr, xzr
-
-        ldp     x11, x12, [x1, #0]
-        ldp     x13, x14, [x1,#16]
-        ldp     x15, x16, [x1,#32]
-        subs    x3, x3, x11
-        sbcs    x4, x4, x12
-        sbcs    x5, x5, x13
-        sbcs    x6, x6, x14
-        sbcs    x7, x7, x15
-        sbcs    x8, x8, x16
-        adc     x9, x9, xzr
-
-        stp     x3, x4,   [x2, #0]
-        stp     x5, x6,   [x2,#16]
-        stp     x7, x8,   [x2,#32]
-
-        ldp     x3, x4,   [x2,#48]
-        ldp     x5, x6,   [x2,#64]
-        ldp     x7, x8,   [x2,#80]
-
-        ldp     x11, x12, [x0,#48]
-        ldp     x13, x14, [x0,#64]
-        ldp     x15, x16, [x0,#80]
-
-        // x9 = 2 - x9
-        neg     x9, x9
-        add     x9, x9, #2
-
-        subs    x3, x3, x9
-        sbcs    x3, x3, x11
-        sbcs    x4, x4, x12
-        sbcs    x5, x5, x13
-        sbcs    x6, x6, x14
-        sbcs    x7, x7, x15
-        sbcs    x8, x8, x16
-        adc     x9, xzr, xzr
-
-        ldp     x11, x12, [x1,#48]
-        ldp     x13, x14, [x1,#64]
-        ldp     x15, x16, [x1,#80]
-        subs    x3, x3, x11
-        sbcs    x4, x4, x12
-        sbcs    x5, x5, x13
-        sbcs    x6, x6, x14
-        sbcs    x7, x7, x15
-        sbcs    x8, x8, x16
-        adc     x9, x9, xzr
-
-        stp     x3, x4,   [x2,#48]
-        stp     x5, x6,   [x2,#64]
-        stp     x7, x8,   [x2,#80]
-
-        ldp      x3,  x4, [x2,#96]
-        ldp     x11, x12, [x0,#96]
-        ldp     x13, x14, [x1,#96]
-
-        // x9 = 2 - x9
-        neg     x9, x9
-        add     x9, x9, #2
-
-        subs    x3, x3, x9
-        sbcs    x3, x3, x11
-        sbcs    x4, x4, x12
-        subs    x3, x3, x13
-        sbc     x4, x4, x14
-        stp     x3, x4,   [x2,#96]
-
-        ldp     x29, x30, [sp],#16
-        ret
-___
-
-foreach (split("\n",$code)) {
-  s/\`([^\`]*)\`/eval($1)/ge;
-  print $_,"\n";
-}
-
-close STDOUT;
diff --git a/third_party/sike/asm/fp-x86_64.pl b/third_party/sike/asm/fp-x86_64.pl
deleted file mode 100755
index cffde1a..0000000
--- a/third_party/sike/asm/fp-x86_64.pl
+++ /dev/null
@@ -1,1626 +0,0 @@
-#! /usr/bin/env perl
-#
-# April 2019
-#
-# Abstract: field arithmetic in x64 assembly for SIDH/p434
-
-$flavour = shift;
-$output  = shift;
-if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-( $xlate="${dir}../../../crypto/perlasm/x86_64-xlate.pl" and -f $xlate) or
-die "can't locate x86_64-xlate.pl";
-
-open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
-*STDOUT=*OUT;
-
-$PREFIX="sike";
-$bmi2_adx = 1;
-
-$code.=<<___;
-.text
-
-# p434 x 2
-.Lp434x2:
-.quad   0xFFFFFFFFFFFFFFFE
-.quad   0xFFFFFFFFFFFFFFFF
-.quad   0xFB82ECF5C5FFFFFF
-.quad   0xF78CB8F062B15D47
-.quad   0xD9F8BFAD038A40AC
-.quad   0x0004683E4E2EE688
-
-# p434 + 1
-.Lp434p1:
-.quad   0xFDC1767AE3000000
-.quad   0x7BC65C783158AEA3
-.quad   0x6CFC5FD681C52056
-.quad   0x0002341F27177344
-
-.extern OPENSSL_ia32cap_P
-.hidden OPENSSL_ia32cap_P
-___
-
-# Jump to alternative implemenatation provided as an
-# argument in case CPU supports ADOX/ADCX and MULX instructions.
-sub alt_impl {
-  $jmp_func = shift;
-
-  $body=<<___;
-  lea OPENSSL_ia32cap_P(%rip), %rcx
-  mov 8(%rcx), %rcx
-  and \$0x80100, %ecx
-  cmp \$0x80100, %ecx
-  je  $jmp_func
-
-___
-  return $body
-}
-
-# Performs schoolbook multiplication of 2 192-bit numbers. Uses
-# MULX instruction. Result is stored in 192 bits pointed by $DST.
-sub mul192 {
-  my ($idxM0,$M0,$idxM1,$M1,$idxDST,$DST,$T0,$T1,$T2,$T3,$T4,$T5,$T6)=@_;
-  my ($ML0,$ML8,$ML16)=map("$idxM0+$_($M0)",(0,8,16));
-  my ($MR0,$MR8,$MR16)=map("$idxM1+$_($M1)",(0,8,16));
-  my ($D0,$D1,$D2,$D3,$D4,$D5)=map("$idxDST+$_($DST)",(0,8,16,24,32,40));
-
-  $body=<<___;
-  mov    $ML0, %rdx
-  mulx   $MR0, $T1, $T0   # T0:T1 = A0*B0
-  mov    $T1, $D0         # DST0
-  mulx   $MR8, $T2, $T1   # T1:T2 = A0*B1
-  xor    %rax, %rax
-  adox   $T2, $T0
-  mulx   $MR16,$T3, $T2   # T2:T3 = A0*B2
-  adox   $T3, $T1
-
-  mov    $ML8, %rdx
-  mulx   $MR0, $T4, $T3   # T3:T4 = A1*B0
-  adox   %rax, $T2
-  xor    %rax, %rax
-
-  mulx   $MR8, $T6, $T5   # T6:T7 = A1*B1
-  adox   $T0, $T4
-  mov    $T4, $D1         # DST1
-  adcx   $T6, $T3
-
-  mulx   $MR16,$T0, $T6   # T6:T0 = A1*B2
-  adox   $T1, $T3
-  adcx   $T0, $T5
-  adcx   %rax, $T6
-  adox   $T2, $T5
-
-  mov    $ML16,%rdx
-  mulx   $MR0, $T0, $T1   # T1:T0 = A2*B0
-  adox   %rax, $T6
-  xor    %rax, %rax
-
-  mulx   $MR8, $T2, $T4   # T4:T2 = A2*B1
-  adox   $T3, $T0
-  mov    $T0, $D2         # DST2
-  adcx   $T5, $T1
-
-  mulx   $MR16,$T3, $T0   # T0:T3 = A2*B2
-  adcx   $T6, $T4
-  adcx   %rax, $T0
-  adox   $T2, $T1
-  adox   $T4, $T3
-  adox   %rax, $T0
-  mov    $T1, $D3          # DST3
-  mov    $T3, $D4          # DST4
-  mov    $T0, $D5          # DST5
-
-___
-  return $body;
-}
-
-# Performs schoolbook multiplication of 2 256-bit numbers. Uses
-# MULX instruction. Result is stored in 256 bits pointed by $DST.
-sub mul256 {
-  my ($idxM0,$M0,$idxM1,$M1,$idxDST,$DST,$T0,$T1,$T2,$T3,$T4,$T5,$T6,$T7,$T8,$T9)=@_;
-  my ($ML0,$ML8,$ML16,$ML24)=map("$idxM0+$_($M0)",(0,8,16,24));
-  my ($MR0,$MR8,$MR16,$MR24)=map("$idxM1+$_($M1)",(0,8,16,24));
-  my ($D0,$D1,$D2,$D3,$D4,$D5,$D6,$D7)=map("$idxDST+$_($DST)",(0,8,16,24,32,40,48,56));
-
-  $body=<<___;
-  mov    $ML0, %rdx
-  mulx   $MR0, $T1, $T0   # T0:T1 = A0*B0
-  mov    $T1, $D0         # DST0_final
-  mulx   $MR8, $T2, $T1   # T1:T2 = A0*B1
-  xor    %rax, %rax
-  adox   $T2, $T0
-  mulx   $MR16,$T3, $T2   # T2:T3 = A0*B2
-  adox   $T3, $T1
-  mulx   $MR24,$T4, $T3   # T3:T4 = A0*B3
-  adox   $T4, $T2
-
-  mov    $ML8, %rdx
-  mulx   $MR0, $T4, $T5   # T5:T4 = A1*B0
-  adox   %rax, $T3
-  xor    %rax, %rax
-  mulx   $MR8, $T7, $T6   # T6:T7 = A1*B1
-  adox   $T0, $T4
-  mov    $T4, $D1         # DST1_final
-  adcx   $T7, $T5
-  mulx   $MR16,$T8, $T7   # T7:T8 = A1*B2
-  adcx   $T8, $T6
-  adox   $T1, $T5
-  mulx   $MR24,$T9, $T8   # T8:T9 = A1*B3
-  adcx   $T9, $T7
-  adcx   %rax, $T8
-  adox   $T2, $T6
-
-  mov    $ML16,%rdx
-  mulx   $MR0, $T0, $T1   # T1:T0 = A2*B0
-  adox   $T3, $T7
-  adox   %rax, $T8
-  xor    %rax, %rax
-  mulx   $MR8, $T3, $T2   # T2:T3 = A2*B1
-  adox   $T5, $T0
-  mov    $T0, $D2         # DST2_final
-  adcx   $T3, $T1
-  mulx   $MR16,$T4, $T3   # T3:T4 = A2*B2
-  adcx   $T4, $T2
-  adox   $T6, $T1
-  mulx   $MR24,$T9, $T4   # T3:T4 = A2*B3
-  adcx   $T9, $T3
-  adcx   %rax, $T4
-
-  adox   $T7, $T2
-  adox   $T8, $T3
-  adox   %rax, $T4
-
-  mov    $ML24,%rdx
-  mulx   $MR0,  $T0, $T5   # T5:T0 = A3*B0
-  xor    %rax,  %rax
-  mulx   $MR8,  $T7, $T6   # T6:T7 = A3*B1
-  adcx   $T7,  $T5
-  adox   $T0,  $T1
-  mulx   $MR16, $T8, $T7   # T7:T8 = A3*B2
-  adcx   $T8,  $T6
-  adox   $T5,  $T2
-  mulx   $MR24, $T9, $T8   # T8:T9 = A3*B3
-  adcx   $T9,  $T7
-  adcx   %rax,  $T8
-  adox   $T6,  $T3
-  adox   $T7,  $T4
-  adox   %rax,  $T8
-  mov    $T1,  $D3          # DST3_final
-  mov    $T2,  $D4          # DST4_final
-  mov    $T3,  $D5          # DST5_final
-  mov    $T4,  $D6          # DST6_final
-  mov    $T8,  $D7          # DST7_final
-
-___
-  return $body;
-}
-
-# Performs schoolbook multiplication of 64-bit with 256-bit
-# number.
-sub mul64x256 {
-  my ($idxM0,$M0,$M1,$T0,$T1,$T2,$T3,$T4,$T5)=@_;
-  my $body.=<<___;
-    mov   $idxM0($M0), $T5
-
-    xor   $T2, $T2
-    mov   0+$M1, %rax
-    mul   $T5
-    mov   %rax, $T0   # C0
-    mov   %rdx, $T1
-
-    xor   $T3, $T3
-    mov   8+$M1, %rax
-    mul   $T5
-    add   %rax, $T1   # C1
-    adc   %rdx, $T2
-
-    xor   $T4, $T4
-    mov   16+$M1, %rax
-    mul   $T5
-    add   %rax, $T2   # C2
-    adc   %rdx, $T3
-
-    mov   24+$M1, %rax
-    mul   $T5
-    add   %rax, $T3   # C3
-    adc   %rdx, $T4   # C4
-___
-  return $body;
-}
-
-# Performs schoolbook multiplication of 64-bit with 256-bit
-# number. Uses MULX and ADOX instructions.
-sub mulx64x256 {
-  my ($idxM0,$M0,$M1,$T0,$T1,$T2,$T3,$T4,$T5)=@_;
-  my $body.=<<___;
-    xor    %rax, %rax
-    mov    $idxM0($M0), %rdx
-    mulx   0+$M1, $T0, $T1    # T0 <- C0
-    mulx   8+$M1, $T4, $T2
-    mulx   16+$M1, $T5, $T3
-
-    adox   $T4, $T1         # T1 <- C1
-    adox   $T5, $T2         # T2 <- C2
-
-    mulx   24+$M1, $T5, $T4
-    adox   $T5, $T3         # T3 <- C3
-    adox   %rax, $T4         # T4 <- C4
-___
-  return $body;
-}
-
-# Performs schoolbook multiplication of 128-bit with 256-bit
-# number. Destroys RAX and RDX
-sub mul128x256 {
-  my ($idxMA,$MA,$MB,$C0,$C1,$C2,$C3,$C4,$C5,$T0,$T1)=@_;
-  my ($MA0,$MA8)=map("$idxMA+$_($MA)", (0,8));
-  my $body.=<<___;
-    # A0 x B0
-    mov   $MA0, $T0
-    mov   0+$MB, %rax
-    mul   $T0
-    xor   $C2, $C2
-    mov   %rax, $C0   # c0
-    mov   %rdx, $C1
-
-    # A0 x B1
-    mov   8+$MB, %rax
-    mul   $T0
-    xor   $C3, $C3
-    add   %rax, $C1
-    adc   %rdx, $C2
-
-    # A1 x B0
-    mov   $MA8, $T1
-    mov   0+$MB, %rax
-    mul   $T1
-    add   %rax, $C1
-    adc   %rdx, $C2
-    adc   \$0x0, $C3
-
-    # A0 x B2
-    xor   $C4, $C4
-    mov   16+$MB, %rax
-    mul   $T0
-    add   %rax, $C2
-    adc   %rdx, $C3
-    adc   \$0x0, $C4
-
-    # A1 x B1
-    mov   8+$MB, %rax
-    mul   $T1
-    add   %rax, $C2           # c2
-    adc   %rdx, $C3
-    adc   \$0x0, $C4
-
-    # A0 x B3
-    mov   24+$MB, %rax
-    mul   $T0
-    xor   $C5, $C5
-    add   %rax, $C3
-    adc   %rdx, $C4
-    adc   \$0x0, $C5
-
-    # A1 x B2
-    mov   16+$MB, %rax
-    mul   $T1
-    add   %rax, $C3          # c3
-    adc   %rdx, $C4
-    adc   \$0x0, $C5
-
-    # A1 x B3
-    mov   24+$MB, %rax
-    mul   $T1
-    add   %rax, $C4
-    adc   %rdx, $C5
-
-___
-  return $body;
-}
-
-# Performs schoolbook multiplication of 128-bit with 256-bit
-# number. Uses MULX, ADOX, ADCX instruction.
-sub mulx128x256 {
-  my ($idxM0,$M0,$M1,$T0,$T1,$T2,$T3,$T4,$T5,$T6)=@_;
-  my ($MUL0,$MUL8)=map("$idxM0+$_($M0)", (0,8));
-  my $body.=<<___;
-    xor     %rax, %rax
-    mov    $MUL0, %rdx
-    mulx   0+$M1, $T0, $T1        # T0 <- C0
-    mulx   8+$M1, $T4, $T2
-    mulx   16+$M1, $T5, $T3
-
-    adox   $T4, $T1               # T1: interm1
-    adox   $T5, $T2               # T2: interm2
-
-    mulx   24+$M1, $T5, $T4
-    adox   $T5, $T3               # T3: interm3
-    adox   %rax, $T4              # T4: interm4
-
-    xor    %rax, %rax
-    mov    $MUL8, %rdx
-    mulx   0+$M1, $T5, $T6
-    adcx   $T5, $T1               # T1 <- C1
-    adcx   $T6, $T2
-
-    mulx   8+$M1, $T6, $T5
-    adcx   $T5, $T3
-    adox   $T6, $T2               # T2 <- C2
-
-    mulx   16+$M1, $T6, $T5
-    adcx   $T5, $T4
-    adox   $T6, $T3               # T3 <- C3
-
-    mulx   24+$M1, $T6, $T5
-    adcx   %rax, $T5
-    adox   $T6, $T4               # T4 <- C4
-    adox   %rax, $T5              # T5 <- C5
-___
-  return $body;
-}
-
-# Compute z = x + y (mod p).
-# Operation: c [rdx] = a [rdi] + b [rsi]
-$code.=<<___;
-.globl  ${PREFIX}_fpadd
-.type   ${PREFIX}_fpadd,\@function,3
-${PREFIX}_fpadd:
-.cfi_startproc
-  push %r12
-.cfi_adjust_cfa_offset  8
-.cfi_offset r12, -16
-  push %r13
-.cfi_adjust_cfa_offset  8
-.cfi_offset r13, -24
-  push %r14
-.cfi_adjust_cfa_offset  8
-.cfi_offset r14, -32
-
-  xor   %rax, %rax
-
-  mov    0x0(%rdi),  %r8
-  add    0x0(%rsi),  %r8
-  mov    0x8(%rdi),  %r9
-  adc    0x8(%rsi),  %r9
-  mov   0x10(%rdi), %r10
-  adc   0x10(%rsi), %r10
-  mov   0x18(%rdi), %r11
-  adc   0x18(%rsi), %r11
-  mov   0x20(%rdi), %r12
-  adc   0x20(%rsi), %r12
-  mov   0x28(%rdi), %r13
-  adc   0x28(%rsi), %r13
-  mov   0x30(%rdi), %r14
-  adc   0x30(%rsi), %r14
-
-  mov        .Lp434x2(%rip), %rcx
-  sub   %rcx, %r8
-  mov    0x8+.Lp434x2(%rip), %rcx
-  sbb   %rcx, %r9
-  sbb   %rcx, %r10
-  mov   0x10+.Lp434x2(%rip), %rcx
-  sbb   %rcx, %r11
-  mov   0x18+.Lp434x2(%rip), %rcx
-  sbb   %rcx, %r12
-  mov   0x20+.Lp434x2(%rip), %rcx
-  sbb   %rcx, %r13
-  mov   0x28+.Lp434x2(%rip), %rcx
-  sbb   %rcx, %r14
-
-  sbb   \$0, %rax
-
-  mov   .Lp434x2(%rip), %rdi
-  and   %rax, %rdi
-  mov   0x8+.Lp434x2(%rip), %rsi
-  and   %rax, %rsi
-  mov   0x10+.Lp434x2(%rip), %rcx
-  and   %rax, %rcx
-
-  add   %rdi,  %r8
-  mov   %r8,   0x0(%rdx)
-  adc   %rsi,  %r9
-  mov   %r9,   0x8(%rdx)
-  adc   %rsi, %r10
-  mov   %r10, 0x10(%rdx)
-  adc   %rcx, %r11
-  mov   %r11, 0x18(%rdx)
-
-  setc  %cl
-  mov   0x18+.Lp434x2(%rip),  %r8
-  and   %rax,  %r8
-  mov   0x20+.Lp434x2(%rip),  %r9
-  and   %rax,  %r9
-  mov   0x28+.Lp434x2(%rip), %r10
-  and   %rax, %r10
-  bt    \$0, %rcx
-
-  adc   %r8, %r12
-  mov   %r12, 0x20(%rdx)
-  adc   %r9, %r13
-  mov   %r13, 0x28(%rdx)
-  adc   %r10, %r14
-  mov  %r14, 0x30(%rdx)
-
-  pop %r14
-.cfi_adjust_cfa_offset  -8
-  pop %r13
-.cfi_adjust_cfa_offset  -8
-  pop %r12
-.cfi_adjust_cfa_offset  -8
-  ret
-.cfi_endproc
-___
-
-# Loads data to XMM0 and XMM1 and
-# conditionaly swaps depending on XMM3
-sub cswap_block16() {
-  my $idx = shift;
-  $idx *= 16;
-  ("
-    movdqu   $idx(%rdi), %xmm0
-    movdqu   $idx(%rsi), %xmm1
-    movdqa   %xmm1, %xmm2
-    pxor     %xmm0, %xmm2
-    pand     %xmm3, %xmm2
-    pxor     %xmm2, %xmm0
-    pxor     %xmm2, %xmm1
-    movdqu   %xmm0, $idx(%rdi)
-    movdqu   %xmm1, $idx(%rsi)
-  ");
-}
-
-# Conditionally swaps bits in x and y in constant time.
-# mask indicates bits to be swapped (set bits are swapped)
-# Operation: [rdi] <-> [rsi] if rdx==1
-sub sike_cswap {
-  # P[0] with Q[0]
-  foreach ( 0.. 6){$BLOCKS.=eval "&cswap_block16($_)";}
-  # P[1] with Q[1]
-  foreach ( 7..13){$BLOCKS.=eval "&cswap_block16($_)";}
-
-  my $body =<<___;
-.globl  ${PREFIX}_cswap_asm
-.type   ${PREFIX}_cswap_asm,\@function,3
-${PREFIX}_cswap_asm:
-  # Fill XMM3. After this step first half of XMM3 is
-  # just zeros and second half is whatever in RDX
-  mov   %rdx, %xmm3
-
-  # Copy lower double word everywhere else. So that
-  # XMM3=RDX|RDX. As RDX has either all bits set
-  # or non result will be that XMM3 has also either
-  # all bits set or non of them. 68 = 01000100b
-  pshufd  \$68, %xmm3, %xmm3
-  $BLOCKS
-  ret
-___
-  ($body)
-}
-$code.=&sike_cswap();
-
-
-# Field subtraction
-# Operation: c [rdx] = a [rdi] - b [rsi]
-$code.=<<___;
-.globl  ${PREFIX}_fpsub
-.type   ${PREFIX}_fpsub,\@function,3
-${PREFIX}_fpsub:
-.cfi_startproc
-  push   %r12
-.cfi_adjust_cfa_offset  8
-.cfi_offset r12, -16
-  push   %r13
-.cfi_adjust_cfa_offset  8
-.cfi_offset r13, -24
-  push   %r14
-.cfi_adjust_cfa_offset  8
-.cfi_offset r14, -32
-
-  xor %rax, %rax
-
-  mov    0x0(%rdi),  %r8
-  sub    0x0(%rsi),  %r8
-  mov    0x8(%rdi),  %r9
-  sbb    0x8(%rsi),  %r9
-  mov   0x10(%rdi), %r10
-  sbb   0x10(%rsi), %r10
-  mov   0x18(%rdi), %r11
-  sbb   0x18(%rsi), %r11
-  mov   0x20(%rdi), %r12
-  sbb   0x20(%rsi), %r12
-  mov   0x28(%rdi), %r13
-  sbb   0x28(%rsi), %r13
-  mov   0x30(%rdi), %r14
-  sbb   0x30(%rsi), %r14
-
-  sbb   \$0x0, %rax
-
-  mov   .Lp434x2(%rip), %rdi
-  and   %rax, %rdi
-  mov   0x08+.Lp434x2(%rip), %rsi
-  and   %rax, %rsi
-  mov   0x10+.Lp434x2(%rip), %rcx
-  and   %rax, %rcx
-
-  add   %rdi,  %r8
-  mov   %r8,   0x0(%rdx)
-  adc   %rsi,  %r9
-  mov   %r9,   0x8(%rdx)
-  adc   %rsi, %r10
-  mov   %r10, 0x10(%rdx)
-  adc   %rcx, %r11
-  mov   %r11, 0x18(%rdx)
-
-  setc  %cl
-  mov   0x18+.Lp434x2(%rip),  %r8
-  and   %rax,  %r8
-  mov   0x20+.Lp434x2(%rip),  %r9
-  and   %rax,  %r9
-  mov   0x28+.Lp434x2(%rip), %r10
-  and   %rax, %r10
-  bt    \$0x0, %rcx
-
-  adc   %r8, %r12
-  adc   %r9, %r13
-  adc   %r10, %r14
-  mov   %r12, 0x20(%rdx)
-  mov   %r13, 0x28(%rdx)
-  mov   %r14, 0x30(%rdx)
-
-  pop %r14
-.cfi_adjust_cfa_offset  -8
-  pop %r13
-.cfi_adjust_cfa_offset  -8
-  pop %r12
-.cfi_adjust_cfa_offset  -8
-  ret
-.cfi_endproc
-___
-
-#  434-bit multiprecision addition
-#  Operation: c [rdx] = a [rdi] + b [rsi]
-$code.=<<___;
-.globl  ${PREFIX}_mpadd_asm
-.type   ${PREFIX}_mpadd_asm,\@function,3
-${PREFIX}_mpadd_asm:
-.cfi_startproc
-  mov    0x0(%rdi), %r8;
-  mov    0x8(%rdi), %r9
-  mov   0x10(%rdi), %r10
-  mov   0x18(%rdi), %r11
-  mov   0x20(%rdi), %rcx
-  add    0x0(%rsi), %r8
-  adc    0x8(%rsi), %r9
-  adc   0x10(%rsi), %r10
-  adc   0x18(%rsi), %r11
-  adc   0x20(%rsi), %rcx
-  mov   %r8,   0x0(%rdx)
-  mov   %r9,   0x8(%rdx)
-  mov   %r10, 0x10(%rdx)
-  mov   %r11, 0x18(%rdx)
-  mov   %rcx, 0x20(%rdx)
-
-  mov   0x28(%rdi), %r8
-  mov   0x30(%rdi), %r9
-  adc   0x28(%rsi), %r8
-  adc   0x30(%rsi), %r9
-  mov   %r8, 0x28(%rdx)
-  mov   %r9, 0x30(%rdx)
-  ret
-.cfi_endproc
-___
-
-#  2x434-bit multiprecision subtraction
-#  Operation: c [rdx] = a [rdi] - b [rsi].
-#  Returns borrow mask
-$code.=<<___;
-.globl  ${PREFIX}_mpsubx2_asm
-.type   ${PREFIX}_mpsubx2_asm,\@function,3
-${PREFIX}_mpsubx2_asm:
-.cfi_startproc
-  xor   %rax, %rax
-
-  mov    0x0(%rdi), %r8
-  mov    0x8(%rdi), %r9
-  mov   0x10(%rdi), %r10
-  mov   0x18(%rdi), %r11
-  mov   0x20(%rdi), %rcx
-  sub    0x0(%rsi), %r8
-  sbb    0x8(%rsi), %r9
-  sbb   0x10(%rsi), %r10
-  sbb   0x18(%rsi), %r11
-  sbb   0x20(%rsi), %rcx
-  mov   %r8,   0x0(%rdx)
-  mov   %r9,   0x8(%rdx)
-  mov   %r10, 0x10(%rdx)
-  mov   %r11, 0x18(%rdx)
-  mov   %rcx, 0x20(%rdx)
-
-  mov   0x28(%rdi), %r8
-  mov   0x30(%rdi), %r9
-  mov   0x38(%rdi), %r10
-  mov   0x40(%rdi), %r11
-  mov   0x48(%rdi), %rcx
-  sbb   0x28(%rsi), %r8
-  sbb   0x30(%rsi), %r9
-  sbb   0x38(%rsi), %r10
-  sbb   0x40(%rsi), %r11
-  sbb   0x48(%rsi), %rcx
-  mov   %r8,  0x28(%rdx)
-  mov   %r9,  0x30(%rdx)
-  mov   %r10, 0x38(%rdx)
-  mov   %r11, 0x40(%rdx)
-  mov   %rcx, 0x48(%rdx)
-
-  mov   0x50(%rdi), %r8
-  mov   0x58(%rdi), %r9
-  mov   0x60(%rdi), %r10
-  mov   0x68(%rdi), %r11
-  sbb   0x50(%rsi), %r8
-  sbb   0x58(%rsi), %r9
-  sbb   0x60(%rsi), %r10
-  sbb   0x68(%rsi), %r11
-  sbb   \$0x0, %rax
-  mov   %r8,  0x50(%rdx)
-  mov   %r9,  0x58(%rdx)
-  mov   %r10, 0x60(%rdx)
-  mov   %r11, 0x68(%rdx)
-  ret
-.cfi_endproc
-___
-
-
-#  Double 2x434-bit multiprecision subtraction
-#  Operation: c [rdx] = c [rdx] - a [rdi] - b [rsi]
-$code.=<<___;
-.globl  ${PREFIX}_mpdblsubx2_asm
-.type   ${PREFIX}_mpdblsubx2_asm,\@function,3
-${PREFIX}_mpdblsubx2_asm:
-.cfi_startproc
-  push   %r12
-.cfi_adjust_cfa_offset 8
-.cfi_offset r12, -16
-  push   %r13
-.cfi_adjust_cfa_offset 8
-.cfi_offset r13, -24
-
-  xor   %rax, %rax
-
-  # ci:low = c:low - a:low
-  mov    0x0(%rdx), %r8
-  mov    0x8(%rdx), %r9
-  mov   0x10(%rdx), %r10
-  mov   0x18(%rdx), %r11
-  mov   0x20(%rdx), %r12
-  mov   0x28(%rdx), %r13
-  mov   0x30(%rdx), %rcx
-  sub    0x0(%rdi), %r8
-  sbb    0x8(%rdi), %r9
-  sbb   0x10(%rdi), %r10
-  sbb   0x18(%rdi), %r11
-  sbb   0x20(%rdi), %r12
-  sbb   0x28(%rdi), %r13
-  sbb   0x30(%rdi), %rcx
-  adc   \$0x0, %rax
-
-  # c:low = ci:low - b:low
-  sub    0x0(%rsi), %r8
-  sbb    0x8(%rsi), %r9
-  sbb   0x10(%rsi), %r10
-  sbb   0x18(%rsi), %r11
-  sbb   0x20(%rsi), %r12
-  sbb   0x28(%rsi), %r13
-  sbb   0x30(%rsi), %rcx
-  adc   \$0x0, %rax
-
-  # store c:low
-  mov   %r8,   0x0(%rdx)
-  mov   %r9,   0x8(%rdx)
-  mov   %r10, 0x10(%rdx)
-  mov   %r11, 0x18(%rdx)
-  mov   %r12, 0x20(%rdx)
-  mov   %r13, 0x28(%rdx)
-  mov   %rcx, 0x30(%rdx)
-
-  # ci:high = c:high - a:high
-  mov   0x38(%rdx), %r8
-  mov   0x40(%rdx), %r9
-  mov   0x48(%rdx), %r10
-  mov   0x50(%rdx), %r11
-  mov   0x58(%rdx), %r12
-  mov   0x60(%rdx), %r13
-  mov   0x68(%rdx), %rcx
-
-  sub   %rax, %r8
-  sbb   0x38(%rdi), %r8
-  sbb   0x40(%rdi), %r9
-  sbb   0x48(%rdi), %r10
-  sbb   0x50(%rdi), %r11
-  sbb   0x58(%rdi), %r12
-  sbb   0x60(%rdi), %r13
-  sbb   0x68(%rdi), %rcx
-
-  # c:high = ci:high - b:high
-  sub   0x38(%rsi), %r8
-  sbb   0x40(%rsi), %r9
-  sbb   0x48(%rsi), %r10
-  sbb   0x50(%rsi), %r11
-  sbb   0x58(%rsi), %r12
-  sbb   0x60(%rsi), %r13
-  sbb   0x68(%rsi), %rcx
-
-  # store c:high
-  mov   %r8,  0x38(%rdx)
-  mov   %r9,  0x40(%rdx)
-  mov   %r10, 0x48(%rdx)
-  mov   %r11, 0x50(%rdx)
-  mov   %r12, 0x58(%rdx)
-  mov   %r13, 0x60(%rdx)
-  mov   %rcx, 0x68(%rdx)
-
-  pop %r13
-.cfi_adjust_cfa_offset -8
-  pop %r12
-.cfi_adjust_cfa_offset -8
-  ret
-.cfi_endproc
-
-___
-
-sub redc_common {
-  my ($mul01, $mul23, $mul45, $mul67)=@_;
-  my $body=<<___;
-    $mul01
-    xor   %rcx, %rcx
-    add   0x18(%rdi), %r8
-    adc   0x20(%rdi), %r9
-    adc   0x28(%rdi), %r10
-    adc   0x30(%rdi), %r11
-    adc   0x38(%rdi), %r12
-    adc   0x40(%rdi), %r13
-    adc   0x48(%rdi), %rcx
-    mov   %r8, 0x18(%rdi)
-    mov   %r9, 0x20(%rdi)
-    mov   %r10, 0x28(%rdi)
-    mov   %r11, 0x30(%rdi)
-    mov   %r12, 0x38(%rdi)
-    mov   %r13, 0x40(%rdi)
-    mov   %rcx, 0x48(%rdi)
-    mov   0x50(%rdi), %r8
-    mov   0x58(%rdi), %r9
-    mov   0x60(%rdi), %r10
-    mov   0x68(%rdi), %r11
-    adc   \$0x0, %r8
-    adc   \$0x0, %r9
-    adc   \$0x0, %r10
-    adc   \$0x0, %r11
-    mov   %r8, 0x50(%rdi)
-    mov   %r9, 0x58(%rdi)
-    mov   %r10, 0x60(%rdi)
-    mov   %r11, 0x68(%rdi)
-
-    $mul23
-    xor   %rcx, %rcx
-    add   0x28(%rdi), %r8
-    adc   0x30(%rdi), %r9
-    adc   0x38(%rdi), %r10
-    adc   0x40(%rdi), %r11
-    adc   0x48(%rdi), %r12
-    adc   0x50(%rdi), %r13
-    adc   0x58(%rdi), %rcx
-    mov   %r8, 0x28(%rdi)
-    mov   %r9, 0x30(%rdi)
-    mov   %r10, 0x38(%rdi)
-    mov   %r11, 0x40(%rdi)
-    mov   %r12, 0x48(%rdi)
-    mov   %r13, 0x50(%rdi)
-    mov   %rcx, 0x58(%rdi)
-    mov   0x60(%rdi), %r8
-    mov   0x68(%rdi), %r9
-    adc   \$0x0, %r8
-    adc   \$0x0, %r9
-    mov   %r8, 0x60(%rdi)
-    mov   %r9, 0x68(%rdi)
-
-    $mul45
-    xor   %rcx, %rcx
-    add   0x38(%rdi), %r8
-    adc   0x40(%rdi), %r9
-    adc   0x48(%rdi), %r10
-    adc   0x50(%rdi), %r11
-    adc   0x58(%rdi), %r12
-    adc   0x60(%rdi), %r13
-    adc   0x68(%rdi), %rcx
-    mov   %r8,   0x0(%rsi)    # C0
-    mov   %r9,   0x8(%rsi)    # C1
-    mov   %r10, 0x48(%rdi)
-    mov   %r11, 0x50(%rdi)
-    mov   %r12, 0x58(%rdi)
-    mov   %r13, 0x60(%rdi)
-    mov   %rcx, 0x68(%rdi)
-
-    $mul67
-    add   0x48(%rdi), %r8
-    adc   0x50(%rdi), %r9
-    adc   0x58(%rdi), %r10
-    adc   0x60(%rdi), %r11
-    adc   0x68(%rdi), %r12
-    mov   %r8,  0x10(%rsi)    # C2
-    mov   %r9,  0x18(%rsi)    # C3
-    mov   %r10, 0x20(%rsi)    # C4
-    mov   %r11, 0x28(%rsi)    # C5
-    mov   %r12, 0x30(%rsi)    # C6
-___
-  return $body;
-}
-
-# Optimized Montgomery reduction for CPUs, based on method described
-# in Faz-Hernandez et al. https://eprint.iacr.org/2017/1015.
-# Operation: c [rsi] = a [rdi]
-# NOTE: a=c is not allowed
-sub sike_rdc {
-  my $jump_redc_bdw=&alt_impl(".Lrdc_bdw") if ($bmi2_adx);
-  # a[0-1] x .Lp434p1 --> result: r8:r13
-  my $mulx1=&mulx128x256( 0,"%rdi",".Lp434p1(%rip)",map("%r$_",(8..13)),"%rcx");
-  # a[2-3] x .Lp434p1 --> result: r8:r13
-  my $mulx2=&mulx128x256(16,"%rdi",".Lp434p1(%rip)",map("%r$_",(8..13)),"%rcx");
-  # a[4-5] x .Lp434p1 --> result: r8:r13
-  my $mulx3=&mulx128x256(32,"%rdi",".Lp434p1(%rip)",map("%r$_",(8..13)),"%rcx");
-  # a[6-7] x .Lp434p1 --> result: r8:r13
-  my $mulx4=&mulx64x256( 48,"%rdi",".Lp434p1(%rip)",map("%r$_",(8..13)));
-
-  # a[0-1] x .Lp434p1 --> result: r8:r13
-  my $mul1=&mul128x256( 0,"%rdi",".Lp434p1(%rip)",map("%r$_",(8..14)),"%rcx");
-  # a[2-3] x .Lp434p1 --> result: r8:r13
-  my $mul2=&mul128x256(16,"%rdi",".Lp434p1(%rip)",map("%r$_",(8..14)),"%rcx");
-  # a[4-5] x .Lp434p1 --> result: r8:r13
-  my $mul3=&mul128x256(32,"%rdi",".Lp434p1(%rip)",map("%r$_",(8..14)),"%rcx");
-  # a[6-7] x .Lp434p1 --> result: r8:r13
-  my $mul4=&mul64x256( 48,"%rdi",".Lp434p1(%rip)",map("%r$_",(8..13)));
-
-  my $redc_mul=&redc_common($mul1, $mul2, $mul3, $mul4);
-  my $redc_bdw=&redc_common($mulx1, $mulx2, $mulx3, $mulx4) if ($bmi2_adx);
-
-  # REDC for Broadwell CPUs
-  my $code=<<___;
-    .Lrdc_bdw:
-    .cfi_startproc
-      # sike_fprdc has already pushed r12--15 by this point.
-    .cfi_adjust_cfa_offset 32
-    .cfi_offset r12, -16
-    .cfi_offset r13, -24
-    .cfi_offset r14, -32
-    .cfi_offset r15, -40
-
-    $redc_bdw
-
-      pop %r15
-    .cfi_adjust_cfa_offset -8
-    .cfi_same_value r15
-      pop %r14
-    .cfi_adjust_cfa_offset -8
-    .cfi_same_value r14
-      pop %r13
-    .cfi_adjust_cfa_offset -8
-    .cfi_same_value r13
-      pop %r12
-    .cfi_adjust_cfa_offset -8
-    .cfi_same_value r12
-      ret
-    .cfi_endproc
-___
-
-  # REDC for CPUs older than Broadwell
-  $code.=<<___;
-    .globl  ${PREFIX}_fprdc
-    .type   ${PREFIX}_fprdc,\@function,3
-    ${PREFIX}_fprdc:
-    .cfi_startproc
-      push %r12
-    .cfi_adjust_cfa_offset  8
-    .cfi_offset r12, -16
-      push %r13
-    .cfi_adjust_cfa_offset  8
-    .cfi_offset r13, -24
-      push %r14
-    .cfi_adjust_cfa_offset  8
-    .cfi_offset r14, -32
-      push %r15
-    .cfi_adjust_cfa_offset  8
-    .cfi_offset r15, -40
-
-      # Jump to optimized implementation if
-      # CPU supports ADCX/ADOX/MULX
-      $jump_redc_bdw
-      # Otherwise use generic implementation
-      $redc_mul
-
-      pop %r15
-    .cfi_adjust_cfa_offset -8
-      pop %r14
-    .cfi_adjust_cfa_offset -8
-      pop %r13
-    .cfi_adjust_cfa_offset -8
-      pop %r12
-    .cfi_adjust_cfa_offset -8
-      ret
-    .cfi_endproc
-___
-  return $code;
-}
-$code.=&sike_rdc();
-
-# 434-bit multiplication using Karatsuba (one level),
-# schoolbook (one level). Uses MULX/ADOX/ADCX instructions
-# available on Broadwell micro-architectures and newer.
-sub mul_bdw {
-  # [rsp] <- (AH+AL) x (BH+BL)
-  my $mul256_low=&mul256(0,"%rsp",32,"%rsp",0,"%rsp",map("%r$_",(8..15)),"%rbx","%rbp");
-  # [rcx] <- AL x BL
-  my $mul256_albl=&mul256(0,"%rdi",0,"%rsi",0,"%rcx",map("%r$_",(8..15)),"%rbx","%rbp");
-  # [rcx+64] <- AH x BH
-  my $mul192_ahbh=&mul192(32,"%rdi",32,"%rsi",64,"%rcx",map("%r$_",(8..14)));
-
-  $body=<<___;
-
-    mov   %rdx, %rcx
-    xor   %rax, %rax
-
-    # r8-r11 <- AH + AL, rax <- mask
-    mov    0x0(%rdi), %r8
-    mov    0x8(%rdi), %r9
-    mov   0x10(%rdi), %r10
-    mov   0x18(%rdi), %r11
-
-    push %rbx
-  .cfi_adjust_cfa_offset 8
-  .cfi_offset rbx, -48
-    push %rbp
-  .cfi_offset rbp, -56
-  .cfi_adjust_cfa_offset 8
-    sub \$96, %rsp
-  .cfi_adjust_cfa_offset 96
-
-    add   0x20(%rdi), %r8
-    adc   0x28(%rdi), %r9
-    adc   0x30(%rdi), %r10
-    adc   \$0x0, %r11
-    sbb   \$0x0, %rax
-    mov   %r8,   0x0(%rsp)
-    mov   %r9,   0x8(%rsp)
-    mov   %r10, 0x10(%rsp)
-    mov   %r11, 0x18(%rsp)
-
-    # r12-r15 <- BH + BL, rbx <- mask
-    xor   %rbx, %rbx
-    mov    0x0(%rsi), %r12
-    mov    0x8(%rsi), %r13
-    mov   0x10(%rsi), %r14
-    mov   0x18(%rsi), %r15
-    add   0x20(%rsi), %r12
-    adc   0x28(%rsi), %r13
-    adc   0x30(%rsi), %r14
-    adc   \$0x0, %r15
-    sbb   \$0x0, %rbx
-    mov   %r12, 0x20(%rsp)
-    mov   %r13, 0x28(%rsp)
-    mov   %r14, 0x30(%rsp)
-    mov   %r15, 0x38(%rsp)
-
-    # r12-r15 <- masked (BH + BL)
-    and   %rax, %r12
-    and   %rax, %r13
-    and   %rax, %r14
-    and   %rax, %r15
-
-    # r8-r11 <- masked (AH + AL)
-    and   %rbx, %r8
-    and   %rbx, %r9
-    and   %rbx, %r10
-    and   %rbx, %r11
-
-    # r8-r11 <- masked (AH + AL) + masked (BH + BL)
-    add   %r12, %r8
-    adc   %r13, %r9
-    adc   %r14, %r10
-    adc   %r15, %r11
-    mov    %r8, 0x40(%rsp)
-    mov    %r9, 0x48(%rsp)
-    mov   %r10, 0x50(%rsp)
-    mov   %r11, 0x58(%rsp)
-
-    # [rsp] <- CM = (AH+AL) x (BH+BL)
-    $mul256_low
-    # [rcx] <- CL = AL x BL (Result c0-c3)
-    $mul256_albl
-    # [rcx+64] <- CH = AH x BH
-    $mul192_ahbh
-
-    # r8-r11 <- (AH+AL) x (BH+BL), final step
-    mov   0x40(%rsp),  %r8
-    mov   0x48(%rsp),  %r9
-    mov   0x50(%rsp), %r10
-    mov   0x58(%rsp), %r11
-
-    mov   0x20(%rsp), %rax
-    add   %rax, %r8
-    mov   0x28(%rsp), %rax
-    adc   %rax, %r9
-    mov   0x30(%rsp), %rax
-    adc   %rax, %r10
-    mov   0x38(%rsp), %rax
-    adc   %rax, %r11
-
-    # [rsp], x3-x5 <- (AH+AL) x (BH+BL) - ALxBL
-    mov    0x0(%rsp), %r12
-    mov    0x8(%rsp), %r13
-    mov   0x10(%rsp), %r14
-    mov   0x18(%rsp), %r15
-    sub    0x0(%rcx), %r12
-    sbb    0x8(%rcx), %r13
-    sbb   0x10(%rcx), %r14
-    sbb   0x18(%rcx), %r15
-    sbb   0x20(%rcx), %r8
-    sbb   0x28(%rcx), %r9
-    sbb   0x30(%rcx), %r10
-    sbb   0x38(%rcx), %r11
-
-    # r8-r15 <- (AH+AL) x (BH+BL) - ALxBL - AHxBH
-    sub   0x40(%rcx), %r12
-    sbb   0x48(%rcx), %r13
-    sbb   0x50(%rcx), %r14
-    sbb   0x58(%rcx), %r15
-    sbb   0x60(%rcx), %r8
-    sbb   0x68(%rcx), %r9
-    sbb   \$0x0, %r10
-    sbb   \$0x0, %r11
-
-    add   0x20(%rcx), %r12
-    mov   %r12, 0x20(%rcx)    # Result C4-C7
-    adc   0x28(%rcx), %r13
-    mov   %r13, 0x28(%rcx)
-    adc   0x30(%rcx), %r14
-    mov   %r14, 0x30(%rcx)
-    adc   0x38(%rcx), %r15
-    mov   %r15, 0x38(%rcx)
-    adc   0x40(%rcx), %r8
-    mov   %r8, 0x40(%rcx)     # Result C8-C15
-    adc   0x48(%rcx), %r9
-    mov   %r9, 0x48(%rcx)
-    adc   0x50(%rcx), %r10
-    mov   %r10, 0x50(%rcx)
-    adc   0x58(%rcx), %r11
-    mov   %r11, 0x58(%rcx)
-    mov   0x60(%rcx), %r12
-    adc   \$0x0, %r12
-    mov   %r12, 0x60(%rcx)
-    mov   0x68(%rcx), %r13
-    adc   \$0x0, %r13
-    mov   %r13, 0x68(%rcx)
-
-    add \$96, %rsp
-  .cfi_adjust_cfa_offset -96
-    pop %rbp
-  .cfi_adjust_cfa_offset -8
-  .cfi_same_value rbp
-    pop %rbx
-  .cfi_adjust_cfa_offset -8
-  .cfi_same_value rbx
-___
-  return $body;
-}
-
-# 434-bit multiplication using Karatsuba (one level),
-# schoolbook (one level).
-sub mul {
-  my $code=<<___;
-    mov %rdx, %rcx
-
-    sub \$112,  %rsp           # Allocating space in stack
-  .cfi_adjust_cfa_offset 112
-
-    # rcx[0-3] <- AH+AL
-    xor %rax, %rax
-    mov 0x20(%rdi), %r8
-    mov 0x28(%rdi), %r9
-    mov 0x30(%rdi), %r10
-    xor       %r11, %r11
-    add  0x0(%rdi), %r8
-    adc  0x8(%rdi), %r9
-    adc 0x10(%rdi), %r10
-    adc 0x18(%rdi), %r11
-    # store AH+AL mask
-    sbb  \$0,  %rax
-    mov %rax, 0x40(%rsp)
-    # store AH+AL in 0-0x18(rcx)
-    mov %r8,   0x0(%rcx)
-    mov %r9,   0x8(%rcx)
-    mov %r10, 0x10(%rcx)
-    mov %r11, 0x18(%rcx)
-
-    # r12-r15 <- BH+BL
-    xor %rdx, %rdx
-    mov 0x20(%rsi), %r12
-    mov 0x28(%rsi), %r13
-    mov 0x30(%rsi), %r14
-    xor       %r15, %r15
-    add  0x0(%rsi), %r12
-    adc  0x8(%rsi), %r13
-    adc 0x10(%rsi), %r14
-    adc 0x18(%rsi), %r15
-    sbb \$0x0, %rdx
-    # store BH+BL mask
-    mov %rdx, 0x48(%rsp)
-
-    # (rsp[0-0x38]) <- (AH+AL)*(BH+BL)
-    mov (%rcx), %rax
-    mul %r12
-    mov %rax, (%rsp)            # c0
-    mov %rdx, %r8
-
-    xor %r9,  %r9
-    mov (%rcx), %rax
-    mul %r13
-    add %rax, %r8
-    adc %rdx, %r9
-
-    xor %r10, %r10
-    mov 0x8(%rcx), %rax
-    mul %r12
-    add %rax, %r8
-    mov %r8,  0x8(%rsp)          # c1
-    adc %rdx, %r9
-    adc \$0x0,%r10
-
-    xor %r8, %r8
-    mov (%rcx), %rax
-    mul %r14
-    add %rax, %r9
-    adc %rdx, %r10
-    adc \$0x0,%r8
-
-    mov 0x10(%rcx), %rax
-    mul %r12
-    add %rax, %r9
-    adc %rdx, %r10
-    adc \$0x0,%r8
-
-    mov 0x8(%rcx), %rax
-    mul %r13
-    add %rax, %r9
-    mov %r9, 0x10(%rsp)         # c2
-    adc %rdx, %r10
-    adc \$0x0, %r8
-
-    xor %r9, %r9
-    mov (%rcx),%rax
-    mul %r15
-    add %rax, %r10
-    adc %rdx, %r8
-    adc \$0x0,%r9
-
-    mov 0x18(%rcx), %rax
-    mul %r12
-    add %rax, %r10
-    adc %rdx, %r8
-    adc \$0x0,%r9
-
-    mov 0x8(%rcx), %rax
-    mul %r14
-    add %rax, %r10
-    adc %rdx, %r8
-    adc \$0x0,%r9
-
-    mov 0x10(%rcx), %rax
-    mul %r13
-    add %rax, %r10
-    mov %r10, 0x18(%rsp)        # c3
-    adc %rdx, %r8
-    adc \$0x0, %r9
-
-    xor %r10, %r10
-    mov 0x8(%rcx), %rax
-    mul %r15
-    add %rax, %r8
-    adc %rdx, %r9
-    adc \$0x0,%r10
-
-    mov 0x18(%rcx), %rax
-    mul %r13
-    add %rax, %r8
-    adc %rdx, %r9
-    adc \$0x0,%r10
-
-    mov 0x10(%rcx), %rax
-    mul %r14
-    add %rax, %r8               # c4
-    mov  %r8, 0x20(%rsp)
-    adc %rdx, %r9
-    adc \$0x0,%r10
-
-    xor %r11, %r11
-    mov 0x10(%rcx), %rax
-    mul %r15
-    add %rax, %r9
-    adc %rdx, %r10
-    adc \$0x0,%r11
-
-    mov 0x18(%rcx), %rax
-    mul %r14
-    add %rax, %r9               # c5
-    mov  %r9, 0x28(%rsp)
-    adc %rdx, %r10
-    adc \$0x0,%r11
-
-    mov 0x18(%rcx), %rax
-    mul %r15
-    add %rax, %r10              # c6
-    mov %r10, 0x30(%rsp)
-    adc %rdx, %r11              # c7
-    mov %r11, 0x38(%rsp)
-
-    # r12-r15 <- masked (BH + BL)
-    mov 0x40(%rsp), %rax
-    and %rax, %r12
-    and %rax, %r13
-    and %rax, %r14
-    and %rax, %r15
-
-    # r8-r11 <- masked (AH + AL)
-    mov 0x48(%rsp),%rax
-    mov 0x00(rcx), %r8
-    and %rax, %r8
-    mov 0x08(rcx), %r9
-    and %rax, %r9
-    mov 0x10(rcx), %r10
-    and %rax, %r10
-    mov 0x18(rcx), %r11
-    and %rax, %r11
-
-    # r12-r15 <- masked (AH + AL) + masked (BH + BL)
-    add  %r8, %r12
-    adc  %r9, %r13
-    adc %r10, %r14
-    adc %r11, %r15
-
-    # rsp[0x20-0x38] <- (AH+AL) x (BH+BL) high
-    mov 0x20(%rsp), %rax
-    add %rax, %r12
-    mov 0x28(%rsp), %rax
-    adc %rax, %r13
-    mov 0x30(%rsp), %rax
-    adc %rax, %r14
-    mov 0x38(%rsp), %rax
-    adc %rax, %r15
-    mov %r12, 0x50(%rsp)
-    mov %r13, 0x58(%rsp)
-    mov %r14, 0x60(%rsp)
-    mov %r15, 0x68(%rsp)
-
-    # [rcx] <- CL = AL x BL
-    mov (%rdi), %r11
-    mov (%rsi), %rax
-    mul %r11
-    xor %r9,  %r9
-    mov %rax, (%rcx)              # c0
-    mov %rdx, %r8
-
-    mov 0x10(%rdi), %r14
-    mov 0x8(%rsi), %rax
-    mul %r11
-    xor %r10, %r10
-    add %rax, %r8
-    adc %rdx, %r9
-
-    mov 0x8(%rdi), %r12
-    mov (%rsi), %rax
-    mul %r12
-    add %rax, %r8
-    mov %r8,  0x8(%rcx)            # c1
-    adc %rdx, %r9
-    adc \$0x0,%r10
-
-    xor %r8,  %r8
-    mov 0x10(%rsi), %rax
-    mul %r11
-    add %rax, %r9
-    adc %rdx, %r10
-    adc \$0x0,%r8
-
-    mov (%rsi),%r13
-    mov %r14,  %rax
-    mul %r13
-    add %rax, %r9
-    adc %rdx, %r10
-    adc \$0x0,%r8
-
-    mov 0x8(%rsi), %rax
-    mul %r12
-    add %rax, %r9
-    mov %r9, 0x10(%rcx)           # c2
-    adc %rdx, %r10
-    adc \$0x0,%r8
-
-    xor %r9,  %r9
-    mov 0x18(%rsi), %rax
-    mul %r11
-    mov 0x18(%rdi), %r15
-    add %rax, %r10
-    adc %rdx, %r8
-    adc \$0x0,%r9
-
-    mov %r15, %rax
-    mul %r13
-    add %rax, %r10
-    adc %rdx, %r8
-    adc \$0x0,%r9
-
-    mov 0x10(%rsi), %rax
-    mul %r12
-    add %rax, %r10
-    adc %rdx, %r8
-    adc \$0x0,%r9
-
-    mov 0x8(%rsi), %rax
-    mul %r14
-    add %rax, %r10
-    mov %r10, 0x18(%rcx)           # c3
-    adc %rdx, %r8
-    adc \$0x0,%r9
-
-    xor %r10, %r10
-    mov 0x18(%rsi), %rax
-    mul %r12
-    add %rax, %r8
-    adc %rdx, %r9
-    adc \$0x0,%r10
-
-    mov 0x8(%rsi), %rax
-    mul %r15
-    add %rax, %r8
-    adc %rdx, %r9
-    adc \$0x0,%r10
-
-    mov 0x10(%rsi), %rax
-    mul %r14
-    add %rax, %r8
-    mov %r8,  0x20(%rcx)           # c4
-    adc %rdx, %r9
-    adc \$0x0,%r10
-
-    xor %r8, %r8
-    mov 0x18(%rsi), %rax
-    mul %r14
-    add %rax, %r9
-    adc %rdx, %r10
-    adc \$0x0,%r8
-
-    mov 0x10(%rsi), %rax
-    mul %r15
-    add %rax, %r9
-    mov %r9,  0x28(%rcx)           # c5
-    adc %rdx, %r10
-    adc \$0x0,%r8
-
-    mov 0x18(%rsi), %rax
-    mul %r15
-    add %rax, %r10
-    mov %r10, 0x30(%rcx)          # c6
-    adc %rdx, %r8
-    mov %r8,  0x38(%rcx)          # c7
-
-    # rcx[0x40-0x68] <- AH*BH
-    # multiplies 2 192-bit numbers A,B
-    mov 0x20(%rdi), %r11
-    mov 0x20(%rsi), %rax
-    mul %r11
-    xor %r9,  %r9
-    mov %rax, 0x40(%rcx)   # c0
-    mov %rdx, %r8
-
-    mov 0x30(%rdi), %r14
-    mov 0x28(%rsi), %rax
-    mul %r11
-    xor %r10, %r10
-    add %rax, %r8
-    adc %rdx, %r9
-
-    mov 0x28(%rdi), %r12
-    mov 0x20(%rsi), %rax
-    mul %r12
-    add %rax, %r8
-    mov %r8,  0x48(%rcx)    # c1
-    adc %rdx, %r9
-    adc \$0x0,%r10
-
-    xor %r8,  %r8
-    mov 0x30(%rsi), %rax
-    mul %r11
-    add %rax, %r9
-    adc %rdx, %r10
-    adc \$0x0,%r8
-
-    mov 0x20(%rsi), %r13
-    mov %r14, %rax
-    mul %r13
-    add %rax, %r9
-    adc %rdx, %r10
-    adc \$0x0,%r8
-
-    mov 0x28(%rsi), %rax
-    mul %r12
-    add %rax, %r9
-    mov %r9,  0x50(%rcx)    # c2
-    adc %rdx, %r10
-    adc \$0x0,%r8
-
-    mov 0x30(%rsi), %rax
-    mul %r12
-    xor %r12, %r12
-    add %rax, %r10
-    adc %rdx, %r8
-    adc \$0x0,%r12
-
-    mov 0x28(%rsi), %rax
-    mul %r14
-    add %rax, %r10
-    adc %rdx, %r8
-    adc \$0x0,%r12
-    mov %r10, 0x58(%rcx)   # c3
-
-    mov 0x30(%rsi), %rax
-    mul %r14
-    add %rax, %r8
-    adc \$0x0,%r12
-    mov %r8,  0x60(%rcx)    # c4
-
-    add %r12, %rdx         # c5
-
-    # [r8-r15] <- (AH+AL)x(BH+BL) - ALxBL
-    mov  0x0(%rsp), %r8
-    sub  0x0(%rcx), %r8
-    mov  0x8(%rsp), %r9
-    sbb  0x8(%rcx), %r9
-    mov 0x10(%rsp), %r10
-    sbb 0x10(%rcx), %r10
-    mov 0x18(%rsp), %r11
-    sbb 0x18(%rcx), %r11
-    mov 0x50(%rsp), %r12
-    sbb 0x20(%rcx), %r12
-    mov 0x58(%rsp), %r13
-    sbb 0x28(%rcx), %r13
-    mov 0x60(%rsp), %r14
-    sbb 0x30(%rcx), %r14
-    mov 0x68(%rsp), %r15
-    sbb 0x38(%rcx), %r15
-
-    # [r8-r15] <- (AH+AL) x (BH+BL) - ALxBL - AHxBH
-    mov 0x40(%rcx), %rax
-    sub %rax, %r8
-    mov 0x48(%rcx), %rax
-    sbb %rax, %r9
-    mov 0x50(%rcx), %rax
-    sbb %rax, %r10
-    mov 0x58(%rcx), %rax
-    sbb %rax, %r11
-    mov 0x60(%rcx), %rax
-    sbb %rax, %r12
-    sbb %rdx, %r13
-    sbb \$0x0,%r14
-    sbb \$0x0,%r15
-
-    # Final result
-    add 0x20(%rcx), %r8
-    mov %r8, 0x20(%rcx)    # Result C4-C7
-    adc 0x28(%rcx), %r9
-    mov %r9, 0x28(%rcx)
-    adc 0x30(%rcx), %r10
-    mov %r10, 0x30(%rcx)
-    adc 0x38(%rcx), %r11
-    mov %r11, 0x38(%rcx)
-    adc 0x40(%rcx), %r12
-    mov %r12, 0x40(%rcx)   # Result C8-C13
-    adc 0x48(%rcx), %r13
-    mov %r13, 0x48(%rcx)
-    adc 0x50(%rcx), %r14
-    mov %r14, 0x50(%rcx)
-    adc 0x58(%rcx), %r15
-    mov %r15, 0x58(%rcx)
-    mov 0x60(%rcx), %r12
-    adc \$0x0, %r12
-    mov %r12, 0x60(%rcx)
-    adc \$0x0, %rdx
-    mov %rdx, 0x68(%rcx)
-
-    add \$112, %rsp        # Restoring space in stack
-  .cfi_adjust_cfa_offset -112
-___
-
-  return $code;
-}
-
-#  Integer multiplication based on Karatsuba method
-#  Operation: c [rdx] = a [rdi] * b [rsi]
-#  NOTE: a=c or b=c are not allowed
-sub sike_mul {
-  my $jump_mul_bdw=&alt_impl(".Lmul_bdw") if ($bmi2_adx);
-  # MUL for Broadwell CPUs
-  my $mul_bdw=&mul_bdw() if ($bmi2_adx);
-  # MUL for CPUs older than Broadwell
-  my $mul=&mul();
-
-  my $body=<<___;
-  .Lmul_bdw:
-  .cfi_startproc
-    # sike_mpmul has already pushed r12--15 by this point.
-  .cfi_adjust_cfa_offset 32
-  .cfi_offset r12, -16
-  .cfi_offset r13, -24
-  .cfi_offset r14, -32
-  .cfi_offset r15, -40
-
-    $mul_bdw
-
-    pop %r15
-  .cfi_adjust_cfa_offset -8
-  .cfi_same_value r15
-    pop %r14
-  .cfi_adjust_cfa_offset -8
-  .cfi_same_value r14
-    pop %r13
-  .cfi_adjust_cfa_offset -8
-  .cfi_same_value r13
-    pop %r12
-  .cfi_adjust_cfa_offset -8
-  .cfi_same_value r12
-      ret
-  .cfi_endproc
-
-  .globl  ${PREFIX}_mpmul
-  .type   ${PREFIX}_mpmul,\@function,3
-  ${PREFIX}_mpmul:
-  .cfi_startproc
-    push %r12
-  .cfi_adjust_cfa_offset 8
-  .cfi_offset r12, -16
-    push %r13
-  .cfi_adjust_cfa_offset 8
-  .cfi_offset r13, -24
-    push %r14
-  .cfi_adjust_cfa_offset 8
-  .cfi_offset r14, -32
-    push %r15
-  .cfi_adjust_cfa_offset 8
-  .cfi_offset r15, -40
-
-    # Jump to optimized implementation if
-    # CPU supports ADCX/ADOX/MULX
-    $jump_mul_bdw
-    # Otherwise use generic implementation
-    $mul
-
-    pop %r15
-  .cfi_adjust_cfa_offset -8
-    pop %r14
-  .cfi_adjust_cfa_offset -8
-    pop %r13
-  .cfi_adjust_cfa_offset -8
-    pop %r12
-  .cfi_adjust_cfa_offset -8
-    ret
-  .cfi_endproc
-
-___
-  return $body;
-}
-
-$code.=&sike_mul();
-
-foreach (split("\n",$code)) {
-  s/\`([^\`]*)\`/eval($1)/ge;
-  print $_,"\n";
-}
-
-close STDOUT;
diff --git a/third_party/sike/asm/fp_generic.c b/third_party/sike/asm/fp_generic.c
deleted file mode 100644
index 991ad1e..0000000
--- a/third_party/sike/asm/fp_generic.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/********************************************************************************************
-* SIDH: an efficient supersingular isogeny cryptography library
-*
-* Abstract: portable modular arithmetic for P503
-*********************************************************************************************/
-
-#include <openssl/base.h>
-
-#if defined(OPENSSL_NO_ASM) || \
-    (!defined(OPENSSL_X86_64) && !defined(OPENSSL_AARCH64))
-
-#include "../utils.h"
-#include "../fpx.h"
-
-// Global constants
-extern const struct params_t sike_params;
-
-static void digit_x_digit(const crypto_word_t a, const crypto_word_t b, crypto_word_t* c)
-{ // Digit multiplication, digit * digit -> 2-digit result
-    crypto_word_t al, ah, bl, bh, temp;
-    crypto_word_t albl, albh, ahbl, ahbh, res1, res2, res3, carry;
-    crypto_word_t mask_low = (crypto_word_t)(-1) >> (sizeof(crypto_word_t)*4);
-    crypto_word_t mask_high = (crypto_word_t)(-1) << (sizeof(crypto_word_t)*4);
-
-    al = a & mask_low;                              // Low part
-    ah = a >> (sizeof(crypto_word_t) * 4);          // High part
-    bl = b & mask_low;
-    bh = b >> (sizeof(crypto_word_t) * 4);
-
-    albl = al*bl;
-    albh = al*bh;
-    ahbl = ah*bl;
-    ahbh = ah*bh;
-    c[0] = albl & mask_low;                         // C00
-
-    res1 = albl >> (sizeof(crypto_word_t) * 4);
-    res2 = ahbl & mask_low;
-    res3 = albh & mask_low;
-    temp = res1 + res2 + res3;
-    carry = temp >> (sizeof(crypto_word_t) * 4);
-    c[0] ^= temp << (sizeof(crypto_word_t) * 4);    // C01
-
-    res1 = ahbl >> (sizeof(crypto_word_t) * 4);
-    res2 = albh >> (sizeof(crypto_word_t) * 4);
-    res3 = ahbh & mask_low;
-    temp = res1 + res2 + res3 + carry;
-    c[1] = temp & mask_low;                         // C10
-    carry = temp & mask_high;
-    c[1] ^= (ahbh & mask_high) + carry;             // C11
-}
-
-void sike_fpadd(const felm_t a, const felm_t b, felm_t c)
-{ // Modular addition, c = a+b mod p434.
-  // Inputs: a, b in [0, 2*p434-1]
-  // Output: c in [0, 2*p434-1]
-    unsigned int i, carry = 0;
-    crypto_word_t mask;
-
-    for (i = 0; i < NWORDS_FIELD; i++) {
-        ADDC(carry, a[i], b[i], carry, c[i]);
-    }
-
-    carry = 0;
-    for (i = 0; i < NWORDS_FIELD; i++) {
-        SUBC(carry, c[i], sike_params.prime_x2[i], carry, c[i]);
-    }
-    mask = 0 - (crypto_word_t)carry;
-
-    carry = 0;
-    for (i = 0; i < NWORDS_FIELD; i++) {
-        ADDC(carry, c[i], sike_params.prime_x2[i] & mask, carry, c[i]);
-    }
-}
-
-void sike_fpsub(const felm_t a, const felm_t b, felm_t c)
-{ // Modular subtraction, c = a-b mod p434.
-  // Inputs: a, b in [0, 2*p434-1]
-  // Output: c in [0, 2*p434-1]
-    unsigned int i, borrow = 0;
-    crypto_word_t mask;
-
-    for (i = 0; i < NWORDS_FIELD; i++) {
-        SUBC(borrow, a[i], b[i], borrow, c[i]);
-    }
-    mask = 0 - (crypto_word_t)borrow;
-
-    borrow = 0;
-    for (i = 0; i < NWORDS_FIELD; i++) {
-        ADDC(borrow, c[i], sike_params.prime_x2[i] & mask, borrow, c[i]);
-    }
-}
-
-void sike_mpmul(const felm_t a, const felm_t b, dfelm_t c)
-{ // Multiprecision comba multiply, c = a*b, where lng(a) = lng(b) = NWORDS_FIELD.
-    unsigned int i, j;
-    crypto_word_t t = 0, u = 0, v = 0, UV[2];
-    unsigned int carry = 0;
-
-    for (i = 0; i < NWORDS_FIELD; i++) {
-        for (j = 0; j <= i; j++) {
-            MUL(a[j], b[i-j], UV+1, UV[0]);
-            ADDC(0, UV[0], v, carry, v);
-            ADDC(carry, UV[1], u, carry, u);
-            t += carry;
-        }
-        c[i] = v;
-        v = u;
-        u = t;
-        t = 0;
-    }
-
-    for (i = NWORDS_FIELD; i < 2*NWORDS_FIELD-1; i++) {
-        for (j = i-NWORDS_FIELD+1; j < NWORDS_FIELD; j++) {
-            MUL(a[j], b[i-j], UV+1, UV[0]);
-            ADDC(0, UV[0], v, carry, v);
-            ADDC(carry, UV[1], u, carry, u);
-            t += carry;
-        }
-        c[i] = v;
-        v = u;
-        u = t;
-        t = 0;
-    }
-    c[2*NWORDS_FIELD-1] = v;
-}
-
-void sike_fprdc(felm_t ma, felm_t mc)
-{ // Efficient Montgomery reduction using comba and exploiting the special form of the prime p434.
-  // mc = ma*R^-1 mod p434x2, where R = 2^448.
-  // If ma < 2^448*p434, the output mc is in the range [0, 2*p434-1].
-  // ma is assumed to be in Montgomery representation.
-    unsigned int i, j, carry, count = ZERO_WORDS;
-    crypto_word_t UV[2], t = 0, u = 0, v = 0;
-
-    for (i = 0; i < NWORDS_FIELD; i++) {
-        mc[i] = 0;
-    }
-
-    for (i = 0; i < NWORDS_FIELD; i++) {
-        for (j = 0; j < i; j++) {
-            if (j < (i-ZERO_WORDS+1)) {
-                MUL(mc[j], sike_params.prime_p1[i-j], UV+1, UV[0]);
-                ADDC(0, UV[0], v, carry, v);
-                ADDC(carry, UV[1], u, carry, u);
-                t += carry;
-            }
-        }
-        ADDC(0, v, ma[i], carry, v);
-        ADDC(carry, u, 0, carry, u);
-        t += carry;
-        mc[i] = v;
-        v = u;
-        u = t;
-        t = 0;
-    }
-
-    for (i = NWORDS_FIELD; i < 2*NWORDS_FIELD-1; i++) {
-        if (count > 0) {
-            count -= 1;
-        }
-        for (j = i-NWORDS_FIELD+1; j < NWORDS_FIELD; j++) {
-            if (j < (NWORDS_FIELD-count)) {
-                MUL(mc[j], sike_params.prime_p1[i-j], UV+1, UV[0]);
-                ADDC(0, UV[0], v, carry, v);
-                ADDC(carry, UV[1], u, carry, u);
-                t += carry;
-            }
-        }
-        ADDC(0, v, ma[i], carry, v);
-        ADDC(carry, u, 0, carry, u);
-        t += carry;
-        mc[i-NWORDS_FIELD] = v;
-        v = u;
-        u = t;
-        t = 0;
-    }
-    ADDC(0, v, ma[2*NWORDS_FIELD-1], carry, v);
-    mc[NWORDS_FIELD-1] = v;
-}
-
-#endif  // NO_ASM || (!X86_64 && !AARCH64)
diff --git a/third_party/sike/curve_params.c b/third_party/sike/curve_params.c
deleted file mode 100644
index a1fbb3f..0000000
--- a/third_party/sike/curve_params.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/********************************************************************************************
-* SIDH: an efficient supersingular isogeny cryptography library
-*
-* Abstract: supersingular isogeny parameters and generation of functions for P434
-*********************************************************************************************/
-
-#include "utils.h"
-
-// Parameters for isogeny system "SIKE"
-const struct params_t sike_params = {
-    .prime = {
-        U64_TO_WORDS(0xFFFFFFFFFFFFFFFF), U64_TO_WORDS(0xFFFFFFFFFFFFFFFF),
-        U64_TO_WORDS(0xFFFFFFFFFFFFFFFF), U64_TO_WORDS(0xFDC1767AE2FFFFFF),
-        U64_TO_WORDS(0x7BC65C783158AEA3), U64_TO_WORDS(0x6CFC5FD681C52056),
-        U64_TO_WORDS(0x0002341F27177344)
-    },
-    .prime_p1 = {
-        U64_TO_WORDS(0x0000000000000000), U64_TO_WORDS(0x0000000000000000),
-        U64_TO_WORDS(0x0000000000000000), U64_TO_WORDS(0xFDC1767AE3000000),
-        U64_TO_WORDS(0x7BC65C783158AEA3), U64_TO_WORDS(0x6CFC5FD681C52056),
-        U64_TO_WORDS(0x0002341F27177344)
-    },
-    .prime_x2 = {
-        U64_TO_WORDS(0xFFFFFFFFFFFFFFFE), U64_TO_WORDS(0xFFFFFFFFFFFFFFFF),
-        U64_TO_WORDS(0xFFFFFFFFFFFFFFFF), U64_TO_WORDS(0xFB82ECF5C5FFFFFF),
-        U64_TO_WORDS(0xF78CB8F062B15D47), U64_TO_WORDS(0xD9F8BFAD038A40AC),
-        U64_TO_WORDS(0x0004683E4E2EE688)
-    },
-    .A_gen = {
-        U64_TO_WORDS(0x05ADF455C5C345BF), U64_TO_WORDS(0x91935C5CC767AC2B),
-        U64_TO_WORDS(0xAFE4E879951F0257), U64_TO_WORDS(0x70E792DC89FA27B1),
-        U64_TO_WORDS(0xF797F526BB48C8CD), U64_TO_WORDS(0x2181DB6131AF621F),
-        U64_TO_WORDS(0x00000A1C08B1ECC4), // XPA0
-        U64_TO_WORDS(0x74840EB87CDA7788), U64_TO_WORDS(0x2971AA0ECF9F9D0B),
-        U64_TO_WORDS(0xCB5732BDF41715D5), U64_TO_WORDS(0x8CD8E51F7AACFFAA),
-        U64_TO_WORDS(0xA7F424730D7E419F), U64_TO_WORDS(0xD671EB919A179E8C),
-        U64_TO_WORDS(0x0000FFA26C5A924A), // XPA1
-        U64_TO_WORDS(0xFEC6E64588B7273B), U64_TO_WORDS(0xD2A626D74CBBF1C6),
-        U64_TO_WORDS(0xF8F58F07A78098C7), U64_TO_WORDS(0xE23941F470841B03),
-        U64_TO_WORDS(0x1B63EDA2045538DD), U64_TO_WORDS(0x735CFEB0FFD49215),
-        U64_TO_WORDS(0x0001C4CB77542876), // XQA0
-        U64_TO_WORDS(0xADB0F733C17FFDD6), U64_TO_WORDS(0x6AFFBD037DA0A050),
-        U64_TO_WORDS(0x680EC43DB144E02F), U64_TO_WORDS(0x1E2E5D5FF524E374),
-        U64_TO_WORDS(0xE2DDA115260E2995), U64_TO_WORDS(0xA6E4B552E2EDE508),
-        U64_TO_WORDS(0x00018ECCDDF4B53E), // XQA1
-        U64_TO_WORDS(0x01BA4DB518CD6C7D), U64_TO_WORDS(0x2CB0251FE3CC0611),
-        U64_TO_WORDS(0x259B0C6949A9121B), U64_TO_WORDS(0x60E17AC16D2F82AD),
-        U64_TO_WORDS(0x3AA41F1CE175D92D), U64_TO_WORDS(0x413FBE6A9B9BC4F3),
-        U64_TO_WORDS(0x00022A81D8D55643), // XRA0
-        U64_TO_WORDS(0xB8ADBC70FC82E54A), U64_TO_WORDS(0xEF9CDDB0D5FADDED),
-        U64_TO_WORDS(0x5820C734C80096A0), U64_TO_WORDS(0x7799994BAA96E0E4),
-        U64_TO_WORDS(0x044961599E379AF8), U64_TO_WORDS(0xDB2B94FBF09F27E2),
-        U64_TO_WORDS(0x0000B87FC716C0C6)  // XRA1
-    },
-    .B_gen = {
-        U64_TO_WORDS(0x6E5497556EDD48A3), U64_TO_WORDS(0x2A61B501546F1C05),
-        U64_TO_WORDS(0xEB919446D049887D), U64_TO_WORDS(0x5864A4A69D450C4F),
-        U64_TO_WORDS(0xB883F276A6490D2B), U64_TO_WORDS(0x22CC287022D5F5B9),
-        U64_TO_WORDS(0x0001BED4772E551F), // XPB0
-        U64_TO_WORDS(0x0000000000000000), U64_TO_WORDS(0x0000000000000000),
-        U64_TO_WORDS(0x0000000000000000), U64_TO_WORDS(0x0000000000000000),
-        U64_TO_WORDS(0x0000000000000000), U64_TO_WORDS(0x0000000000000000),
-        U64_TO_WORDS(0x0000000000000000), // XPB1
-        U64_TO_WORDS(0xFAE2A3F93D8B6B8E), U64_TO_WORDS(0x494871F51700FE1C),
-        U64_TO_WORDS(0xEF1A94228413C27C), U64_TO_WORDS(0x498FF4A4AF60BD62),
-        U64_TO_WORDS(0xB00AD2A708267E8A), U64_TO_WORDS(0xF4328294E017837F),
-        U64_TO_WORDS(0x000034080181D8AE), // XQB0
-        U64_TO_WORDS(0x0000000000000000), U64_TO_WORDS(0x0000000000000000),
-        U64_TO_WORDS(0x0000000000000000), U64_TO_WORDS(0x0000000000000000),
-        U64_TO_WORDS(0x0000000000000000), U64_TO_WORDS(0x0000000000000000),
-        U64_TO_WORDS(0x0000000000000000), // XQB1
-        U64_TO_WORDS(0x283B34FAFEFDC8E4), U64_TO_WORDS(0x9208F44977C3E647),
-        U64_TO_WORDS(0x7DEAE962816F4E9A), U64_TO_WORDS(0x68A2BA8AA262EC9D),
-        U64_TO_WORDS(0x8176F112EA43F45B), U64_TO_WORDS(0x02106D022634F504),
-        U64_TO_WORDS(0x00007E8A50F02E37), // XRB0
-        U64_TO_WORDS(0xB378B7C1DA22CCB1), U64_TO_WORDS(0x6D089C99AD1D9230),
-        U64_TO_WORDS(0xEBE15711813E2369), U64_TO_WORDS(0x2B35A68239D48A53),
-        U64_TO_WORDS(0x445F6FD138407C93), U64_TO_WORDS(0xBEF93B29A3F6B54B),
-        U64_TO_WORDS(0x000173FA910377D3)  // XRB1
-    },
-    .mont_R2 = {
-        U64_TO_WORDS(0x28E55B65DCD69B30), U64_TO_WORDS(0xACEC7367768798C2),
-        U64_TO_WORDS(0xAB27973F8311688D), U64_TO_WORDS(0x175CC6AF8D6C7C0B),
-        U64_TO_WORDS(0xABCD92BF2DDE347E), U64_TO_WORDS(0x69E16A61C7686D9A),
-        U64_TO_WORDS(0x000025A89BCDD12A)
-    },
-    .mont_one = {
-        U64_TO_WORDS(0x000000000000742C), U64_TO_WORDS(0x0000000000000000),
-        U64_TO_WORDS(0x0000000000000000), U64_TO_WORDS(0xB90FF404FC000000),
-        U64_TO_WORDS(0xD801A4FB559FACD4), U64_TO_WORDS(0xE93254545F77410C),
-        U64_TO_WORDS(0x0000ECEEA7BD2EDA)
-    },
-    .mont_six = {
-        U64_TO_WORDS(0x000000000002B90A), U64_TO_WORDS(0x0000000000000000),
-        U64_TO_WORDS(0x0000000000000000), U64_TO_WORDS(0x5ADCCB2822000000),
-        U64_TO_WORDS(0x187D24F39F0CAFB4), U64_TO_WORDS(0x9D353A4D394145A0),
-        U64_TO_WORDS(0x00012559A0403298)
-    },
-    .A_strat = {
-        0x30, 0x1C, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01,
-        0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x08, 0x04,
-        0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01,
-        0x02, 0x01, 0x01, 0x0D, 0x07, 0x04, 0x02, 0x01, 0x01, 0x02,
-        0x01, 0x01, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x05, 0x04,
-        0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
-        0x15, 0x0C, 0x07, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01,
-        0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x05, 0x03, 0x02, 0x01,
-        0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x09, 0x05, 0x03,
-        0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x04,
-        0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01
-    },
-    .B_strat = {
-        0x42, 0x21, 0x11, 0x09, 0x05, 0x03, 0x02, 0x01, 0x01, 0x01,
-        0x01, 0x02, 0x01, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x01,
-        0x02, 0x01, 0x01, 0x08, 0x04, 0x02, 0x01, 0x01, 0x01, 0x02,
-        0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x10,
-        0x08, 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04,
-        0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x08, 0x04, 0x02, 0x01,
-        0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01,
-        0x01, 0x20, 0x10, 0x08, 0x04, 0x03, 0x01, 0x01, 0x01, 0x01,
-        0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01,
-        0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04, 0x02,
-        0x01, 0x01, 0x02, 0x01, 0x01, 0x10, 0x08, 0x04, 0x02, 0x01,
-        0x01, 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01,
-        0x01, 0x08, 0x04, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x04,
-        0x02, 0x01, 0x01, 0x02, 0x01, 0x01
-    }
-};
diff --git a/third_party/sike/fpx.c b/third_party/sike/fpx.c
deleted file mode 100644
index 9917116..0000000
--- a/third_party/sike/fpx.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/********************************************************************************************
-* SIDH: an efficient supersingular isogeny cryptography library
-*
-* Abstract: core functions over GF(p) and GF(p^2)
-*********************************************************************************************/
-#include <openssl/base.h>
-
-#include "utils.h"
-#include "fpx.h"
-
-extern const struct params_t sike_params;
-
-// Multiprecision squaring, c = a^2 mod p.
-static void fpsqr_mont(const felm_t ma, felm_t mc)
-{
-    dfelm_t temp = {0};
-    sike_mpmul(ma, ma, temp);
-    sike_fprdc(temp, mc);
-}
-
-// Chain to compute a^(p-3)/4 using Montgomery arithmetic.
-static void fpinv_chain_mont(felm_t a)
-{
-    unsigned int i, j;
-    felm_t t[31], tt;
-
-    // Precomputed table
-    fpsqr_mont(a, tt);
-    sike_fpmul_mont(a, tt, t[0]);
-    for (i = 0; i <= 29; i++) sike_fpmul_mont(t[i], tt, t[i+1]);
-
-    sike_fpcopy(a, tt);
-    for (i = 0; i < 7; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[5], tt, tt);
-    for (i = 0; i < 10; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[14], tt, tt);
-    for (i = 0; i < 6; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[3], tt, tt);
-    for (i = 0; i < 6; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[23], tt, tt);
-    for (i = 0; i < 6; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[13], tt, tt);
-    for (i = 0; i < 6; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[24], tt, tt);
-    for (i = 0; i < 6; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[7], tt, tt);
-    for (i = 0; i < 8; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[12], tt, tt);
-    for (i = 0; i < 8; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[30], tt, tt);
-    for (i = 0; i < 6; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[1], tt, tt);
-    for (i = 0; i < 6; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[30], tt, tt);
-    for (i = 0; i < 7; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[21], tt, tt);
-    for (i = 0; i < 9; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[2], tt, tt);
-    for (i = 0; i < 9; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[19], tt, tt);
-    for (i = 0; i < 9; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[1], tt, tt);
-    for (i = 0; i < 7; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[24], tt, tt);
-    for (i = 0; i < 6; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[26], tt, tt);
-    for (i = 0; i < 6; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[16], tt, tt);
-    for (i = 0; i < 7; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[10], tt, tt);
-    for (i = 0; i < 7; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[6], tt, tt);
-    for (i = 0; i < 7; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[0], tt, tt);
-    for (i = 0; i < 9; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[20], tt, tt);
-    for (i = 0; i < 8; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[9], tt, tt);
-    for (i = 0; i < 6; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[25], tt, tt);
-    for (i = 0; i < 9; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[30], tt, tt);
-    for (i = 0; i < 6; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[26], tt, tt);
-    for (i = 0; i < 6; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(a, tt, tt);
-    for (i = 0; i < 7; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[28], tt, tt);
-    for (i = 0; i < 6; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[6], tt, tt);
-    for (i = 0; i < 6; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[10], tt, tt);
-    for (i = 0; i < 9; i++) fpsqr_mont(tt, tt);
-    sike_fpmul_mont(t[22], tt, tt);
-    for (j = 0; j < 35; j++) {
-        for (i = 0; i < 6; i++) fpsqr_mont(tt, tt);
-        sike_fpmul_mont(t[30], tt, tt);
-    }
-    sike_fpcopy(tt, a);
-}
-
-// Field inversion using Montgomery arithmetic, a = a^(-1)*R mod p.
-static void fpinv_mont(felm_t a)
-{
-    felm_t tt = {0};
-    sike_fpcopy(a, tt);
-    fpinv_chain_mont(tt);
-    fpsqr_mont(tt, tt);
-    fpsqr_mont(tt, tt);
-    sike_fpmul_mont(a, tt, a);
-}
-
-// Multiprecision addition, c = a+b, where lng(a) = lng(b) = nwords. Returns the carry bit.
-#if defined(OPENSSL_NO_ASM) || (!defined(OPENSSL_X86_64) && !defined(OPENSSL_AARCH64))
-inline static unsigned int mp_add(const felm_t a, const felm_t b, felm_t c, const unsigned int nwords) {
-    uint8_t carry = 0;
-    for (size_t i = 0; i < nwords; i++) {
-        ADDC(carry, a[i], b[i], carry, c[i]);
-    }
-    return carry;
-}
-
-// Multiprecision subtraction, c = a-b, where lng(a) = lng(b) = nwords. Returns the borrow bit.
-inline static unsigned int mp_sub(const felm_t a, const felm_t b, felm_t c, const unsigned int nwords) {
-    uint32_t borrow = 0;
-    for (size_t i = 0; i < nwords; i++) {
-        SUBC(borrow, a[i], b[i], borrow, c[i]);
-    }
-    return borrow;
-}
-#endif
-
-// Multiprecision addition, c = a+b.
-inline static void mp_addfast(const felm_t a, const felm_t b, felm_t c)
-{
-#if defined(OPENSSL_NO_ASM) || (!defined(OPENSSL_X86_64) && !defined(OPENSSL_AARCH64))
-    mp_add(a, b, c, NWORDS_FIELD);
-#else
-    sike_mpadd_asm(a, b, c);
-#endif
-}
-
-// Multiprecision subtraction, c = a-b, where lng(a) = lng(b) = 2*NWORDS_FIELD.
-// If c < 0 then returns mask = 0xFF..F, else mask = 0x00..0
-inline static crypto_word_t mp_subfast(const dfelm_t a, const dfelm_t b, dfelm_t c) {
-#if defined(OPENSSL_NO_ASM) || (!defined(OPENSSL_X86_64) && !defined(OPENSSL_AARCH64))
-    return (0 - (crypto_word_t)mp_sub(a, b, c, 2*NWORDS_FIELD));
-#else
-    return sike_mpsubx2_asm(a, b, c);
-#endif
-}
-
-// Multiprecision subtraction, c = c-a-b, where lng(a) = lng(b) = 2*NWORDS_FIELD.
-// Inputs should be s.t. c > a and c > b
-inline static void mp_dblsubfast(const dfelm_t a, const dfelm_t b, dfelm_t c) {
-#if defined(OPENSSL_NO_ASM) || (!defined(OPENSSL_X86_64) && !defined(OPENSSL_AARCH64))
-    mp_sub(c, a, c, 2*NWORDS_FIELD);
-    mp_sub(c, b, c, 2*NWORDS_FIELD);
-#else
-    sike_mpdblsubx2_asm(a, b, c);
-#endif
-}
-
-// Copy a field element, c = a.
-void sike_fpcopy(const felm_t a, felm_t c) {
-    for (size_t i = 0; i < NWORDS_FIELD; i++) {
-        c[i] = a[i];
-    }
-}
-
-// Field multiplication using Montgomery arithmetic, c = a*b*R^-1 mod prime, where R=2^768
-void sike_fpmul_mont(const felm_t ma, const felm_t mb, felm_t mc)
-{
-    dfelm_t temp = {0};
-    sike_mpmul(ma, mb, temp);
-    sike_fprdc(temp, mc);
-}
-
-// Conversion from Montgomery representation to standard representation,
-// c = ma*R^(-1) mod p = a mod p, where ma in [0, p-1].
-void sike_from_mont(const felm_t ma, felm_t c)
-{
-    felm_t one = {0};
-    one[0] = 1;
-
-    sike_fpmul_mont(ma, one, c);
-    sike_fpcorrection(c);
-}
-
-// GF(p^2) squaring using Montgomery arithmetic, c = a^2 in GF(p^2).
-// Inputs: a = a0+a1*i, where a0, a1 are in [0, 2*p-1]
-// Output: c = c0+c1*i, where c0, c1 are in [0, 2*p-1]
-void sike_fp2sqr_mont(const f2elm_t a, f2elm_t c) {
-    felm_t t1, t2, t3;
-
-    mp_addfast(a->c0, a->c1, t1);                      // t1 = a0+a1
-    sike_fpsub(a->c0, a->c1, t2);                      // t2 = a0-a1
-    mp_addfast(a->c0, a->c0, t3);                      // t3 = 2a0
-    sike_fpmul_mont(t1, t2, c->c0);                    // c0 = (a0+a1)(a0-a1)
-    sike_fpmul_mont(t3, a->c1, c->c1);                 // c1 = 2a0*a1
-}
-
-// Modular negation, a = -a mod p503.
-// Input/output: a in [0, 2*p503-1]
-void sike_fpneg(felm_t a) {
-  uint32_t borrow = 0;
-  for (size_t i = 0; i < NWORDS_FIELD; i++) {
-    SUBC(borrow, sike_params.prime_x2[i], a[i], borrow, a[i]);
-  }
-}
-
-// Modular division by two, c = a/2 mod p503.
-// Input : a in [0, 2*p503-1]
-// Output: c in [0, 2*p503-1]
-void sike_fpdiv2(const felm_t a, felm_t c) {
-  uint32_t carry = 0;
-  crypto_word_t mask;
-
-  mask = 0 - (crypto_word_t)(a[0] & 1);    // If a is odd compute a+p503
-  for (size_t i = 0; i < NWORDS_FIELD; i++) {
-    ADDC(carry, a[i], sike_params.prime[i] & mask, carry, c[i]);
-  }
-
-  // Multiprecision right shift by one.
-  for (size_t i = 0; i < NWORDS_FIELD-1; i++) {
-    c[i] = (c[i] >> 1) ^ (c[i+1] << (RADIX - 1));
-  }
-  c[NWORDS_FIELD-1] >>= 1;
-}
-
-// Modular correction to reduce field element a in [0, 2*p503-1] to [0, p503-1].
-void sike_fpcorrection(felm_t a) {
-  uint32_t borrow = 0;
-  crypto_word_t mask;
-
-  for (size_t i = 0; i < NWORDS_FIELD; i++) {
-    SUBC(borrow, a[i], sike_params.prime[i], borrow, a[i]);
-  }
-  mask = 0 - (crypto_word_t)borrow;
-
-  borrow = 0;
-  for (size_t i = 0; i < NWORDS_FIELD; i++) {
-    ADDC(borrow, a[i], sike_params.prime[i] & mask, borrow, a[i]);
-  }
-}
-
-// GF(p^2) multiplication using Montgomery arithmetic, c = a*b in GF(p^2).
-// Inputs: a = a0+a1*i and b = b0+b1*i, where a0, a1, b0, b1 are in [0, 2*p-1]
-// Output: c = c0+c1*i, where c0, c1 are in [0, 2*p-1]
-void sike_fp2mul_mont(const f2elm_t a, const f2elm_t b, f2elm_t c) {
-    felm_t t1, t2;
-    dfelm_t tt1, tt2, tt3;
-    crypto_word_t mask;
-
-    mp_addfast(a->c0, a->c1, t1);                      // t1 = a0+a1
-    mp_addfast(b->c0, b->c1, t2);                      // t2 = b0+b1
-    sike_mpmul(a->c0, b->c0, tt1);                     // tt1 = a0*b0
-    sike_mpmul(a->c1, b->c1, tt2);                     // tt2 = a1*b1
-    sike_mpmul(t1, t2, tt3);                           // tt3 = (a0+a1)*(b0+b1)
-    mp_dblsubfast(tt1, tt2, tt3);                      // tt3 = (a0+a1)*(b0+b1) - a0*b0 - a1*b1
-    mask = mp_subfast(tt1, tt2, tt1);                  // tt1 = a0*b0 - a1*b1. If tt1 < 0 then mask = 0xFF..F, else if tt1 >= 0 then mask = 0x00..0
-
-    for (size_t i = 0; i < NWORDS_FIELD; i++) {
-        t1[i] = sike_params.prime[i] & mask;
-    }
-
-    sike_fprdc(tt3, c->c1);                             // c[1] = (a0+a1)*(b0+b1) - a0*b0 - a1*b1
-    mp_addfast(&tt1[NWORDS_FIELD], t1, &tt1[NWORDS_FIELD]);
-    sike_fprdc(tt1, c->c0);                             // c[0] = a0*b0 - a1*b1
-}
-
-// GF(p^2) inversion using Montgomery arithmetic, a = (a0-i*a1)/(a0^2+a1^2).
-void sike_fp2inv_mont(f2elm_t a) {
-    f2elm_t t1;
-
-    fpsqr_mont(a->c0, t1->c0);                         // t10 = a0^2
-    fpsqr_mont(a->c1, t1->c1);                         // t11 = a1^2
-    sike_fpadd(t1->c0, t1->c1, t1->c0);                // t10 = a0^2+a1^2
-    fpinv_mont(t1->c0);                                // t10 = (a0^2+a1^2)^-1
-    sike_fpneg(a->c1);                                 // a = a0-i*a1
-    sike_fpmul_mont(a->c0, t1->c0, a->c0);
-    sike_fpmul_mont(a->c1, t1->c0, a->c1);             // a = (a0-i*a1)*(a0^2+a1^2)^-1
-}
diff --git a/third_party/sike/fpx.h b/third_party/sike/fpx.h
deleted file mode 100644
index e697688..0000000
--- a/third_party/sike/fpx.h
+++ /dev/null
@@ -1,113 +0,0 @@
-#ifndef FPX_H_
-#define FPX_H_
-
-#include "utils.h"
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-// Modular addition, c = a+b mod p.
-void sike_fpadd(const felm_t a, const felm_t b, felm_t c);
-// Modular subtraction, c = a-b mod p.
-void sike_fpsub(const felm_t a, const felm_t b, felm_t c);
-// Modular division by two, c = a/2 mod p.
-void sike_fpdiv2(const felm_t a, felm_t c);
-// Modular correction to reduce field element a in [0, 2*p-1] to [0, p-1].
-void sike_fpcorrection(felm_t a);
-// Multiprecision multiply, c = a*b, where lng(a) = lng(b) = nwords.
-void sike_mpmul(const felm_t a, const felm_t b, dfelm_t c);
-// 443-bit Montgomery reduction, c = a mod p. Buffer 'a' is modified after
-// call returns.
-void sike_fprdc(dfelm_t a, felm_t c);
-// Double 2x443-bit multiprecision subtraction, c = c-a-b
-void sike_mpdblsubx2_asm(const felm_t a, const felm_t b, felm_t c);
-// Multiprecision subtraction, c = a-b
-crypto_word_t sike_mpsubx2_asm(const dfelm_t a, const dfelm_t b, dfelm_t c);
-// 443-bit multiprecision addition, c = a+b
-void sike_mpadd_asm(const felm_t a, const felm_t b, felm_t c);
-// Modular negation, a = -a mod p.
-void sike_fpneg(felm_t a);
-// Copy of a field element, c = a
-void sike_fpcopy(const felm_t a, felm_t c);
-// Copy a field element, c = a.
-void sike_fpzero(felm_t a);
-// If option = 0xFF...FF x=y; y=x, otherwise swap doesn't happen. Constant time.
-void sike_cswap_asm(point_proj_t x, point_proj_t y, const crypto_word_t option);
-// Conversion from Montgomery representation to standard representation,
-// c = ma*R^(-1) mod p = a mod p, where ma in [0, p-1].
-void sike_from_mont(const felm_t ma, felm_t c);
-// Field multiplication using Montgomery arithmetic, c = a*b*R^-1 mod p443, where R=2^768
-void sike_fpmul_mont(const felm_t ma, const felm_t mb, felm_t mc);
-// GF(p443^2) multiplication using Montgomery arithmetic, c = a*b in GF(p443^2)
-void sike_fp2mul_mont(const f2elm_t a, const f2elm_t b, f2elm_t c);
-// GF(p443^2) inversion using Montgomery arithmetic, a = (a0-i*a1)/(a0^2+a1^2)
-void sike_fp2inv_mont(f2elm_t a);
-// GF(p^2) squaring using Montgomery arithmetic, c = a^2 in GF(p^2).
-void sike_fp2sqr_mont(const f2elm_t a, f2elm_t c);
-// Modular correction, a = a in GF(p^2).
-void sike_fp2correction(f2elm_t a);
-
-#if defined(__cplusplus)
-}  // extern C
-#endif
-
-// GF(p^2) addition, c = a+b in GF(p^2).
-#define sike_fp2add(a, b, c)             \
-do {                                     \
-    sike_fpadd(a->c0, b->c0, c->c0);     \
-    sike_fpadd(a->c1, b->c1, c->c1);     \
-} while(0)
-
-// GF(p^2) subtraction, c = a-b in GF(p^2).
-#define sike_fp2sub(a,b,c)               \
-do {                                     \
-    sike_fpsub(a->c0, b->c0, c->c0);     \
-    sike_fpsub(a->c1, b->c1, c->c1);     \
-} while(0)
-
-// Copy a GF(p^2) element, c = a.
-#define sike_fp2copy(a, c)               \
-do {                                     \
-    sike_fpcopy(a->c0, c->c0);           \
-    sike_fpcopy(a->c1, c->c1);           \
-} while(0)
-
-// GF(p^2) negation, a = -a in GF(p^2).
-#define sike_fp2neg(a)                   \
-do {                                     \
-    sike_fpneg(a->c0);                   \
-    sike_fpneg(a->c1);                   \
-} while(0)
-
-// GF(p^2) division by two, c = a/2  in GF(p^2).
-#define sike_fp2div2(a, c)               \
-do {                                     \
-    sike_fpdiv2(a->c0, c->c0);           \
-    sike_fpdiv2(a->c1, c->c1);           \
-} while(0)
-
-// Modular correction, a = a in GF(p^2).
-#define sike_fp2correction(a)            \
-do {                                     \
-    sike_fpcorrection(a->c0);            \
-    sike_fpcorrection(a->c1);            \
-} while(0)
-
-// Conversion of a GF(p^2) element to Montgomery representation,
-// mc_i = a_i*R^2*R^(-1) = a_i*R in GF(p^2).
-#define sike_to_fp2mont(a, mc)                           \
-  do {                                                   \
-    sike_fpmul_mont(a->c0, sike_params.mont_R2, mc->c0); \
-    sike_fpmul_mont(a->c1, sike_params.mont_R2, mc->c1); \
-  } while (0)
-
-// Conversion of a GF(p^2) element from Montgomery representation to standard representation,
-// c_i = ma_i*R^(-1) = a_i in GF(p^2).
-#define sike_from_fp2mont(ma, c)         \
-do {                                     \
-    sike_from_mont(ma->c0, c->c0);       \
-    sike_from_mont(ma->c1, c->c1);       \
-} while(0)
-
-#endif // FPX_H_
diff --git a/third_party/sike/isogeny.c b/third_party/sike/isogeny.c
deleted file mode 100644
index 6b910e0..0000000
--- a/third_party/sike/isogeny.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/********************************************************************************************
-* SIDH: an efficient supersingular isogeny cryptography library
-*
-* Abstract: elliptic curve and isogeny functions
-*********************************************************************************************/
-#include "utils.h"
-#include "isogeny.h"
-#include "fpx.h"
-
-static void xDBL(const point_proj_t P, point_proj_t Q, const f2elm_t A24plus, const f2elm_t C24)
-{ // Doubling of a Montgomery point in projective coordinates (X:Z).
-  // Input: projective Montgomery x-coordinates P = (X1:Z1), where x1=X1/Z1 and Montgomery curve constants A+2C and 4C.
-  // Output: projective Montgomery x-coordinates Q = 2*P = (X2:Z2).
-    f2elm_t t0, t1;
-
-    sike_fp2sub(P->X, P->Z, t0);                         // t0 = X1-Z1
-    sike_fp2add(P->X, P->Z, t1);                         // t1 = X1+Z1
-    sike_fp2sqr_mont(t0, t0);                            // t0 = (X1-Z1)^2
-    sike_fp2sqr_mont(t1, t1);                            // t1 = (X1+Z1)^2
-    sike_fp2mul_mont(C24, t0, Q->Z);                     // Z2 = C24*(X1-Z1)^2
-    sike_fp2mul_mont(t1, Q->Z, Q->X);                    // X2 = C24*(X1-Z1)^2*(X1+Z1)^2
-    sike_fp2sub(t1, t0, t1);                             // t1 = (X1+Z1)^2-(X1-Z1)^2
-    sike_fp2mul_mont(A24plus, t1, t0);                   // t0 = A24plus*[(X1+Z1)^2-(X1-Z1)^2]
-    sike_fp2add(Q->Z, t0, Q->Z);                         // Z2 = A24plus*[(X1+Z1)^2-(X1-Z1)^2] + C24*(X1-Z1)^2
-    sike_fp2mul_mont(Q->Z, t1, Q->Z);                    // Z2 = [A24plus*[(X1+Z1)^2-(X1-Z1)^2] + C24*(X1-Z1)^2]*[(X1+Z1)^2-(X1-Z1)^2]
-}
-
-void sike_xDBLe(const point_proj_t P, point_proj_t Q, const f2elm_t A24plus, const f2elm_t C24, size_t e)
-{ // Computes [2^e](X:Z) on Montgomery curve with projective constant via e repeated doublings.
-  // Input: projective Montgomery x-coordinates P = (XP:ZP), such that xP=XP/ZP and Montgomery curve constants A+2C and 4C.
-  // Output: projective Montgomery x-coordinates Q <- (2^e)*P.
-
-    memmove(Q, P, sizeof(*P));
-    for (size_t i = 0; i < e; i++) {
-        xDBL(Q, Q, A24plus, C24);
-    }
-}
-
-void sike_get_4_isog(const point_proj_t P, f2elm_t A24plus, f2elm_t C24, f2elm_t* coeff)
-{ // Computes the corresponding 4-isogeny of a projective Montgomery point (X4:Z4) of order 4.
-  // Input:  projective point of order four P = (X4:Z4).
-  // Output: the 4-isogenous Montgomery curve with projective coefficients A+2C/4C and the 3 coefficients
-  //         that are used to evaluate the isogeny at a point in eval_4_isog().
-
-    sike_fp2sub(P->X, P->Z, coeff[1]);                   // coeff[1] = X4-Z4
-    sike_fp2add(P->X, P->Z, coeff[2]);                   // coeff[2] = X4+Z4
-    sike_fp2sqr_mont(P->Z, coeff[0]);                    // coeff[0] = Z4^2
-    sike_fp2add(coeff[0], coeff[0], coeff[0]);           // coeff[0] = 2*Z4^2
-    sike_fp2sqr_mont(coeff[0], C24);                     // C24 = 4*Z4^4
-    sike_fp2add(coeff[0], coeff[0], coeff[0]);           // coeff[0] = 4*Z4^2
-    sike_fp2sqr_mont(P->X, A24plus);                     // A24plus = X4^2
-    sike_fp2add(A24plus, A24plus, A24plus);              // A24plus = 2*X4^2
-    sike_fp2sqr_mont(A24plus, A24plus);                  // A24plus = 4*X4^4
-}
-
-void sike_eval_4_isog(point_proj_t P, f2elm_t* coeff)
-{ // Evaluates the isogeny at the point (X:Z) in the domain of the isogeny, given a 4-isogeny phi defined
-  // by the 3 coefficients in coeff (computed in the function get_4_isog()).
-  // Inputs: the coefficients defining the isogeny, and the projective point P = (X:Z).
-  // Output: the projective point P = phi(P) = (X:Z) in the codomain.
-    f2elm_t t0, t1;
-
-    sike_fp2add(P->X, P->Z, t0);                         // t0 = X+Z
-    sike_fp2sub(P->X, P->Z, t1);                         // t1 = X-Z
-    sike_fp2mul_mont(t0, coeff[1], P->X);                // X = (X+Z)*coeff[1]
-    sike_fp2mul_mont(t1, coeff[2], P->Z);                // Z = (X-Z)*coeff[2]
-    sike_fp2mul_mont(t0, t1, t0);                        // t0 = (X+Z)*(X-Z)
-    sike_fp2mul_mont(t0, coeff[0], t0);                  // t0 = coeff[0]*(X+Z)*(X-Z)
-    sike_fp2add(P->X, P->Z, t1);                         // t1 = (X-Z)*coeff[2] + (X+Z)*coeff[1]
-    sike_fp2sub(P->X, P->Z, P->Z);                       // Z = (X-Z)*coeff[2] - (X+Z)*coeff[1]
-    sike_fp2sqr_mont(t1, t1);                            // t1 = [(X-Z)*coeff[2] + (X+Z)*coeff[1]]^2
-    sike_fp2sqr_mont(P->Z, P->Z);                        // Z = [(X-Z)*coeff[2] - (X+Z)*coeff[1]]^2
-    sike_fp2add(t1, t0, P->X);                           // X = coeff[0]*(X+Z)*(X-Z) + [(X-Z)*coeff[2] + (X+Z)*coeff[1]]^2
-    sike_fp2sub(P->Z, t0, t0);                           // t0 = [(X-Z)*coeff[2] - (X+Z)*coeff[1]]^2 - coeff[0]*(X+Z)*(X-Z)
-    sike_fp2mul_mont(P->X, t1, P->X);                    // Xfinal
-    sike_fp2mul_mont(P->Z, t0, P->Z);                    // Zfinal
-}
-
-
-void sike_xTPL(const point_proj_t P, point_proj_t Q, const f2elm_t A24minus, const f2elm_t A24plus)
-{ // Tripling of a Montgomery point in projective coordinates (X:Z).
-  // Input: projective Montgomery x-coordinates P = (X:Z), where x=X/Z and Montgomery curve constants A24plus = A+2C and A24minus = A-2C.
-  // Output: projective Montgomery x-coordinates Q = 3*P = (X3:Z3).
-    f2elm_t t0, t1, t2, t3, t4, t5, t6;
-
-    sike_fp2sub(P->X, P->Z, t0);                         // t0 = X-Z
-    sike_fp2sqr_mont(t0, t2);                            // t2 = (X-Z)^2
-    sike_fp2add(P->X, P->Z, t1);                         // t1 = X+Z
-    sike_fp2sqr_mont(t1, t3);                            // t3 = (X+Z)^2
-    sike_fp2add(t0, t1, t4);                             // t4 = 2*X
-    sike_fp2sub(t1, t0, t0);                             // t0 = 2*Z
-    sike_fp2sqr_mont(t4, t1);                            // t1 = 4*X^2
-    sike_fp2sub(t1, t3, t1);                             // t1 = 4*X^2 - (X+Z)^2
-    sike_fp2sub(t1, t2, t1);                             // t1 = 4*X^2 - (X+Z)^2 - (X-Z)^2
-    sike_fp2mul_mont(t3, A24plus, t5);                   // t5 = A24plus*(X+Z)^2
-    sike_fp2mul_mont(t3, t5, t3);                        // t3 = A24plus*(X+Z)^3
-    sike_fp2mul_mont(A24minus, t2, t6);                  // t6 = A24minus*(X-Z)^2
-    sike_fp2mul_mont(t2, t6, t2);                        // t2 = A24minus*(X-Z)^3
-    sike_fp2sub(t2, t3, t3);                             // t3 = A24minus*(X-Z)^3 - coeff*(X+Z)^3
-    sike_fp2sub(t5, t6, t2);                             // t2 = A24plus*(X+Z)^2 - A24minus*(X-Z)^2
-    sike_fp2mul_mont(t1, t2, t1);                        // t1 = [4*X^2 - (X+Z)^2 - (X-Z)^2]*[A24plus*(X+Z)^2 - A24minus*(X-Z)^2]
-    sike_fp2add(t3, t1, t2);                             // t2 = [4*X^2 - (X+Z)^2 - (X-Z)^2]*[A24plus*(X+Z)^2 - A24minus*(X-Z)^2] + A24minus*(X-Z)^3 - coeff*(X+Z)^3
-    sike_fp2sqr_mont(t2, t2);                            // t2 = t2^2
-    sike_fp2mul_mont(t4, t2, Q->X);                      // X3 = 2*X*t2
-    sike_fp2sub(t3, t1, t1);                             // t1 = A24minus*(X-Z)^3 - A24plus*(X+Z)^3 - [4*X^2 - (X+Z)^2 - (X-Z)^2]*[A24plus*(X+Z)^2 - A24minus*(X-Z)^2]
-    sike_fp2sqr_mont(t1, t1);                            // t1 = t1^2
-    sike_fp2mul_mont(t0, t1, Q->Z);                      // Z3 = 2*Z*t1
-}
-
-void sike_xTPLe(const point_proj_t P, point_proj_t Q, const f2elm_t A24minus, const f2elm_t A24plus, size_t e)
-{ // Computes [3^e](X:Z) on Montgomery curve with projective constant via e repeated triplings.
-  // Input: projective Montgomery x-coordinates P = (XP:ZP), such that xP=XP/ZP and Montgomery curve constants A24plus = A+2C and A24minus = A-2C.
-  // Output: projective Montgomery x-coordinates Q <- (3^e)*P.
-    memmove(Q, P, sizeof(*P));
-    for (size_t i = 0; i < e; i++) {
-        sike_xTPL(Q, Q, A24minus, A24plus);
-    }
-}
-
-void sike_get_3_isog(const point_proj_t P, f2elm_t A24minus, f2elm_t A24plus, f2elm_t* coeff)
-{ // Computes the corresponding 3-isogeny of a projective Montgomery point (X3:Z3) of order 3.
-  // Input:  projective point of order three P = (X3:Z3).
-  // Output: the 3-isogenous Montgomery curve with projective coefficient A/C.
-    f2elm_t t0, t1, t2, t3, t4;
-
-    sike_fp2sub(P->X, P->Z, coeff[0]);                   // coeff0 = X-Z
-    sike_fp2sqr_mont(coeff[0], t0);                      // t0 = (X-Z)^2
-    sike_fp2add(P->X, P->Z, coeff[1]);                   // coeff1 = X+Z
-    sike_fp2sqr_mont(coeff[1], t1);                      // t1 = (X+Z)^2
-    sike_fp2add(t0, t1, t2);                             // t2 = (X+Z)^2 + (X-Z)^2
-    sike_fp2add(coeff[0], coeff[1], t3);                 // t3 = 2*X
-    sike_fp2sqr_mont(t3, t3);                            // t3 = 4*X^2
-    sike_fp2sub(t3, t2, t3);                             // t3 = 4*X^2 - (X+Z)^2 - (X-Z)^2
-    sike_fp2add(t1, t3, t2);                             // t2 = 4*X^2 - (X-Z)^2
-    sike_fp2add(t3, t0, t3);                             // t3 = 4*X^2 - (X+Z)^2
-    sike_fp2add(t0, t3, t4);                             // t4 = 4*X^2 - (X+Z)^2 + (X-Z)^2
-    sike_fp2add(t4, t4, t4);                             // t4 = 2(4*X^2 - (X+Z)^2 + (X-Z)^2)
-    sike_fp2add(t1, t4, t4);                             // t4 = 8*X^2 - (X+Z)^2 + 2*(X-Z)^2
-    sike_fp2mul_mont(t2, t4, A24minus);                  // A24minus = [4*X^2 - (X-Z)^2]*[8*X^2 - (X+Z)^2 + 2*(X-Z)^2]
-    sike_fp2add(t1, t2, t4);                             // t4 = 4*X^2 + (X+Z)^2 - (X-Z)^2
-    sike_fp2add(t4, t4, t4);                             // t4 = 2(4*X^2 + (X+Z)^2 - (X-Z)^2)
-    sike_fp2add(t0, t4, t4);                             // t4 = 8*X^2 + 2*(X+Z)^2 - (X-Z)^2
-    sike_fp2mul_mont(t3, t4, t4);                        // t4 = [4*X^2 - (X+Z)^2]*[8*X^2 + 2*(X+Z)^2 - (X-Z)^2]
-    sike_fp2sub(t4, A24minus, t0);                       // t0 = [4*X^2 - (X+Z)^2]*[8*X^2 + 2*(X+Z)^2 - (X-Z)^2] - [4*X^2 - (X-Z)^2]*[8*X^2 - (X+Z)^2 + 2*(X-Z)^2]
-    sike_fp2add(A24minus, t0, A24plus);                  // A24plus = 8*X^2 - (X+Z)^2 + 2*(X-Z)^2
-}
-
-
-void sike_eval_3_isog(point_proj_t Q, f2elm_t* coeff)
-{ // Computes the 3-isogeny R=phi(X:Z), given projective point (X3:Z3) of order 3 on a Montgomery curve and
-  // a point P with 2 coefficients in coeff (computed in the function get_3_isog()).
-  // Inputs: projective points P = (X3:Z3) and Q = (X:Z).
-  // Output: the projective point Q <- phi(Q) = (X3:Z3).
-    f2elm_t t0, t1, t2;
-
-    sike_fp2add(Q->X, Q->Z, t0);                       // t0 = X+Z
-    sike_fp2sub(Q->X, Q->Z, t1);                       // t1 = X-Z
-    sike_fp2mul_mont(t0, coeff[0], t0);                // t0 = coeff0*(X+Z)
-    sike_fp2mul_mont(t1, coeff[1], t1);                // t1 = coeff1*(X-Z)
-    sike_fp2add(t0, t1, t2);                           // t2 = coeff0*(X+Z) + coeff1*(X-Z)
-    sike_fp2sub(t1, t0, t0);                           // t0 = coeff1*(X-Z) - coeff0*(X+Z)
-    sike_fp2sqr_mont(t2, t2);                          // t2 = [coeff0*(X+Z) + coeff1*(X-Z)]^2
-    sike_fp2sqr_mont(t0, t0);                          // t0 = [coeff1*(X-Z) - coeff0*(X+Z)]^2
-    sike_fp2mul_mont(Q->X, t2, Q->X);                  // X3final = X*[coeff0*(X+Z) + coeff1*(X-Z)]^2
-    sike_fp2mul_mont(Q->Z, t0, Q->Z);                  // Z3final = Z*[coeff1*(X-Z) - coeff0*(X+Z)]^2
-}
-
-
-void sike_inv_3_way(f2elm_t z1, f2elm_t z2, f2elm_t z3)
-{ // 3-way simultaneous inversion
-  // Input:  z1,z2,z3
-  // Output: 1/z1,1/z2,1/z3 (override inputs).
-    f2elm_t t0, t1, t2, t3;
-
-    sike_fp2mul_mont(z1, z2, t0);                      // t0 = z1*z2
-    sike_fp2mul_mont(z3, t0, t1);                      // t1 = z1*z2*z3
-    sike_fp2inv_mont(t1);                              // t1 = 1/(z1*z2*z3)
-    sike_fp2mul_mont(z3, t1, t2);                      // t2 = 1/(z1*z2)
-    sike_fp2mul_mont(t2, z2, t3);                      // t3 = 1/z1
-    sike_fp2mul_mont(t2, z1, z2);                      // z2 = 1/z2
-    sike_fp2mul_mont(t0, t1, z3);                      // z3 = 1/z3
-    sike_fp2copy(t3, z1);                              // z1 = 1/z1
-}
-
-
-void sike_get_A(const f2elm_t xP, const f2elm_t xQ, const f2elm_t xR, f2elm_t A)
-{ // Given the x-coordinates of P, Q, and R, returns the value A corresponding to the Montgomery curve E_A: y^2=x^3+A*x^2+x such that R=Q-P on E_A.
-  // Input:  the x-coordinates xP, xQ, and xR of the points P, Q and R.
-  // Output: the coefficient A corresponding to the curve E_A: y^2=x^3+A*x^2+x.
-    f2elm_t t0, t1, one = F2ELM_INIT;
-
-    extern const struct params_t sike_params;
-    sike_fpcopy(sike_params.mont_one, one->c0);
-    sike_fp2add(xP, xQ, t1);                           // t1 = xP+xQ
-    sike_fp2mul_mont(xP, xQ, t0);                      // t0 = xP*xQ
-    sike_fp2mul_mont(xR, t1, A);                       // A = xR*t1
-    sike_fp2add(t0, A, A);                             // A = A+t0
-    sike_fp2mul_mont(t0, xR, t0);                      // t0 = t0*xR
-    sike_fp2sub(A, one, A);                            // A = A-1
-    sike_fp2add(t0, t0, t0);                           // t0 = t0+t0
-    sike_fp2add(t1, xR, t1);                           // t1 = t1+xR
-    sike_fp2add(t0, t0, t0);                           // t0 = t0+t0
-    sike_fp2sqr_mont(A, A);                            // A = A^2
-    sike_fp2inv_mont(t0);                              // t0 = 1/t0
-    sike_fp2mul_mont(A, t0, A);                        // A = A*t0
-    sike_fp2sub(A, t1, A);                             // Afinal = A-t1
-}
-
-
-void sike_j_inv(const f2elm_t A, const f2elm_t C, f2elm_t jinv)
-{ // Computes the j-invariant of a Montgomery curve with projective constant.
-  // Input: A,C in GF(p^2).
-  // Output: j=256*(A^2-3*C^2)^3/(C^4*(A^2-4*C^2)), which is the j-invariant of the Montgomery curve B*y^2=x^3+(A/C)*x^2+x or (equivalently) j-invariant of B'*y^2=C*x^3+A*x^2+C*x.
-    f2elm_t t0, t1;
-
-    sike_fp2sqr_mont(A, jinv);                           // jinv = A^2
-    sike_fp2sqr_mont(C, t1);                             // t1 = C^2
-    sike_fp2add(t1, t1, t0);                             // t0 = t1+t1
-    sike_fp2sub(jinv, t0, t0);                           // t0 = jinv-t0
-    sike_fp2sub(t0, t1, t0);                             // t0 = t0-t1
-    sike_fp2sub(t0, t1, jinv);                           // jinv = t0-t1
-    sike_fp2sqr_mont(t1, t1);                            // t1 = t1^2
-    sike_fp2mul_mont(jinv, t1, jinv);                    // jinv = jinv*t1
-    sike_fp2add(t0, t0, t0);                             // t0 = t0+t0
-    sike_fp2add(t0, t0, t0);                             // t0 = t0+t0
-    sike_fp2sqr_mont(t0, t1);                            // t1 = t0^2
-    sike_fp2mul_mont(t0, t1, t0);                        // t0 = t0*t1
-    sike_fp2add(t0, t0, t0);                             // t0 = t0+t0
-    sike_fp2add(t0, t0, t0);                             // t0 = t0+t0
-    sike_fp2inv_mont(jinv);                              // jinv = 1/jinv
-    sike_fp2mul_mont(jinv, t0, jinv);                    // jinv = t0*jinv
-}
-
-
-void sike_xDBLADD(point_proj_t P, point_proj_t Q, const f2elm_t xPQ, const f2elm_t A24)
-{ // Simultaneous doubling and differential addition.
-  // Input: projective Montgomery points P=(XP:ZP) and Q=(XQ:ZQ) such that xP=XP/ZP and xQ=XQ/ZQ, affine difference xPQ=x(P-Q) and Montgomery curve constant A24=(A+2)/4.
-  // Output: projective Montgomery points P <- 2*P = (X2P:Z2P) such that x(2P)=X2P/Z2P, and Q <- P+Q = (XQP:ZQP) such that = x(Q+P)=XQP/ZQP.
-    f2elm_t t0, t1, t2;
-
-    sike_fp2add(P->X, P->Z, t0);                         // t0 = XP+ZP
-    sike_fp2sub(P->X, P->Z, t1);                         // t1 = XP-ZP
-    sike_fp2sqr_mont(t0, P->X);                          // XP = (XP+ZP)^2
-    sike_fp2sub(Q->X, Q->Z, t2);                         // t2 = XQ-ZQ
-    sike_fp2correction(t2);
-    sike_fp2add(Q->X, Q->Z, Q->X);                       // XQ = XQ+ZQ
-    sike_fp2mul_mont(t0, t2, t0);                        // t0 = (XP+ZP)*(XQ-ZQ)
-    sike_fp2sqr_mont(t1, P->Z);                          // ZP = (XP-ZP)^2
-    sike_fp2mul_mont(t1, Q->X, t1);                      // t1 = (XP-ZP)*(XQ+ZQ)
-    sike_fp2sub(P->X, P->Z, t2);                         // t2 = (XP+ZP)^2-(XP-ZP)^2
-    sike_fp2mul_mont(P->X, P->Z, P->X);                  // XP = (XP+ZP)^2*(XP-ZP)^2
-    sike_fp2mul_mont(t2, A24, Q->X);                     // XQ = A24*[(XP+ZP)^2-(XP-ZP)^2]
-    sike_fp2sub(t0, t1, Q->Z);                           // ZQ = (XP+ZP)*(XQ-ZQ)-(XP-ZP)*(XQ+ZQ)
-    sike_fp2add(Q->X, P->Z, P->Z);                       // ZP = A24*[(XP+ZP)^2-(XP-ZP)^2]+(XP-ZP)^2
-    sike_fp2add(t0, t1, Q->X);                           // XQ = (XP+ZP)*(XQ-ZQ)+(XP-ZP)*(XQ+ZQ)
-    sike_fp2mul_mont(P->Z, t2, P->Z);                    // ZP = [A24*[(XP+ZP)^2-(XP-ZP)^2]+(XP-ZP)^2]*[(XP+ZP)^2-(XP-ZP)^2]
-    sike_fp2sqr_mont(Q->Z, Q->Z);                        // ZQ = [(XP+ZP)*(XQ-ZQ)-(XP-ZP)*(XQ+ZQ)]^2
-    sike_fp2sqr_mont(Q->X, Q->X);                        // XQ = [(XP+ZP)*(XQ-ZQ)+(XP-ZP)*(XQ+ZQ)]^2
-    sike_fp2mul_mont(Q->Z, xPQ, Q->Z);                   // ZQ = xPQ*[(XP+ZP)*(XQ-ZQ)-(XP-ZP)*(XQ+ZQ)]^2
-}
diff --git a/third_party/sike/isogeny.h b/third_party/sike/isogeny.h
deleted file mode 100644
index 18337dd..0000000
--- a/third_party/sike/isogeny.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef ISOGENY_H_
-#define ISOGENY_H_
-
-// Computes [2^e](X:Z) on Montgomery curve with projective
-// constant via e repeated doublings.
-void sike_xDBLe(
-    const point_proj_t P, point_proj_t Q, const f2elm_t A24plus,
-    const f2elm_t C24, size_t e);
-// Simultaneous doubling and differential addition.
-void sike_xDBLADD(
-    point_proj_t P, point_proj_t Q, const f2elm_t xPQ,
-    const f2elm_t A24);
-// Tripling of a Montgomery point in projective coordinates (X:Z).
-void sike_xTPL(
-    const point_proj_t P, point_proj_t Q, const f2elm_t A24minus,
-    const f2elm_t A24plus);
-// Computes [3^e](X:Z) on Montgomery curve with projective constant
-// via e repeated triplings.
-void sike_xTPLe(
-    const point_proj_t P, point_proj_t Q, const f2elm_t A24minus,
-    const f2elm_t A24plus, size_t e);
-// Given the x-coordinates of P, Q, and R, returns the value A
-// corresponding to the Montgomery curve E_A: y^2=x^3+A*x^2+x such that R=Q-P on E_A.
-void sike_get_A(
-    const f2elm_t xP, const f2elm_t xQ, const f2elm_t xR, f2elm_t A);
-// Computes the j-invariant of a Montgomery curve with projective constant.
-void sike_j_inv(
-    const f2elm_t A, const f2elm_t C, f2elm_t jinv);
-// Computes the corresponding 4-isogeny of a projective Montgomery
-// point (X4:Z4) of order 4.
-void sike_get_4_isog(
-    const point_proj_t P, f2elm_t A24plus, f2elm_t C24, f2elm_t* coeff);
-// Computes the corresponding 3-isogeny of a projective Montgomery
-// point (X3:Z3) of order 3.
-void sike_get_3_isog(
-    const point_proj_t P, f2elm_t A24minus, f2elm_t A24plus,
-    f2elm_t* coeff);
-// Computes the 3-isogeny R=phi(X:Z), given projective point (X3:Z3)
-// of order 3 on a Montgomery curve and a point P with coefficients given in coeff.
-void sike_eval_3_isog(
-    point_proj_t Q, f2elm_t* coeff);
-// Evaluates the isogeny at the point (X:Z) in the domain of the isogeny.
-void sike_eval_4_isog(
-    point_proj_t P, f2elm_t* coeff);
-// 3-way simultaneous inversion
-void sike_inv_3_way(
-    f2elm_t z1, f2elm_t z2, f2elm_t z3);
-
-#endif // ISOGENY_H_
diff --git a/third_party/sike/sike.c b/third_party/sike/sike.c
deleted file mode 100644
index 87b7417..0000000
--- a/third_party/sike/sike.c
+++ /dev/null
@@ -1,531 +0,0 @@
-/********************************************************************************************
-* SIDH: an efficient supersingular isogeny cryptography library
-*
-* Abstract: supersingular isogeny key encapsulation (SIKE) protocol
-*********************************************************************************************/
-
-#include <assert.h>
-#include <stdint.h>
-#include <string.h>
-#include <openssl/bn.h>
-#include <openssl/base.h>
-#include <openssl/rand.h>
-#include <openssl/mem.h>
-#include <openssl/sha.h>
-
-#include "utils.h"
-#include "isogeny.h"
-#include "fpx.h"
-
-extern const struct params_t sike_params;
-
-// SIDH_JINV_BYTESZ is a number of bytes used for encoding j-invariant.
-#define SIDH_JINV_BYTESZ    110U
-// SIDH_PRV_A_BITSZ is a number of bits of SIDH private key (2-isogeny)
-#define SIDH_PRV_A_BITSZ    216U
-// SIDH_PRV_A_BITSZ is a number of bits of SIDH private key (3-isogeny)
-#define SIDH_PRV_B_BITSZ    217U
-// MAX_INT_POINTS_ALICE is a number of points used in 2-isogeny tree computation
-#define MAX_INT_POINTS_ALICE    7U
-// MAX_INT_POINTS_ALICE is a number of points used in 3-isogeny tree computation
-#define MAX_INT_POINTS_BOB      8U
-
-// Swap points.
-// If option = 0 then P <- P and Q <- Q, else if option = 0xFF...FF then P <- Q and Q <- P
-#if !defined(OPENSSL_X86_64) || defined(OPENSSL_NO_ASM)
-static void sike_cswap(point_proj_t P, point_proj_t Q, const crypto_word_t option)
-{
-    crypto_word_t temp;
-    for (size_t i = 0; i < NWORDS_FIELD; i++) {
-        temp = option & (P->X->c0[i] ^ Q->X->c0[i]);
-        P->X->c0[i] = temp ^ P->X->c0[i];
-        Q->X->c0[i] = temp ^ Q->X->c0[i];
-        temp = option & (P->Z->c0[i] ^ Q->Z->c0[i]);
-        P->Z->c0[i] = temp ^ P->Z->c0[i];
-        Q->Z->c0[i] = temp ^ Q->Z->c0[i];
-        temp = option & (P->X->c1[i] ^ Q->X->c1[i]);
-        P->X->c1[i] = temp ^ P->X->c1[i];
-        Q->X->c1[i] = temp ^ Q->X->c1[i];
-        temp = option & (P->Z->c1[i] ^ Q->Z->c1[i]);
-        P->Z->c1[i] = temp ^ P->Z->c1[i];
-        Q->Z->c1[i] = temp ^ Q->Z->c1[i];
-    }
-}
-#endif
-
-// Swap points.
-// If option = 0 then P <- P and Q <- Q, else if option = 0xFF...FF then P <- Q and Q <- P
-static inline void sike_fp2cswap(point_proj_t P, point_proj_t Q, const crypto_word_t option)
-{
-#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM)
-    sike_cswap_asm(P, Q, option);
-#else
-    sike_cswap(P, Q, option);
-#endif
-}
-
-static void ladder3Pt(
-    const f2elm_t xP, const f2elm_t xQ, const f2elm_t xPQ, const uint8_t* m,
-    int is_A, point_proj_t R, const f2elm_t A) {
-    point_proj_t R0 = POINT_PROJ_INIT, R2 = POINT_PROJ_INIT;
-    f2elm_t A24 = F2ELM_INIT;
-    crypto_word_t mask;
-    int bit, swap, prevbit = 0;
-
-    const size_t nbits = is_A?SIDH_PRV_A_BITSZ:SIDH_PRV_B_BITSZ;
-
-    // Initializing constant
-    sike_fpcopy(sike_params.mont_one, A24[0].c0);
-    sike_fp2add(A24, A24, A24);
-    sike_fp2add(A, A24, A24);
-    sike_fp2div2(A24, A24);
-    sike_fp2div2(A24, A24); // A24 = (A+2)/4
-
-    // Initializing points
-    sike_fp2copy(xQ, R0->X);
-    sike_fpcopy(sike_params.mont_one, R0->Z[0].c0);
-    sike_fp2copy(xPQ, R2->X);
-    sike_fpcopy(sike_params.mont_one, R2->Z[0].c0);
-    sike_fp2copy(xP, R->X);
-    sike_fpcopy(sike_params.mont_one, R->Z[0].c0);
-    memset(R->Z->c1, 0, sizeof(R->Z->c1));
-
-    // Main loop
-    for (size_t i = 0; i < nbits; i++) {
-        bit = (m[i >> 3] >> (i & 7)) & 1;
-        swap = bit ^ prevbit;
-        prevbit = bit;
-        mask = 0 - (crypto_word_t)swap;
-
-        sike_fp2cswap(R, R2, mask);
-        sike_xDBLADD(R0, R2, R->X, A24);
-        sike_fp2mul_mont(R2->X, R->Z, R2->X);
-    }
-
-    mask = 0 - (crypto_word_t)prevbit;
-    sike_fp2cswap(R, R2, mask);
-}
-
-// Initialization of basis points
-static inline void sike_init_basis(const crypto_word_t *gen, f2elm_t XP, f2elm_t XQ, f2elm_t XR) {
-    sike_fpcopy(gen,                  XP->c0);
-    sike_fpcopy(gen +   NWORDS_FIELD, XP->c1);
-    sike_fpcopy(gen + 2*NWORDS_FIELD, XQ->c0);
-    sike_fpcopy(gen + 3*NWORDS_FIELD, XQ->c1);
-    sike_fpcopy(gen + 4*NWORDS_FIELD, XR->c0);
-    sike_fpcopy(gen + 5*NWORDS_FIELD, XR->c1);
-}
-
-// Conversion of GF(p^2) element from Montgomery to standard representation.
-static inline void sike_fp2_encode(const f2elm_t x, uint8_t *enc) {
-    f2elm_t t;
-    sike_from_fp2mont(x, t);
-
-    // convert to bytes in little endian form
-    for (size_t i=0; i<FIELD_BYTESZ; i++) {
-        enc[i+           0] = (t[0].c0[i/LSZ] >> (8*(i%LSZ))) & 0xFF;
-        enc[i+FIELD_BYTESZ] = (t[0].c1[i/LSZ] >> (8*(i%LSZ))) & 0xFF;
-    }
-}
-
-// Parse byte sequence back into GF(p^2) element, and conversion to Montgomery representation.
-// Elements over GF(p503) are encoded in 63 octets in little endian format
-// (i.e., the least significant octet is located in the lowest memory address).
-static inline void fp2_decode(const uint8_t *enc, f2elm_t t) {
-    memset(t[0].c0, 0, sizeof(t[0].c0));
-    memset(t[0].c1, 0, sizeof(t[0].c1));
-    // convert bytes in little endian form to f2elm_t
-    for (size_t i = 0; i < FIELD_BYTESZ; i++) {
-        t[0].c0[i/LSZ] |= ((crypto_word_t)enc[i+           0]) << (8*(i%LSZ));
-        t[0].c1[i/LSZ] |= ((crypto_word_t)enc[i+FIELD_BYTESZ]) << (8*(i%LSZ));
-    }
-    sike_to_fp2mont(t, t);
-}
-
-// Alice's ephemeral public key generation
-// Input:  a private key prA in the range [0, 2^250 - 1], stored in 32 bytes.
-// Output: the public key pkA consisting of 3 GF(p503^2) elements encoded in 378 bytes.
-static void gen_iso_A(const uint8_t* skA, uint8_t* pkA)
-{
-    point_proj_t R, pts[MAX_INT_POINTS_ALICE];
-    point_proj_t phiP = POINT_PROJ_INIT;
-    point_proj_t phiQ = POINT_PROJ_INIT;
-    point_proj_t phiR = POINT_PROJ_INIT;
-    f2elm_t XPA, XQA, XRA, coeff[3];
-    f2elm_t A24plus = F2ELM_INIT;
-    f2elm_t C24 = F2ELM_INIT;
-    f2elm_t A = F2ELM_INIT;
-    unsigned int m, index = 0, pts_index[MAX_INT_POINTS_ALICE], npts = 0, ii = 0;
-
-    // Initialize basis points
-    sike_init_basis(sike_params.A_gen, XPA, XQA, XRA);
-    sike_init_basis(sike_params.B_gen, phiP->X, phiQ->X, phiR->X);
-    sike_fpcopy(sike_params.mont_one, (phiP->Z)->c0);
-    sike_fpcopy(sike_params.mont_one, (phiQ->Z)->c0);
-    sike_fpcopy(sike_params.mont_one, (phiR->Z)->c0);
-
-    // Initialize constants: A24plus = A+2C, C24 = 4C, where A=6, C=1
-    sike_fpcopy(sike_params.mont_one, A24plus->c0);
-    sike_fp2add(A24plus, A24plus, A24plus);
-    sike_fp2add(A24plus, A24plus, C24);
-    sike_fp2add(A24plus, C24, A);
-    sike_fp2add(C24, C24, A24plus);
-
-    // Retrieve kernel point
-    ladder3Pt(XPA, XQA, XRA, skA, 1, R, A);
-
-    // Traverse tree
-    index = 0;
-    for (size_t row = 1; row < A_max; row++) {
-        while (index < A_max-row) {
-            sike_fp2copy(R->X, pts[npts]->X);
-            sike_fp2copy(R->Z, pts[npts]->Z);
-            pts_index[npts++] = index;
-            m = sike_params.A_strat[ii++];
-            sike_xDBLe(R, R, A24plus, C24, (2*m));
-            index += m;
-        }
-        sike_get_4_isog(R, A24plus, C24, coeff);
-
-        for (size_t i = 0; i < npts; i++) {
-            sike_eval_4_isog(pts[i], coeff);
-        }
-        sike_eval_4_isog(phiP, coeff);
-        sike_eval_4_isog(phiQ, coeff);
-        sike_eval_4_isog(phiR, coeff);
-
-        sike_fp2copy(pts[npts-1]->X, R->X);
-        sike_fp2copy(pts[npts-1]->Z, R->Z);
-        index = pts_index[npts-1];
-        npts -= 1;
-    }
-
-    sike_get_4_isog(R, A24plus, C24, coeff);
-    sike_eval_4_isog(phiP, coeff);
-    sike_eval_4_isog(phiQ, coeff);
-    sike_eval_4_isog(phiR, coeff);
-
-    sike_inv_3_way(phiP->Z, phiQ->Z, phiR->Z);
-    sike_fp2mul_mont(phiP->X, phiP->Z, phiP->X);
-    sike_fp2mul_mont(phiQ->X, phiQ->Z, phiQ->X);
-    sike_fp2mul_mont(phiR->X, phiR->Z, phiR->X);
-
-    // Format public key
-    sike_fp2_encode(phiP->X, pkA);
-    sike_fp2_encode(phiQ->X, pkA + SIDH_JINV_BYTESZ);
-    sike_fp2_encode(phiR->X, pkA + 2*SIDH_JINV_BYTESZ);
-}
-
-// Bob's ephemeral key-pair generation
-// It produces a private key skB and computes the public key pkB.
-// The private key is an integer in the range [0, 2^Floor(Log(2,3^159)) - 1], stored in 32 bytes.
-// The public key consists of 3 GF(p503^2) elements encoded in 378 bytes.
-static void gen_iso_B(const uint8_t* skB, uint8_t* pkB)
-{
-    point_proj_t R, pts[MAX_INT_POINTS_BOB];
-    point_proj_t phiP = POINT_PROJ_INIT;
-    point_proj_t phiQ = POINT_PROJ_INIT;
-    point_proj_t phiR = POINT_PROJ_INIT;
-    f2elm_t XPB, XQB, XRB, coeff[3];
-    f2elm_t A24plus = F2ELM_INIT;
-    f2elm_t A24minus = F2ELM_INIT;
-    f2elm_t A = F2ELM_INIT;
-    unsigned int m, index = 0, pts_index[MAX_INT_POINTS_BOB], npts = 0, ii = 0;
-
-    // Initialize basis points
-    sike_init_basis(sike_params.B_gen, XPB, XQB, XRB);
-    sike_init_basis(sike_params.A_gen, phiP->X, phiQ->X, phiR->X);
-    sike_fpcopy(sike_params.mont_one, (phiP->Z)->c0);
-    sike_fpcopy(sike_params.mont_one, (phiQ->Z)->c0);
-    sike_fpcopy(sike_params.mont_one, (phiR->Z)->c0);
-
-    // Initialize constants: A24minus = A-2C, A24plus = A+2C, where A=6, C=1
-    sike_fpcopy(sike_params.mont_one, A24plus->c0);
-    sike_fp2add(A24plus, A24plus, A24plus);
-    sike_fp2add(A24plus, A24plus, A24minus);
-    sike_fp2add(A24plus, A24minus, A);
-    sike_fp2add(A24minus, A24minus, A24plus);
-
-    // Retrieve kernel point
-    ladder3Pt(XPB, XQB, XRB, skB, 0, R, A);
-
-    // Traverse tree
-    index = 0;
-    for (size_t row = 1; row < B_max; row++) {
-        while (index < B_max-row) {
-            sike_fp2copy(R->X, pts[npts]->X);
-            sike_fp2copy(R->Z, pts[npts]->Z);
-            pts_index[npts++] = index;
-            m = sike_params.B_strat[ii++];
-            sike_xTPLe(R, R, A24minus, A24plus, m);
-            index += m;
-        }
-        sike_get_3_isog(R, A24minus, A24plus, coeff);
-
-        for (size_t i = 0; i < npts; i++) {
-            sike_eval_3_isog(pts[i], coeff);
-        }
-        sike_eval_3_isog(phiP, coeff);
-        sike_eval_3_isog(phiQ, coeff);
-        sike_eval_3_isog(phiR, coeff);
-
-        sike_fp2copy(pts[npts-1]->X, R->X);
-        sike_fp2copy(pts[npts-1]->Z, R->Z);
-        index = pts_index[npts-1];
-        npts -= 1;
-    }
-
-    sike_get_3_isog(R, A24minus, A24plus, coeff);
-    sike_eval_3_isog(phiP, coeff);
-    sike_eval_3_isog(phiQ, coeff);
-    sike_eval_3_isog(phiR, coeff);
-
-    sike_inv_3_way(phiP->Z, phiQ->Z, phiR->Z);
-    sike_fp2mul_mont(phiP->X, phiP->Z, phiP->X);
-    sike_fp2mul_mont(phiQ->X, phiQ->Z, phiQ->X);
-    sike_fp2mul_mont(phiR->X, phiR->Z, phiR->X);
-
-    // Format public key
-    sike_fp2_encode(phiP->X, pkB);
-    sike_fp2_encode(phiQ->X, pkB + SIDH_JINV_BYTESZ);
-    sike_fp2_encode(phiR->X, pkB + 2*SIDH_JINV_BYTESZ);
-}
-
-// Alice's ephemeral shared secret computation
-// It produces a shared secret key ssA using her secret key skA and Bob's public key pkB
-// Inputs: Alice's skA is an integer in the range [0, 2^250 - 1], stored in 32 bytes.
-//         Bob's pkB consists of 3 GF(p503^2) elements encoded in 378 bytes.
-// Output: a shared secret ssA that consists of one element in GF(p503^2) encoded in 126 bytes.
-static void ex_iso_A(const uint8_t* skA, const uint8_t* pkB, uint8_t* ssA)
-{
-    point_proj_t R, pts[MAX_INT_POINTS_ALICE];
-    f2elm_t coeff[3], PKB[3], jinv;
-    f2elm_t A24plus = F2ELM_INIT;
-    f2elm_t C24 = F2ELM_INIT;
-    f2elm_t A = F2ELM_INIT;
-    unsigned int m, index = 0, pts_index[MAX_INT_POINTS_ALICE], npts = 0, ii = 0;
-
-    // Initialize images of Bob's basis
-    fp2_decode(pkB, PKB[0]);
-    fp2_decode(pkB + SIDH_JINV_BYTESZ, PKB[1]);
-    fp2_decode(pkB + 2*SIDH_JINV_BYTESZ, PKB[2]);
-
-    // Initialize constants
-    sike_get_A(PKB[0], PKB[1], PKB[2], A);
-    sike_fpadd(sike_params.mont_one, sike_params.mont_one, C24->c0);
-    sike_fp2add(A, C24, A24plus);
-    sike_fpadd(C24->c0, C24->c0, C24->c0);
-
-    // Retrieve kernel point
-    ladder3Pt(PKB[0], PKB[1], PKB[2], skA, 1, R, A);
-
-    // Traverse tree
-    index = 0;
-    for (size_t row = 1; row < A_max; row++) {
-        while (index < A_max-row) {
-            sike_fp2copy(R->X, pts[npts]->X);
-            sike_fp2copy(R->Z, pts[npts]->Z);
-            pts_index[npts++] = index;
-            m = sike_params.A_strat[ii++];
-            sike_xDBLe(R, R, A24plus, C24, (2*m));
-            index += m;
-        }
-        sike_get_4_isog(R, A24plus, C24, coeff);
-
-        for (size_t i = 0; i < npts; i++) {
-            sike_eval_4_isog(pts[i], coeff);
-        }
-
-        sike_fp2copy(pts[npts-1]->X, R->X);
-        sike_fp2copy(pts[npts-1]->Z, R->Z);
-        index = pts_index[npts-1];
-        npts -= 1;
-    }
-
-    sike_get_4_isog(R, A24plus, C24, coeff);
-    sike_fp2add(A24plus, A24plus, A24plus);
-    sike_fp2sub(A24plus, C24, A24plus);
-    sike_fp2add(A24plus, A24plus, A24plus);
-    sike_j_inv(A24plus, C24, jinv);
-    sike_fp2_encode(jinv, ssA);
-}
-
-// Bob's ephemeral shared secret computation
-// It produces a shared secret key ssB using his secret key skB and Alice's public key pkA
-// Inputs: Bob's skB is an integer in the range [0, 2^Floor(Log(2,3^159)) - 1], stored in 32 bytes.
-//         Alice's pkA consists of 3 GF(p503^2) elements encoded in 378 bytes.
-// Output: a shared secret ssB that consists of one element in GF(p503^2) encoded in 126 bytes.
-static void ex_iso_B(const uint8_t* skB, const uint8_t* pkA, uint8_t* ssB)
-{
-    point_proj_t R, pts[MAX_INT_POINTS_BOB];
-    f2elm_t coeff[3], PKB[3], jinv;
-    f2elm_t A24plus = F2ELM_INIT;
-    f2elm_t A24minus = F2ELM_INIT;
-    f2elm_t A = F2ELM_INIT;
-    unsigned int m, index = 0, pts_index[MAX_INT_POINTS_BOB], npts = 0, ii = 0;
-
-    // Initialize images of Alice's basis
-    fp2_decode(pkA, PKB[0]);
-    fp2_decode(pkA + SIDH_JINV_BYTESZ, PKB[1]);
-    fp2_decode(pkA + 2*SIDH_JINV_BYTESZ, PKB[2]);
-
-    // Initialize constants
-    sike_get_A(PKB[0], PKB[1], PKB[2], A);
-    sike_fpadd(sike_params.mont_one, sike_params.mont_one, A24minus->c0);
-    sike_fp2add(A, A24minus, A24plus);
-    sike_fp2sub(A, A24minus, A24minus);
-
-    // Retrieve kernel point
-    ladder3Pt(PKB[0], PKB[1], PKB[2], skB, 0, R, A);
-
-    // Traverse tree
-    index = 0;
-    for (size_t row = 1; row < B_max; row++) {
-        while (index < B_max-row) {
-            sike_fp2copy(R->X, pts[npts]->X);
-            sike_fp2copy(R->Z, pts[npts]->Z);
-            pts_index[npts++] = index;
-            m = sike_params.B_strat[ii++];
-            sike_xTPLe(R, R, A24minus, A24plus, m);
-            index += m;
-        }
-        sike_get_3_isog(R, A24minus, A24plus, coeff);
-
-        for (size_t i = 0; i < npts; i++) {
-            sike_eval_3_isog(pts[i], coeff);
-        }
-
-        sike_fp2copy(pts[npts-1]->X, R->X);
-        sike_fp2copy(pts[npts-1]->Z, R->Z);
-        index = pts_index[npts-1];
-        npts -= 1;
-    }
-
-    sike_get_3_isog(R, A24minus, A24plus, coeff);
-    sike_fp2add(A24plus, A24minus, A);
-    sike_fp2add(A, A, A);
-    sike_fp2sub(A24plus, A24minus, A24plus);
-    sike_j_inv(A, A24plus, jinv);
-    sike_fp2_encode(jinv, ssB);
-}
-
-int SIKE_keypair(uint8_t out_priv[SIKE_PRV_BYTESZ],
-                 uint8_t out_pub[SIKE_PUB_BYTESZ]) {
-  int ret = 0;
-
-  // Calculate private key for Alice. Needs to be in range [0, 2^0xFA - 1] and <
-  // 253 bits
-  BIGNUM *bn_sidh_prv = BN_new();
-  if (!bn_sidh_prv ||
-      !BN_rand(bn_sidh_prv, SIDH_PRV_B_BITSZ, BN_RAND_TOP_ONE,
-               BN_RAND_BOTTOM_ANY) ||
-      !BN_bn2le_padded(out_priv, BITS_TO_BYTES(SIDH_PRV_B_BITSZ),
-                       bn_sidh_prv)) {
-    goto end;
-  }
-
-  gen_iso_B(out_priv, out_pub);
-  ret = 1;
-
-end:
-  BN_free(bn_sidh_prv);
-  return ret;
-}
-
-void SIKE_encaps(uint8_t out_shared_key[SIKE_SS_BYTESZ],
-                 uint8_t out_ciphertext[SIKE_CT_BYTESZ],
-                 const uint8_t pub_key[SIKE_PUB_BYTESZ]) {
-  // Secret buffer is reused by the function to store some ephemeral
-  // secret data. It's size must be maximum of SHA256_CBLOCK,
-  // SIKE_MSG_BYTESZ and SIDH_PRV_A_BITSZ in bytes.
-  uint8_t secret[SHA256_CBLOCK];
-  uint8_t j[SIDH_JINV_BYTESZ];
-  uint8_t temp[SIKE_MSG_BYTESZ + SIKE_CT_BYTESZ];
-  SHA256_CTX ctx;
-
-  // Generate secret key for A
-  // secret key A = SHA256({0,1}^n || pub_key)) mod SIDH_PRV_A_BITSZ
-  RAND_bytes(temp, SIKE_MSG_BYTESZ);
-
-  SHA256_Init(&ctx);
-  SHA256_Update(&ctx, temp, SIKE_MSG_BYTESZ);
-  SHA256_Update(&ctx, pub_key, SIKE_PUB_BYTESZ);
-  SHA256_Final(secret, &ctx);
-
-  // Generate public key for A - first part of the ciphertext
-  gen_iso_A(secret, out_ciphertext);
-
-  // Generate c1:
-  //  h = SHA256(j-invariant)
-  // c1 = h ^ m
-  ex_iso_A(secret, pub_key, j);
-  SHA256_Init(&ctx);
-  SHA256_Update(&ctx, j, sizeof(j));
-  SHA256_Final(secret, &ctx);
-
-  // c1 = h ^ m
-  uint8_t *c1 = &out_ciphertext[SIKE_PUB_BYTESZ];
-  for (size_t i = 0; i < SIKE_MSG_BYTESZ; i++) {
-    c1[i] = temp[i] ^ secret[i];
-  }
-
-  SHA256_Init(&ctx);
-  SHA256_Update(&ctx, temp, SIKE_MSG_BYTESZ);
-  SHA256_Update(&ctx, out_ciphertext, SIKE_CT_BYTESZ);
-  SHA256_Final(secret, &ctx);
-  // Generate shared secret out_shared_key = SHA256(m||out_ciphertext)
-  memcpy(out_shared_key, secret, SIKE_SS_BYTESZ);
-}
-
-void SIKE_decaps(uint8_t out_shared_key[SIKE_SS_BYTESZ],
-                 const uint8_t ciphertext[SIKE_CT_BYTESZ],
-                 const uint8_t pub_key[SIKE_PUB_BYTESZ],
-                 const uint8_t priv_key[SIKE_PRV_BYTESZ]) {
-  // Secret buffer is reused by the function to store some ephemeral
-  // secret data. It's size must be maximum of SHA256_CBLOCK,
-  // SIKE_MSG_BYTESZ and SIDH_PRV_A_BITSZ in bytes.
-  uint8_t secret[SHA256_CBLOCK];
-  uint8_t j[SIDH_JINV_BYTESZ];
-  uint8_t c0[SIKE_PUB_BYTESZ];
-  uint8_t temp[SIKE_MSG_BYTESZ];
-  uint8_t shared_nok[SIKE_MSG_BYTESZ];
-  SHA256_CTX ctx;
-
-  // This is OK as we are only using ephemeral keys in BoringSSL
-  RAND_bytes(shared_nok, SIKE_MSG_BYTESZ);
-
-  // Recover m
-  // Let ciphertext = c0 || c1 - both have fixed sizes
-  // m = F(j-invariant(c0, priv_key)) ^ c1
-  ex_iso_B(priv_key, ciphertext, j);
-
-  SHA256_Init(&ctx);
-  SHA256_Update(&ctx, j, sizeof(j));
-  SHA256_Final(secret, &ctx);
-
-  const uint8_t *c1 = &ciphertext[sizeof(c0)];
-  for (size_t i = 0; i < SIKE_MSG_BYTESZ; i++) {
-    temp[i] = c1[i] ^ secret[i];
-  }
-
-  SHA256_Init(&ctx);
-  SHA256_Update(&ctx, temp, SIKE_MSG_BYTESZ);
-  SHA256_Update(&ctx, pub_key, SIKE_PUB_BYTESZ);
-  SHA256_Final(secret, &ctx);
-
-  // Recover c0 = public key A
-  gen_iso_A(secret, c0);
-  crypto_word_t ok = constant_time_is_zero_w(
-      CRYPTO_memcmp(c0, ciphertext, SIKE_PUB_BYTESZ));
-  for (size_t i = 0; i < SIKE_MSG_BYTESZ; i++) {
-    temp[i] = constant_time_select_8(ok, temp[i], shared_nok[i]);
-  }
-
-  SHA256_Init(&ctx);
-  SHA256_Update(&ctx, temp, SIKE_MSG_BYTESZ);
-  SHA256_Update(&ctx, ciphertext, SIKE_CT_BYTESZ);
-  SHA256_Final(secret, &ctx);
-
-  // Generate shared secret out_shared_key = SHA256(m||ciphertext)
-  memcpy(out_shared_key, secret, SIKE_SS_BYTESZ);
-}
diff --git a/third_party/sike/sike.h b/third_party/sike/sike.h
deleted file mode 100644
index 5819ebf..0000000
--- a/third_party/sike/sike.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/********************************************************************************************
-* SIDH: an efficient supersingular isogeny cryptography library
-*
-* Abstract: API header file for SIKE
-*********************************************************************************************/
-
-#ifndef SIKE_H_
-#define SIKE_H_
-
-#include <stdint.h>
-#include <openssl/base.h>
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-/* SIKE
- *
- * SIKE is a isogeny based post-quantum key encapsulation mechanism. Description of the
- * algorithm is provided in [SIKE]. This implementation uses 434-bit field size. The code
- * is based on "Additional_Implementations" from PQC NIST submission package which can
- * be found here:
- * https://csrc.nist.gov/CSRC/media/Projects/Post-Quantum-Cryptography/documents/round-1/submissions/SIKE.zip
- *
- * [SIKE] https://sike.org/files/SIDH-spec.pdf
- */
-
-// SIKE_PUB_BYTESZ is the number of bytes in a public key.
-#define SIKE_PUB_BYTESZ 330
-// SIKE_PRV_BYTESZ is the number of bytes in a private key.
-#define SIKE_PRV_BYTESZ 28
-// SIKE_SS_BYTESZ is the number of bytes in a shared key.
-#define SIKE_SS_BYTESZ  16
-// SIKE_MSG_BYTESZ is the number of bytes in a random bit string concatenated
-// with the public key (see 1.4 of SIKE).
-#define SIKE_MSG_BYTESZ 16
-// SIKE_SS_BYTESZ is the number of bytes in a ciphertext.
-#define SIKE_CT_BYTESZ  (SIKE_PUB_BYTESZ + SIKE_MSG_BYTESZ)
-
-// SIKE_keypair outputs a public and secret key. Internally it uses BN_rand() as
-// an entropy source. In case of success function returns 1, otherwise 0.
-OPENSSL_EXPORT int SIKE_keypair(
-    uint8_t out_priv[SIKE_PRV_BYTESZ],
-    uint8_t out_pub[SIKE_PUB_BYTESZ]);
-
-// SIKE_encaps generates and encrypts a random session key, writing those values to
-// |out_shared_key| and |out_ciphertext|, respectively.
-OPENSSL_EXPORT void SIKE_encaps(
-    uint8_t out_shared_key[SIKE_SS_BYTESZ],
-    uint8_t out_ciphertext[SIKE_CT_BYTESZ],
-    const uint8_t pub_key[SIKE_PUB_BYTESZ]);
-
-// SIKE_decaps outputs a random session key, writing it to |out_shared_key|.
-OPENSSL_EXPORT void SIKE_decaps(
-    uint8_t out_shared_key[SIKE_SS_BYTESZ],
-    const uint8_t ciphertext[SIKE_CT_BYTESZ],
-    const uint8_t pub_key[SIKE_PUB_BYTESZ],
-    const uint8_t priv_key[SIKE_PRV_BYTESZ]);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
diff --git a/third_party/sike/sike_test.cc b/third_party/sike/sike_test.cc
deleted file mode 100644
index 2180a52..0000000
--- a/third_party/sike/sike_test.cc
+++ /dev/null
@@ -1,251 +0,0 @@
-/* Copyright (c) 2018, 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. */
-
-#include <gtest/gtest.h>
-#include <stdint.h>
-
-#include "sike.h"
-#include "fpx.h"
-#include "../../crypto/test/abi_test.h"
-
-TEST(SIKE, RoundTrip) {
-  uint8_t sk[SIKE_PRV_BYTESZ] = {0};
-  uint8_t pk[SIKE_PUB_BYTESZ] = {0};
-  uint8_t ct[SIKE_CT_BYTESZ] = {0};
-  uint8_t ss_enc[SIKE_SS_BYTESZ] = {0};
-  uint8_t ss_dec[SIKE_SS_BYTESZ] = {0};
-
-  for (size_t i = 0; i < 30; i++) {
-    EXPECT_EQ(SIKE_keypair(sk, pk), 1);
-    SIKE_encaps(ss_enc, ct, pk);
-    SIKE_decaps(ss_dec, ct, pk, sk);
-
-    EXPECT_EQ(memcmp(ss_enc, ss_dec, SIKE_SS_BYTESZ), 0);
-  }
-}
-
-TEST(SIKE, Decapsulation) {
-  const uint8_t sk[SIKE_PRV_BYTESZ] = {
-      0xB1, 0xFD, 0x34, 0x42, 0xDB, 0x02, 0xBC, 0x9D, 0x4C, 0xD0,
-      0x72, 0x34, 0x4D, 0xBD, 0x06, 0xDF, 0x1C, 0x7D, 0x0A, 0x88,
-      0xB2, 0x50, 0xC4, 0xF6, 0xAE, 0xE8, 0x25, 0x01};
-
-  const uint8_t pk[SIKE_PUB_BYTESZ] = {
-      0x6D, 0x8D, 0xF5, 0x7B, 0xCD, 0x47, 0xCA, 0xCB, 0x7A, 0x38, 0xB7, 0xA6,
-      0x90, 0xB7, 0x37, 0x03, 0xD4, 0x6F, 0x27, 0x73, 0x74, 0x17, 0x5A, 0xA4,
-      0x0D, 0xC6, 0x81, 0xAD, 0xDB, 0xF7, 0x18, 0xB2, 0x3C, 0x30, 0xCF, 0xAA,
-      0x08, 0x11, 0x91, 0xCC, 0x27, 0x4E, 0xF1, 0xA6, 0xB7, 0xDA, 0xD2, 0xCF,
-      0x99, 0x7F, 0xF7, 0xE1, 0xD0, 0xCE, 0x00, 0xD2, 0x4B, 0xA4, 0x33, 0xB4,
-      0x87, 0x01, 0x3F, 0x02, 0xF7, 0xF9, 0xDE, 0xC3, 0x60, 0x62, 0xDA, 0x3F,
-      0x74, 0xA9, 0x44, 0xBE, 0x19, 0xD5, 0x03, 0x2A, 0x79, 0x8C, 0xA7, 0xFF,
-      0xEA, 0xB3, 0xBB, 0xB5, 0xD4, 0x1D, 0x8F, 0x92, 0xCE, 0x62, 0x6E, 0x99,
-      0x24, 0xD7, 0x57, 0xFA, 0xCD, 0xB6, 0xE2, 0x8E, 0xFD, 0x22, 0x0E, 0x31,
-      0x21, 0x01, 0x8D, 0x79, 0xF8, 0x3E, 0x27, 0xEC, 0x43, 0x40, 0xDB, 0x82,
-      0xE5, 0xEB, 0x6C, 0x97, 0x66, 0x29, 0x15, 0x68, 0xB7, 0x4D, 0x84, 0xD1,
-      0x8A, 0x0B, 0x12, 0x36, 0x2C, 0x0C, 0x0A, 0x6E, 0x4E, 0xDE, 0xA5, 0x8A,
-      0xDE, 0x77, 0xDD, 0x70, 0x49, 0x73, 0xAC, 0x27, 0x6D, 0x8D, 0x25, 0x9A,
-      0xE4, 0x25, 0xE8, 0x95, 0x8F, 0xFE, 0x90, 0x3B, 0x00, 0x69, 0x20, 0xE8,
-      0x7C, 0xA5, 0xF5, 0x79, 0xC0, 0x61, 0x51, 0x91, 0x35, 0x25, 0x3F, 0x17,
-      0x2F, 0x70, 0x73, 0xF0, 0x89, 0xB5, 0xC8, 0x25, 0xB8, 0xE5, 0x7E, 0x34,
-      0xDD, 0x11, 0xE5, 0xD6, 0xC3, 0xD5, 0x29, 0x89, 0xC6, 0x2C, 0x99, 0x53,
-      0x1D, 0x2C, 0x77, 0xB0, 0xB6, 0xA1, 0xBD, 0x79, 0xFB, 0x4A, 0xC2, 0x48,
-      0x4C, 0x62, 0x51, 0x00, 0xE3, 0x91, 0x2A, 0xCB, 0x84, 0x03, 0x5D, 0x2D,
-      0xC8, 0x33, 0xE9, 0x14, 0xBF, 0x74, 0x21, 0xBC, 0xF4, 0x76, 0xE5, 0x42,
-      0xB8, 0xBD, 0xE2, 0xE7, 0x20, 0x95, 0x54, 0xF2, 0xED, 0xC0, 0x79, 0x38,
-      0x1E, 0xD2, 0xEA, 0x1A, 0x63, 0x85, 0xE7, 0x3A, 0xDA, 0xAD, 0xAB, 0x1B,
-      0x1E, 0x19, 0x9E, 0x73, 0xD0, 0x10, 0x2E, 0x38, 0xAC, 0x8B, 0x00, 0x6A,
-      0x30, 0x2C, 0x3D, 0x70, 0x8E, 0x39, 0x6D, 0xC0, 0x12, 0x61, 0x7D, 0x2A,
-      0x0A, 0x04, 0x95, 0x8E, 0x09, 0x3C, 0x7B, 0xEC, 0x2E, 0xBC, 0xE8, 0xE8,
-      0xE8, 0x37, 0x29, 0xC4, 0x7E, 0x76, 0x48, 0xB9, 0x3B, 0x72, 0xE5, 0x99,
-      0x9B, 0xF9, 0xE3, 0x99, 0x72, 0x3F, 0x35, 0x29, 0x85, 0xE0, 0xC8, 0xBF,
-      0xB1, 0x6B, 0xB1, 0x6E, 0x72, 0x00};
-
-  const uint8_t ct[SIKE_CT_BYTESZ] = {
-      0xFF, 0xEB, 0xEF, 0x4A, 0xC0, 0x57, 0x0F, 0x26, 0xAC, 0x76, 0xA8, 0xB0,
-      0xA3, 0x5D, 0x9C, 0xD9, 0x25, 0xD1, 0x7F, 0x92, 0x5D, 0xF4, 0x23, 0x34,
-      0xC3, 0x03, 0x10, 0xE1, 0xB0, 0x24, 0x9B, 0x44, 0x58, 0x26, 0x13, 0x56,
-      0x83, 0x43, 0x72, 0x69, 0x28, 0x0D, 0x55, 0x07, 0x1F, 0xDB, 0xC0, 0x23,
-      0x34, 0x83, 0x1A, 0x09, 0x9B, 0x80, 0x00, 0x64, 0x56, 0xDC, 0x79, 0x7A,
-      0xD2, 0xCE, 0x23, 0xC9, 0x72, 0x27, 0xFC, 0x8D, 0xAB, 0xBF, 0xD3, 0x17,
-      0xF6, 0x91, 0x7B, 0x15, 0x93, 0x83, 0x8A, 0x4F, 0x6C, 0xCA, 0x4A, 0x94,
-      0xDA, 0xC7, 0x9D, 0xB6, 0xD6, 0xBA, 0xBD, 0x81, 0x9A, 0x78, 0xE5, 0xE5,
-      0xBE, 0x17, 0xBC, 0xCB, 0xC8, 0x23, 0x80, 0x5F, 0x75, 0xF8, 0xDB, 0x51,
-      0x55, 0x00, 0x25, 0x33, 0x52, 0x64, 0xB2, 0xD6, 0xD8, 0x9A, 0x2A, 0x9E,
-      0x29, 0x99, 0x13, 0x33, 0xE2, 0xA7, 0x98, 0xAC, 0xD7, 0x79, 0x5C, 0x2F,
-      0xBA, 0x07, 0xC3, 0x03, 0x37, 0xD6, 0xE6, 0xB5, 0xA1, 0xF5, 0x29, 0xB6,
-      0xF6, 0xC0, 0x5C, 0x44, 0x68, 0x2B, 0x0B, 0xF5, 0x00, 0x01, 0x44, 0xD5,
-      0xCC, 0x23, 0xB5, 0x27, 0x4F, 0xCA, 0xB4, 0x05, 0x01, 0xF9, 0xD4, 0x41,
-      0xE0, 0xE1, 0x1E, 0xCF, 0xA9, 0xBC, 0x79, 0xD7, 0xD5, 0xF5, 0x3C, 0xE6,
-      0x93, 0xF4, 0x6C, 0x84, 0x5A, 0x2C, 0x4B, 0xE4, 0x91, 0xB2, 0xB2, 0xB8,
-      0xAD, 0x74, 0x9A, 0x69, 0x79, 0x4C, 0x84, 0xB7, 0xBF, 0xF1, 0x68, 0x4B,
-      0xAE, 0x0F, 0x7F, 0x45, 0x3B, 0x18, 0x3F, 0xFA, 0x00, 0x48, 0xE0, 0x3A,
-      0xE2, 0xC0, 0xAE, 0x00, 0xCE, 0x90, 0x28, 0xA4, 0x1B, 0xBE, 0xCA, 0x0C,
-      0x21, 0x29, 0x64, 0x30, 0x5E, 0x35, 0xAD, 0xFD, 0x83, 0x47, 0x40, 0x6D,
-      0x15, 0x56, 0xFC, 0xF8, 0x5F, 0xAB, 0x81, 0xFE, 0x6B, 0xE9, 0x6B, 0xED,
-      0x27, 0x35, 0x7C, 0xD8, 0x2C, 0xD4, 0xF2, 0x11, 0xE6, 0xAF, 0xDF, 0xB8,
-      0x91, 0x96, 0xEB, 0xF7, 0x4C, 0x8D, 0x70, 0x77, 0x90, 0x81, 0x00, 0x09,
-      0x19, 0x27, 0x8A, 0x9E, 0xB6, 0x1A, 0xE9, 0xAC, 0x6C, 0xC9, 0xF8, 0xEA,
-      0xA2, 0x34, 0xB8, 0xAC, 0xB3, 0xB3, 0x68, 0xA1, 0xB7, 0x29, 0x55, 0xCA,
-      0x40, 0x23, 0x92, 0x5C, 0x0C, 0x79, 0x6B, 0xD6, 0x9F, 0x5B, 0xD2, 0xE6,
-      0xAE, 0x04, 0xCB, 0xEC, 0xC7, 0x88, 0x18, 0xDB, 0x7A, 0xE6, 0xD6, 0xC9,
-      0x39, 0xFD, 0x93, 0x9B, 0xC8, 0x01, 0x6F, 0x3E, 0x6C, 0x90, 0x3E, 0x73,
-      0x76, 0x99, 0x7C, 0x48, 0xDA, 0x68, 0x48, 0x80, 0x2B, 0x63};
-
-  const uint8_t ss_exp[SIKE_SS_BYTESZ] = {0xA1, 0xF9, 0x5A, 0x67, 0xB9, 0x3D,
-                                          0x1E, 0x72, 0xE8, 0xC5, 0x71, 0xF1,
-                                          0x4C, 0xB2, 0xAA, 0x6D};
-
-  uint8_t ss_dec[SIKE_SS_BYTESZ] = {0};
-  SIKE_decaps(ss_dec, ct, pk, sk);
-  EXPECT_EQ(memcmp(ss_dec, ss_exp, sizeof(ss_exp)), 0);
-}
-
-// SIKE_encaps and SIKE_keypair doesn't return zeros.
-TEST(SIKE, NonZero) {
-  uint8_t sk[SIKE_PRV_BYTESZ] = {0};
-  uint8_t pk[SIKE_PUB_BYTESZ] = {0};
-  uint8_t ct[SIKE_CT_BYTESZ] = {0};
-  uint8_t ss[SIKE_SS_BYTESZ] = {0};
-
-  // Check secret and public key returned by SIKE_keypair
-  EXPECT_EQ(SIKE_keypair(sk, pk), 1);
-  uint8_t tmp = 0;
-  for (size_t i = 0; i < sizeof(sk); i++) {
-    tmp |= sk[i];
-  }
-  EXPECT_NE(tmp, 0);
-
-  tmp = 0;
-  for (size_t i = 0; i < sizeof(pk); i++) {
-    tmp |= pk[i];
-  }
-  EXPECT_NE(tmp, 0);
-
-  // Check shared secret and ciphertext returned by SIKE_encaps
-  SIKE_encaps(ss, ct, pk);
-  tmp = 0;
-  for (size_t i = 0; i < sizeof(ct); i++) {
-    tmp |= ct[i];
-  }
-  EXPECT_NE(tmp, 0);
-
-  tmp = 0;
-  for (size_t i = 0; i < sizeof(ss); i++) {
-    tmp |= ss[i];
-  }
-  EXPECT_NE(tmp, 0);
-}
-
-TEST(SIKE, Negative) {
-  uint8_t sk[SIKE_PRV_BYTESZ] = {0};
-  uint8_t pk[SIKE_PUB_BYTESZ] = {0};
-  uint8_t ct[SIKE_CT_BYTESZ] = {0};
-  uint8_t ss_enc[SIKE_SS_BYTESZ] = {0};
-  uint8_t ss_dec[SIKE_SS_BYTESZ] = {0};
-
-  EXPECT_EQ(SIKE_keypair(sk, pk), 1);
-  SIKE_encaps(ss_enc, ct, pk);
-
-  // Change cipertext
-  uint8_t ct_tmp[SIKE_CT_BYTESZ] = {0};
-  memcpy(ct_tmp, ct, sizeof(ct));
-  ct_tmp[0] = ~ct_tmp[0];
-  SIKE_decaps(ss_dec, ct_tmp, pk, sk);
-  EXPECT_NE(memcmp(ss_enc, ss_dec, SIKE_SS_BYTESZ), 0);
-
-  // Change secret key
-  uint8_t sk_tmp[SIKE_PRV_BYTESZ] = {0};
-  memcpy(sk_tmp, sk, sizeof(sk));
-  sk_tmp[0] = ~sk_tmp[0];
-  SIKE_decaps(ss_dec, ct, pk, sk_tmp);
-  EXPECT_NE(memcmp(ss_enc, ss_dec, SIKE_SS_BYTESZ), 0);
-
-  // Change public key
-  uint8_t pk_tmp[SIKE_PUB_BYTESZ] = {0};
-  memcpy(pk_tmp, pk, sizeof(pk));
-  pk_tmp[0] = ~pk_tmp[0];
-  SIKE_decaps(ss_dec, ct, pk_tmp, sk);
-  EXPECT_NE(memcmp(ss_enc, ss_dec, SIKE_SS_BYTESZ), 0);
-}
-
-TEST(SIKE, Unaligned) {
-  alignas(4) uint8_t priv[SIKE_PRV_BYTESZ + 1];
-  alignas(4) uint8_t pub[SIKE_PUB_BYTESZ + 1];
-  alignas(4) uint8_t shared_key1[SIKE_SS_BYTESZ + 1];
-  alignas(4) uint8_t ciphertext[SIKE_CT_BYTESZ + 1];
-  alignas(4) uint8_t shared_key2[SIKE_SS_BYTESZ + 1];
-
-  ASSERT_TRUE(SIKE_keypair(priv + 1, pub + 1));
-  SIKE_encaps(shared_key1 + 1, ciphertext + 1, pub + 1);
-  SIKE_decaps(shared_key2 + 1, ciphertext + 1, pub + 1, priv + 1);
-
-  EXPECT_EQ(memcmp(shared_key1 + 1, shared_key2 + 1, SIKE_SS_BYTESZ), 0);
-}
-
-#if defined(SUPPORTS_ABI_TEST) && \
-    (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64))
-TEST(SIKE, ABI) {
-  felm_t a, b, c;
-  dfelm_t d, e, f;
-  CHECK_ABI(sike_fpadd, a, b, c);
-  CHECK_ABI(sike_fpsub, a, b, c);
-  CHECK_ABI(sike_mpmul, a, b, d);
-  CHECK_ABI(sike_fprdc, d, a);
-  CHECK_ABI(sike_mpadd_asm, a, b, c);
-  CHECK_ABI(sike_mpsubx2_asm, d, e, f);
-  CHECK_ABI(sike_mpdblsubx2_asm, d, e, f);
-}
-
-// Additional tests for checking if assembly implementation
-// of MUL and REDC handles carry chains correctly.
-TEST(SIKE, CarryChains) {
-  // Expected results
-  const dfelm_t exp_mul = {
-    0x0000000000000001, 0x0000000000000000, 0x0000000000000000,
-    0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
-    0x0000000000000000, 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF,
-    0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
-    0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
-  };
-
-  const felm_t exp_redc = {
-    0x93AA0C8C2D3235BE, 0xA8CD35DDDE399B46, 0xB9BBA5469509CA65,
-    0x6B2FB3A5A2FB86E4, 0x585591BA6DBE862C, 0xD92D3FF5FE0938F2,
-    0x0001E1F0EE75A1E1
-  };
-
-  // Input
-  dfelm_t in14 = {
-    0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
-    0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
-    0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
-    0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
-    0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF
-  };
-
-  felm_t in7 = {
-    0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
-    0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
-    0xFFFFFFFFFFFFFFFF
-  };
-
-  dfelm_t res;
-  sike_mpmul(in7, in7, res);
-  EXPECT_EQ(memcmp(exp_mul, res, sizeof(exp_mul)), 0);
-
-  // modifies in14 and in7
-  sike_fprdc(in14, in7);
-  EXPECT_EQ(memcmp(exp_redc, in7, sizeof(exp_redc)), 0);
-}
-#endif  // SUPPORTS_ABI_TEST && (X86_64 || AARCH64)
diff --git a/third_party/sike/utils.h b/third_party/sike/utils.h
deleted file mode 100644
index bc806da..0000000
--- a/third_party/sike/utils.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/********************************************************************************************
-* SIDH: an efficient supersingular isogeny cryptography library
-*
-* Abstract: internal header file for P434
-*********************************************************************************************/
-
-#ifndef UTILS_H_
-#define UTILS_H_
-
-#include <openssl/base.h>
-
-#include "../../crypto/internal.h"
-#include "sike.h"
-
-// Conversion macro from number of bits to number of bytes
-#define BITS_TO_BYTES(nbits)      (((nbits)+7)/8)
-
-// Bit size of the field
-#define BITS_FIELD              434
-// Byte size of the field
-#define FIELD_BYTESZ            BITS_TO_BYTES(BITS_FIELD)
-// Number of 64-bit words of a 224-bit element
-#define NBITS_ORDER             224
-#define NWORDS64_ORDER          ((NBITS_ORDER+63)/64)
-// Number of elements in Alice's strategy
-#define A_max                   108
-// Number of elements in Bob's strategy
-#define B_max                   137
-// Word size size
-#define RADIX                   sizeof(crypto_word_t)*8
-// Byte size of a limb
-#define LSZ                     sizeof(crypto_word_t)
-
-#if defined(OPENSSL_64_BIT)
-    // Number of words of a 434-bit field element
-    #define NWORDS_FIELD    7
-    // Number of "0" digits in the least significant part of p434 + 1
-    #define ZERO_WORDS 3
-    // U64_TO_WORDS expands |x| for a |crypto_word_t| array literal.
-    #define U64_TO_WORDS(x) UINT64_C(x)
-#else
-    // Number of words of a 434-bit field element
-    #define NWORDS_FIELD    14
-    // Number of "0" digits in the least significant part of p434 + 1
-    #define ZERO_WORDS 6
-    // U64_TO_WORDS expands |x| for a |crypto_word_t| array literal.
-    #define U64_TO_WORDS(x) \
-        (uint32_t)(UINT64_C(x) & 0xffffffff), (uint32_t)(UINT64_C(x) >> 32)
-#endif
-
-// Extended datatype support
-#if !defined(BORINGSSL_HAS_UINT128)
-    typedef uint64_t uint128_t[2];
-#endif
-
-// The following functions return 1 (TRUE) if condition is true, 0 (FALSE) otherwise
-// Digit multiplication
-#define MUL(multiplier, multiplicand, hi, lo) digit_x_digit((multiplier), (multiplicand), &(lo));
-
-// If mask |x|==0xff.ff set |x| to 1, otherwise 0
-#define M2B(x) ((x)>>(RADIX-1))
-
-// Digit addition with carry
-#define ADDC(carryIn, addend1, addend2, carryOut, sumOut)                   \
-do {                                                                        \
-  crypto_word_t tempReg = (addend1) + (crypto_word_t)(carryIn);             \
-  (sumOut) = (addend2) + tempReg;                                           \
-  (carryOut) = M2B(constant_time_lt_w(tempReg, (crypto_word_t)(carryIn)) |  \
-                   constant_time_lt_w((sumOut), tempReg));                  \
-} while(0)
-
-// Digit subtraction with borrow
-#define SUBC(borrowIn, minuend, subtrahend, borrowOut, differenceOut)           \
-do {                                                                            \
-    crypto_word_t tempReg = (minuend) - (subtrahend);                           \
-    crypto_word_t borrowReg = M2B(constant_time_lt_w((minuend), (subtrahend))); \
-    borrowReg |= ((borrowIn) & constant_time_is_zero_w(tempReg));               \
-    (differenceOut) = tempReg - (crypto_word_t)(borrowIn);                      \
-    (borrowOut) = borrowReg;                                                    \
-} while(0)
-
-/* Old GCC 4.9 (jessie) doesn't implement {0} initialization properly,
-   which violates C11 as described in 6.7.9, 21 (similarily C99, 6.7.8).
-   Defines below are used to work around the bug, and provide a way
-   to initialize f2elem_t and point_proj_t structs.
-   Bug has been fixed in GCC6 (debian stretch).
-*/
-#define F2ELM_INIT {{ {0}, {0} }}
-#define POINT_PROJ_INIT {{ F2ELM_INIT, F2ELM_INIT }}
-
-// Datatype for representing 434-bit field elements (448-bit max.)
-// Elements over GF(p434) are encoded in 63 octets in little endian format
-// (i.e., the least significant octet is located in the lowest memory address).
-typedef crypto_word_t felm_t[NWORDS_FIELD];
-
-// An element in F_{p^2}, is composed of two coefficients from F_p, * i.e.
-// Fp2 element = c0 + c1*i in F_{p^2}
-// Datatype for representing double-precision 2x434-bit field elements (448-bit max.)
-// Elements (a+b*i) over GF(p434^2), where a and b are defined over GF(p434), are
-// encoded as {a, b}, with a in the lowest memory portion.
-typedef struct {
-    felm_t c0;
-    felm_t c1;
-} fp2;
-
-// Our F_{p^2} element type is a pointer to the struct.
-typedef fp2 f2elm_t[1];
-
-// Datatype for representing double-precision 2x434-bit
-// field elements in contiguous memory.
-typedef crypto_word_t dfelm_t[2*NWORDS_FIELD];
-
-// Constants used during SIKE computation.
-struct params_t {
-    // Stores a prime
-    const crypto_word_t prime[NWORDS_FIELD];
-    // Stores prime + 1
-    const crypto_word_t prime_p1[NWORDS_FIELD];
-    // Stores prime * 2
-    const crypto_word_t prime_x2[NWORDS_FIELD];
-    // Alice's generator values {XPA0 + XPA1*i, XQA0 + XQA1*i, XRA0 + XRA1*i}
-    // in GF(prime^2), expressed in Montgomery representation
-    const crypto_word_t A_gen[6*NWORDS_FIELD];
-    // Bob's generator values {XPB0 + XPB1*i, XQB0 + XQB1*i, XRB0 + XRB1*i}
-    // in GF(prime^2), expressed in Montgomery representation
-    const crypto_word_t B_gen[6*NWORDS_FIELD];
-    // Montgomery constant mont_R2 = (2^448)^2 mod prime
-    const crypto_word_t mont_R2[NWORDS_FIELD];
-    // Value 'one' in Montgomery representation
-    const crypto_word_t mont_one[NWORDS_FIELD];
-    // Value '6' in Montgomery representation
-    const crypto_word_t mont_six[NWORDS_FIELD];
-    // Fixed parameters for isogeny tree computation
-    const unsigned int A_strat[A_max-1];
-    const unsigned int B_strat[B_max-1];
-};
-
-// Point representation in projective XZ Montgomery coordinates.
-typedef struct {
-    f2elm_t X;
-    f2elm_t Z;
-} point_proj;
-typedef point_proj point_proj_t[1];
-
-#endif // UTILS_H_
diff --git a/tool/speed.cc b/tool/speed.cc
index 68073a9..224a72b 100644
--- a/tool/speed.cc
+++ b/tool/speed.cc
@@ -52,8 +52,6 @@
 #include "../crypto/internal.h"
 #include "internal.h"
 
-#include "../third_party/sike/sike.h"
-
 // g_print_json is true if printed output is JSON formatted.
 static bool g_print_json = false;
 
@@ -338,64 +336,6 @@
   return true;
 }
 
-static bool SpeedSIKEP434(const std::string &selected) {
-  if (!selected.empty() && selected.find("SIKE") == std::string::npos) {
-    return true;
-  }
-  // speed generation
-  uint8_t public_SIKE[SIKE_PUB_BYTESZ];
-  uint8_t private_SIKE[SIKE_PRV_BYTESZ];
-  uint8_t ct[SIKE_CT_BYTESZ];
-  bool res;
-
-  {
-    TimeResults results;
-    res = TimeFunction(&results,
-                [&private_SIKE, &public_SIKE]() -> bool {
-      return (SIKE_keypair(private_SIKE, public_SIKE) == 1);
-    });
-    results.Print("SIKE/P434 generate");
-  }
-
-  if (!res) {
-    fprintf(stderr, "Failed to time SIKE_keypair.\n");
-    return false;
-  }
-
-  {
-    TimeResults results;
-    TimeFunction(&results,
-                [&ct, &public_SIKE]() -> bool {
-      uint8_t ss[SIKE_SS_BYTESZ];
-      SIKE_encaps(ss, ct, public_SIKE);
-      return true;
-    });
-    results.Print("SIKE/P434 encap");
-  }
-
-  if (!res) {
-    fprintf(stderr, "Failed to time SIKE_encaps.\n");
-    return false;
-  }
-
-  {
-    TimeResults results;
-    TimeFunction(&results,
-                [&ct, &public_SIKE, &private_SIKE]() -> bool {
-      uint8_t ss[SIKE_SS_BYTESZ];
-      SIKE_decaps(ss, ct, public_SIKE, private_SIKE);
-      return true;
-    });
-    results.Print("SIKE/P434 decap");
-  }
-
-  if (!res) {
-    fprintf(stderr, "Failed to time SIKE_decaps.\n");
-    return false;
-  }
-  return true;
-}
-
 static uint8_t *align(uint8_t *in, unsigned alignment) {
   return reinterpret_cast<uint8_t *>(
       (reinterpret_cast<uintptr_t>(in) + alignment) &
@@ -1128,7 +1068,6 @@
       !SpeedECDH(selected) ||
       !SpeedECDSA(selected) ||
       !Speed25519(selected) ||
-      !SpeedSIKEP434(selected) ||
       !SpeedSPAKE2(selected) ||
       !SpeedScrypt(selected) ||
       !SpeedRSAKeyGen(selected) ||
diff --git a/util/generate_build_files.py b/util/generate_build_files.py
index 8a5df75..6bd3abc 100644
--- a/util/generate_build_files.py
+++ b/util/generate_build_files.py
@@ -640,8 +640,7 @@
 def main(platforms):
   cmake = ExtractVariablesFromCMakeFile(os.path.join('src', 'sources.cmake'))
   crypto_c_files = (FindCFiles(os.path.join('src', 'crypto'), NoTestsNorFIPSFragments) +
-                    FindCFiles(os.path.join('src', 'third_party', 'fiat'), NoTestsNorFIPSFragments) +
-                    FindCFiles(os.path.join('src', 'third_party', 'sike'), NoTestsNorFIPSFragments))
+                    FindCFiles(os.path.join('src', 'third_party', 'fiat'), NoTestsNorFIPSFragments))
   fips_fragments = FindCFiles(os.path.join('src', 'crypto', 'fipsmodule'), OnlyFIPSFragments)
   ssl_source_files = FindCFiles(os.path.join('src', 'ssl'), NoTests)
   tool_c_files = FindCFiles(os.path.join('src', 'tool'), NoTests)
@@ -721,8 +720,7 @@
   ssl_internal_h_files = FindHeaderFiles(os.path.join('src', 'ssl'), NoTests)
   crypto_internal_h_files = (
       FindHeaderFiles(os.path.join('src', 'crypto'), NoTests) +
-      FindHeaderFiles(os.path.join('src', 'third_party', 'fiat'), NoTests) +
-      FindHeaderFiles(os.path.join('src', 'third_party', 'sike'), NoTests))
+      FindHeaderFiles(os.path.join('src', 'third_party', 'fiat'), NoTests))
 
   files = {
       'bcm_crypto': bcm_crypto_c_files,