diff --git a/include/jwt/algorithm.hpp b/include/jwt/algorithm.hpp
index 7dd0f08..becbd98 100644
--- a/include/jwt/algorithm.hpp
+++ b/include/jwt/algorithm.hpp
@@ -483,6 +483,31 @@ private:
   /*!
    */
   static std::string public_key_ser(EVP_PKEY* pkey, string_view sign, std::error_code& ec);
+
+  //ATTN: Below 2 functions
+  //are Taken from https://github.com/nginnever/zogminer/issues/39
+
+  /**
+   */
+  static void ECDSA_SIG_get0(const ECDSA_SIG* sig, const BIGNUM** pr, const BIGNUM** ps)
+  {
+    if (pr != nullptr) *pr = sig->r;
+    if (ps != nullptr) *ps = sig->s;
+  };
+
+  /**
+   */
+  static int ECDSA_SIG_set0(ECDSA_SIG* sig, BIGNUM* r, BIGNUM* s)
+  { 
+    if (r == nullptr || s == nullptr) return 0;
+
+    BN_clear_free(sig->r);
+    BN_clear_free(sig->s);
+
+    sig->r = r;
+    sig->s = s;
+    return 1;
+  }
 };
 
 } // END namespace jwt
diff --git a/include/jwt/impl/algorithm.ipp b/include/jwt/impl/algorithm.ipp
index 6352388..ce29e34 100644
--- a/include/jwt/impl/algorithm.ipp
+++ b/include/jwt/impl/algorithm.ipp
@@ -77,21 +77,100 @@ verify_result_t PEMSign<Hasher>::verify(
     const string_view head,
     const string_view jwt_sign)
 {
-  /*
-   * unsigned char *sig = NULL;
-   * EVP_MD_CTX *mdctx = NULL;
-   * ECDSA_SIG *ec_sig = NULL;
-   * BIGNUM *ec_sig_r = NULL;
-   * BIGNUM *ec_sig_s = NULL;
-   * EVP_PKEY *pkey = NULL;
-   * const EVP_MD *alg;
-   * int type;
-   * int pkey_type;
-   * BIO *bufkey = NULL;
-   * int ret = 0;
-   * int slen;
-   */
   std::error_code ec{};
+  std::string dec_sig = base64_uri_decode(jwt_sign.data(), jwt_sign.length());
+
+  BIO_uptr bufkey{
+      BIO_new_mem_buf((void*)key.data(), key.length()),
+      bio_deletor};
+
+  if (!bufkey) {
+    throw MemoryAllocationException("BIO_new_mem_buf failed");
+  }
+
+  EC_PKEY_uptr pkey{
+    PEM_read_bio_PUBKEY(bufkey.get(), nullptr, nullptr, nullptr),
+    ev_pkey_deletor};
+
+  if (!pkey) {
+    ec = AlgorithmErrc::VerificationErr;
+    return { false, ec };
+  }
+
+  int pkey_type = EVP_PKEY_id(pkey.get());
+
+  if (pkey_type != Hasher::type) {
+    ec = AlgorithmErrc::VerificationErr;
+    return { false, ec };
+  }
+
+  //Convert EC signature back to ASN1
+  if (Hasher::type == EVP_PKEY_EC) {
+    EC_SIG_uptr ec_sig{ECDSA_SIG_new(), ec_sig_deletor};
+    if (!ec_sig) {
+      throw MemoryAllocationException("ECDSA_SIG_new failed");
+    }
+
+    //Get the actual ec_key
+    EC_KEY_uptr ec_key{EVP_PKEY_get1_EC_KEY(pkey.get()), ec_key_deletor};
+    if (!ec_key) {
+      throw MemoryAllocationException("EVP_PKEY_get1_EC_KEY failed");
+    }
+
+    unsigned int degree = EC_GROUP_get_degree(
+        EC_KEY_get0_group(ec_key.get()));
+    
+    unsigned int bn_len = (degree + 7) / 8;
+
+    if ((bn_len * 2) != dec_sig.length()) {
+      ec = AlgorithmErrc::VerificationErr;
+      return { false, ec };
+    }
+
+    BIGNUM* ec_sig_r = BN_bin2bn((unsigned char*)dec_sig.data(), bn_len, nullptr);
+    BIGNUM* ec_sig_s = BN_bin2bn((unsigned char*)dec_sig.data() + bn_len, bn_len, nullptr);
+
+    if (!ec_sig_r || !ec_sig_s) {
+      ec = AlgorithmErrc::VerificationErr;
+      return { false, ec };
+    }
+
+    ECDSA_SIG_set0(ec_sig.get(), ec_sig_r, ec_sig_s);
+
+    size_t nlen = i2d_ECDSA_SIG(ec_sig.get(), nullptr);
+    dec_sig.resize(nlen);
+
+    auto data = reinterpret_cast<unsigned char*>(&dec_sig[0]);
+    nlen = i2d_ECDSA_SIG(ec_sig.get(), &data);
+
+    if (nlen == 0) {
+      ec = AlgorithmErrc::VerificationErr;
+      return { false, ec };
+    }
+  }
+
+  EVP_MDCTX_uptr mdctx_ptr{EVP_MD_CTX_create(), evp_md_ctx_deletor};
+  if (!mdctx_ptr) {
+    throw MemoryAllocationException("EVP_MD_CTX_create failed");
+  }
+
+  if (EVP_DigestVerifyInit(
+        mdctx_ptr.get(), nullptr, Hasher{}(), nullptr, pkey.get()) != 1) {
+    ec = AlgorithmErrc::VerificationErr;
+    return { false, ec };
+  }
+
+  if (EVP_DigestVerifyUpdate(mdctx_ptr.get(), head.data(), head.length()) != 1) {
+    ec = AlgorithmErrc::VerificationErr;
+    return { false, ec };
+  }
+
+  if (EVP_DigestVerifyFinal(
+        mdctx_ptr.get(), (unsigned char*)&dec_sig[0], dec_sig.length()) != 1) {
+    ec = AlgorithmErrc::VerificationErr;
+    return { false, ec };
+  }
+
   return { true, ec };
 }
 
@@ -199,16 +278,6 @@ std::string PEMSign<Hasher>::public_key_ser(
   const BIGNUM* ec_sig_r = nullptr;
   const BIGNUM* ec_sig_s = nullptr;
 
-#if 1
-  //Taken from https://github.com/nginnever/zogminer/issues/39
-  static auto ECDSA_SIG_get0 = [](const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
-  {
-    if (pr != nullptr) *pr = sig->r;
-    if (ps != nullptr) *ps = sig->s;
-  };
-
-#endif
-
   ECDSA_SIG_get0(ec_sig.get(), &ec_sig_r, &ec_sig_s);
 
   auto r_len = BN_num_bytes(ec_sig_r);
diff --git a/include/jwt/test/test_jwt_object b/include/jwt/test/test_jwt_object
index 696b3a1..849029f 100755
Binary files a/include/jwt/test/test_jwt_object and b/include/jwt/test/test_jwt_object differ