[
  {
    "path": "C/SM2_SM3_SM4_C语言实现/SM2/kdf.h",
    "content": "\n#include <memory.h>\n#include <openssl/evp.h>\n\n// ----- KDF FUNCTIONS START -----\n//typedef void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen);\n\nint x9_63_kdf(const EVP_MD *md, const unsigned char *share, size_t sharelen, size_t keylen, unsigned char *outkey)\n{\n\tint ret = 0;\n\n\tEVP_MD_CTX ctx;\n\tunsigned char counter[4] = {0, 0, 0, 1};\n\tunsigned char dgst[EVP_MAX_MD_SIZE];\n\tunsigned int dgstlen;\n\tint rlen = (int)keylen;\n\tunsigned char * pp;\n\n\tpp = outkey;\n\n\tif (keylen > (size_t)EVP_MD_size(md)*255)\n\t{\n\t\tfprintf(stderr, \"%s(%d):\", __FILE__, __LINE__);\n\t\tgoto end;\n\t}\n\n\twhile (rlen > 0)\n\t{\n\t\tEVP_MD_CTX_init(&ctx);\n\n\t\tif (!EVP_DigestInit(&ctx, md))\n\t\t{\n\t\t\tfprintf(stderr, \"%s(%d):\", __FILE__, __LINE__);\n\t\t\tgoto end;\n\t\t}\n\n\t\tif (!EVP_DigestUpdate(&ctx, share, sharelen))\n\t\t{\n\t\t\tfprintf(stderr, \"%s(%d):\", __FILE__, __LINE__);\n\t\t\tgoto end;\n\t\t}\n\t\tif (!EVP_DigestUpdate(&ctx, counter, 4))\n\t\t{\n\t\t\tfprintf(stderr, \"%s(%d):\", __FILE__, __LINE__);\n\t\t\tgoto end;\n\t\t}\n\t\tif (!EVP_DigestFinal(&ctx, dgst, &dgstlen))\n\t\t{\n\t\t\tfprintf(stderr, \"%s(%d):\", __FILE__, __LINE__);\n\t\t\tgoto end;\n\t\t}\n\n\t\tEVP_MD_CTX_cleanup(&ctx);\n\n\t\tmemcpy(pp, dgst, keylen>=dgstlen ? dgstlen:keylen);\n\n\t\trlen -= dgstlen;\n\t\tpp += dgstlen;\n\t\tcounter[3]++;\n\t}\n\n\tret = 1;\n\nend:\n\treturn ret;\n}\n\n// ----- KDF FUNCTIONS END -----"
  },
  {
    "path": "C/SM2_SM3_SM4_C语言实现/SM2/sm2.c",
    "content": "// \\file:sm2.c\n//SM2 Algorithm\n//2011-11-10\n//author:goldboar\n//email:goldboar@163.com\n//depending:opnessl library\n\n//SM2 Standards: http://www.oscca.gov.cn/News/201012/News_1197.htm\n\n#include <limits.h>\n#include <openssl/ec.h>\n#include <openssl/bn.h>\n#include <openssl/rand.h>\n#include <openssl/err.h>\n#include <openssl/ecdsa.h>\n#include <openssl/ecdh.h>\n#include \"kdf.h\"\n\n#define  NID_X9_62_prime_field 406\nstatic void BNPrintf(BIGNUM* bn)\n{\n\tchar *p=NULL;\n\tp=BN_bn2hex(bn);\n\tprintf(\"%s\",p);\n\tOPENSSL_free(p);\n}\n\n\nstatic int sm2_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kp, BIGNUM **rp)\n{\n\tBN_CTX   *ctx = NULL;\n\tBIGNUM\t *k = NULL, *r = NULL, *order = NULL, *X = NULL;\n\tEC_POINT *tmp_point=NULL;\n\tconst EC_GROUP *group;\n\tint \t ret = 0;\n\n\tif (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL)\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);\n\t\treturn 0;\n\t}\n\n\tif (ctx_in == NULL) \n\t{\n\t\tif ((ctx = BN_CTX_new()) == NULL)\n\t\t{\n\t\t\tECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE);\n\t\t\treturn 0;\n\t\t}\n\t}\n\telse\n\t\tctx = ctx_in;\n\n\tk     = BN_new();\t/* this value is later returned in *kp */\n\tr     = BN_new();\t/* this value is later returned in *rp */\n\torder = BN_new();\n\tX     = BN_new();\n\tif (!k || !r || !order || !X)\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);\n\t\tgoto err;\n\t}\n\tif ((tmp_point = EC_POINT_new(group)) == NULL)\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);\n\t\tgoto err;\n\t}\n\tif (!EC_GROUP_get_order(group, order, ctx))\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);\n\t\tgoto err;\n\t}\n\t\n\tdo\n\t{\n\t\t/* get random k */\t\n\t\tdo\n\t\t\tif (!BN_rand_range(k, order))\n\t\t\t{\n\t\t\t\tECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);\t\n\t\t\t\tgoto err;\n\t\t\t}\n\t\twhile (BN_is_zero(k));\n\n\t\t/* compute r the x-coordinate of generator * k */\n\t\tif (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))\n\t\t{\n\t\t\tECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);\n\t\t\tgoto err;\n\t\t}\n\t\tif (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)\n\t\t{\n\t\t\tif (!EC_POINT_get_affine_coordinates_GFp(group,\n\t\t\t\ttmp_point, X, NULL, ctx))\n\t\t\t{\n\t\t\t\tECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);\n\t\t\t\tgoto err;\n\t\t\t}\n\t\t}\n\t\telse /* NID_X9_62_characteristic_two_field */\n\t\t{\n\t\t\tif (!EC_POINT_get_affine_coordinates_GF2m(group,\n\t\t\t\ttmp_point, X, NULL, ctx))\n\t\t\t{\n\t\t\t\tECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);\n\t\t\t\tgoto err;\n\t\t\t}\n\t\t}\n\t\tif (!BN_nnmod(r, X, order, ctx))\n\t\t{\n\t\t\tECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);\n\t\t\tgoto err;\n\t\t}\n\t}\n\twhile (BN_is_zero(r));\n\n\t/* compute the inverse of k */\n// \tif (!BN_mod_inverse(k, k, order, ctx))\n// \t{\n// \t\tECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);\n// \t\tgoto err;\t\n// \t}\n\t/* clear old values if necessary */\n\tif (*rp != NULL)\n\t\tBN_clear_free(*rp);\n\tif (*kp != NULL) \n\t\tBN_clear_free(*kp);\n\t/* save the pre-computed values  */\n\t*rp = r;\n\t*kp = k;\n\tret = 1;\nerr:\n\tif (!ret)\n\t{\n\t\tif (k != NULL) BN_clear_free(k);\n\t\tif (r != NULL) BN_clear_free(r);\n\t}\n\tif (ctx_in == NULL) \n\t\tBN_CTX_free(ctx);\n\tif (order != NULL)\n\t\tBN_free(order);\n\tif (tmp_point != NULL) \n\t\tEC_POINT_free(tmp_point);\n\tif (X)\n\t\tBN_clear_free(X);\n\treturn(ret);\n}\n\n\nstatic ECDSA_SIG *sm2_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *in_k, const BIGNUM *in_r, EC_KEY *eckey)\n{\n\tint     ok = 0, i;\n\tBIGNUM *k=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL;\n\tconst BIGNUM *ck;\n\tBN_CTX     *ctx = NULL;\n\tconst EC_GROUP   *group;\n\tECDSA_SIG  *ret;\n\t//ECDSA_DATA *ecdsa;\n\tconst BIGNUM *priv_key;\n    BIGNUM *r,*x=NULL,*a=NULL;\t//new added\n\t//ecdsa    = ecdsa_check(eckey);\n\tgroup    = EC_KEY_get0_group(eckey);\n\tpriv_key = EC_KEY_get0_private_key(eckey);\n\t\n\tif (group == NULL || priv_key == NULL /*|| ecdsa == NULL*/)\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);\n\t\treturn NULL;\n\t}\n\n\tret = ECDSA_SIG_new();\n\tif (!ret)\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);\n\t\treturn NULL;\n\t}\n\ts = ret->s;\n\tr = ret->r;\n\n\tif ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||\n\t\t(tmp = BN_new()) == NULL || (m = BN_new()) == NULL || \n\t\t(x = BN_new()) == NULL || (a = BN_new()) == NULL)\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);\n\t\tgoto err;\n\t}\n\n\tif (!EC_GROUP_get_order(group, order, ctx))\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);\n\t\tgoto err;\n\t}\n// \tfor(i=0;i<dgst_len;i++)\n// \t\tprintf(\"%02X\",dgst[i]);\n//  \tprintf(\"\\n\");\n\ti = BN_num_bits(order);\n\t/* Need to truncate digest if it is too long: first truncate whole\n\t * bytes.\n\t */\n\tif (8 * dgst_len > i)\n\t\tdgst_len = (i + 7)/8;\n\tif (!BN_bin2bn(dgst, dgst_len, m))\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);\n\t\tgoto err;\n\t}\n\t/* If still too long truncate remaining bits with a shift */\n\tif ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);\n\t\tgoto err;\n\t}\n// \tfprintf(stdout,\"m: \");\n// \tBNPrintf(m);\n// \tfprintf(stdout,\"\\n\");\n\tdo\n\t{\n\t\tif (in_k == NULL || in_r == NULL)\n\t\t{\n\t\t\tif (!sm2_sign_setup(eckey, ctx, &k, &x))\n\t\t\t{\n\t\t\t\tECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB);\n\t\t\t\tgoto err;\n\t\t\t}\n\t\t\tck = k;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tck  = in_k;\n\t\t\tif (BN_copy(x, in_r) == NULL)\n\t\t\t{\n\t\t\t\tECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);\n\t\t\t\tgoto err;\n\t\t\t}\n\t\t}\n\t\t\n\t\t//r=(e+x1) mod n\n\t\tif (!BN_mod_add_quick(r, m, x, order))\n\t\t{\n\t\t\tECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);\n\t\t\tgoto err;\n\t\t}\n\n// \t    BNPrintf(r);\n// \t\tfprintf(stdout,\"\\n\");\n\n\t\tif(BN_is_zero(r) )\n\t\t\tcontinue;\n\n\t\tBN_add(tmp,r,ck);\n\t\tif(BN_ucmp(tmp,order) == 0)\n\t\t\tcontinue;\n\t\t\n\t\tif (!BN_mod_mul(tmp, priv_key, r, order, ctx))\n\t\t{\n\t\t\tECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);\n\t\t\tgoto err;\n\t\t}\n\t\tif (!BN_mod_sub_quick(s, ck, tmp, order))\n\t\t{\n\t\t\tECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);\n\t\t\tgoto err;\n\t\t}\n\t\tBN_one(a);\n\t\t//BN_set_word((a),1);\n\n\t\tif (!BN_mod_add_quick(tmp, priv_key, a, order))\n\t\t{\n\t\t\tECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);\n\t\t\tgoto err;\n\t\t}\n\t\t/* compute the inverse of 1+dA */\n\t\tif (!BN_mod_inverse(tmp, tmp, order, ctx))\n\t\t{\n\t\t\tECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);\n\t\t\tgoto err;\t\n\t\t}\n// \t\tBNPrintf(tmp);\n// \t\tfprintf(stdout,\"\\n\");\n\n\t\tif (!BN_mod_mul(s, s, tmp, order, ctx))\n\t\t{\n\t\t\tECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);\n\t\t\tgoto err;\n\t\t}\n\t\tif (BN_is_zero(s))\n\t\t{\n\t\t\t/* if k and r have been supplied by the caller\n\t\t\t * don't to generate new k and r values */\n\t\t\tif (in_k != NULL && in_r != NULL)\n\t\t\t{\n\t\t\t\tECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES);\n\t\t\t\tgoto err;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\t/* s != 0 => we have a valid signature */\n\t\t\tbreak;\n\t}\n\twhile (1);\n\n\tok = 1;\nerr:\n\tif (!ok)\n\t{\n\t\tECDSA_SIG_free(ret);\n\t\tret = NULL;\n\t}\n\tif (ctx)\n\t\tBN_CTX_free(ctx);\n\tif (m)\n\t\tBN_clear_free(m);\n\tif (tmp)\n\t\tBN_clear_free(tmp);\n\tif (order)\n\t\tBN_free(order);\n\tif (k)\n\t\tBN_clear_free(k);\n\tif (x)\n\t\tBN_clear_free(x);\n\tif (a)\n\t\tBN_clear_free(a);\n\treturn ret;\n}\n\nstatic int sm2_do_verify(const unsigned char *dgst, int dgst_len,\n\t\tconst ECDSA_SIG *sig, EC_KEY *eckey)\n{\n\tint ret = -1, i;\n\tBN_CTX   *ctx;\n\tBIGNUM   *order, *R,  *m, *X,*t;\n\tEC_POINT *point = NULL;\n\tconst EC_GROUP *group;\n\tconst EC_POINT *pub_key;\n\n\t/* check input values */\n\tif (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||\n\t    (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL)\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);\n\t\treturn -1;\n\t}\n\n\tctx = BN_CTX_new();\n\tif (!ctx)\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);\n\t\treturn -1;\n\t}\n\tBN_CTX_start(ctx);\n\torder = BN_CTX_get(ctx);\t\n\tR    = BN_CTX_get(ctx);\n\tt    = BN_CTX_get(ctx);\n\tm     = BN_CTX_get(ctx);\n\tX     = BN_CTX_get(ctx);\n\tif (!X)\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);\n\t\tgoto err;\n\t}\n\t\n\tif (!EC_GROUP_get_order(group, order, ctx))\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);\n\t\tgoto err;\n\t}\n\n\tif (BN_is_zero(sig->r)          || BN_is_negative(sig->r) || \n\t    BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s)  ||\n\t    BN_is_negative(sig->s)      || BN_ucmp(sig->s, order) >= 0)\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);\n\t\tret = 0;\t/* signature is invalid */\n\t\tgoto err;\n\t}\n\n\t//t =(r+s) mod n\n\tif (!BN_mod_add_quick(t, sig->s, sig->r,order))\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);\n\t\tgoto err;\n\t}\n\tif (BN_is_zero(t))\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);\n\t\tret = 0;\t/* signature is invalid */\n\t\tgoto err;\n\t}\n\t\n\t//point = s*G+t*PA\n\tif ((point = EC_POINT_new(group)) == NULL)\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);\n\t\tgoto err;\n\t}\n\tif (!EC_POINT_mul(group, point, sig->s, pub_key, t, ctx))\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);\n\t\tgoto err;\n\t}\n\tif (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)\n\t{\n\t\tif (!EC_POINT_get_affine_coordinates_GFp(group,\n\t\t\tpoint, X, NULL, ctx))\n\t\t{\n\t\t\tECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);\n\t\t\tgoto err;\n\t\t}\n\t}\n\telse /* NID_X9_62_characteristic_two_field */\n\t{\n\t\tif (!EC_POINT_get_affine_coordinates_GF2m(group,\n\t\t\tpoint, X, NULL, ctx))\n\t\t{\n\t\t\tECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);\n\t\t\tgoto err;\n\t\t}\n\t}\n \t\n\ti = BN_num_bits(order);\n\t/* Need to truncate digest if it is too long: first truncate whole\n\t * bytes.\n\t */\n\tif (8 * dgst_len > i)\n\t\tdgst_len = (i + 7)/8;\n\tif (!BN_bin2bn(dgst, dgst_len, m))\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);\n\t\tgoto err;\n\t}\n\t/* If still too long truncate remaining bits with a shift */\n\tif ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);\n\t\tgoto err;\n\t}\n\n\t/* R = m + X mod order */\n\tif (!BN_mod_add_quick(R, m, X, order))\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);\n\t\tgoto err;\n\t}\n\n\t/*  if the signature is correct R is equal to sig->r */\n\tret = (BN_ucmp(R, sig->r) == 0);\nerr:\n\tBN_CTX_end(ctx);\n\tBN_CTX_free(ctx);\n\tif (point)\n\t\tEC_POINT_free(point);\n\treturn ret;\n}\n\n\nEC_POINT *sm2_compute_key(const EC_POINT *b_pub_key_r, const EC_POINT *b_pub_key, const BIGNUM *a_r,EC_KEY *a_eckey)\n{\n\tBN_CTX *ctx;\n\tEC_POINT *tmp=NULL;\n\tBIGNUM *x=NULL, *y=NULL, *order=NULL,*z=NULL;\n\tconst BIGNUM *priv_key;\n\tconst EC_GROUP* group;\n\tEC_POINT *ret= NULL;\n/*\tsize_t buflen, len;*/\n\tunsigned char *buf=NULL;\n\tint i, j;\n\t//char *p=NULL;\n\tBIGNUM *x1,*x2,*t,*h;\n\n\tif ((ctx = BN_CTX_new()) == NULL) goto err;\n\tBN_CTX_start(ctx);\n\tx = BN_CTX_get(ctx);\n\ty = BN_CTX_get(ctx);\n\torder = BN_CTX_get(ctx);\n\tz = BN_CTX_get(ctx);\n\tx1 = BN_CTX_get(ctx);\n\tx2 = BN_CTX_get(ctx);\n\tt = BN_CTX_get(ctx);\n\th = BN_CTX_get(ctx);\n\n\t\n\tpriv_key = EC_KEY_get0_private_key(a_eckey);\n\tif (priv_key == NULL)\n\t{\n\t\tECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);\n\t\tgoto err;\n\t}\n\n\tgroup = EC_KEY_get0_group(a_eckey);\n\tif ((tmp=EC_POINT_new(group)) == NULL)\n\t{\n\t\tECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);\n\t\tgoto err;\n\t}\n\n\tif (!EC_POINT_mul(group, tmp, a_r, NULL, NULL, ctx)) \n\t{\n\t\tECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);\n\t\tgoto err;\n\t}\n\t\n\tif (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) \n\t{\n\t\tif (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, NULL, ctx)) \n\t\t{\n\t\t\tECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);\n\t\t\tgoto err;\n\t\t}\n\t}\n\telse\n\t{\n\t\tif (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, NULL, ctx)) \n\t\t{\n\t\t\tECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);\n\t\t\tgoto err;\n\t\t}\n\t}\n\t\n\tif (!EC_GROUP_get_order(group, order, ctx))\n\t{\n\t\tECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);\n\t\tgoto err;\n\t}\n\t\t\n\ti = BN_num_bits(order);\n\tj = i/2 -1;\n\tBN_mask_bits(x,j);\n\tBN_set_word(y,2);\n\tBN_set_word(z,j);\n\tBN_exp(y,y,z,ctx);\n\tBN_add(x1,x,y);\n\t\n// \tfprintf(stdout,\"X1=: \");\n// \tBNPrintf(x1);\n// \tfprintf(stdout,\"\\n\");\n\n\tBN_mod_mul(t,x1,a_r,order,ctx);\n\tBN_mod_add_quick(t,t,priv_key,order);\n// \n// \tfprintf(stdout,\"ta=: \");\n// \tBNPrintf(t);\n// \tfprintf(stdout,\"\\n\");\n\n\t\n\tif (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) \n\t{\n\t\tif (!EC_POINT_get_affine_coordinates_GFp(group, b_pub_key_r, x, NULL, ctx)) \n\t\t{\n\t\t\tECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);\n\t\t\tgoto err;\n\t\t}\n\t}\n\telse\n\t{\n\t\tif (!EC_POINT_get_affine_coordinates_GF2m(group, b_pub_key_r, x, NULL, ctx)) \n\t\t{\n\t\t\tECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);\n\t\t\tgoto err;\n\t\t}\n\t}\n\n\ti = BN_num_bits(order);\n\tj = i/2 -1;\n\tBN_mask_bits(x,j);\n\tBN_set_word(y,2);\n\tBN_set_word(z,j);\n\tBN_exp(y,y,z,ctx);\n\tBN_add(x2,x,y);\n\t\n// \tfprintf(stdout,\"X2=: \");\n// \tBNPrintf(x2);\n// \tfprintf(stdout,\"\\n\");\n\n\n\t//x2*Rb+Pb;\n\tif (!EC_POINT_mul(group, tmp, NULL,b_pub_key_r,x2,ctx) )\n\t{\n\t\tECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);\n\t\tgoto err;\n\t}\n\tif ((ret=EC_POINT_new(group)) == NULL)\n\t{\n\t\tECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);\n\t\tgoto err;\n\t}\n\tif (!EC_POINT_add(group, ret, b_pub_key, tmp, ctx))\n\t{\n\t\tECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);\n\t\tgoto err;\n\t}\n\tif (!EC_POINT_get_affine_coordinates_GFp(group,ret, x, y, ctx)) \n\t{\n\t\tgoto err;\n\t}\n// \tfprintf(stdout, \"\\nTesting x2*Rb+Pb Key Point\\n     x = 0x\");\n// \tBNPrintf(x);\n// \tfprintf(stdout, \"\\n     y = 0x\");\n// \tBNPrintf( y);\n// \tfprintf(stdout, \"\\n\");\n// \t\n\tif(!EC_GROUP_get_cofactor(group, h, ctx))\n\t{\n\t\tgoto err;\n\t}\n    BN_mul(t,t,h,ctx);\n\n\t//h*t*(x2*Rb+Pb)\n\tif (!EC_POINT_mul(group, ret, NULL,ret,t,ctx) ) \n\t{\n\t\tgoto err;\n\t}\n\tif (!EC_POINT_get_affine_coordinates_GFp(group,ret, x, y, ctx)) \n\t{\n\t\tgoto err;\n\t}\n// \tfprintf(stdout, \"\\nTesting ret Key Point\\n     x = 0x\");\n// \tBNPrintf(x);\n// \tfprintf(stdout, \"\\n     y = 0x\");\n// \tBNPrintf( y);\n// \tfprintf(stdout, \"\\n\");\n\n\t\nerr:\n\tif (tmp) EC_POINT_free(tmp);\n\tif (ctx) BN_CTX_end(ctx);\n\tif (ctx) BN_CTX_free(ctx);\n\tif (buf) OPENSSL_free(buf);\n\treturn(ret);\n}\n\n/** SM2_sign_setup\n* precompute parts of the signing operation. \n* \\param eckey pointer to the EC_KEY object containing a private EC key\n* \\param ctx  pointer to a BN_CTX object (may be NULL)\n* \\param k pointer to a BIGNUM pointer for the inverse of k\n* \\param rp   pointer to a BIGNUM pointer for x coordinate of k * generator\n* \\return 1 on success and 0 otherwise\n */\n\nint  SM2_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)\n{\n// \tECDSA_DATA *ecdsa = ecdsa_check(eckey);\n// \tif (ecdsa == NULL)\n// \t\treturn 0;\n\treturn SM2_sign_setup(eckey, ctx_in, kinvp, rp); \n}\n/** SM2_sign_ex\n * computes ECDSA signature of a given hash value using the supplied\n * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).\n * \\param type this parameter is ignored\n * \\param dgst pointer to the hash value to sign\n * \\param dgstlen length of the hash value\n * \\param sig buffer to hold the DER encoded signature\n * \\param siglen pointer to the length of the returned signature\n * \\param k optional pointer to a pre-computed inverse k\n * \\param rp optional pointer to the pre-computed rp value (see \n *        ECDSA_sign_setup\n * \\param eckey pointer to the EC_KEY object containing a private EC key\n * \\return 1 on success and 0 otherwise\n */\nint\t  SM2_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char \n\t*sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, \n\tEC_KEY *eckey)\n{\n\tECDSA_SIG *s;\n\tRAND_seed(dgst, dlen);\n\ts = sm2_do_sign(dgst, dlen, kinv, r, eckey);\n\tif (s == NULL)\n\t{\n\t\t*siglen=0;\n\t\treturn 0;\n\t}\n\t*siglen = i2d_ECDSA_SIG(s, &sig);\n\tECDSA_SIG_free(s);\n\treturn 1;\n}\n\n/** SM2_sign\n  * computes ECDSA signature of a given hash value using the supplied\n  * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).\n  * \\param type this parameter is ignored\n  * \\param dgst pointer to the hash value to sign\n  * \\param dgstlen length of the hash value\n  * \\param sig buffer to hold the DER encoded signature\n  * \\param siglen pointer to the length of the returned signature\n  * \\param eckey pointer to the EC_KEY object containing a private EC key\n  * \\return 1 on success and 0 otherwise\n */\nint\t  SM2_sign(int type, const unsigned char *dgst, int dlen, unsigned char \n\t\t*sig, unsigned int *siglen, EC_KEY *eckey)\n{\n\n\treturn SM2_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey);\n\n}\n\n\n/** SM2_verify\n  * verifies that the given signature is valid ECDSA signature\n  * of the supplied hash value using the specified public key.\n  * \\param type this parameter is ignored\n  * \\param dgst pointer to the hash value \n  * \\param dgstlen length of the hash value\n  * \\param sig  pointer to the DER encoded signature\n  * \\param siglen length of the DER encoded signature\n  * \\param eckey pointer to the EC_KEY object containing a public EC key\n  * \\return 1 if the signature is valid, 0 if the signature is invalid and -1 on error\n  */\nint SM2_verify(int type, const unsigned char *dgst, int dgst_len,\n\t\tconst unsigned char *sigbuf, int sig_len, EC_KEY *eckey)\n {\n\tECDSA_SIG *s;\n\tint ret=-1;\n\n\ts = ECDSA_SIG_new();\n\tif (s == NULL) return(ret);\n\tif (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err;\n\tret=sm2_do_verify(dgst, dgst_len, s, eckey);\nerr:\n\tECDSA_SIG_free(s);\n\treturn(ret);\n}\n\nint SM2_DH_key(const EC_GROUP * group, const EC_POINT *b_pub_key_r, const EC_POINT *b_pub_key, const BIGNUM *a_r,EC_KEY *a_eckey,\n\t\t\t   unsigned char *outkey,size_t keylen)\n{\n\tEC_POINT *dhpoint = NULL;\n\tBN_CTX * ctx;\n\tEC_POINT *P;\n\tBIGNUM *x, *y;\n\tint ret = 0;\n\tunsigned char in[128];\n\tint inlen;\n\tint len;\n\n\tP = EC_POINT_new(group);\n\tif (!P ) goto err;\n\tctx = BN_CTX_new();\n\tx = BN_new();\n\ty = BN_new();\n\tif (!x || !y ) goto err;\n\t\n\tdhpoint = sm2_compute_key(b_pub_key_r,b_pub_key,a_r,a_eckey);\n\n\tif (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) \n\t{\n\t\tif (!EC_POINT_get_affine_coordinates_GFp(group,dhpoint, x, y, ctx))\n\t\t{\n\t\t\tfprintf(stdout, \" failed\\n\");\n\t\t\tgoto err;\n\t\t}\n\t}\n\telse\n\t{\n\t\tif (!EC_POINT_get_affine_coordinates_GF2m(group,dhpoint, x, y, ctx)) \n\t\t{\n\t\t\tECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);\n\t\t\tgoto err;\n\t\t}\n\t}\n\n// \tif (!EC_POINT_get_affine_coordinates_GFp(group,dhpoint, x, y, ctx))\n// \t{\n// \t\tfprintf(stdout, \" failed\\n\");\n// \t\tgoto err;\n// \t}\n\tfprintf(stdout, \"\\nTesting DH Point\\n     Xv = 0x\");\n\tBNPrintf(x);\n\tfprintf(stdout, \"\\n     Yv = 0x\");\n\tBNPrintf( y);\n\tfprintf(stdout, \"\\n\");\n\n\tlen = BN_bn2bin(x,in);\n\tinlen =BN_bn2bin(y,in+len);\n\tinlen = inlen + len;\n\tret = x9_63_kdf(EVP_sha256(),in,inlen,keylen,outkey);\n\t//ret  = 1;\nerr:\n\tEC_POINT_free(P);\n\tEC_POINT_free(dhpoint);\n\tBN_CTX_free(ctx);\n\n\treturn ret;\n}\n\n"
  },
  {
    "path": "C/SM2_SM3_SM4_C语言实现/SM2/sm2.dsp",
    "content": "# Microsoft Developer Studio Project File - Name=\"sm2\" - Package Owner=<4>\n# Microsoft Developer Studio Generated Build File, Format Version 6.00\n# ** DO NOT EDIT **\n\n# TARGTYPE \"Win32 (x86) Console Application\" 0x0103\n\nCFG=sm2 - Win32 Debug\n!MESSAGE This is not a valid makefile. To build this project using NMAKE,\n!MESSAGE use the Export Makefile command and run\n!MESSAGE \n!MESSAGE NMAKE /f \"sm2.mak\".\n!MESSAGE \n!MESSAGE You can specify a configuration when running NMAKE\n!MESSAGE by defining the macro CFG on the command line. For example:\n!MESSAGE \n!MESSAGE NMAKE /f \"sm2.mak\" CFG=\"sm2 - Win32 Debug\"\n!MESSAGE \n!MESSAGE Possible choices for configuration are:\n!MESSAGE \n!MESSAGE \"sm2 - Win32 Release\" (based on \"Win32 (x86) Console Application\")\n!MESSAGE \"sm2 - Win32 Debug\" (based on \"Win32 (x86) Console Application\")\n!MESSAGE \n\n# Begin Project\n# PROP AllowPerConfigDependencies 0\n# PROP Scc_ProjName \"\"\n# PROP Scc_LocalPath \"\"\nCPP=cl.exe\nRSC=rc.exe\n\n!IF  \"$(CFG)\" == \"sm2 - Win32 Release\"\n\n# PROP BASE Use_MFC 0\n# PROP BASE Use_Debug_Libraries 0\n# PROP BASE Output_Dir \"Release\"\n# PROP BASE Intermediate_Dir \"Release\"\n# PROP BASE Target_Dir \"\"\n# PROP Use_MFC 0\n# PROP Use_Debug_Libraries 0\n# PROP Output_Dir \"Release\"\n# PROP Intermediate_Dir \"Release\"\n# PROP Target_Dir \"\"\n# ADD BASE CPP /nologo /W3 /GX /O2 /D \"WIN32\" /D \"NDEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /YX /FD /c\n# ADD CPP /nologo /W3 /GX /O2 /D \"WIN32\" /D \"NDEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /YX /FD /c\n# ADD BASE RSC /l 0x804 /d \"NDEBUG\"\n# ADD RSC /l 0x804 /d \"NDEBUG\"\nBSC32=bscmake.exe\n# ADD BASE BSC32 /nologo\n# ADD BSC32 /nologo\nLINK32=link.exe\n# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\n# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\n\n!ELSEIF  \"$(CFG)\" == \"sm2 - Win32 Debug\"\n\n# PROP BASE Use_MFC 0\n# PROP BASE Use_Debug_Libraries 1\n# PROP BASE Output_Dir \"Debug\"\n# PROP BASE Intermediate_Dir \"Debug\"\n# PROP BASE Target_Dir \"\"\n# PROP Use_MFC 0\n# PROP Use_Debug_Libraries 1\n# PROP Output_Dir \"Debug\"\n# PROP Intermediate_Dir \"Debug\"\n# PROP Target_Dir \"\"\n# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /YX /FD /GZ /c\n# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /FR /YX /FD /GZ /c\n# ADD BASE RSC /l 0x804 /d \"_DEBUG\"\n# ADD RSC /l 0x804 /d \"_DEBUG\"\nBSC32=bscmake.exe\n# ADD BASE BSC32 /nologo\n# ADD BSC32 /nologo\nLINK32=link.exe\n# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\n# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\n\n!ENDIF \n\n# Begin Target\n\n# Name \"sm2 - Win32 Release\"\n# Name \"sm2 - Win32 Debug\"\n# Begin Source File\n\nSOURCE=.\\kdf.h\n# End Source File\n# Begin Source File\n\nSOURCE=.\\sm2.c\n# End Source File\n# Begin Source File\n\nSOURCE=.\\sm2.h\n# End Source File\n# Begin Source File\n\nSOURCE=.\\sm2test.c\n# End Source File\n# End Target\n# End Project\n"
  },
  {
    "path": "C/SM2_SM3_SM4_C语言实现/SM2/sm2.dsw",
    "content": "Microsoft Developer Studio Workspace File, Format Version 6.00\n# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\n\n###############################################################################\n\nProject: \"sm2\"=.\\sm2.dsp - Package Owner=<4>\n\nPackage=<5>\n{{{\n}}}\n\nPackage=<4>\n{{{\n}}}\n\n###############################################################################\n\nGlobal:\n\nPackage=<5>\n{{{\n}}}\n\nPackage=<3>\n{{{\n}}}\n\n###############################################################################\n\n"
  },
  {
    "path": "C/SM2_SM3_SM4_C语言实现/SM2/sm2.h",
    "content": "// \\file:sm2.h\n//SM2 Algorithm\n//2011-11-09\n//author:goldboar\n//email:goldboar@163.com\n//comment:2011-11-10 sm2-sign-verify sm2-dh\n\n//SM2_sign_setup\nint SM2_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);\n\n//SM2_sign_ex\nint\tSM2_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char \n\t*sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey);\n\n//SM2_sign\nint\tSM2_sign(int type, const unsigned char *dgst, int dlen, unsigned char \n\t\t*sig, unsigned int *siglen, EC_KEY *eckey);\n\n//SM2_verify\nint SM2_verify(int type, const unsigned char *dgst, int dgst_len,\n\t\tconst unsigned char *sigbuf, int sig_len, EC_KEY *eckey);\n\n//SM2 DH, comupting shared point\nint SM2_DH_key(const EC_GROUP * group,const EC_POINT *b_pub_key_r, const EC_POINT *b_pub_key, const BIGNUM *a_r,EC_KEY *a_eckey,\n\t\t\t   unsigned char *outkey,size_t keylen);\n"
  },
  {
    "path": "C/SM2_SM3_SM4_C语言实现/SM2/sm2test.c",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <openssl/bn.h>\n#include <openssl/ec.h>\n#include <openssl/rand.h>\n#include <openssl/err.h>\n#include <openssl/ecdsa.h>\n#include <openssl/ecdh.h>\n#include \"sm2.h\"\n\n\n#pragma comment(lib,\"libeay32.lib\")\n\n#define ABORT do { \\\n\tfflush(stdout); \\\n\tfprintf(stderr, \"%s:%d: ABORT\\n\", __FILE__, __LINE__); \\\n\tERR_print_errors_fp(stderr); \\\n\texit(1); \\\n} while (0)\n\nstatic const char rnd_seed[] = \"string to make the random number generator think it has entropy\";\n\nvoid BNPrintf(BIGNUM* bn)\n{\n\tchar *p=NULL;\n\tp=BN_bn2hex(bn);\n\tprintf(\"%s\",p);\n\tOPENSSL_free(p);\n}\n\n\nint SM2_Test_Vecotor()\n{\n\tBN_CTX *ctx = NULL;\n\tBIGNUM *p, *a, *b;\n\tEC_GROUP *group;\n\tEC_POINT *P, *Q, *R;\n\tBIGNUM *x, *y, *z;\n\tEC_KEY\t*eckey = NULL;\n\tunsigned char\tdigest[20];\n\tunsigned char\t*signature = NULL; \n\tint\tsig_len;\n\n\n\tCRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);\n\tCRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);\n\tERR_load_crypto_strings();\n\tRAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */\n\t\n\tctx = BN_CTX_new();\n\tif (!ctx) ABORT;\n\n\t/* Curve SM2 (Chinese National Algorithm) */\n\t//http://www.oscca.gov.cn/News/201012/News_1197.htm\n\tp = BN_new();\n\ta = BN_new();\n\tb = BN_new();\n\tif (!p || !a || !b) ABORT;\n\tgroup = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp\n \t                                             * so that the library gets to choose the EC_METHOD */\n\tif (!group) ABORT;\n\t\n\tif (!BN_hex2bn(&p, \"8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3\")) ABORT;\n\tif (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;\n\tif (!BN_hex2bn(&a, \"787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498\")) ABORT;\n\tif (!BN_hex2bn(&b, \"63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A\")) ABORT;\n\tif (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;\n\n\tP = EC_POINT_new(group);\n\tQ = EC_POINT_new(group);\n\tR = EC_POINT_new(group);\n\tif (!P || !Q || !R) ABORT;\n\n\tx = BN_new();\n\ty = BN_new();\n\tz = BN_new();\n\tif (!x || !y || !z) ABORT;\n\n\t// sm2 testing P256 Vetor\n\t// p8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3\n\t// a787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498\n\t// b63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A\n\t// xG 421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D\n\t// yG 0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2\n\t// n: 8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7\n\n\tif (!BN_hex2bn(&x, \"421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D\")) ABORT;\n\tif (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;\n\tif (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;\n\tif (!BN_hex2bn(&z, \"8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7\")) ABORT;\n\tif (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;\n\t\n\tif (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;\n\tfprintf(stdout, \"\\nChinese sm2 algorithm test -- Generator:\\n     x = 0x\");\n\tBNPrintf(x);\n\tfprintf(stdout, \"\\n     y = 0x\");\n\tBNPrintf( y);\n\tfprintf(stdout, \"\\n\");\n\t/* G_y value taken from the standard: */\n\tif (!BN_hex2bn(&z, \"0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2\")) ABORT;\n\tif (0 != BN_cmp(y, z)) ABORT;\n\t\n\tfprintf(stdout, \"verify degree ...\");\n\tif (EC_GROUP_get_degree(group) != 256) ABORT;\n\tfprintf(stdout, \" ok\\n\");\n\t\n\tfprintf(stdout, \"verify group order ...\");\n\tfflush(stdout);\n\tif (!EC_GROUP_get_order(group, z, ctx)) ABORT;\n\tif (!EC_GROUP_precompute_mult(group, ctx)) ABORT;\n\tif (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;\n\tif (!EC_POINT_is_at_infinity(group, Q)) ABORT;\n \tfflush(stdout);\n\tfprintf(stdout, \" ok\\n\");\n\n\t//testing ECDSA for SM2\n\t/* create new ecdsa key */\n\tif ((eckey = EC_KEY_new()) == NULL)\n\t\tgoto builtin_err;\n\tif (EC_KEY_set_group(eckey, group) == 0)\n\t{\n\t\tfprintf(stdout,\" failed\\n\");\n\t\tgoto builtin_err;\n\t}\n\t/* create key */\n\tif (!EC_KEY_generate_key(eckey))\n\t{\n\t\tfprintf(stdout,\" failed\\n\");\n\t\tgoto builtin_err;\n\t}\n\t/* check key */\n\tif (!EC_KEY_check_key(eckey))\n\t{\n\t\tfprintf(stdout,\" failed\\n\");\n\t\tgoto builtin_err;\n\t}\n\t/* create signature */\n\tsig_len = ECDSA_size(eckey);\n\tfprintf(stdout,\"Siglength is: %d \\n\",sig_len);\n\tif (!RAND_pseudo_bytes(digest, 20))\n\t{\n\t\tfprintf(stdout,\" failed\\n\");\n\t\tgoto builtin_err;\n\t}\n\tif ((signature = OPENSSL_malloc(sig_len)) == NULL)\n\t\tgoto builtin_err;\n\tif (!SM2_sign(0, digest, 20, signature, &sig_len, eckey))\n\t{\n\t\tfprintf(stdout, \" failed\\n\");\n\t\tgoto builtin_err;\n\t}\n\tfprintf(stdout, \"ECSign OK\\n\");\n\t/* verify signature */\n\tif (SM2_verify(0, digest, 20, signature, sig_len, eckey) != 1)\n\t{\n\t\tfprintf(stdout, \" failed\\n\");\n\t\tgoto builtin_err;\n\t}\n\tfprintf(stdout, \"ECVerify OK\\n\");\n\t/* cleanup */\n\tOPENSSL_free(signature);\n\tsignature = NULL;\n\tEC_KEY_free(eckey);\n\teckey = NULL;\n\t\nbuiltin_err:\t\n\t\n\tEC_POINT_free(P);\n\tEC_POINT_free(Q);\n\tEC_POINT_free(R);\n\tEC_GROUP_free(group);\n\tBN_CTX_free(ctx);\n\treturn 0;\n\n}\n\nint SM2_Test_Vecotor2()\n{\n\tBN_CTX *ctx = NULL;\n\tBIGNUM *p, *a, *b;\n\tEC_GROUP *group;\n\tEC_POINT *P, *Q, *R;\n\tBIGNUM *x, *y, *z;\n\tEC_KEY\t*eckey = NULL;\n\tunsigned char\t*signature;\n\tunsigned char\tdigest[32] = \"\\xB5\\x24\\xF5\\x52\\xCD\\x82\\xB8\\xB0\\x28\\x47\\x6E\\x00\\x5C\\x37\\x7F\\xB1\\x9A\\x87\\xE6\\xFC\\x68\\x2D\\x48\\xBB\\x5D\\x42\\xE3\\xD9\\xB9\\xEF\\xFE\\x76\"; \n\tint\tsig_len;\n\tBIGNUM *kinv, *rp,*order; \n\tECDSA_SIG *ecsig = ECDSA_SIG_new();\n\tEC_POINT * DHPoint = NULL;\n// \tunsigned char *in=\"123456\";\n// \tsize_t inlen = 6;\n \tsize_t outlen = 256;\n\tunsigned char outkey[256];\n\tsize_t keylen = 256;\n\n\tsize_t i;\n\n\tCRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);\n\tCRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);\n\tERR_load_crypto_strings();\n\tRAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */\n\t\n\tctx = BN_CTX_new();\n\tif (!ctx) ABORT;\n\n\t/* Curve SM2 (Chinese National Algorithm) */\n\t//http://www.oscca.gov.cn/News/201012/News_1197.htm\n\tp = BN_new();\n\ta = BN_new();\n\tb = BN_new();\n\tif (!p || !a || !b) ABORT;\n\tgroup = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp\n \t                                             * so that the library gets to choose the EC_METHOD */\n\tif (!group) ABORT;\n\t\n\tif (!BN_hex2bn(&p, \"8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3\")) ABORT;\n\tif (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;\n\tif (!BN_hex2bn(&a, \"787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498\")) ABORT;\n\tif (!BN_hex2bn(&b, \"63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A\")) ABORT;\n\tif (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;\n\n\tP = EC_POINT_new(group);\n\tQ = EC_POINT_new(group);\n\tR = EC_POINT_new(group);\n\tif (!P || !Q || !R) ABORT;\n\n\tx = BN_new();\n\ty = BN_new();\n\tz = BN_new();\n\tif (!x || !y || !z) ABORT;\n\n\t// sm2 testing P256 Vetor\n\t// p8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3\n\t// a787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498\n\t// b63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A\n\t// xG 421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D\n\t// yG 0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2\n\t// n: 8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7\n\n\tif (!BN_hex2bn(&x, \"421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D\")) ABORT;\n\tif (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;\n\tif (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;\n\tif (!BN_hex2bn(&z, \"8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7\")) ABORT;\n\tif (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;\n\t\n\tif (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;\n\tfprintf(stdout, \"\\nChinese sm2 algorithm test -- Generator:\\n     x = 0x\");\n\tBNPrintf(x);\n\tfprintf(stdout, \"\\n     y = 0x\");\n\tBNPrintf( y);\n\tfprintf(stdout, \"\\n\");\n\t/* G_y value taken from the standard: */\n\tif (!BN_hex2bn(&z, \"0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2\")) ABORT;\n\tif (0 != BN_cmp(y, z)) ABORT;\n\t\n\tfprintf(stdout, \"verify degree ...\");\n\tif (EC_GROUP_get_degree(group) != 256) ABORT;\n\tfprintf(stdout, \" ok\\n\");\n\t\n\tfprintf(stdout, \"verify group order ...\");\n\tfflush(stdout);\n\tif (!EC_GROUP_get_order(group, z, ctx)) ABORT;\n\tif (!EC_GROUP_precompute_mult(group, ctx)) ABORT;\n\tif (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;\n\tif (!EC_POINT_is_at_infinity(group, Q)) ABORT;\n \tfflush(stdout);\n\tfprintf(stdout, \" ok\\n\");\n\n\t//testing ECDSA for SM2\n\t/* create new ecdsa key */\n\tif ((eckey = EC_KEY_new()) == NULL)\n\t\tgoto builtin_err;\n\tif (EC_KEY_set_group(eckey, group) == 0)\n\t{\n\t\tfprintf(stdout,\" failed\\n\");\n\t\tgoto builtin_err;\n\t}\n\t/* create key */\n\tif (!BN_hex2bn(&z, \"128B2FA8BD433C6C068C8D803DFF79792A519A55171B1B650C23661D15897263\")) ABORT;\n\tif (!EC_POINT_mul(group,P, z, NULL, NULL, ctx)) ABORT;\n\tif (!EC_POINT_get_affine_coordinates_GFp(group,P, x, y, ctx)) ABORT;\n\tfprintf(stdout, \"\\nTesting ECKey Point\\n     x = 0x\");\n\tBNPrintf(x);\n\tfprintf(stdout, \"\\n     y = 0x\");\n\tBNPrintf( y);\n\tfprintf(stdout, \"\\n\");\n\tEC_KEY_set_private_key(eckey,z);\n\tEC_KEY_set_public_key(eckey, P);\n\n\t/* check key */\n\tif (!EC_KEY_check_key(eckey))\n\t{\n\t\tfprintf(stdout,\" failed\\n\");\n\t\tgoto builtin_err;\n\t}\n\n\t/* create signature */\n\tsig_len = ECDSA_size(eckey);\n \t//fprintf(stdout,\"Siglength is: %d \\n\",sig_len);\n\tif ((signature = OPENSSL_malloc(sig_len)) == NULL)\n\t\tgoto builtin_err;\n\n\trp    = BN_new();\n\tkinv  = BN_new();\n\torder = BN_new();\n\n\tif (!BN_hex2bn(&z, \"6CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F\")) ABORT;\n\tif (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx))\n\t{\n\t\tfprintf(stdout, \" failed\\n\");\n\t\tgoto builtin_err;\n\t}\n\tif (!EC_POINT_get_affine_coordinates_GFp(group,Q, x, y, ctx))\n\t{\n\t\tfprintf(stdout, \" failed\\n\");\n\t\tgoto builtin_err;\n\t}\n\tfprintf(stdout, \"\\nTesting K Point\\n     x = 0x\");\n\tBNPrintf(x);\n\tfprintf(stdout, \"\\n     y = 0x\");\n\tBNPrintf( y);\n\tfprintf(stdout, \"\\n\");\n\n\tEC_GROUP_get_order(group, order, ctx);\n\tif (!BN_nnmod(rp, x, order, ctx))\n\t{\n\t\tfprintf(stdout, \" failed\\n\");\n\t\tgoto builtin_err;\n\t}\n\tif (!BN_copy(kinv, z ))\n\t{\n\t\tfprintf(stdout, \" failed\\n\");\n\t\tgoto builtin_err;\n\t}\n\n// \tfor(i=0;i<32;i++)\n// \t\tprintf(\"%02X\",digest[i]);\n// \tprintf(\"\\n\");\n\n\tif (!SM2_sign_ex(1, digest, 32, signature, &sig_len, kinv, rp, eckey))\n\t{\n\t\tfprintf(stdout, \" failed\\n\");\n\t\tgoto builtin_err;\n\t}\n\tfprintf(stdout, \"ECSign OK\\n\");\n\n\t/* verify signature */\n\tif (SM2_verify(1, digest, 32, signature, sig_len, eckey) != 1)\n\t{\n\t\tfprintf(stdout, \" failed\\n\");\n\t\tgoto builtin_err;\n\t}\n\tfprintf(stdout, \"ECVerify OK\\n     r = 0x\");\n\td2i_ECDSA_SIG(&ecsig, &signature, sig_len);\n\tBNPrintf(ecsig->r);\n\tfprintf(stdout,\"\\n     s = 0x\");\n\tBNPrintf(ecsig->s);\n\tfprintf(stdout,\"\\n\");\n\n\t//testing SM2DH vector\n\t/* create key */\n\tif (!BN_hex2bn(&z, \"6FCBA2EF9AE0AB902BC3BDE3FF915D44BA4CC78F88E2F8E7F8996D3B8CCEEDEE\")) ABORT;\n\tif (!EC_POINT_mul(group,P, z, NULL, NULL, ctx)) ABORT;\n\tif (!EC_POINT_get_affine_coordinates_GFp(group,P, x, y, ctx)) ABORT;\n\tfprintf(stdout, \"\\nTesting A Key Point\\n     x = 0x\");\n\tBNPrintf(x);\n\tfprintf(stdout, \"\\n     y = 0x\");\n\tBNPrintf( y);\n\tfprintf(stdout, \"\\n\");\n\tEC_KEY_set_private_key(eckey,z);\n\tEC_KEY_set_public_key(eckey, P);\n\n\tif (!BN_hex2bn(&z, \"5E35D7D3F3C54DBAC72E61819E730B019A84208CA3A35E4C2E353DFCCB2A3B53\")) ABORT;\n\tif (!EC_POINT_mul(group,Q, z, NULL, NULL, ctx)) ABORT;\n\tif (!EC_POINT_get_affine_coordinates_GFp(group,Q, x, y, ctx)) ABORT;\n\tfprintf(stdout, \"\\nTesting B Key Point\\n     x = 0x\");\n\tBNPrintf(x);\n\tfprintf(stdout, \"\\n     y = 0x\");\n\tBNPrintf( y);\n\tfprintf(stdout, \"\\n\");\n\t//EC_KEY_set_private_key(eckey,z);\n\t//EC_KEY_set_public_key(eckey, P);\n\n\tif (!BN_hex2bn(&z, \"33FE21940342161C55619C4A0C060293D543C80AF19748CE176D83477DE71C80\")) ABORT;\n\tif (!EC_POINT_mul(group,P, z, NULL, NULL, ctx)) ABORT;\n\tif (!EC_POINT_get_affine_coordinates_GFp(group,P, x, y, ctx)) ABORT;\n\tfprintf(stdout, \"\\nTesting Rb Key Point\\n     x = 0x\");\n\tBNPrintf(x);\n\tfprintf(stdout, \"\\n     y = 0x\");\n\tBNPrintf( y);\n\tfprintf(stdout, \"\\n\");\n\n\tif (!BN_hex2bn(&z, \"83A2C9C8B96E5AF70BD480B472409A9A327257F1EBB73F5B073354B248668563\")) ABORT;\n\tif (!EC_POINT_mul(group,R, z, NULL, NULL, ctx)) ABORT;\n\tif (!EC_POINT_get_affine_coordinates_GFp(group,R, x, y, ctx)) ABORT;\n\tfprintf(stdout, \"\\nTesting Ra Key Point\\n     x = 0x\");\n\tBNPrintf(x);\n\tfprintf(stdout, \"\\n     y = 0x\");\n\tBNPrintf( y);\n\tfprintf(stdout, \"\\n\");\n    \n\tSM2_DH_key(group,P, Q, z,eckey,outkey,keylen);\n\n\tfprintf(stdout,\"\\nExchange key --KDF(Xv||Yv)--  :\");\n\tfor(i=0; i<outlen; i++)\n\t\tprintf(\"%02X\",outkey[i]);\n\tprintf(\"\\n\");\n\n\n\nbuiltin_err:\t\n\tOPENSSL_free(signature);\n\tsignature = NULL;\n\tEC_POINT_free(P);\n\tEC_POINT_free(Q);\n\tEC_POINT_free(R);\n\tEC_POINT_free(DHPoint);\n\tEC_KEY_free(eckey);\n\teckey = NULL;\n\tEC_GROUP_free(group);\n\tBN_CTX_free(ctx);\n\treturn 0;\n\n}\n\nint main()\n{\n\tCRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);\n\tCRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);\n\tERR_load_crypto_strings();\n\tRAND_seed(rnd_seed, sizeof rnd_seed); \n\t\n\tSM2_Test_Vecotor2();\n\t\n\t\n\tCRYPTO_cleanup_all_ex_data();\n\tERR_free_strings();\n\tERR_remove_state(0);\n\tCRYPTO_mem_leaks_fp(stderr);\n\t\n\treturn 0;\n\n}"
  },
  {
    "path": "C/SM2_SM3_SM4_C语言实现/SM3/sm3.c",
    "content": "/*\n * SM3 Hash alogrith \n * thanks to Xyssl\n * author:goldboar\n * email:goldboar@163.com\n * 2011-10-26\n */\n\n//Testing data from SM3 Standards\n//http://www.oscca.gov.cn/News/201012/News_1199.htm \n// Sample 1\n// Input:\"abc\"  \n// Output:66c7f0f4 62eeedd9 d1f2d46b dc10e4e2 4167c487 5cf2f7a2 297da02b 8f4ba8e0\n\n// Sample 2 \n// Input:\"abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd\"\n// Outpuf:debe9ff9 2275b8a1 38604889 c18e5a4d 6fdb70e5 387e5765 293dcba3 9c0c5732\n\n#include \"sm3.h\"\n#include <string.h>\n#include <stdio.h>\n\n/*\n * 32-bit integer manipulation macros (big endian)\n */\n#ifndef GET_ULONG_BE\n#define GET_ULONG_BE(n,b,i)                             \\\n{                                                       \\\n    (n) = ( (unsigned long) (b)[(i)    ] << 24 )        \\\n        | ( (unsigned long) (b)[(i) + 1] << 16 )        \\\n        | ( (unsigned long) (b)[(i) + 2] <<  8 )        \\\n        | ( (unsigned long) (b)[(i) + 3]       );       \\\n}\n#endif\n\n#ifndef PUT_ULONG_BE\n#define PUT_ULONG_BE(n,b,i)                             \\\n{                                                       \\\n    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \\\n    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \\\n    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \\\n    (b)[(i) + 3] = (unsigned char) ( (n)       );       \\\n}\n#endif\n\n/*\n * SM3 context setup\n */\nvoid sm3_starts( sm3_context *ctx )\n{\n    ctx->total[0] = 0;\n    ctx->total[1] = 0;\n\n    ctx->state[0] = 0x7380166F;\n    ctx->state[1] = 0x4914B2B9;\n    ctx->state[2] = 0x172442D7;\n    ctx->state[3] = 0xDA8A0600;\n    ctx->state[4] = 0xA96F30BC;\n    ctx->state[5] = 0x163138AA;\n    ctx->state[6] = 0xE38DEE4D;\n    ctx->state[7] = 0xB0FB0E4E;\n\n}\n\nstatic void sm3_process( sm3_context *ctx, unsigned char data[64] )\n{\n    unsigned long SS1, SS2, TT1, TT2, W[68],W1[64];\n    unsigned long A, B, C, D, E, F, G, H;\n\tunsigned long T[64];\n\tunsigned long Temp1,Temp2,Temp3,Temp4,Temp5;\n\tint j;\n#ifdef _DEBUG\n\tint i;\n#endif\n\n// \tfor(j=0; j < 68; j++)\n// \t\tW[j] = 0;\n// \tfor(j=0; j < 64; j++)\n// \t\tW1[j] = 0;\n\t\n\tfor(j = 0; j < 16; j++)\n\t\tT[j] = 0x79CC4519;\n\tfor(j =16; j < 64; j++)\n\t\tT[j] = 0x7A879D8A;\n\n    GET_ULONG_BE( W[ 0], data,  0 );\n    GET_ULONG_BE( W[ 1], data,  4 );\n    GET_ULONG_BE( W[ 2], data,  8 );\n    GET_ULONG_BE( W[ 3], data, 12 );\n    GET_ULONG_BE( W[ 4], data, 16 );\n    GET_ULONG_BE( W[ 5], data, 20 );\n    GET_ULONG_BE( W[ 6], data, 24 );\n    GET_ULONG_BE( W[ 7], data, 28 );\n    GET_ULONG_BE( W[ 8], data, 32 );\n    GET_ULONG_BE( W[ 9], data, 36 );\n    GET_ULONG_BE( W[10], data, 40 );\n    GET_ULONG_BE( W[11], data, 44 );\n    GET_ULONG_BE( W[12], data, 48 );\n    GET_ULONG_BE( W[13], data, 52 );\n    GET_ULONG_BE( W[14], data, 56 );\n    GET_ULONG_BE( W[15], data, 60 );\n\n#ifdef _DEBUG \n\tprintf(\"Message with padding:\\n\");\n\tfor(i=0; i< 8; i++)\n\t\tprintf(\"%08x \",W[i]);\n\tprintf(\"\\n\");\n\tfor(i=8; i< 16; i++)\n\t\tprintf(\"%08x \",W[i]);\n\tprintf(\"\\n\");\n#endif\n\n#define FF0(x,y,z) ( (x) ^ (y) ^ (z)) \n#define FF1(x,y,z) (((x) & (y)) | ( (x) & (z)) | ( (y) & (z)))\n\n#define GG0(x,y,z) ( (x) ^ (y) ^ (z)) \n#define GG1(x,y,z) (((x) & (y)) | ( (~(x)) & (z)) )\n\n\n#define  SHL(x,n) (((x) & 0xFFFFFFFF) << n)\n#define ROTL(x,n) (SHL((x),n) | ((x) >> (32 - n)))\n\n#define P0(x) ((x) ^  ROTL((x),9) ^ ROTL((x),17)) \n#define P1(x) ((x) ^  ROTL((x),15) ^ ROTL((x),23)) \n\n\tfor(j = 16; j < 68; j++ )\n\t{\n\t\t//W[j] = P1( W[j-16] ^ W[j-9] ^ ROTL(W[j-3],15)) ^ ROTL(W[j - 13],7 ) ^ W[j-6];\n\t\t//Why thd release's result is different with the debug's ?\n\t\t//Below is okay. Interesting, Perhaps VC6 has a bug of Optimizaiton.\n\t\t\n\t\tTemp1 = W[j-16] ^ W[j-9];\n\t\tTemp2 = ROTL(W[j-3],15);\n\t\tTemp3 = Temp1 ^ Temp2;\n\t\tTemp4 = P1(Temp3);\n\t\tTemp5 =  ROTL(W[j - 13],7 ) ^ W[j-6];\n\t\tW[j] = Temp4 ^ Temp5;\n\t}\n\n#ifdef _DEBUG \n\tprintf(\"Expanding message W0-67:\\n\");\n\tfor(i=0; i<68; i++)\n\t{\n\t\tprintf(\"%08x \",W[i]);\n\t\tif(((i+1) % 8) == 0) printf(\"\\n\");\n\t}\n\tprintf(\"\\n\");\n#endif\n\n\tfor(j =  0; j < 64; j++)\n\t{\n        W1[j] = W[j] ^ W[j+4];\n\t}\n\n#ifdef _DEBUG \n\tprintf(\"Expanding message W'0-63:\\n\");\n\tfor(i=0; i<64; i++)\n\t{\n\t\tprintf(\"%08x \",W1[i]);\n\t\tif(((i+1) % 8) == 0) printf(\"\\n\");\n\t}\n\tprintf(\"\\n\");\n#endif\n\n    A = ctx->state[0];\n    B = ctx->state[1];\n    C = ctx->state[2];\n    D = ctx->state[3];\n    E = ctx->state[4];\n    F = ctx->state[5];\n    G = ctx->state[6];\n    H = ctx->state[7];\n#ifdef _DEBUG       \n\tprintf(\"j     A       B        C         D         E        F        G       H\\n\");\n\tprintf(\"   %08x %08x %08x %08x %08x %08x %08x %08x\\n\",A,B,C,D,E,F,G,H);\n#endif\n\n\tfor(j =0; j < 16; j++)\n\t{\n\t\tSS1 = ROTL((ROTL(A,12) + E + ROTL(T[j],j)), 7); \n\t\tSS2 = SS1 ^ ROTL(A,12);\n\t\tTT1 = FF0(A,B,C) + D + SS2 + W1[j];\n\t\tTT2 = GG0(E,F,G) + H + SS1 + W[j];\n\t\tD = C;\n\t\tC = ROTL(B,9);\n\t\tB = A;\n\t\tA = TT1;\n\t\tH = G;\n\t\tG = ROTL(F,19);\n\t\tF = E;\n\t\tE = P0(TT2);\n#ifdef _DEBUG \n\t\tprintf(\"%02d %08x %08x %08x %08x %08x %08x %08x %08x\\n\",j,A,B,C,D,E,F,G,H);\n#endif\n\t}\n\t\n\tfor(j =16; j < 64; j++)\n\t{\n\t\tSS1 = ROTL((ROTL(A,12) + E + ROTL(T[j],j)), 7); \n\t\tSS2 = SS1 ^ ROTL(A,12);\n\t\tTT1 = FF1(A,B,C) + D + SS2 + W1[j];\n\t\tTT2 = GG1(E,F,G) + H + SS1 + W[j];\n\t\tD = C;\n\t\tC = ROTL(B,9);\n\t\tB = A;\n\t\tA = TT1;\n\t\tH = G;\n\t\tG = ROTL(F,19);\n\t\tF = E;\n\t\tE = P0(TT2);\n#ifdef _DEBUG \n\t\tprintf(\"%02d %08x %08x %08x %08x %08x %08x %08x %08x\\n\",j,A,B,C,D,E,F,G,H);\n#endif\t\n\t}\n\n    ctx->state[0] ^= A;\n    ctx->state[1] ^= B;\n    ctx->state[2] ^= C;\n    ctx->state[3] ^= D;\n    ctx->state[4] ^= E;\n    ctx->state[5] ^= F;\n    ctx->state[6] ^= G;\n    ctx->state[7] ^= H;\n#ifdef _DEBUG \n\t   printf(\"   %08x %08x %08x %08x %08x %08x %08x %08x\\n\",ctx->state[0],ctx->state[1],ctx->state[2],\n\t\t                          ctx->state[3],ctx->state[4],ctx->state[5],ctx->state[6],ctx->state[7]);\n#endif\n}\n\n/*\n * SM3 process buffer\n */\nvoid sm3_update( sm3_context *ctx, unsigned char *input, int ilen )\n{\n    int fill;\n    unsigned long left;\n\n    if( ilen <= 0 )\n        return;\n\n    left = ctx->total[0] & 0x3F;\n    fill = 64 - left;\n\n    ctx->total[0] += ilen;\n    ctx->total[0] &= 0xFFFFFFFF;\n\n    if( ctx->total[0] < (unsigned long) ilen )\n        ctx->total[1]++;\n\n    if( left && ilen >= fill )\n    {\n        memcpy( (void *) (ctx->buffer + left),\n                (void *) input, fill );\n        sm3_process( ctx, ctx->buffer );\n        input += fill;\n        ilen  -= fill;\n        left = 0;\n    }\n\n    while( ilen >= 64 )\n    {\n        sm3_process( ctx, input );\n        input += 64;\n        ilen  -= 64;\n    }\n\n    if( ilen > 0 )\n    {\n        memcpy( (void *) (ctx->buffer + left),\n                (void *) input, ilen );\n    }\n}\n\nstatic const unsigned char sm3_padding[64] =\n{\n 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n};\n\n/*\n * SM3 final digest\n */\nvoid sm3_finish( sm3_context *ctx, unsigned char output[32] )\n{\n    unsigned long last, padn;\n    unsigned long high, low;\n    unsigned char msglen[8];\n\n    high = ( ctx->total[0] >> 29 )\n         | ( ctx->total[1] <<  3 );\n    low  = ( ctx->total[0] <<  3 );\n\n    PUT_ULONG_BE( high, msglen, 0 );\n    PUT_ULONG_BE( low,  msglen, 4 );\n\n    last = ctx->total[0] & 0x3F;\n    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );\n\n    sm3_update( ctx, (unsigned char *) sm3_padding, padn );\n    sm3_update( ctx, msglen, 8 );\n\n    PUT_ULONG_BE( ctx->state[0], output,  0 );\n    PUT_ULONG_BE( ctx->state[1], output,  4 );\n    PUT_ULONG_BE( ctx->state[2], output,  8 );\n    PUT_ULONG_BE( ctx->state[3], output, 12 );\n    PUT_ULONG_BE( ctx->state[4], output, 16 );\n    PUT_ULONG_BE( ctx->state[5], output, 20 );\n    PUT_ULONG_BE( ctx->state[6], output, 24 );\n    PUT_ULONG_BE( ctx->state[7], output, 28 );\n}\n\n/*\n * output = SM3( input buffer )\n */\nvoid sm3( unsigned char *input, int ilen,\n           unsigned char output[32] )\n{\n    sm3_context ctx;\n\n    sm3_starts( &ctx );\n    sm3_update( &ctx, input, ilen );\n    sm3_finish( &ctx, output );\n\n    memset( &ctx, 0, sizeof( sm3_context ) );\n}\n\n/*\n * output = SM3( file contents )\n */\nint sm3_file( char *path, unsigned char output[32] )\n{\n    FILE *f;\n    size_t n;\n    sm3_context ctx;\n    unsigned char buf[1024];\n\n    if( ( f = fopen( path, \"rb\" ) ) == NULL )\n        return( 1 );\n\n    sm3_starts( &ctx );\n\n    while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )\n        sm3_update( &ctx, buf, (int) n );\n\n    sm3_finish( &ctx, output );\n\n    memset( &ctx, 0, sizeof( sm3_context ) );\n\n    if( ferror( f ) != 0 )\n    {\n        fclose( f );\n        return( 2 );\n    }\n\n    fclose( f );\n    return( 0 );\n}\n\n/*\n * SM3 HMAC context setup\n */\nvoid sm3_hmac_starts( sm3_context *ctx, unsigned char *key, int keylen )\n{\n    int i;\n    unsigned char sum[32];\n\n    if( keylen > 64 )\n    {\n        sm3( key, keylen, sum );\n        keylen = 32;\n\t\t//keylen = ( is224 ) ? 28 : 32;\n        key = sum;\n    }\n\n    memset( ctx->ipad, 0x36, 64 );\n    memset( ctx->opad, 0x5C, 64 );\n\n    for( i = 0; i < keylen; i++ )\n    {\n        ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );\n        ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );\n    }\n\n    sm3_starts( ctx);\n    sm3_update( ctx, ctx->ipad, 64 );\n\n    memset( sum, 0, sizeof( sum ) );\n}\n\n/*\n * SM3 HMAC process buffer\n */\nvoid sm3_hmac_update( sm3_context *ctx, unsigned char *input, int ilen )\n{\n    sm3_update( ctx, input, ilen );\n}\n\n/*\n * SM3 HMAC final digest\n */\nvoid sm3_hmac_finish( sm3_context *ctx, unsigned char output[32] )\n{\n    int hlen;\n    unsigned char tmpbuf[32];\n\n    //is224 = ctx->is224;\n    hlen =  32;\n\n    sm3_finish( ctx, tmpbuf );\n    sm3_starts( ctx );\n    sm3_update( ctx, ctx->opad, 64 );\n    sm3_update( ctx, tmpbuf, hlen );\n    sm3_finish( ctx, output );\n\n    memset( tmpbuf, 0, sizeof( tmpbuf ) );\n}\n\n/*\n * output = HMAC-SM#( hmac key, input buffer )\n */\nvoid sm3_hmac( unsigned char *key, int keylen,\n                unsigned char *input, int ilen,\n                unsigned char output[32] )\n{\n    sm3_context ctx;\n\n    sm3_hmac_starts( &ctx, key, keylen);\n    sm3_hmac_update( &ctx, input, ilen );\n    sm3_hmac_finish( &ctx, output );\n\n    memset( &ctx, 0, sizeof( sm3_context ) );\n}\n\n\n\n\n\n\n\n"
  },
  {
    "path": "C/SM2_SM3_SM4_C语言实现/SM3/sm3.h",
    "content": "/**\n * \\file sm3.h\n * thanks to Xyssl\n * SM3 standards:http://www.oscca.gov.cn/News/201012/News_1199.htm\n * author:goldboar\n * email:goldboar@163.com\n * 2011-10-26\n */\n#ifndef XYSSL_SM3_H\n#define XYSSL_SM3_H\n\n\n/**\n * \\brief          SM3 context structure\n */\ntypedef struct\n{\n    unsigned long total[2];     /*!< number of bytes processed  */\n    unsigned long state[8];     /*!< intermediate digest state  */\n    unsigned char buffer[64];   /*!< data block being processed */\n\n    unsigned char ipad[64];     /*!< HMAC: inner padding        */\n    unsigned char opad[64];     /*!< HMAC: outer padding        */\n\n}\nsm3_context;\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * \\brief          SM3 context setup\n *\n * \\param ctx      context to be initialized\n */\nvoid sm3_starts( sm3_context *ctx );\n\n/**\n * \\brief          SM3 process buffer\n *\n * \\param ctx      SM3 context\n * \\param input    buffer holding the  data\n * \\param ilen     length of the input data\n */\nvoid sm3_update( sm3_context *ctx, unsigned char *input, int ilen );\n\n/**\n * \\brief          SM3 final digest\n *\n * \\param ctx      SM3 context\n */\nvoid sm3_finish( sm3_context *ctx, unsigned char output[32] );\n\n/**\n * \\brief          Output = SM3( input buffer )\n *\n * \\param input    buffer holding the  data\n * \\param ilen     length of the input data\n * \\param output   SM3 checksum result\n */\nvoid sm3( unsigned char *input, int ilen,\n           unsigned char output[32]);\n\n/**\n * \\brief          Output = SM3( file contents )\n *\n * \\param path     input file name\n * \\param output   SM3 checksum result\n *\n * \\return         0 if successful, 1 if fopen failed,\n *                 or 2 if fread failed\n */\nint sm3_file( char *path, unsigned char output[32] );\n\n/**\n * \\brief          SM3 HMAC context setup\n *\n * \\param ctx      HMAC context to be initialized\n * \\param key      HMAC secret key\n * \\param keylen   length of the HMAC key\n */\nvoid sm3_hmac_starts( sm3_context *ctx, unsigned char *key, int keylen);\n\n/**\n * \\brief          SM3 HMAC process buffer\n *\n * \\param ctx      HMAC context\n * \\param input    buffer holding the  data\n * \\param ilen     length of the input data\n */\nvoid sm3_hmac_update( sm3_context *ctx, unsigned char *input, int ilen );\n\n/**\n * \\brief          SM3 HMAC final digest\n *\n * \\param ctx      HMAC context\n * \\param output   SM3 HMAC checksum result\n */\nvoid sm3_hmac_finish( sm3_context *ctx, unsigned char output[32] );\n\n/**\n * \\brief          Output = HMAC-SM3( hmac key, input buffer )\n *\n * \\param key      HMAC secret key\n * \\param keylen   length of the HMAC key\n * \\param input    buffer holding the  data\n * \\param ilen     length of the input data\n * \\param output   HMAC-SM3 result\n */\nvoid sm3_hmac( unsigned char *key, int keylen,\n                unsigned char *input, int ilen,\n                unsigned char output[32] );\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* sm3.h */\n"
  },
  {
    "path": "C/SM2_SM3_SM4_C语言实现/SM3/sm3test.c",
    "content": "\n#include <string.h>\n#include <stdio.h>\n#include \"sm3.h\"\n\nint main( int argc, char *argv[] )\n{\n\tunsigned char *input = \"abc\";\n\tint ilen = 3;\n\tunsigned char output[32];\n\tint i;\n\tsm3_context ctx;\n\n\tprintf(\"Message:\\n\");\n\tprintf(\"%s\\n\",input);\n\n\tsm3(input, ilen, output);\n\tprintf(\"Hash:\\n   \");\n\tfor(i=0; i<32; i++)\n\t{\n\t\tprintf(\"%02x\",output[i]);\n\t\tif (((i+1) % 4 ) == 0) printf(\" \");\n\t} \n\tprintf(\"\\n\");\n\n\tprintf(\"Message:\\n\");\n\tfor(i=0; i < 16; i++)\n\t\tprintf(\"abcd\");\n\tprintf(\"\\n\");\n\n    sm3_starts( &ctx );\n\tfor(i=0; i < 16; i++)\n\t\tsm3_update( &ctx, \"abcd\", 4 );\n    sm3_finish( &ctx, output );\n    memset( &ctx, 0, sizeof( sm3_context ) );\n\t\n\tprintf(\"Hash:\\n   \");\n\tfor(i=0; i<32; i++)\n\t{\n\t\tprintf(\"%02x\",output[i]);\n\t\tif (((i+1) % 4 ) == 0) printf(\" \");\n\t}   \n\tprintf(\"\\n\");\n    //getch();\t//VS2008 \n}"
  },
  {
    "path": "C/SM2_SM3_SM4_C语言实现/SM3/sm3test.dsp",
    "content": "# Microsoft Developer Studio Project File - Name=\"sm3test\" - Package Owner=<4>\n# Microsoft Developer Studio Generated Build File, Format Version 6.00\n# ** DO NOT EDIT **\n\n# TARGTYPE \"Win32 (x86) Console Application\" 0x0103\n\nCFG=sm3test - Win32 Debug\n!MESSAGE This is not a valid makefile. To build this project using NMAKE,\n!MESSAGE use the Export Makefile command and run\n!MESSAGE \n!MESSAGE NMAKE /f \"sm3test.mak\".\n!MESSAGE \n!MESSAGE You can specify a configuration when running NMAKE\n!MESSAGE by defining the macro CFG on the command line. For example:\n!MESSAGE \n!MESSAGE NMAKE /f \"sm3test.mak\" CFG=\"sm3test - Win32 Debug\"\n!MESSAGE \n!MESSAGE Possible choices for configuration are:\n!MESSAGE \n!MESSAGE \"sm3test - Win32 Release\" (based on \"Win32 (x86) Console Application\")\n!MESSAGE \"sm3test - Win32 Debug\" (based on \"Win32 (x86) Console Application\")\n!MESSAGE \n\n# Begin Project\n# PROP AllowPerConfigDependencies 0\n# PROP Scc_ProjName \"\"\n# PROP Scc_LocalPath \"\"\nCPP=cl.exe\nRSC=rc.exe\n\n!IF  \"$(CFG)\" == \"sm3test - Win32 Release\"\n\n# PROP BASE Use_MFC 0\n# PROP BASE Use_Debug_Libraries 0\n# PROP BASE Output_Dir \"Release\"\n# PROP BASE Intermediate_Dir \"Release\"\n# PROP BASE Target_Dir \"\"\n# PROP Use_MFC 0\n# PROP Use_Debug_Libraries 0\n# PROP Output_Dir \"Release\"\n# PROP Intermediate_Dir \"Release\"\n# PROP Ignore_Export_Lib 0\n# PROP Target_Dir \"\"\n# ADD BASE CPP /nologo /W3 /GX /O2 /D \"WIN32\" /D \"NDEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /YX /FD /c\n# ADD CPP /nologo /W3 /GX /O2 /D \"WIN32\" /D \"NDEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /YX /FD /c\n# ADD BASE RSC /l 0x804 /d \"NDEBUG\"\n# ADD RSC /l 0x804 /d \"NDEBUG\"\nBSC32=bscmake.exe\n# ADD BASE BSC32 /nologo\n# ADD BSC32 /nologo\nLINK32=link.exe\n# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\n# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\n# SUBTRACT LINK32 /debug\n\n!ELSEIF  \"$(CFG)\" == \"sm3test - Win32 Debug\"\n\n# PROP BASE Use_MFC 0\n# PROP BASE Use_Debug_Libraries 1\n# PROP BASE Output_Dir \"Debug\"\n# PROP BASE Intermediate_Dir \"Debug\"\n# PROP BASE Target_Dir \"\"\n# PROP Use_MFC 0\n# PROP Use_Debug_Libraries 1\n# PROP Output_Dir \"Debug\"\n# PROP Intermediate_Dir \"Debug\"\n# PROP Target_Dir \"\"\n# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /YX /FD /GZ /c\n# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /YX /FD /GZ /c\n# ADD BASE RSC /l 0x804 /d \"_DEBUG\"\n# ADD RSC /l 0x804 /d \"_DEBUG\"\nBSC32=bscmake.exe\n# ADD BASE BSC32 /nologo\n# ADD BSC32 /nologo\nLINK32=link.exe\n# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\n# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\n\n!ENDIF \n\n# Begin Target\n\n# Name \"sm3test - Win32 Release\"\n# Name \"sm3test - Win32 Debug\"\n# Begin Source File\n\nSOURCE=.\\sm3.c\n# End Source File\n# Begin Source File\n\nSOURCE=.\\sm3.h\n# End Source File\n# Begin Source File\n\nSOURCE=.\\sm3test.c\n# End Source File\n# End Target\n# End Project\n"
  },
  {
    "path": "C/SM2_SM3_SM4_C语言实现/SM3/sm3test.dsw",
    "content": "Microsoft Developer Studio Workspace File, Format Version 6.00\n# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\n\n###############################################################################\n\nProject: \"sm3test\"=\".\\sm3test.dsp\" - Package Owner=<4>\n\nPackage=<5>\n{{{\n}}}\n\nPackage=<4>\n{{{\n}}}\n\n###############################################################################\n\nGlobal:\n\nPackage=<5>\n{{{\n}}}\n\nPackage=<3>\n{{{\n}}}\n\n###############################################################################\n\n"
  },
  {
    "path": "C/SM2_SM3_SM4_C语言实现/SM4/sm4.c",
    "content": "/*\n * SM4 Encryption alogrithm (SMS4 algorithm)\n * GM/T 0002-2012 Chinese National Standard ref:http://www.oscca.gov.cn/ \n * thanks to Xyssl\n * thnaks and refers to http://hi.baidu.com/numax/blog/item/80addfefddfb93e4cf1b3e61.html\n * author:goldboar\n * email:goldboar@163.com\n * 2012-4-20\n */\n\n// Test vector 1\n// plain: 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10\n// key:   01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10\n// \t   round key and temp computing result:\n//     rk[ 0] = f12186f9 X[ 0] = 27fad345\n//     rk[ 1] = 41662b61 X[ 1] = a18b4cb2\n//     rk[ 2] = 5a6ab19a X[ 2] = 11c1e22a\n//     rk[ 3] = 7ba92077 X[ 3] = cc13e2ee\n//     rk[ 4] = 367360f4 X[ 4] = f87c5bd5\n//     rk[ 5] = 776a0c61 X[ 5] = 33220757\n//     rk[ 6] = b6bb89b3 X[ 6] = 77f4c297\n//     rk[ 7] = 24763151 X[ 7] = 7a96f2eb\n//     rk[ 8] = a520307c X[ 8] = 27dac07f\n//     rk[ 9] = b7584dbd X[ 9] = 42dd0f19\n//     rk[10] = c30753ed X[10] = b8a5da02\n//     rk[11] = 7ee55b57 X[11] = 907127fa\n//     rk[12] = 6988608c X[12] = 8b952b83\n//     rk[13] = 30d895b7 X[13] = d42b7c59\n//     rk[14] = 44ba14af X[14] = 2ffc5831\n//     rk[15] = 104495a1 X[15] = f69e6888\n//     rk[16] = d120b428 X[16] = af2432c4\n//     rk[17] = 73b55fa3 X[17] = ed1ec85e\n//     rk[18] = cc874966 X[18] = 55a3ba22\n//     rk[19] = 92244439 X[19] = 124b18aa\n//     rk[20] = e89e641f X[20] = 6ae7725f\n//     rk[21] = 98ca015a X[21] = f4cba1f9\n//     rk[22] = c7159060 X[22] = 1dcdfa10\n//     rk[23] = 99e1fd2e X[23] = 2ff60603\n//     rk[24] = b79bd80c X[24] = eff24fdc\n//     rk[25] = 1d2115b0 X[25] = 6fe46b75\n//     rk[26] = 0e228aeb X[26] = 893450ad\n//     rk[27] = f1780c81 X[27] = 7b938f4c\n//     rk[28] = 428d3654 X[28] = 536e4246\n//     rk[29] = 62293496 X[29] = 86b3e94f\n//     rk[30] = 01cf72e5 X[30] = d206965e\n//     rk[31] = 9124a012 X[31] = 681edf34\n// cypher: 68 1e df 34 d2 06 96 5e 86 b3 e9 4f 53 6e 42 46\n// \t\t\n// test vector 2\n// the same key and plain 1000000 times coumpting \n// plain:  01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10\n// key:    01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10\n// cypher: 59 52 98 c7 c6 fd 27 1f 04 02 f8 04 c3 3d 3f 66\n\n#include \"sm4.h\"\n#include <string.h>\n#include <stdio.h>\n\n/*\n * 32-bit integer manipulation macros (big endian)\n */\n#ifndef GET_ULONG_BE\n#define GET_ULONG_BE(n,b,i)                             \\\n{                                                       \\\n    (n) = ( (unsigned long) (b)[(i)    ] << 24 )        \\\n        | ( (unsigned long) (b)[(i) + 1] << 16 )        \\\n        | ( (unsigned long) (b)[(i) + 2] <<  8 )        \\\n        | ( (unsigned long) (b)[(i) + 3]       );       \\\n}\n#endif\n\n#ifndef PUT_ULONG_BE\n#define PUT_ULONG_BE(n,b,i)                             \\\n{                                                       \\\n    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \\\n    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \\\n    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \\\n    (b)[(i) + 3] = (unsigned char) ( (n)       );       \\\n}\n#endif\n\n/*\n *rotate shift left marco definition\n *\n */\n#define  SHL(x,n) (((x) & 0xFFFFFFFF) << n)\n#define ROTL(x,n) (SHL((x),n) | ((x) >> (32 - n)))\n\n#define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; }\n\n/*\n * Expanded SM4 S-boxes\n /* Sbox table: 8bits input convert to 8 bits output*/\n \nstatic const unsigned char SboxTable[16][16] = \n{\n{0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05},\n{0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99},\n{0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62},\n{0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6},\n{0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8},\n{0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35},\n{0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87},\n{0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e},\n{0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1},\n{0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3},\n{0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f},\n{0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51},\n{0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8},\n{0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0},\n{0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84},\n{0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48}\n};\n\n/* System parameter */\nstatic const unsigned long FK[4] = {0xa3b1bac6,0x56aa3350,0x677d9197,0xb27022dc};\n\n/* fixed parameter */\nstatic const unsigned long CK[32] =\n{\n0x00070e15,0x1c232a31,0x383f464d,0x545b6269,\n0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9,\n0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249,\n0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9,\n0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229,\n0x30373e45,0x4c535a61,0x686f767d,0x848b9299,\n0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209,\n0x10171e25,0x2c333a41,0x484f565d,0x646b7279\n};\n\n\n/*\n * private function:\n * look up in SboxTable and get the related value.\n * args:    [in] inch: 0x00~0xFF (8 bits unsigned value).\n */\nstatic unsigned char sm4Sbox(unsigned char inch)\n{\n    unsigned char *pTable = (unsigned char *)SboxTable;\n    unsigned char retVal = (unsigned char)(pTable[inch]);\n    return retVal;\n}\n\n/*\n * private F(Lt) function:\n * \"T algorithm\" == \"L algorithm\" + \"t algorithm\".\n * args:    [in] a: a is a 32 bits unsigned value;\n * return: c: c is calculated with line algorithm \"L\" and nonline algorithm \"t\"\n */\nstatic unsigned long sm4Lt(unsigned long ka)\n{\n    unsigned long bb = 0;\n    unsigned long c = 0;\n    unsigned char a[4];\n\tunsigned char b[4];\n    PUT_ULONG_BE(ka,a,0)\n    b[0] = sm4Sbox(a[0]);\n    b[1] = sm4Sbox(a[1]);\n    b[2] = sm4Sbox(a[2]);\n    b[3] = sm4Sbox(a[3]);\n\tGET_ULONG_BE(bb,b,0)\n    c =bb^(ROTL(bb, 2))^(ROTL(bb, 10))^(ROTL(bb, 18))^(ROTL(bb, 24));\n    return c;\n}\n\n/*\n * private F function:\n * Calculating and getting encryption/decryption contents.\n * args:    [in] x0: original contents;\n * args:    [in] x1: original contents;\n * args:    [in] x2: original contents;\n * args:    [in] x3: original contents;\n * args:    [in] rk: encryption/decryption key;\n * return the contents of encryption/decryption contents.\n */\nstatic unsigned long sm4F(unsigned long x0, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long rk)\n{\n    return (x0^sm4Lt(x1^x2^x3^rk));\n}\n\n\n/* private function:\n * Calculating round encryption key.\n * args:    [in] a: a is a 32 bits unsigned value;\n * return: sk[i]: i{0,1,2,3,...31}.\n */\nstatic unsigned long sm4CalciRK(unsigned long ka)\n{\n    unsigned long bb = 0;\n    unsigned long rk = 0;\n    unsigned char a[4];\n    unsigned char b[4];\n    PUT_ULONG_BE(ka,a,0)\n    b[0] = sm4Sbox(a[0]);\n    b[1] = sm4Sbox(a[1]);\n    b[2] = sm4Sbox(a[2]);\n    b[3] = sm4Sbox(a[3]);\n\tGET_ULONG_BE(bb,b,0)\n    rk = bb^(ROTL(bb, 13))^(ROTL(bb, 23));\n    return rk;\n}\n\nstatic void sm4_setkey( unsigned long SK[32], unsigned char key[16] )\n{\n    unsigned long MK[4];\n    unsigned long k[36];\n    unsigned long i = 0;\n\n    GET_ULONG_BE( MK[0], key, 0 );\n    GET_ULONG_BE( MK[1], key, 4 );\n    GET_ULONG_BE( MK[2], key, 8 );\n    GET_ULONG_BE( MK[3], key, 12 );\n    k[0] = MK[0]^FK[0];\n    k[1] = MK[1]^FK[1];\n    k[2] = MK[2]^FK[2];\n    k[3] = MK[3]^FK[3];\n    for(; i<32; i++)\n    {\n        k[i+4] = k[i] ^ (sm4CalciRK(k[i+1]^k[i+2]^k[i+3]^CK[i]));\n        SK[i] = k[i+4];\n\t}\n\n}\n\n/*\n * SM4 standard one round processing\n *\n */\nstatic void sm4_one_round( unsigned long sk[32],\n                    unsigned char input[16],\n                    unsigned char output[16] )\n{\n    unsigned long i = 0;\n    unsigned long ulbuf[36];\n\n    memset(ulbuf, 0, sizeof(ulbuf));\n    GET_ULONG_BE( ulbuf[0], input, 0 )\n    GET_ULONG_BE( ulbuf[1], input, 4 )\n    GET_ULONG_BE( ulbuf[2], input, 8 )\n    GET_ULONG_BE( ulbuf[3], input, 12 )\n    while(i<32)\n    {\n        ulbuf[i+4] = sm4F(ulbuf[i], ulbuf[i+1], ulbuf[i+2], ulbuf[i+3], sk[i]);\n// #ifdef _DEBUG\n//        \tprintf(\"rk(%02d) = 0x%08x,  X(%02d) = 0x%08x \\n\",i,sk[i], i, ulbuf[i+4] );\n// #endif\n\t    i++;\n    }\n\tPUT_ULONG_BE(ulbuf[35],output,0);\n\tPUT_ULONG_BE(ulbuf[34],output,4);\n\tPUT_ULONG_BE(ulbuf[33],output,8);\n\tPUT_ULONG_BE(ulbuf[32],output,12);\n}\n\n/*\n * SM4 key schedule (128-bit, encryption)\n */\nvoid sm4_setkey_enc( sm4_context *ctx, unsigned char key[16] )\n{\n    ctx->mode = SM4_ENCRYPT;\n\tsm4_setkey( ctx->sk, key );\n}\n\n/*\n * SM4 key schedule (128-bit, decryption)\n */\nvoid sm4_setkey_dec( sm4_context *ctx, unsigned char key[16] )\n{\n    int i;\n\tctx->mode = SM4_ENCRYPT;\n    sm4_setkey( ctx->sk, key );\n    for( i = 0; i < 16; i ++ )\n    {\n        SWAP( ctx->sk[ i ], ctx->sk[ 31-i] );\n    }\n}\n\n\n/*\n * SM4-ECB block encryption/decryption\n */\n\nvoid sm4_crypt_ecb( sm4_context *ctx,\n\t\t\t\t   int mode,\n\t\t\t\t   int length,\n\t\t\t\t   unsigned char *input,\n                   unsigned char *output)\n{\n    while( length > 0 )\n    {\n        sm4_one_round( ctx->sk, input, output );\n        input  += 16;\n        output += 16;\n        length -= 16;\n    }\n\n}\n\n/*\n * SM4-CBC buffer encryption/decryption\n */\nvoid sm4_crypt_cbc( sm4_context *ctx,\n                    int mode,\n                    int length,\n                    unsigned char iv[16],\n                    unsigned char *input,\n                    unsigned char *output )\n{\n    int i;\n    unsigned char temp[16];\n\n    if( mode == SM4_ENCRYPT )\n    {\n        while( length > 0 )\n        {\n            for( i = 0; i < 16; i++ )\n                output[i] = (unsigned char)( input[i] ^ iv[i] );\n\n            sm4_one_round( ctx->sk, output, output );\n            memcpy( iv, output, 16 );\n\n            input  += 16;\n            output += 16;\n            length -= 16;\n        }\n    }\n    else /* SM4_DECRYPT */\n    {\n        while( length > 0 )\n        {\n            memcpy( temp, input, 16 );\n            sm4_one_round( ctx->sk, input, output );\n\n            for( i = 0; i < 16; i++ )\n                output[i] = (unsigned char)( output[i] ^ iv[i] );\n\n            memcpy( iv, temp, 16 );\n\n            input  += 16;\n            output += 16;\n            length -= 16;\n        }\n    }\n}\n"
  },
  {
    "path": "C/SM2_SM3_SM4_C语言实现/SM4/sm4.dsp",
    "content": "# Microsoft Developer Studio Project File - Name=\"sm4\" - Package Owner=<4>\n# Microsoft Developer Studio Generated Build File, Format Version 6.00\n# ** DO NOT EDIT **\n\n# TARGTYPE \"Win32 (x86) Console Application\" 0x0103\n\nCFG=sm4 - Win32 Debug\n!MESSAGE This is not a valid makefile. To build this project using NMAKE,\n!MESSAGE use the Export Makefile command and run\n!MESSAGE \n!MESSAGE NMAKE /f \"sm4.mak\".\n!MESSAGE \n!MESSAGE You can specify a configuration when running NMAKE\n!MESSAGE by defining the macro CFG on the command line. For example:\n!MESSAGE \n!MESSAGE NMAKE /f \"sm4.mak\" CFG=\"sm4 - Win32 Debug\"\n!MESSAGE \n!MESSAGE Possible choices for configuration are:\n!MESSAGE \n!MESSAGE \"sm4 - Win32 Release\" (based on \"Win32 (x86) Console Application\")\n!MESSAGE \"sm4 - Win32 Debug\" (based on \"Win32 (x86) Console Application\")\n!MESSAGE \n\n# Begin Project\n# PROP AllowPerConfigDependencies 0\n# PROP Scc_ProjName \"\"\n# PROP Scc_LocalPath \"\"\nCPP=cl.exe\nRSC=rc.exe\n\n!IF  \"$(CFG)\" == \"sm4 - Win32 Release\"\n\n# PROP BASE Use_MFC 0\n# PROP BASE Use_Debug_Libraries 0\n# PROP BASE Output_Dir \"Release\"\n# PROP BASE Intermediate_Dir \"Release\"\n# PROP BASE Target_Dir \"\"\n# PROP Use_MFC 0\n# PROP Use_Debug_Libraries 0\n# PROP Output_Dir \"Release\"\n# PROP Intermediate_Dir \"Release\"\n# PROP Target_Dir \"\"\n# ADD BASE CPP /nologo /W3 /GX /O2 /D \"WIN32\" /D \"NDEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /YX /FD /c\n# ADD CPP /nologo /W3 /GX /O2 /D \"WIN32\" /D \"NDEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /YX /FD /c\n# ADD BASE RSC /l 0x804 /d \"NDEBUG\"\n# ADD RSC /l 0x804 /d \"NDEBUG\"\nBSC32=bscmake.exe\n# ADD BASE BSC32 /nologo\n# ADD BSC32 /nologo\nLINK32=link.exe\n# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\n# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386\n\n!ELSEIF  \"$(CFG)\" == \"sm4 - Win32 Debug\"\n\n# PROP BASE Use_MFC 0\n# PROP BASE Use_Debug_Libraries 1\n# PROP BASE Output_Dir \"Debug\"\n# PROP BASE Intermediate_Dir \"Debug\"\n# PROP BASE Target_Dir \"\"\n# PROP Use_MFC 0\n# PROP Use_Debug_Libraries 1\n# PROP Output_Dir \"Debug\"\n# PROP Intermediate_Dir \"Debug\"\n# PROP Target_Dir \"\"\n# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /YX /FD /GZ /c\n# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /YX /FD /GZ /c\n# ADD BASE RSC /l 0x804 /d \"_DEBUG\"\n# ADD RSC /l 0x804 /d \"_DEBUG\"\nBSC32=bscmake.exe\n# ADD BASE BSC32 /nologo\n# ADD BSC32 /nologo\nLINK32=link.exe\n# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\n# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept\n\n!ENDIF \n\n# Begin Target\n\n# Name \"sm4 - Win32 Release\"\n# Name \"sm4 - Win32 Debug\"\n# Begin Source File\n\nSOURCE=.\\sm4.c\n# End Source File\n# Begin Source File\n\nSOURCE=.\\sm4.h\n# End Source File\n# Begin Source File\n\nSOURCE=.\\sm4test.c\n# End Source File\n# End Target\n# End Project\n"
  },
  {
    "path": "C/SM2_SM3_SM4_C语言实现/SM4/sm4.dsw",
    "content": "Microsoft Developer Studio Workspace File, Format Version 6.00\n# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\n\n###############################################################################\n\nProject: \"sm4\"=.\\sm4.dsp - Package Owner=<4>\n\nPackage=<5>\n{{{\n}}}\n\nPackage=<4>\n{{{\n}}}\n\n###############################################################################\n\nGlobal:\n\nPackage=<5>\n{{{\n}}}\n\nPackage=<3>\n{{{\n}}}\n\n###############################################################################\n\n"
  },
  {
    "path": "C/SM2_SM3_SM4_C语言实现/SM4/sm4.h",
    "content": "/**\n * \\file sm4.h\n */\n#ifndef XYSSL_SM4_H\n#define XYSSL_SM4_H\n\n#define SM4_ENCRYPT     1\n#define SM4_DECRYPT     0\n\n/**\n * \\brief          SM4 context structure\n */\ntypedef struct\n{\n    int mode;                   /*!<  encrypt/decrypt   */\n    unsigned long sk[32];       /*!<  SM4 subkeys       */\n}\nsm4_context;\n\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * \\brief          SM4 key schedule (128-bit, encryption)\n *\n * \\param ctx      SM4 context to be initialized\n * \\param key      16-byte secret key\n */\nvoid sm4_setkey_enc( sm4_context *ctx, unsigned char key[16] );\n\n/**\n * \\brief          SM4 key schedule (128-bit, decryption)\n *\n * \\param ctx      SM4 context to be initialized\n * \\param key      16-byte secret key\n */\nvoid sm4_setkey_dec( sm4_context *ctx, unsigned char key[16] );\n\n/**\n * \\brief          SM4-ECB block encryption/decryption\n * \\param ctx      SM4 context\n * \\param mode     SM4_ENCRYPT or SM4_DECRYPT\n * \\param length   length of the input data\n * \\param input    input block\n * \\param output   output block\n */\nvoid sm4_crypt_ecb( sm4_context *ctx,\n\t\t\t\t     int mode,\n\t\t\t\t\t int length,\n                     unsigned char *input,\n                     unsigned char *output);\n\n/**\n * \\brief          SM4-CBC buffer encryption/decryption\n * \\param ctx      SM4 context\n * \\param mode     SM4_ENCRYPT or SM4_DECRYPT\n * \\param length   length of the input data\n * \\param iv       initialization vector (updated after use)\n * \\param input    buffer holding the input data\n * \\param output   buffer holding the output data\n */\nvoid sm4_crypt_cbc( sm4_context *ctx,\n                     int mode,\n                     int length,\n                     unsigned char iv[16],\n                     unsigned char *input,\n                     unsigned char *output );\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* sm4.h */\n"
  },
  {
    "path": "C/SM2_SM3_SM4_C语言实现/SM4/sm4test.c",
    "content": "/*\n * SM4/SMS4 algorithm test programme\n * 2012-4-21\n */\n\n#include <string.h>\n#include <stdio.h>\n#include \"sm4.h\"\n\nint main()\n{\n\tunsigned char key[16] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};\n\tunsigned char input[16] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};\n\tunsigned char output[16];\n\tsm4_context ctx;\n\tunsigned long i;\n\n\t//encrypt standard testing vector\n\tsm4_setkey_enc(&ctx,key);\n\tsm4_crypt_ecb(&ctx,1,16,input,output);\n\tfor(i=0;i<16;i++)\n\t\tprintf(\"%02x \", output[i]);\n\tprintf(\"\\n\");\n\n\t//decrypt testing\n\tsm4_setkey_dec(&ctx,key);\n\tsm4_crypt_ecb(&ctx,0,16,output,output);\n\tfor(i=0;i<16;i++)\n\t\tprintf(\"%02x \", output[i]);\n\tprintf(\"\\n\");\n\n\t//decrypt 1M times testing vector based on standards.\n\ti = 0;\n\tsm4_setkey_enc(&ctx,key);\n\twhile (i<1000000) \n    {\n\t\tsm4_crypt_ecb(&ctx,1,16,input,input);\n\t\ti++;\n    }\n\tfor(i=0;i<16;i++)\n\t\tprintf(\"%02x \", input[i]);\n\tprintf(\"\\n\");\n\t\n    return 0;\n}\n"
  },
  {
    "path": "C/SM2_SM3_SM4_C语言实现/SM4/sms4.c",
    "content": "/* sms4.c\n** SMS4 Encryption algorithm for wireless networks\n**\n** $Id: sms4.c 2009-12-31 14:41:57 tao.tang <$\">emhmily@gmail.com>$\n**\n**\n** This program is free software; you can redistribute it and/or\n** modify it under the terms of the GNU General Public License\n** as published by the Free Software Foundation; either version 2\n** of the License, or (at your option) any later version.\n**\n** This program is distributed in the hope that it will be useful,\n** but WITHOUT ANY WARRANTY; without even the implied warranty of\n** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n** GNU General Public License for more details.\n**\n** You should have received a copy of the GNU General Public License\n** along with this program; if not, write to the Free Software\n** Foundation, Inc.\n**/\n\n#include <string.h>\n#include <stdio.h>\n/*#include \"sms4.h\"*/\n\n#ifndef unlong\ntypedef unsigned long unlong;\n#endif /* unlong */\n\n#ifndef unchar\ntypedef unsigned char unchar;\n#endif /* unchar */\n\n/* define SMS4CROL for rotating left */\n#define SMS4CROL(uval, bits) ((uval << bits) | (uval >> (0x20 - bits)))\n\n/* define MASK code for selecting expected bits from a 32 bits value */\n#define SMS4MASK3 0xFF000000\n#define SMS4MASK2 0x00FF0000\n#define SMS4MASK1 0x0000FF00\n#define SMS4MASK0 0x000000FF\n\n/* Sbox table: 8bits input convert to 8 bits output*/\nstatic unchar SboxTable[16][16] = \n{\n{0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05},\n{0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99},\n{0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62},\n{0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6},\n{0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8},\n{0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35},\n{0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87},\n{0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e},\n{0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1},\n{0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3},\n{0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f},\n{0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51},\n{0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8},\n{0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0},\n{0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84},\n{0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48}\n};\n\n/* Encryption key: 128bits */\nstatic unlong MK[4] = {0x01234567,0x89abcdef,0xfedcba98,0x76543210};\n\n/* System parameter */\nstatic unlong FK[4] = {0xa3b1bac6,0x56aa3350,0x677d9197,0xb27022dc};\n\n/* fixed parameter */\nstatic unlong CK[32] =\n{\n0x00070e15,0x1c232a31,0x383f464d,0x545b6269,\n0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9,\n0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249,\n0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9,\n0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229,\n0x30373e45,0x4c535a61,0x686f767d,0x848b9299,\n0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209,\n0x10171e25,0x2c333a41,0x484f565d,0x646b7279\n};\n\n/* buffer for round encryption key */\nstatic unlong ENRK[32];\nstatic unlong DERK[32];\n\n/* original contents for debugging */\nunlong pData[4] = \n{\n0x01234567,\n0x89abcdef,\n0xfedcba98,\n0x76543210\n};\n\n/* original contents for debugging */\nunlong pData2[9] = \n{\n0x01234567,\n0x89abcdef,\n0xfedcba98,\n0x76543210,\n0x12121212,\n0x34343434,\n0x56565656,\n0x78787878,\n0x12341234\n};\n\n/*=============================================================================\n** private function:\n**   look up in SboxTable and get the related value.\n** args:    [in] inch: 0x00~0xFF (8 bits unsigned value).\n**============================================================================*/\nstatic unchar SMS4Sbox(unchar inch)\n{\n    unchar *pTable = (unchar *)SboxTable;\n    unchar retVal = (unchar)(pTable[inch]);\n\n    return retVal;\n}\n\n/*=============================================================================\n** private function:\n**   \"T algorithm\" == \"L algorithm\" + \"t algorithm\".\n** args:    [in] a: a is a 32 bits unsigned value;\n** return: c: c is calculated with line algorithm \"L\" and nonline algorithm \"t\"\n**============================================================================*/\nstatic unlong SMS4Lt(unlong a)\n{\n    unlong b = 0;\n    unlong c = 0;\n    unchar a0 = (unchar)(a & SMS4MASK0);\n    unchar a1 = (unchar)((a & SMS4MASK1) >> 8);\n    unchar a2 = (unchar)((a & SMS4MASK2) >> 16);\n    unchar a3 = (unchar)((a & SMS4MASK3) >> 24);\n    unchar b0 = SMS4Sbox(a0);\n    unchar b1 = SMS4Sbox(a1);\n    unchar b2 = SMS4Sbox(a2);\n    unchar b3 = SMS4Sbox(a3);\n\n    b =b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);\n    c =b^(SMS4CROL(b, 2))^(SMS4CROL(b, 10))^(SMS4CROL(b, 18))^(SMS4CROL(b, 24));\n\n    return c;\n}\n\n/*=============================================================================\n** private function:\n**   Calculating round encryption key.\n** args:    [in] a: a is a 32 bits unsigned value;\n** return: ENRK[i]: i{0,1,2,3,...31}.\n**============================================================================*/\nstatic unlong SMS4CalciRK(unlong a)\n{\n    unlong b = 0;\n    unlong rk = 0;\n    unchar a0 = (unchar)(a & SMS4MASK0);\n    unchar a1 = (unchar)((a & SMS4MASK1) >> 8);\n    unchar a2 = (unchar)((a & SMS4MASK2) >> 16);\n    unchar a3 = (unchar)((a & SMS4MASK3) >> 24);\n    unchar b0 = SMS4Sbox(a0);\n    unchar b1 = SMS4Sbox(a1);\n    unchar b2 = SMS4Sbox(a2);\n    unchar b3 = SMS4Sbox(a3);\n\n    b = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24);\n    rk = b^(SMS4CROL(b, 13))^(SMS4CROL(b, 23));\n\n    return rk;\n}\n\n/*=============================================================================\n** private function:\n**   Calculating round encryption key.\n** args:    [in] ulflag: if 0: not calculate DERK , else calculate;\n** return: NONE.\n**============================================================================*/\nstatic void SMS4CalcRK(unlong ulflag)\n{\n    unlong k[36];\n    unlong i = 0;\n\n    k[0] = MK[0]^FK[0];\n    k[1] = MK[1]^FK[1];\n    k[2] = MK[2]^FK[2];\n    k[3] = MK[3]^FK[3];\n\n    for(; i<32; i++)\n    {\n        k[i+4] = k[i] ^ (SMS4CalciRK(k[i+1]^k[i+2]^k[i+3]^CK[i]));\n        ENRK[i] = k[i+4];\n    }\n\n    if (ulflag != 0x00) \n    {\n        for (i=0; i<32; i++) \n        {\n            DERK[i] = ENRK[31-i];\n        }\n    }\n}\n\n/*=============================================================================\n** private function:\n**   \"T algorithm\" == \"L algorithm\" + \"t algorithm\".\n** args:    [in] a: a is a 32 bits unsigned value.\n**============================================================================*/\nstatic unlong SMS4T(unlong a)\n{\n    return (SMS4Lt(a));\n}\n\n/*=============================================================================\n** private function:\n**   Calculating and getting encryption/decryption contents.\n** args:    [in] x0: original contents;\n** args:    [in] x1: original contents;\n** args:    [in] x2: original contents;\n** args:    [in] x3: original contents;\n** args:    [in] rk: encryption/decryption key;\n** return the contents of encryption/decryption contents.\n**============================================================================*/\nstatic unlong SMS4F(unlong x0, unlong x1, unlong x2, unlong x3, unlong rk)\n{\n    return (x0^SMS4Lt(x1^x2^x3^rk));\n}\n\n/*=============================================================================\n** public function:\n**   \"T algorithm\" == \"L algorithm\" + \"t algorithm\".\n** args:    [in] ulkey: password defined by user(NULL: default encryption key);\n** args:    [in] flag: if 0: not calculate DERK , else calculate;\n** return ulkey: NULL for default encryption key.\n**============================================================================*/\nunlong *SMS4SetKey(unlong *ulkey, unlong flag)\n{\n    if (ulkey != NULL) \n    {\n        memcpy(MK, ulkey, sizeof(MK));\n    }\n\n    SMS4CalcRK(flag);\n\n    return ulkey;\n}\n\n/*=============================================================================\n** public function:\n**   sms4 encryption algorithm.\n** args:   [in/out] psrc: a pointer point to original contents;\n** args:   [in] lgsrc: the length of original contents;\n** args:   [in] derk: a pointer point to encryption/decryption key;\n** return: pRet: a pointer point to encrypted contents.\n**============================================================================*/\nunlong *SMS4Encrypt(unlong *psrc, unlong lgsrc, unlong rk[])\n{\n    unlong *pRet = NULL;\n    unlong i = 0;\n    \n    unlong ulbuf[36];\n\n    unlong ulCnter = 0;\n    unlong ulTotal = (lgsrc >> 4);\n\n    \n    if(psrc != NULL)\n    {\n        pRet = psrc;\n        \n        /* !!!It's a temporary scheme: start!!! */\n        /*========================================\n        ** 16 bytes(128 bits) is deemed as an unit.\n        **======================================*/\n        while (ulCnter<ulTotal) \n        {\n            /* reset number counter */\n            i = 0;\n\n            /* filled up with 0*/\n            memset(ulbuf, 0, sizeof(ulbuf));\n            memcpy(ulbuf, psrc, 16);\n#ifdef SMS4DBG0\n            printf(\"0x%08x, 0x%08x, 0x%08x, 0x%08x, \\n\", \n                   ulbuf[0], ulbuf[1], ulbuf[2], ulbuf[3]);\n#endif /* SMS4DBG0 */\n            \n            while(i<32)\n            {\n                ulbuf[i+4] = SMS4F(ulbuf[i], ulbuf[i+1], \n                                   ulbuf[i+2], ulbuf[i+3], rk[i]);\n#ifdef SMS4DBG0\n                printf(\"0x%08x, \\n\", ulbuf[i+4]);\n#endif /* SMS4DBG0 */\n                i++;\n            }\n\n            /* save encrypted contents to original area */\n            psrc[0] = ulbuf[35];\n            psrc[1] = ulbuf[34];\n            psrc[2] = ulbuf[33];\n            psrc[3] = ulbuf[32];\n\n            ulCnter++;\n            psrc += 4;\n        }\n        /* !!!It's a temporary scheme: end!!! */\n    }\n\n    return pRet;\n}\n\n/*=============================================================================\n** public function:\n**   sms4 decryption algorithm.\n** args:   [in/out] psrc: a pointer point to encrypted contents;\n** args:   [in] lgsrc: the length of encrypted contents;\n** args:   [in] derk: a pointer point to decryption key;\n** return: pRet: a pointer point to decrypted contents.\n**============================================================================*/\nunlong *SMS4Decrypt(unlong *psrc, unlong lgsrc, unlong derk[])\n{\n    unlong *pRet = NULL;\n    unlong i = 0;\n\n    if(psrc != NULL)\n    {\n        pRet = psrc;\n\n        /* the same arithmetic, different encryption key sequence. */\n        SMS4Encrypt(psrc, lgsrc, derk);\n    }\n    \n    return pRet;\n}\n\n\nvoid SMS4Encrypt1M()\n{\n    unlong i = 0;\n\n    while (i<1000000) \n    {\n        SMS4Encrypt(pData, sizeof(pData), ENRK);\n        i++;\n\n//         if (0 == i%10000) \n//         {\n//             printf(\"encrypted times: %d\\n\", i);\n//         }\n    }\n\n    printf(\"0x%08x, 0x%08x, 0x%08x, 0x%08x. \\n\", \n           pData[0], pData[1], pData[2], pData[3]);\n}\n\n\n/* entry-point for debugging */\nint main()\n{\n    SMS4SetKey(NULL, 1);\n\n    /* cycle1: common test */\n\tprintf(\"0x%08x, 0x%08x, 0x%08x, 0x%08x. \\n\", \n           pData[0], pData[1], pData[2], pData[3]);\n    SMS4Encrypt(pData, sizeof(pData), ENRK);\n\tprintf(\"0x%08x, 0x%08x, 0x%08x, 0x%08x. \\n\", \n           pData[0], pData[1], pData[2], pData[3]);\n    SMS4Decrypt(pData, sizeof(pData), DERK);\n\tprintf(\"0x%08x, 0x%08x, 0x%08x, 0x%08x. \\n\", \n           pData[0], pData[1], pData[2], pData[3]);\n\n    /* cycle2: encrypted 1000000 times */\n    SMS4Encrypt1M();\n\n    /* cycle3: longer contents */\n    SMS4Encrypt(pData2, sizeof(pData2), ENRK);\n    SMS4Decrypt(pData2, sizeof(pData2), DERK);\n\n    return 0;\n}\n\n"
  },
  {
    "path": "C/sm4.c",
    "content": "/*\n * SM4 Encryption alogrithm (SMS4 algorithm)\n * GM/T 0002-2012 Chinese National Standard ref:http://www.oscca.gov.cn/ \n * thanks to Xyssl\n * thnaks and refers to http://hi.baidu.com/numax/blog/item/80addfefddfb93e4cf1b3e61.html\n * author:goldboar\n * email:goldboar@163.com\n * 2012-4-20\n */\n#define SM4_ENCRYPT     1\n#define SM4_DECRYPT     0\n\n/**\n * \\brief          SM4 context structure\n */\ntypedef struct\n{\n    int mode;                   /*!<  encrypt/decrypt   */\n    unsigned long sk[32];       /*!<  SM4 subkeys       */\n}\nsm4_context;\n\n/**\n * \\brief          SM4 key schedule (128-bit, encryption)\n *\n * \\param ctx      SM4 context to be initialized\n * \\param key      16-byte secret key\n */\nvoid sm4_setkey_enc( sm4_context *ctx, unsigned char key[16] );\n\n/**\n * \\brief          SM4 key schedule (128-bit, decryption)\n *\n * \\param ctx      SM4 context to be initialized\n * \\param key      16-byte secret key\n */\nvoid sm4_setkey_dec( sm4_context *ctx, unsigned char key[16] );\n\n/**\n * \\brief          SM4-ECB block encryption/decryption\n * \\param ctx      SM4 context\n * \\param mode     SM4_ENCRYPT or SM4_DECRYPT\n * \\param length   length of the input data\n * \\param input    input block\n * \\param output   output block\n */\nvoid sm4_crypt_ecb( sm4_context *ctx,\n                     int mode,\n                     int length,\n                     unsigned char *input,\n                     unsigned char *output);\n\n/**\n * \\brief          SM4-CBC buffer encryption/decryption\n * \\param ctx      SM4 context\n * \\param mode     SM4_ENCRYPT or SM4_DECRYPT\n * \\param length   length of the input data\n * \\param iv       initialization vector (updated after use)\n * \\param input    buffer holding the input data\n * \\param output   buffer holding the output data\n */\nvoid sm4_crypt_cbc( sm4_context *ctx,\n                     int mode,\n                     int length,\n                     unsigned char iv[16],\n                     unsigned char *input,\n                     unsigned char *output );\n                     \n// Test vector 1\n// plain: 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10\n// key:   01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10\n// \t   round key and temp computing result:\n//     rk[ 0] = f12186f9 X[ 0] = 27fad345\n//     rk[ 1] = 41662b61 X[ 1] = a18b4cb2\n//     rk[ 2] = 5a6ab19a X[ 2] = 11c1e22a\n//     rk[ 3] = 7ba92077 X[ 3] = cc13e2ee\n//     rk[ 4] = 367360f4 X[ 4] = f87c5bd5\n//     rk[ 5] = 776a0c61 X[ 5] = 33220757\n//     rk[ 6] = b6bb89b3 X[ 6] = 77f4c297\n//     rk[ 7] = 24763151 X[ 7] = 7a96f2eb\n//     rk[ 8] = a520307c X[ 8] = 27dac07f\n//     rk[ 9] = b7584dbd X[ 9] = 42dd0f19\n//     rk[10] = c30753ed X[10] = b8a5da02\n//     rk[11] = 7ee55b57 X[11] = 907127fa\n//     rk[12] = 6988608c X[12] = 8b952b83\n//     rk[13] = 30d895b7 X[13] = d42b7c59\n//     rk[14] = 44ba14af X[14] = 2ffc5831\n//     rk[15] = 104495a1 X[15] = f69e6888\n//     rk[16] = d120b428 X[16] = af2432c4\n//     rk[17] = 73b55fa3 X[17] = ed1ec85e\n//     rk[18] = cc874966 X[18] = 55a3ba22\n//     rk[19] = 92244439 X[19] = 124b18aa\n//     rk[20] = e89e641f X[20] = 6ae7725f\n//     rk[21] = 98ca015a X[21] = f4cba1f9\n//     rk[22] = c7159060 X[22] = 1dcdfa10\n//     rk[23] = 99e1fd2e X[23] = 2ff60603\n//     rk[24] = b79bd80c X[24] = eff24fdc\n//     rk[25] = 1d2115b0 X[25] = 6fe46b75\n//     rk[26] = 0e228aeb X[26] = 893450ad\n//     rk[27] = f1780c81 X[27] = 7b938f4c\n//     rk[28] = 428d3654 X[28] = 536e4246\n//     rk[29] = 62293496 X[29] = 86b3e94f\n//     rk[30] = 01cf72e5 X[30] = d206965e\n//     rk[31] = 9124a012 X[31] = 681edf34\n// cypher: 68 1e df 34 d2 06 96 5e 86 b3 e9 4f 53 6e 42 46\n// \t\t\n// test vector 2\n// the same key and plain 1000000 times coumpting \n// plain:  01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10\n// key:    01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10\n// cypher: 59 52 98 c7 c6 fd 27 1f 04 02 f8 04 c3 3d 3f 66\n\n#include <string.h>\n#include <stdio.h>\n#include <time.h>\n\n/*\n * 32-bit integer manipulation macros (big endian)\n */\n#ifndef GET_ULONG_BE\n#define GET_ULONG_BE(n,b,i)                             \\\n{                                                       \\\n    (n) = ( (unsigned long) (b)[(i)    ] << 24 )        \\\n        | ( (unsigned long) (b)[(i) + 1] << 16 )        \\\n        | ( (unsigned long) (b)[(i) + 2] <<  8 )        \\\n        | ( (unsigned long) (b)[(i) + 3]       );       \\\n}\n#endif\n\n#ifndef PUT_ULONG_BE\n#define PUT_ULONG_BE(n,b,i)                             \\\n{                                                       \\\n    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \\\n    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \\\n    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \\\n    (b)[(i) + 3] = (unsigned char) ( (n)       );       \\\n}\n#endif\n\n/*\n *rotate shift left marco definition\n *\n */\n#define  SHL(x,n) (((x) & 0xFFFFFFFF) << n)\n#define ROTL(x,n) (SHL((x),n) | ((x) >> (32 - n)))\n\n#define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; }\n\n/*\n * Expanded SM4 S-boxes\n /* Sbox table: 8bits input convert to 8 bits output*/\n \nstatic const unsigned char SboxTable[16][16] = \n{\n{0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05},\n{0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99},\n{0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62},\n{0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6},\n{0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8},\n{0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35},\n{0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87},\n{0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e},\n{0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1},\n{0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3},\n{0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f},\n{0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51},\n{0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8},\n{0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0},\n{0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84},\n{0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48}\n};\n\n/* System parameter */\nstatic const unsigned long FK[4] = {0xa3b1bac6,0x56aa3350,0x677d9197,0xb27022dc};\n\n/* fixed parameter */\nstatic const unsigned long CK[32] =\n{\n0x00070e15,0x1c232a31,0x383f464d,0x545b6269,\n0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9,\n0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249,\n0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9,\n0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229,\n0x30373e45,0x4c535a61,0x686f767d,0x848b9299,\n0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209,\n0x10171e25,0x2c333a41,0x484f565d,0x646b7279\n};\n\n\n/*\n * private function:\n * look up in SboxTable and get the related value.\n * args:    [in] inch: 0x00~0xFF (8 bits unsigned value).\n */\nstatic unsigned char sm4Sbox(unsigned char inch)\n{\n    unsigned char *pTable = (unsigned char *)SboxTable;\n    unsigned char retVal = (unsigned char)(pTable[inch]);\n    return retVal;\n}\n\n/*\n * private F(Lt) function:\n * \"T algorithm\" == \"L algorithm\" + \"t algorithm\".\n * args:    [in] a: a is a 32 bits unsigned value;\n * return: c: c is calculated with line algorithm \"L\" and nonline algorithm \"t\"\n */\nstatic unsigned long sm4Lt(unsigned long ka)\n{\n    unsigned long bb = 0;\n    unsigned long c = 0;\n    unsigned char a[4];\n\tunsigned char b[4];\n    PUT_ULONG_BE(ka,a,0)\n    b[0] = sm4Sbox(a[0]);\n    b[1] = sm4Sbox(a[1]);\n    b[2] = sm4Sbox(a[2]);\n    b[3] = sm4Sbox(a[3]);\n\tGET_ULONG_BE(bb,b,0)\n    c =bb^(ROTL(bb, 2))^(ROTL(bb, 10))^(ROTL(bb, 18))^(ROTL(bb, 24));\n    return c;\n}\n\n/*\n * private F function:\n * Calculating and getting encryption/decryption contents.\n * args:    [in] x0: original contents;\n * args:    [in] x1: original contents;\n * args:    [in] x2: original contents;\n * args:    [in] x3: original contents;\n * args:    [in] rk: encryption/decryption key;\n * return the contents of encryption/decryption contents.\n */\nstatic unsigned long sm4F(unsigned long x0, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long rk)\n{\n    return (x0^sm4Lt(x1^x2^x3^rk));\n}\n\n\n/* private function:\n * Calculating round encryption key.\n * args:    [in] a: a is a 32 bits unsigned value;\n * return: sk[i]: i{0,1,2,3,...31}.\n */\nstatic unsigned long sm4CalciRK(unsigned long ka)\n{\n    unsigned long bb = 0;\n    unsigned long rk = 0;\n    unsigned char a[4];\n    unsigned char b[4];\n    PUT_ULONG_BE(ka,a,0)\n    b[0] = sm4Sbox(a[0]);\n    b[1] = sm4Sbox(a[1]);\n    b[2] = sm4Sbox(a[2]);\n    b[3] = sm4Sbox(a[3]);\n\tGET_ULONG_BE(bb,b,0)\n    rk = bb^(ROTL(bb, 13))^(ROTL(bb, 23));\n    return rk;\n}\n\nstatic void sm4_setkey( unsigned long SK[32], unsigned char key[16] )\n{\n    unsigned long MK[4];\n    unsigned long k[36];\n    unsigned long i = 0;\n\n    GET_ULONG_BE( MK[0], key, 0 );\n    GET_ULONG_BE( MK[1], key, 4 );\n    GET_ULONG_BE( MK[2], key, 8 );\n    GET_ULONG_BE( MK[3], key, 12 );\n    k[0] = MK[0]^FK[0];\n    k[1] = MK[1]^FK[1];\n    k[2] = MK[2]^FK[2];\n    k[3] = MK[3]^FK[3];\n    for(; i<32; i++)\n    {\n        k[i+4] = k[i] ^ (sm4CalciRK(k[i+1]^k[i+2]^k[i+3]^CK[i]));\n        SK[i] = k[i+4];\n\t}\n\n}\n\n/*\n * SM4 standard one round processing\n *\n */\nstatic void sm4_one_round( unsigned long sk[32],\n                    unsigned char input[16],\n                    unsigned char output[16] )\n{\n    unsigned long i = 0;\n    unsigned long ulbuf[36];\n\n    memset(ulbuf, 0, sizeof(ulbuf));\n    GET_ULONG_BE( ulbuf[0], input, 0 )\n    GET_ULONG_BE( ulbuf[1], input, 4 )\n    GET_ULONG_BE( ulbuf[2], input, 8 )\n    GET_ULONG_BE( ulbuf[3], input, 12 )\n    while(i<32)\n    {\n        ulbuf[i+4] = sm4F(ulbuf[i], ulbuf[i+1], ulbuf[i+2], ulbuf[i+3], sk[i]);\n// #ifdef _DEBUG\n//        \tprintf(\"rk(%02d) = 0x%08x,  X(%02d) = 0x%08x \\n\",i,sk[i], i, ulbuf[i+4] );\n// #endif\n\t    i++;\n    }\n\tPUT_ULONG_BE(ulbuf[35],output,0);\n\tPUT_ULONG_BE(ulbuf[34],output,4);\n\tPUT_ULONG_BE(ulbuf[33],output,8);\n\tPUT_ULONG_BE(ulbuf[32],output,12);\n}\n\n/*\n * SM4 key schedule (128-bit, encryption)\n */\nvoid sm4_setkey_enc( sm4_context *ctx, unsigned char key[16] )\n{\n    ctx->mode = SM4_ENCRYPT;\n\tsm4_setkey( ctx->sk, key );\n}\n\n/*\n * SM4 key schedule (128-bit, decryption)\n */\nvoid sm4_setkey_dec( sm4_context *ctx, unsigned char key[16] )\n{\n    int i;\n\tctx->mode = SM4_ENCRYPT;\n    sm4_setkey( ctx->sk, key );\n    for( i = 0; i < 16; i ++ )\n    {\n        SWAP( ctx->sk[ i ], ctx->sk[ 31-i] );\n    }\n}\n\n\n/*\n * SM4-ECB block encryption/decryption\n */\n\nvoid sm4_crypt_ecb( sm4_context *ctx,\n\t\t\t\t   int mode,\n\t\t\t\t   int length,\n\t\t\t\t   unsigned char *input,\n                   unsigned char *output)\n{\n    while( length > 0 )\n    {\n        sm4_one_round( ctx->sk, input, output );\n        input  += 16;\n        output += 16;\n        length -= 16;\n    }\n\n}\n\n/*\n * SM4-CBC buffer encryption/decryption\n */\nvoid sm4_crypt_cbc( sm4_context *ctx,\n                    int mode,\n                    int length,\n                    unsigned char iv[16],\n                    unsigned char *input,\n                    unsigned char *output )\n{\n    int i;\n    unsigned char temp[16];\n\n    if( mode == SM4_ENCRYPT )\n    {\n        while( length > 0 )\n        {\n            for( i = 0; i < 16; i++ )\n                output[i] = (unsigned char)( input[i] ^ iv[i] );\n\n            sm4_one_round( ctx->sk, output, output );\n            memcpy( iv, output, 16 );\n\n            input  += 16;\n            output += 16;\n            length -= 16;\n        }\n    }\n    else /* SM4_DECRYPT */\n    {\n        while( length > 0 )\n        {\n            memcpy( temp, input, 16 );\n            sm4_one_round( ctx->sk, input, output );\n\n            for( i = 0; i < 16; i++ )\n                output[i] = (unsigned char)( output[i] ^ iv[i] );\n\n            memcpy( iv, temp, 16 );\n\n            input  += 16;\n            output += 16;\n            length -= 16;\n        }\n    }\n}\n\nint main()\n{\n    unsigned char key[16] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};\n    unsigned char input[16] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};\n    unsigned char output[16];\n    sm4_context ctx;\n    unsigned long i;\n\n    //encrypt standard testing vector\n    // sm4_setkey_enc(&ctx,key);\n    // sm4_crypt_ecb(&ctx,1,16,input,output);\n    // for(i=0;i<16;i++)\n    //     printf(\"%02x \", output[i]);\n    // printf(\"\\n\");\n\n    //decrypt testing\n    // sm4_setkey_dec(&ctx,key);\n    // sm4_crypt_ecb(&ctx,0,16,output,output);\n    // for(i=0;i<16;i++)\n    //     printf(\"%02x \", output[i]);\n    // printf(\"\\n\");\n\n    //decrypt 1M times testing vector based on standards.\n    \n    #include <time.h>\n    time_t c_start, c_end;  \n    c_start = clock();\n    i = 0;\n    sm4_setkey_enc(&ctx,key);\n    while (i<1000000) \n    {\n        sm4_crypt_ecb(&ctx,1,16,input,input);\n        i++;\n    }\n    for(i=0;i<16;i++)\n        printf(\"%02x \", input[i]);\n    printf(\"\\n\");\n    c_end   = clock();\n    printf(\"run 1000000 times  used %f ms \\n\",difftime(c_end,c_start));\n    \n    return 0;\n}\n"
  },
  {
    "path": "Java/JavaSM4.java",
    "content": "public class JavaSM4 {\n           \n    public static int[] key = new int[4];\n    public static int[] temp = new int[4];\n    public static int[] rkey = new int[32];\n    public static int[] fk = {0xa3b1bac6, 0x56AA3350, 0x677d9197, 0xb27022dc}; \n    public static int[] ck = {\n        0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,\n        0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,\n        0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,\n        0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,\n        0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,\n        0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,\n        0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,\n        0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279};\n    private static int[] sbi = { \n        0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05,\n        0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99,\n        0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62,\n        0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6,\n        0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8,\n        0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35,\n        0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87,\n        0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e,\n        0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1,\n        0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3,\n        0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f,\n        0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51,\n        0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8,\n        0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0,\n        0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84,\n        0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48};\n           \n           \n    public static void main(String[] args)\n    {\n        JavaSM4 sm = new JavaSM4();\n        int[] msg = {0x01234567, 0x89abcdef, 0xfedcba98, 0x76543210};\n        int[] smsg = {0x595298c7, 0xc6fd271f, 0x0402f804, 0xc33d3f66};\n        key[0] = 0x01234567;\n        key[1] = 0x89abcdef;\n        key[2] = 0xfedcba98;\n        key[3] = 0x76543210;\n        // int j=0,n=1000000;\n        int j=0,n=1000000;\n        long startTime = System.currentTimeMillis();   // start time\n        for(j=0; j<n; j++)\n        {\n            //msg = sm4(msg,1);// encode\n            smsg = sm4(smsg,0);// decode\n        }\n        long endTime = System.currentTimeMillis(); // end time\n        System.out.println(\" Run \"+n+\" times: \"+(endTime-startTime)+\"ms\");\n    }\n           \n    private static int[] sm4(int[] t,int s) \n    {\n        rkey = initrk();\n        if(s == 0)\n        {\n            rkey = r(rkey);\n        }\n        int[] x = new int[36];\n        x[0] = t[0];\n        x[1] = t[1];\n        x[2] = t[2];\n        x[3] = t[3];\n        int i;\n        for(i=0;i<32;i++)\n        {\n            x[i+4] = f(x[i],x[i+1],x[i+2],x[i+3],rkey[i]);\n        }\n        x = r(x);\n        temp[0] = x[0];\n        temp[1] = x[1];\n        temp[2] = x[2];\n        temp[3] = x[3];\n        return temp;\n    }\n             \n    private static int[] initrk()\n    {\n        int i;\n        int[] k = new int[36];\n        int[] rk = new int[32];\n        k[0] = key[0] ^ fk[0];\n        k[1] = key[1] ^ fk[1];\n        k[2] = key[2] ^ fk[2];\n        k[3] = key[3] ^ fk[3];\n        for(i=0;i<32;i++)\n        {\n            rk[i] = k[i+4] = k[i] ^ tn(k[i+1]^k[i+2]^k[i+3]^ck[i]);\n        }\n        return rk;\n    }\n           \n    private static int[] r(int[] x)\n    {\n        int[] t = new int[x.length];\n        int i;\n        for(i=0; i<x.length; i++)\n        {\n            t[i] = x[x.length - 1 -i];\n        }\n        return t;\n    }\n           \n    private static int f(int x0,int x1,int x2,int x3,int k)\n    {\n        return (x0 ^ t(x1 ^ x2 ^ x3 ^ k));\n    }\n           \n    private static int t(int ta)\n    {\n        return l(tj(ta));\n    }\n           \n    private static int tn(int ta)\n    {\n        return ln(tj(ta));\n    }\n           \n    private static int l(int temp)\n    {\n        return temp ^ Px(temp,2) ^ Px(temp,10) ^ Px(temp,18) ^ Px(temp,24);\n    }\n    private static int ln(int temp)\n    {\n        return temp ^ Px(temp,13) ^ Px(temp,23);\n    }\n           \n    private static int tj(int a)\n    {\n        byte[] b = new byte[4];\n        byte[] c = new byte[4];\n        c = intToBytes(a);\n        b[0] = sbox(c[0]);\n        b[1] = sbox(c[1]);\n        b[2] = sbox(c[2]);\n        b[3] = sbox(c[3]);\n        a = bytesToInt(b[0],b[1],b[2],b[3]);\n        return a;\n    }\n           \n    private static byte sbox(byte a) \n    {\n        int t = (a << 24) >>> 24;\n        return (byte)sbi[t];\n    }\n           \n    private static int Px(int x,int n) \n    {\n        return ((x<<n)|(x>>>(32-n)));\n    }\n    private static int bytesToInt(byte b0,byte b1,byte b2,byte b3) // int = 4 * byte = 32 bit unsigned\n    {\n        int tint = 0;\n        int temp = b0 << 24;\n        tint = temp;\n        temp = (b1 << 24) >>> 8;\n        tint |= temp;\n        temp = (b2 << 24) >>> 16;\n        tint |= temp;\n        temp = (b3 << 24) >>> 24;\n        tint |= temp;\n        return tint;\n    }\n    private static byte[] intToBytes(int i)\n    {\n        byte[] tbyte = new byte[4];\n        tbyte[0] = (byte)(i >>> 24);\n        tbyte[1] = (byte)((i<<8)>>>24);\n        tbyte[2] = (byte)((i<<16)>>>24);\n        tbyte[3] = (byte)((i<<24)>>>24);\n        return tbyte;\n    }\n}"
  },
  {
    "path": "JavaScript/demo/js/asn1-1.0.js",
    "content": "/*! asn1-1.0.4.js (c) 2013 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n/*\n * asn1.js - ASN.1 DER encoder classes\n *\n * Copyright (c) 2013 Kenji Urushima (kenji.urushima@gmail.com)\n *\n * This software is licensed under the terms of the MIT License.\n * http://kjur.github.com/jsrsasign/license\n *\n * The above copyright and license notice shall be \n * included in all copies or substantial portions of the Software.\n */\n\n/**\n * @fileOverview\n * @name asn1-1.0.js\n * @author Kenji Urushima kenji.urushima@gmail.com\n * @version asn1 1.0.4 (2013-Oct-02)\n * @since jsrsasign 2.1\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\n */\n\n/** \n * kjur's class library name space\n * <p>\n * This name space provides following name spaces:\n * <ul>\n * <li>{@link KJUR.asn1} - ASN.1 primitive hexadecimal encoder</li>\n * <li>{@link KJUR.asn1.x509} - ASN.1 structure for X.509 certificate and CRL</li>\n * <li>{@link KJUR.crypto} - Java Cryptographic Extension(JCE) style MessageDigest/Signature \n * class and utilities</li>\n * </ul>\n * </p> \n * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.\n  * @name KJUR\n * @namespace kjur's class library name space\n */\nif (typeof KJUR == \"undefined\" || !KJUR) KJUR = {};\n\n/**\n * kjur's ASN.1 class library name space\n * <p>\n * This is ITU-T X.690 ASN.1 DER encoder class library and\n * class structure and methods is very similar to \n * org.bouncycastle.asn1 package of \n * well known BouncyCaslte Cryptography Library.\n *\n * <h4>PROVIDING ASN.1 PRIMITIVES</h4>\n * Here are ASN.1 DER primitive classes.\n * <ul>\n * <li>0x01 {@link KJUR.asn1.DERBoolean}</li>\n * <li>0x02 {@link KJUR.asn1.DERInteger}</li>\n * <li>0x03 {@link KJUR.asn1.DERBitString}</li>\n * <li>0x04 {@link KJUR.asn1.DEROctetString}</li>\n * <li>0x05 {@link KJUR.asn1.DERNull}</li>\n * <li>0x06 {@link KJUR.asn1.DERObjectIdentifier}</li>\n * <li>0x0c {@link KJUR.asn1.DERUTF8String}</li>\n * <li>0x12 {@link KJUR.asn1.DERNumericString}</li>\n * <li>0x13 {@link KJUR.asn1.DERPrintableString}</li>\n * <li>0x14 {@link KJUR.asn1.DERTeletexString}</li>\n * <li>0x16 {@link KJUR.asn1.DERIA5String}</li>\n * <li>0x17 {@link KJUR.asn1.DERUTCTime}</li>\n * <li>0x18 {@link KJUR.asn1.DERGeneralizedTime}</li>\n * <li>0x30 {@link KJUR.asn1.DERSequence}</li>\n * <li>0x31 {@link KJUR.asn1.DERSet}</li>\n * </ul>\n *\n * <h4>OTHER ASN.1 CLASSES</h4>\n * <ul>\n * <li>{@link KJUR.asn1.ASN1Object}</li>\n * <li>{@link KJUR.asn1.DERAbstractString}</li>\n * <li>{@link KJUR.asn1.DERAbstractTime}</li>\n * <li>{@link KJUR.asn1.DERAbstractStructured}</li>\n * <li>{@link KJUR.asn1.DERTaggedObject}</li>\n * </ul>\n * </p>\n * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.\n * @name KJUR.asn1\n * @namespace\n */\nif (typeof KJUR.asn1 == \"undefined\" || !KJUR.asn1) KJUR.asn1 = {};\n\n/**\n * ASN1 utilities class\n * @name KJUR.asn1.ASN1Util\n * @class ASN1 utilities class\n * @since asn1 1.0.2\n */\nKJUR.asn1.ASN1Util = new function() {\n    this.integerToByteHex = function(i) {\n\tvar h = i.toString(16);\n\tif ((h.length % 2) == 1) h = '0' + h;\n\treturn h;\n    };\n    this.bigIntToMinTwosComplementsHex = function(bigIntegerValue) {\n\tvar h = bigIntegerValue.toString(16);\n\tif (h.substr(0, 1) != '-') {\n\t    if (h.length % 2 == 1) {\n\t\th = '0' + h;\n\t    } else {\n\t\tif (! h.match(/^[0-7]/)) {\n\t\t    h = '00' + h;\n\t\t}\n\t    }\n\t} else {\n\t    var hPos = h.substr(1);\n\t    var xorLen = hPos.length;\n\t    if (xorLen % 2 == 1) {\n\t\txorLen += 1;\n\t    } else {\n\t\tif (! h.match(/^[0-7]/)) {\n\t\t    xorLen += 2;\n\t\t}\n\t    }\n\t    var hMask = '';\n\t    for (var i = 0; i < xorLen; i++) {\n\t\thMask += 'f';\n\t    }\n\t    var biMask = new BigInteger(hMask, 16);\n\t    var biNeg = biMask.xor(bigIntegerValue).add(BigInteger.ONE);\n\t    h = biNeg.toString(16).replace(/^-/, '');\n\t}\n\treturn h;\n    };\n    /**\n     * get PEM string from hexadecimal data and header string\n     * @name getPEMStringFromHex\n     * @memberOf KJUR.asn1.ASN1Util\n     * @function\n     * @param {String} dataHex hexadecimal string of PEM body\n     * @param {String} pemHeader PEM header string (ex. 'RSA PRIVATE KEY')\n     * @return {String} PEM formatted string of input data\n     * @description\n     * @example\n     * var pem  = KJUR.asn1.ASN1Util.getPEMStringFromHex('616161', 'RSA PRIVATE KEY');\n     * // value of pem will be:\n     * -----BEGIN PRIVATE KEY-----\n     * YWFh\n     * -----END PRIVATE KEY-----\n     */\n    this.getPEMStringFromHex = function(dataHex, pemHeader) {\n\tvar ns1 = KJUR.asn1;\n\tvar dataWA = CryptoJS.enc.Hex.parse(dataHex);\n\tvar dataB64 = CryptoJS.enc.Base64.stringify(dataWA);\n\tvar pemBody = dataB64.replace(/(.{64})/g, \"$1\\r\\n\");\n        pemBody = pemBody.replace(/\\r\\n$/, '');\n\treturn \"-----BEGIN \" + pemHeader + \"-----\\r\\n\" + \n               pemBody + \n               \"\\r\\n-----END \" + pemHeader + \"-----\\r\\n\";\n    };\n\n    /**\n     * generate ASN1Object specifed by JSON parameters\n     * @name newObject\n     * @memberOf KJUR.asn1.ASN1Util\n     * @function\n     * @param {Array} param JSON parameter to generate ASN1Object\n     * @return {KJUR.asn1.ASN1Object} generated object\n     * @since asn1 1.0.3\n     * @description\n     * generate any ASN1Object specified by JSON param\n     * including ASN.1 primitive or structured.\n     * Generally 'param' can be described as follows:\n     * <blockquote>\n     * {TYPE-OF-ASNOBJ: ASN1OBJ-PARAMETER}\n     * </blockquote>\n     * 'TYPE-OF-ASN1OBJ' can be one of following symbols:\n     * <ul>\n     * <li>'bool' - DERBoolean</li>\n     * <li>'int' - DERInteger</li>\n     * <li>'bitstr' - DERBitString</li>\n     * <li>'octstr' - DEROctetString</li>\n     * <li>'null' - DERNull</li>\n     * <li>'oid' - DERObjectIdentifier</li>\n     * <li>'utf8str' - DERUTF8String</li>\n     * <li>'numstr' - DERNumericString</li>\n     * <li>'prnstr' - DERPrintableString</li>\n     * <li>'telstr' - DERTeletexString</li>\n     * <li>'ia5str' - DERIA5String</li>\n     * <li>'utctime' - DERUTCTime</li>\n     * <li>'gentime' - DERGeneralizedTime</li>\n     * <li>'seq' - DERSequence</li>\n     * <li>'set' - DERSet</li>\n     * <li>'tag' - DERTaggedObject</li>\n     * </ul>\n     * @example\n     * newObject({'prnstr': 'aaa'});\n     * newObject({'seq': [{'int': 3}, {'prnstr': 'aaa'}]})\n     * // ASN.1 Tagged Object\n     * newObject({'tag': {'tag': 'a1', \n     *                    'explicit': true,\n     *                    'obj': {'seq': [{'int': 3}, {'prnstr': 'aaa'}]}}});\n     * // more simple representation of ASN.1 Tagged Object\n     * newObject({'tag': ['a1',\n     *                    true,\n     *                    {'seq': [\n     *                      {'int': 3}, \n     *                      {'prnstr': 'aaa'}]}\n     *                   ]});\n     */\n    this.newObject = function(param) {\n\tvar ns1 = KJUR.asn1;\n\tvar keys = Object.keys(param);\n\tif (keys.length != 1)\n\t    throw \"key of param shall be only one.\";\n\tvar key = keys[0];\n\n\tif (\":bool:int:bitstr:octstr:null:oid:utf8str:numstr:prnstr:telstr:ia5str:utctime:gentime:seq:set:tag:\".indexOf(\":\" + key + \":\") == -1)\n\t    throw \"undefined key: \" + key;\n\n\tif (key == \"bool\")    return new ns1.DERBoolean(param[key]);\n\tif (key == \"int\")     return new ns1.DERInteger(param[key]);\n\tif (key == \"bitstr\")  return new ns1.DERBitString(param[key]);\n\tif (key == \"octstr\")  return new ns1.DEROctetString(param[key]);\n\tif (key == \"null\")    return new ns1.DERNull(param[key]);\n\tif (key == \"oid\")     return new ns1.DERObjectIdentifier(param[key]);\n\tif (key == \"utf8str\") return new ns1.DERUTF8String(param[key]);\n\tif (key == \"numstr\")  return new ns1.DERNumericString(param[key]);\n\tif (key == \"prnstr\")  return new ns1.DERPrintableString(param[key]);\n\tif (key == \"telstr\")  return new ns1.DERTeletexString(param[key]);\n\tif (key == \"ia5str\")  return new ns1.DERIA5String(param[key]);\n\tif (key == \"utctime\") return new ns1.DERUTCTime(param[key]);\n\tif (key == \"gentime\") return new ns1.DERGeneralizedTime(param[key]);\n\n\tif (key == \"seq\") {\n\t    var paramList = param[key];\n\t    var a = [];\n\t    for (var i = 0; i < paramList.length; i++) {\n\t\tvar asn1Obj = ns1.ASN1Util.newObject(paramList[i]);\n\t\ta.push(asn1Obj);\n\t    }\n\t    return new ns1.DERSequence({'array': a});\n\t}\n\n\tif (key == \"set\") {\n\t    var paramList = param[key];\n\t    var a = [];\n\t    for (var i = 0; i < paramList.length; i++) {\n\t\tvar asn1Obj = ns1.ASN1Util.newObject(paramList[i]);\n\t\ta.push(asn1Obj);\n\t    }\n\t    return new ns1.DERSet({'array': a});\n\t}\n\n\tif (key == \"tag\") {\n\t    var tagParam = param[key];\n\t    if (Object.prototype.toString.call(tagParam) === '[object Array]' &&\n\t\ttagParam.length == 3) {\n\t\tvar obj = ns1.ASN1Util.newObject(tagParam[2]);\n\t\treturn new ns1.DERTaggedObject({tag: tagParam[0], explicit: tagParam[1], obj: obj});\n\t    } else {\n\t\tvar newParam = {};\n\t\tif (tagParam.explicit !== undefined)\n\t\t    newParam.explicit = tagParam.explicit;\n\t\tif (tagParam.tag !== undefined)\n\t\t    newParam.tag = tagParam.tag;\n\t\tif (tagParam.obj === undefined)\n\t\t    throw \"obj shall be specified for 'tag'.\";\n\t\tnewParam.obj = ns1.ASN1Util.newObject(tagParam.obj);\n\t\treturn new ns1.DERTaggedObject(newParam);\n\t    }\n\t}\n    };\n\n    /**\n     * get encoded hexadecimal string of ASN1Object specifed by JSON parameters\n     * @name jsonToASN1HEX\n     * @memberOf KJUR.asn1.ASN1Util\n     * @function\n     * @param {Array} param JSON parameter to generate ASN1Object\n     * @return hexadecimal string of ASN1Object\n     * @since asn1 1.0.4\n     * @description\n     * As for ASN.1 object representation of JSON object,\n     * please see {@link newObject}.\n     * @example\n     * jsonToASN1HEX({'prnstr': 'aaa'}); \n     */\n    this.jsonToASN1HEX = function(param) {\n\tvar asn1Obj = this.newObject(param);\n\treturn asn1Obj.getEncodedHex();\n    };\n};\n\n// ********************************************************************\n//  Abstract ASN.1 Classes\n// ********************************************************************\n\n// ********************************************************************\n\n/**\n * base class for ASN.1 DER encoder object\n * @name KJUR.asn1.ASN1Object\n * @class base class for ASN.1 DER encoder object\n * @property {Boolean} isModified flag whether internal data was changed\n * @property {String} hTLV hexadecimal string of ASN.1 TLV\n * @property {String} hT hexadecimal string of ASN.1 TLV tag(T)\n * @property {String} hL hexadecimal string of ASN.1 TLV length(L)\n * @property {String} hV hexadecimal string of ASN.1 TLV value(V)\n * @description\n */\nKJUR.asn1.ASN1Object = function() {\n    var isModified = true;\n    var hTLV = null;\n    var hT = '00';\n    var hL = '00';\n    var hV = '';\n\n    /**\n     * get hexadecimal ASN.1 TLV length(L) bytes from TLV value(V)\n     * @name getLengthHexFromValue\n     * @memberOf KJUR.asn1.ASN1Object\n     * @function\n     * @return {String} hexadecimal string of ASN.1 TLV length(L)\n     */\n    this.getLengthHexFromValue = function() {\n\tif (typeof this.hV == \"undefined\" || this.hV == null) {\n\t    throw \"this.hV is null or undefined.\";\n\t}\n\tif (this.hV.length % 2 == 1) {\n\t    throw \"value hex must be even length: n=\" + hV.length + \",v=\" + this.hV;\n\t}\n\tvar n = this.hV.length / 2;\n\tvar hN = n.toString(16);\n\tif (hN.length % 2 == 1) {\n\t    hN = \"0\" + hN;\n\t}\n\tif (n < 128) {\n\t    return hN;\n\t} else {\n\t    var hNlen = hN.length / 2;\n\t    if (hNlen > 15) {\n\t\tthrow \"ASN.1 length too long to represent by 8x: n = \" + n.toString(16);\n\t    }\n\t    var head = 128 + hNlen;\n\t    return head.toString(16) + hN;\n\t}\n    };\n\n    /**\n     * get hexadecimal string of ASN.1 TLV bytes\n     * @name getEncodedHex\n     * @memberOf KJUR.asn1.ASN1Object\n     * @function\n     * @return {String} hexadecimal string of ASN.1 TLV\n     */\n    this.getEncodedHex = function() {\n\tif (this.hTLV == null || this.isModified) {\n\t    this.hV = this.getFreshValueHex();\n\t    this.hL = this.getLengthHexFromValue();\n\t    this.hTLV = this.hT + this.hL + this.hV;\n\t    this.isModified = false;\n\t    //alert(\"first time: \" + this.hTLV);\n\t}\n\treturn this.hTLV;\n    };\n\n    /**\n     * get hexadecimal string of ASN.1 TLV value(V) bytes\n     * @name getValueHex\n     * @memberOf KJUR.asn1.ASN1Object\n     * @function\n     * @return {String} hexadecimal string of ASN.1 TLV value(V) bytes\n     */\n    this.getValueHex = function() {\n\tthis.getEncodedHex();\n\treturn this.hV;\n    }\n\n    this.getFreshValueHex = function() {\n\treturn '';\n    };\n};\n\n// == BEGIN DERAbstractString ================================================\n/**\n * base class for ASN.1 DER string classes\n * @name KJUR.asn1.DERAbstractString\n * @class base class for ASN.1 DER string classes\n * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})\n * @property {String} s internal string of value\n * @extends KJUR.asn1.ASN1Object\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>str - specify initial ASN.1 value(V) by a string</li>\n * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n */\nKJUR.asn1.DERAbstractString = function(params) {\n    KJUR.asn1.DERAbstractString.superclass.constructor.call(this);\n    var s = null;\n    var hV = null;\n\n    /**\n     * get string value of this string object\n     * @name getString\n     * @memberOf KJUR.asn1.DERAbstractString\n     * @function\n     * @return {String} string value of this string object\n     */\n    this.getString = function() {\n\treturn this.s;\n    };\n\n    /**\n     * set value by a string\n     * @name setString\n     * @memberOf KJUR.asn1.DERAbstractString\n     * @function\n     * @param {String} newS value by a string to set\n     */\n    this.setString = function(newS) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.s = newS;\n\tthis.hV = stohex(this.s);\n    };\n\n    /**\n     * set value by a hexadecimal string\n     * @name setStringHex\n     * @memberOf KJUR.asn1.DERAbstractString\n     * @function\n     * @param {String} newHexString value by a hexadecimal string to set\n     */\n    this.setStringHex = function(newHexString) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.s = null;\n\tthis.hV = newHexString;\n    };\n\n    this.getFreshValueHex = function() {\n\treturn this.hV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params == \"string\") {\n\t    this.setString(params);\n\t} else if (typeof params['str'] != \"undefined\") {\n\t    this.setString(params['str']);\n\t} else if (typeof params['hex'] != \"undefined\") {\n\t    this.setStringHex(params['hex']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.DERAbstractString, KJUR.asn1.ASN1Object);\n// == END   DERAbstractString ================================================\n\n// == BEGIN DERAbstractTime ==================================================\n/**\n * base class for ASN.1 DER Generalized/UTCTime class\n * @name KJUR.asn1.DERAbstractTime\n * @class base class for ASN.1 DER Generalized/UTCTime class\n * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @see KJUR.asn1.ASN1Object - superclass\n */\nKJUR.asn1.DERAbstractTime = function(params) {\n    KJUR.asn1.DERAbstractTime.superclass.constructor.call(this);\n    var s = null;\n    var date = null;\n\n    // --- PRIVATE METHODS --------------------\n    this.localDateToUTC = function(d) {\n\tutc = d.getTime() + (d.getTimezoneOffset() * 60000);\n\tvar utcDate = new Date(utc);\n\treturn utcDate;\n    };\n\n    this.formatDate = function(dateObject, type) {\n\tvar pad = this.zeroPadding;\n\tvar d = this.localDateToUTC(dateObject);\n\tvar year = String(d.getFullYear());\n\tif (type == 'utc') year = year.substr(2, 2);\n\tvar month = pad(String(d.getMonth() + 1), 2);\n\tvar day = pad(String(d.getDate()), 2);\n\tvar hour = pad(String(d.getHours()), 2);\n\tvar min = pad(String(d.getMinutes()), 2);\n\tvar sec = pad(String(d.getSeconds()), 2);\n\treturn year + month + day + hour + min + sec + 'Z';\n    };\n\n    this.zeroPadding = function(s, len) {\n\tif (s.length >= len) return s;\n\treturn new Array(len - s.length + 1).join('0') + s;\n    };\n\n    // --- PUBLIC METHODS --------------------\n    /**\n     * get string value of this string object\n     * @name getString\n     * @memberOf KJUR.asn1.DERAbstractTime\n     * @function\n     * @return {String} string value of this time object\n     */\n    this.getString = function() {\n\treturn this.s;\n    };\n\n    /**\n     * set value by a string\n     * @name setString\n     * @memberOf KJUR.asn1.DERAbstractTime\n     * @function\n     * @param {String} newS value by a string to set such like \"130430235959Z\"\n     */\n    this.setString = function(newS) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.s = newS;\n\tthis.hV = stohex(newS);\n    };\n\n    /**\n     * set value by a Date object\n     * @name setByDateValue\n     * @memberOf KJUR.asn1.DERAbstractTime\n     * @function\n     * @param {Integer} year year of date (ex. 2013)\n     * @param {Integer} month month of date between 1 and 12 (ex. 12)\n     * @param {Integer} day day of month\n     * @param {Integer} hour hours of date\n     * @param {Integer} min minutes of date\n     * @param {Integer} sec seconds of date\n     */\n    this.setByDateValue = function(year, month, day, hour, min, sec) {\n\tvar dateObject = new Date(Date.UTC(year, month - 1, day, hour, min, sec, 0));\n\tthis.setByDate(dateObject);\n    };\n\n    this.getFreshValueHex = function() {\n\treturn this.hV;\n    };\n};\nYAHOO.lang.extend(KJUR.asn1.DERAbstractTime, KJUR.asn1.ASN1Object);\n// == END   DERAbstractTime ==================================================\n\n// == BEGIN DERAbstractStructured ============================================\n/**\n * base class for ASN.1 DER structured class\n * @name KJUR.asn1.DERAbstractStructured\n * @class base class for ASN.1 DER structured class\n * @property {Array} asn1Array internal array of ASN1Object\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @see KJUR.asn1.ASN1Object - superclass\n */\nKJUR.asn1.DERAbstractStructured = function(params) {\n    KJUR.asn1.DERAbstractString.superclass.constructor.call(this);\n    var asn1Array = null;\n\n    /**\n     * set value by array of ASN1Object\n     * @name setByASN1ObjectArray\n     * @memberOf KJUR.asn1.DERAbstractStructured\n     * @function\n     * @param {array} asn1ObjectArray array of ASN1Object to set\n     */\n    this.setByASN1ObjectArray = function(asn1ObjectArray) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.asn1Array = asn1ObjectArray;\n    };\n\n    /**\n     * append an ASN1Object to internal array\n     * @name appendASN1Object\n     * @memberOf KJUR.asn1.DERAbstractStructured\n     * @function\n     * @param {ASN1Object} asn1Object to add\n     */\n    this.appendASN1Object = function(asn1Object) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.asn1Array.push(asn1Object);\n    };\n\n    this.asn1Array = new Array();\n    if (typeof params != \"undefined\") {\n\tif (typeof params['array'] != \"undefined\") {\n\t    this.asn1Array = params['array'];\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.DERAbstractStructured, KJUR.asn1.ASN1Object);\n\n\n// ********************************************************************\n//  ASN.1 Object Classes\n// ********************************************************************\n\n// ********************************************************************\n/**\n * class for ASN.1 DER Boolean\n * @name KJUR.asn1.DERBoolean\n * @class class for ASN.1 DER Boolean\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @see KJUR.asn1.ASN1Object - superclass\n */\nKJUR.asn1.DERBoolean = function() {\n    KJUR.asn1.DERBoolean.superclass.constructor.call(this);\n    this.hT = \"01\";\n    this.hTLV = \"0101ff\";\n};\nYAHOO.lang.extend(KJUR.asn1.DERBoolean, KJUR.asn1.ASN1Object);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER Integer\n * @name KJUR.asn1.DERInteger\n * @class class for ASN.1 DER Integer\n * @extends KJUR.asn1.ASN1Object\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>int - specify initial ASN.1 value(V) by integer value</li>\n * <li>bigint - specify initial ASN.1 value(V) by BigInteger object</li>\n * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n */\nKJUR.asn1.DERInteger = function(params) {\n    KJUR.asn1.DERInteger.superclass.constructor.call(this);\n    this.hT = \"02\";\n\n    /**\n     * set value by Tom Wu's BigInteger object\n     * @name setByBigInteger\n     * @memberOf KJUR.asn1.DERInteger\n     * @function\n     * @param {BigInteger} bigIntegerValue to set\n     */\n    this.setByBigInteger = function(bigIntegerValue) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue);\n    };\n\n    /**\n     * set value by integer value\n     * @name setByInteger\n     * @memberOf KJUR.asn1.DERInteger\n     * @function\n     * @param {Integer} integer value to set\n     */\n    this.setByInteger = function(intValue) {\n\tvar bi = new BigInteger(String(intValue), 10);\n\tthis.setByBigInteger(bi);\n    };\n\n    /**\n     * set value by integer value\n     * @name setValueHex\n     * @memberOf KJUR.asn1.DERInteger\n     * @function\n     * @param {String} hexadecimal string of integer value\n     * @description\n     * <br/>\n     * NOTE: Value shall be represented by minimum octet length of\n     * two's complement representation.\n     * @example\n     * new KJUR.asn1.DERInteger(123);\n     * new KJUR.asn1.DERInteger({'int': 123});\n     * new KJUR.asn1.DERInteger({'hex': '1fad'});\n     */\n    this.setValueHex = function(newHexString) {\n\tthis.hV = newHexString;\n    };\n\n    this.getFreshValueHex = function() {\n\treturn this.hV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['bigint'] != \"undefined\") {\n\t    this.setByBigInteger(params['bigint']);\n\t} else if (typeof params['int'] != \"undefined\") {\n\t    this.setByInteger(params['int']);\n\t} else if (typeof params == \"number\") {\n\t    this.setByInteger(params);\n\t} else if (typeof params['hex'] != \"undefined\") {\n\t    this.setValueHex(params['hex']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.DERInteger, KJUR.asn1.ASN1Object);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER encoded BitString primitive\n * @name KJUR.asn1.DERBitString\n * @class class for ASN.1 DER encoded BitString primitive\n * @extends KJUR.asn1.ASN1Object\n * @description \n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>bin - specify binary string (ex. '10111')</li>\n * <li>array - specify array of boolean (ex. [true,false,true,true])</li>\n * <li>hex - specify hexadecimal string of ASN.1 value(V) including unused bits</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n */\nKJUR.asn1.DERBitString = function(params) {\n    KJUR.asn1.DERBitString.superclass.constructor.call(this);\n    this.hT = \"03\";\n\n    /**\n     * set ASN.1 value(V) by a hexadecimal string including unused bits\n     * @name setHexValueIncludingUnusedBits\n     * @memberOf KJUR.asn1.DERBitString\n     * @function\n     * @param {String} newHexStringIncludingUnusedBits\n     */\n    this.setHexValueIncludingUnusedBits = function(newHexStringIncludingUnusedBits) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.hV = newHexStringIncludingUnusedBits;\n    };\n\n    /**\n     * set ASN.1 value(V) by unused bit and hexadecimal string of value\n     * @name setUnusedBitsAndHexValue\n     * @memberOf KJUR.asn1.DERBitString\n     * @function\n     * @param {Integer} unusedBits\n     * @param {String} hValue\n     */\n    this.setUnusedBitsAndHexValue = function(unusedBits, hValue) {\n\tif (unusedBits < 0 || 7 < unusedBits) {\n\t    throw \"unused bits shall be from 0 to 7: u = \" + unusedBits;\n\t}\n\tvar hUnusedBits = \"0\" + unusedBits;\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.hV = hUnusedBits + hValue;\n    };\n\n    /**\n     * set ASN.1 DER BitString by binary string\n     * @name setByBinaryString\n     * @memberOf KJUR.asn1.DERBitString\n     * @function\n     * @param {String} binaryString binary value string (i.e. '10111')\n     * @description\n     * Its unused bits will be calculated automatically by length of \n     * 'binaryValue'. <br/>\n     * NOTE: Trailing zeros '0' will be ignored.\n     */\n    this.setByBinaryString = function(binaryString) {\n\tbinaryString = binaryString.replace(/0+$/, '');\n\tvar unusedBits = 8 - binaryString.length % 8;\n\tif (unusedBits == 8) unusedBits = 0;\n\tfor (var i = 0; i <= unusedBits; i++) {\n\t    binaryString += '0';\n\t}\n\tvar h = '';\n\tfor (var i = 0; i < binaryString.length - 1; i += 8) {\n\t    var b = binaryString.substr(i, 8);\n\t    var x = parseInt(b, 2).toString(16);\n\t    if (x.length == 1) x = '0' + x;\n\t    h += x;  \n\t}\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.hV = '0' + unusedBits + h;\n    };\n\n    /**\n     * set ASN.1 TLV value(V) by an array of boolean\n     * @name setByBooleanArray\n     * @memberOf KJUR.asn1.DERBitString\n     * @function\n     * @param {array} booleanArray array of boolean (ex. [true, false, true])\n     * @description\n     * NOTE: Trailing falses will be ignored.\n     */\n    this.setByBooleanArray = function(booleanArray) {\n\tvar s = '';\n\tfor (var i = 0; i < booleanArray.length; i++) {\n\t    if (booleanArray[i] == true) {\n\t\ts += '1';\n\t    } else {\n\t\ts += '0';\n\t    }\n\t}\n\tthis.setByBinaryString(s);\n    };\n\n    /**\n     * generate an array of false with specified length\n     * @name newFalseArray\n     * @memberOf KJUR.asn1.DERBitString\n     * @function\n     * @param {Integer} nLength length of array to generate\n     * @return {array} array of boolean faluse\n     * @description\n     * This static method may be useful to initialize boolean array.\n     */\n    this.newFalseArray = function(nLength) {\n\tvar a = new Array(nLength);\n\tfor (var i = 0; i < nLength; i++) {\n\t    a[i] = false;\n\t}\n\treturn a;\n    };\n\n    this.getFreshValueHex = function() {\n\treturn this.hV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params == \"string\" && params.toLowerCase().match(/^[0-9a-f]+$/)) {\n\t    this.setHexValueIncludingUnusedBits(params);\n        } else if (typeof params['hex'] != \"undefined\") {\n\t    this.setHexValueIncludingUnusedBits(params['hex']);\n\t} else if (typeof params['bin'] != \"undefined\") {\n\t    this.setByBinaryString(params['bin']);\n\t} else if (typeof params['array'] != \"undefined\") {\n\t    this.setByBooleanArray(params['array']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.DERBitString, KJUR.asn1.ASN1Object);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER OctetString\n * @name KJUR.asn1.DEROctetString\n * @class class for ASN.1 DER OctetString\n * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})\n * @extends KJUR.asn1.DERAbstractString\n * @description\n * @see KJUR.asn1.DERAbstractString - superclass\n */\nKJUR.asn1.DEROctetString = function(params) {\n    KJUR.asn1.DEROctetString.superclass.constructor.call(this, params);\n    this.hT = \"04\";\n};\nYAHOO.lang.extend(KJUR.asn1.DEROctetString, KJUR.asn1.DERAbstractString);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER Null\n * @name KJUR.asn1.DERNull\n * @class class for ASN.1 DER Null\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @see KJUR.asn1.ASN1Object - superclass\n */\nKJUR.asn1.DERNull = function() {\n    KJUR.asn1.DERNull.superclass.constructor.call(this);\n    this.hT = \"05\";\n    this.hTLV = \"0500\";\n};\nYAHOO.lang.extend(KJUR.asn1.DERNull, KJUR.asn1.ASN1Object);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER ObjectIdentifier\n * @name KJUR.asn1.DERObjectIdentifier\n * @class class for ASN.1 DER ObjectIdentifier\n * @param {Array} params associative array of parameters (ex. {'oid': '2.5.4.5'})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>oid - specify initial ASN.1 value(V) by a oid string (ex. 2.5.4.13)</li>\n * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n */\nKJUR.asn1.DERObjectIdentifier = function(params) {\n    var itox = function(i) {\n\tvar h = i.toString(16);\n\tif (h.length == 1) h = '0' + h;\n\treturn h;\n    };\n    var roidtox = function(roid) {\n\tvar h = '';\n\tvar bi = new BigInteger(roid, 10);\n\tvar b = bi.toString(2);\n\tvar padLen = 7 - b.length % 7;\n\tif (padLen == 7) padLen = 0;\n\tvar bPad = '';\n\tfor (var i = 0; i < padLen; i++) bPad += '0';\n\tb = bPad + b;\n\tfor (var i = 0; i < b.length - 1; i += 7) {\n\t    var b8 = b.substr(i, 7);\n\t    if (i != b.length - 7) b8 = '1' + b8;\n\t    h += itox(parseInt(b8, 2));\n\t}\n\treturn h;\n    }\n\n    KJUR.asn1.DERObjectIdentifier.superclass.constructor.call(this);\n    this.hT = \"06\";\n\n    /**\n     * set value by a hexadecimal string\n     * @name setValueHex\n     * @memberOf KJUR.asn1.DERObjectIdentifier\n     * @function\n     * @param {String} newHexString hexadecimal value of OID bytes\n     */\n    this.setValueHex = function(newHexString) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.s = null;\n\tthis.hV = newHexString;\n    };\n\n    /**\n     * set value by a OID string\n     * @name setValueOidString\n     * @memberOf KJUR.asn1.DERObjectIdentifier\n     * @function\n     * @param {String} oidString OID string (ex. 2.5.4.13)\n     */\n    this.setValueOidString = function(oidString) {\n\tif (! oidString.match(/^[0-9.]+$/)) {\n\t    throw \"malformed oid string: \" + oidString;\n\t}\n\tvar h = '';\n\tvar a = oidString.split('.');\n\tvar i0 = parseInt(a[0]) * 40 + parseInt(a[1]);\n\th += itox(i0);\n\ta.splice(0, 2);\n\tfor (var i = 0; i < a.length; i++) {\n\t    h += roidtox(a[i]);\n\t}\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.s = null;\n\tthis.hV = h;\n    };\n\n    /**\n     * set value by a OID name\n     * @name setValueName\n     * @memberOf KJUR.asn1.DERObjectIdentifier\n     * @function\n     * @param {String} oidName OID name (ex. 'serverAuth')\n     * @since 1.0.1\n     * @description\n     * OID name shall be defined in 'KJUR.asn1.x509.OID.name2oidList'.\n     * Otherwise raise error.\n     */\n    this.setValueName = function(oidName) {\n\tif (typeof KJUR.asn1.x509.OID.name2oidList[oidName] != \"undefined\") {\n\t    var oid = KJUR.asn1.x509.OID.name2oidList[oidName];\n\t    this.setValueOidString(oid);\n\t} else {\n\t    throw \"DERObjectIdentifier oidName undefined: \" + oidName;\n\t}\n    };\n\n    this.getFreshValueHex = function() {\n\treturn this.hV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params == \"string\" && params.match(/^[0-2].[0-9.]+$/)) {\n\t    this.setValueOidString(params);\n\t} else if (KJUR.asn1.x509.OID.name2oidList[params] !== undefined) {\n\t    this.setValueOidString(KJUR.asn1.x509.OID.name2oidList[params]);\n\t} else if (typeof params['oid'] != \"undefined\") {\n\t    this.setValueOidString(params['oid']);\n\t} else if (typeof params['hex'] != \"undefined\") {\n\t    this.setValueHex(params['hex']);\n\t} else if (typeof params['name'] != \"undefined\") {\n\t    this.setValueName(params['name']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.DERObjectIdentifier, KJUR.asn1.ASN1Object);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER UTF8String\n * @name KJUR.asn1.DERUTF8String\n * @class class for ASN.1 DER UTF8String\n * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})\n * @extends KJUR.asn1.DERAbstractString\n * @description\n * @see KJUR.asn1.DERAbstractString - superclass\n */\nKJUR.asn1.DERUTF8String = function(params) {\n    KJUR.asn1.DERUTF8String.superclass.constructor.call(this, params);\n    this.hT = \"0c\";\n};\nYAHOO.lang.extend(KJUR.asn1.DERUTF8String, KJUR.asn1.DERAbstractString);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER NumericString\n * @name KJUR.asn1.DERNumericString\n * @class class for ASN.1 DER NumericString\n * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})\n * @extends KJUR.asn1.DERAbstractString\n * @description\n * @see KJUR.asn1.DERAbstractString - superclass\n */\nKJUR.asn1.DERNumericString = function(params) {\n    KJUR.asn1.DERNumericString.superclass.constructor.call(this, params);\n    this.hT = \"12\";\n};\nYAHOO.lang.extend(KJUR.asn1.DERNumericString, KJUR.asn1.DERAbstractString);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER PrintableString\n * @name KJUR.asn1.DERPrintableString\n * @class class for ASN.1 DER PrintableString\n * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})\n * @extends KJUR.asn1.DERAbstractString\n * @description\n * @see KJUR.asn1.DERAbstractString - superclass\n */\nKJUR.asn1.DERPrintableString = function(params) {\n    KJUR.asn1.DERPrintableString.superclass.constructor.call(this, params);\n    this.hT = \"13\";\n};\nYAHOO.lang.extend(KJUR.asn1.DERPrintableString, KJUR.asn1.DERAbstractString);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER TeletexString\n * @name KJUR.asn1.DERTeletexString\n * @class class for ASN.1 DER TeletexString\n * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})\n * @extends KJUR.asn1.DERAbstractString\n * @description\n * @see KJUR.asn1.DERAbstractString - superclass\n */\nKJUR.asn1.DERTeletexString = function(params) {\n    KJUR.asn1.DERTeletexString.superclass.constructor.call(this, params);\n    this.hT = \"14\";\n};\nYAHOO.lang.extend(KJUR.asn1.DERTeletexString, KJUR.asn1.DERAbstractString);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER IA5String\n * @name KJUR.asn1.DERIA5String\n * @class class for ASN.1 DER IA5String\n * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})\n * @extends KJUR.asn1.DERAbstractString\n * @description\n * @see KJUR.asn1.DERAbstractString - superclass\n */\nKJUR.asn1.DERIA5String = function(params) {\n    KJUR.asn1.DERIA5String.superclass.constructor.call(this, params);\n    this.hT = \"16\";\n};\nYAHOO.lang.extend(KJUR.asn1.DERIA5String, KJUR.asn1.DERAbstractString);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER UTCTime\n * @name KJUR.asn1.DERUTCTime\n * @class class for ASN.1 DER UTCTime\n * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'})\n * @extends KJUR.asn1.DERAbstractTime\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>str - specify initial ASN.1 value(V) by a string (ex.'130430235959Z')</li>\n * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>\n * <li>date - specify Date object.</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n * <h4>EXAMPLES</h4>\n * @example\n * var d1 = new KJUR.asn1.DERUTCTime();\n * d1.setString('130430125959Z');\n *\n * var d2 = new KJUR.asn1.DERUTCTime({'str': '130430125959Z'});\n * var d3 = new KJUR.asn1.DERUTCTime({'date': new Date(Date.UTC(2015, 0, 31, 0, 0, 0, 0))});\n * var d4 = new KJUR.asn1.DERUTCTime('130430125959Z');\n */\nKJUR.asn1.DERUTCTime = function(params) {\n    KJUR.asn1.DERUTCTime.superclass.constructor.call(this, params);\n    this.hT = \"17\";\n\n    /**\n     * set value by a Date object\n     * @name setByDate\n     * @memberOf KJUR.asn1.DERUTCTime\n     * @function\n     * @param {Date} dateObject Date object to set ASN.1 value(V)\n     */\n    this.setByDate = function(dateObject) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.date = dateObject;\n\tthis.s = this.formatDate(this.date, 'utc');\n\tthis.hV = stohex(this.s);\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['str'] != \"undefined\") {\n\t    this.setString(params['str']);\n\t} else if (typeof params == \"string\" && params.match(/^[0-9]{12}Z$/)) {\n\t    this.setString(params);\n\t} else if (typeof params['hex'] != \"undefined\") {\n\t    this.setStringHex(params['hex']);\n\t} else if (typeof params['date'] != \"undefined\") {\n\t    this.setByDate(params['date']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.DERUTCTime, KJUR.asn1.DERAbstractTime);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER GeneralizedTime\n * @name KJUR.asn1.DERGeneralizedTime\n * @class class for ASN.1 DER GeneralizedTime\n * @param {Array} params associative array of parameters (ex. {'str': '20130430235959Z'})\n * @extends KJUR.asn1.DERAbstractTime\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>str - specify initial ASN.1 value(V) by a string (ex.'20130430235959Z')</li>\n * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>\n * <li>date - specify Date object.</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n */\nKJUR.asn1.DERGeneralizedTime = function(params) {\n    KJUR.asn1.DERGeneralizedTime.superclass.constructor.call(this, params);\n    this.hT = \"18\";\n\n    /**\n     * set value by a Date object\n     * @name setByDate\n     * @memberOf KJUR.asn1.DERGeneralizedTime\n     * @function\n     * @param {Date} dateObject Date object to set ASN.1 value(V)\n     * @example\n     * When you specify UTC time, use 'Date.UTC' method like this:<br/>\n     * var o = new DERUTCTime();\n     * var date = new Date(Date.UTC(2015, 0, 31, 23, 59, 59, 0)); #2015JAN31 23:59:59\n     * o.setByDate(date);\n     */\n    this.setByDate = function(dateObject) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.date = dateObject;\n\tthis.s = this.formatDate(this.date, 'gen');\n\tthis.hV = stohex(this.s);\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['str'] != \"undefined\") {\n\t    this.setString(params['str']);\n\t} else if (typeof params == \"string\" && params.match(/^[0-9]{14}Z$/)) {\n\t    this.setString(params);\n\t} else if (typeof params['hex'] != \"undefined\") {\n\t    this.setStringHex(params['hex']);\n\t} else if (typeof params['date'] != \"undefined\") {\n\t    this.setByDate(params['date']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.DERGeneralizedTime, KJUR.asn1.DERAbstractTime);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER Sequence\n * @name KJUR.asn1.DERSequence\n * @class class for ASN.1 DER Sequence\n * @extends KJUR.asn1.DERAbstractStructured\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>array - specify array of ASN1Object to set elements of content</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n */\nKJUR.asn1.DERSequence = function(params) {\n    KJUR.asn1.DERSequence.superclass.constructor.call(this, params);\n    this.hT = \"30\";\n    this.getFreshValueHex = function() {\n\tvar h = '';\n\tfor (var i = 0; i < this.asn1Array.length; i++) {\n\t    var asn1Obj = this.asn1Array[i];\n\t    h += asn1Obj.getEncodedHex();\n\t}\n\tthis.hV = h;\n\treturn this.hV;\n    };\n};\nYAHOO.lang.extend(KJUR.asn1.DERSequence, KJUR.asn1.DERAbstractStructured);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER Set\n * @name KJUR.asn1.DERSet\n * @class class for ASN.1 DER Set\n * @extends KJUR.asn1.DERAbstractStructured\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>array - specify array of ASN1Object to set elements of content</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n */\nKJUR.asn1.DERSet = function(params) {\n    KJUR.asn1.DERSet.superclass.constructor.call(this, params);\n    this.hT = \"31\";\n    this.getFreshValueHex = function() {\n\tvar a = new Array();\n\tfor (var i = 0; i < this.asn1Array.length; i++) {\n\t    var asn1Obj = this.asn1Array[i];\n\t    a.push(asn1Obj.getEncodedHex());\n\t}\n\ta.sort();\n\tthis.hV = a.join('');\n\treturn this.hV;\n    };\n};\nYAHOO.lang.extend(KJUR.asn1.DERSet, KJUR.asn1.DERAbstractStructured);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER TaggedObject\n * @name KJUR.asn1.DERTaggedObject\n * @class class for ASN.1 DER TaggedObject\n * @extends KJUR.asn1.ASN1Object\n * @description\n * <br/>\n * Parameter 'tagNoNex' is ASN.1 tag(T) value for this object.\n * For example, if you find '[1]' tag in a ASN.1 dump, \n * 'tagNoHex' will be 'a1'.\n * <br/>\n * As for optional argument 'params' for constructor, you can specify *ANY* of\n * following properties:\n * <ul>\n * <li>explicit - specify true if this is explicit tag otherwise false \n *     (default is 'true').</li>\n * <li>tag - specify tag (default is 'a0' which means [0])</li>\n * <li>obj - specify ASN1Object which is tagged</li>\n * </ul>\n * @example\n * d1 = new KJUR.asn1.DERUTF8String({'str':'a'});\n * d2 = new KJUR.asn1.DERTaggedObject({'obj': d1});\n * hex = d2.getEncodedHex();\n */\nKJUR.asn1.DERTaggedObject = function(params) {\n    KJUR.asn1.DERTaggedObject.superclass.constructor.call(this);\n    this.hT = \"a0\";\n    this.hV = '';\n    this.isExplicit = true;\n    this.asn1Object = null;\n\n    /**\n     * set value by an ASN1Object\n     * @name setString\n     * @memberOf KJUR.asn1.DERTaggedObject\n     * @function\n     * @param {Boolean} isExplicitFlag flag for explicit/implicit tag\n     * @param {Integer} tagNoHex hexadecimal string of ASN.1 tag\n     * @param {ASN1Object} asn1Object ASN.1 to encapsulate\n     */\n    this.setASN1Object = function(isExplicitFlag, tagNoHex, asn1Object) {\n\tthis.hT = tagNoHex;\n\tthis.isExplicit = isExplicitFlag;\n\tthis.asn1Object = asn1Object;\n\tif (this.isExplicit) {\n\t    this.hV = this.asn1Object.getEncodedHex();\n\t    this.hTLV = null;\n\t    this.isModified = true;\n\t} else {\n\t    this.hV = null;\n\t    this.hTLV = asn1Object.getEncodedHex();\n\t    this.hTLV = this.hTLV.replace(/^../, tagNoHex);\n\t    this.isModified = false;\n\t}\n    };\n\n    this.getFreshValueHex = function() {\n\treturn this.hV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['tag'] != \"undefined\") {\n\t    this.hT = params['tag'];\n\t}\n\tif (typeof params['explicit'] != \"undefined\") {\n\t    this.isExplicit = params['explicit'];\n\t}\n\tif (typeof params['obj'] != \"undefined\") {\n\t    this.asn1Object = params['obj'];\n\t    this.setASN1Object(this.isExplicit, this.hT, this.asn1Object);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.DERTaggedObject, KJUR.asn1.ASN1Object);\n"
  },
  {
    "path": "JavaScript/demo/js/asn1hex-1.1.js",
    "content": "/*! asn1hex-1.1.4.js (c) 2012-2013 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n/*\n * asn1hex.js - Hexadecimal represented ASN.1 string library\n *\n * Copyright (c) 2010-2013 Kenji Urushima (kenji.urushima@gmail.com)\n *\n * This software is licensed under the terms of the MIT License.\n * http://kjur.github.com/jsrsasign/license/\n *\n * The above copyright and license notice shall be \n * included in all copies or substantial portions of the Software.\n */\n\n/**\n * @fileOverview\n * @name asn1hex-1.1.js\n * @author Kenji Urushima kenji.urushima@gmail.com\n * @version asn1hex 1.1.4 (2013-Oct-02)\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\n */\n\n/*\n * MEMO:\n *   f('3082025b02...', 2) ... 82025b ... 3bytes\n *   f('020100', 2) ... 01 ... 1byte\n *   f('0203001...', 2) ... 03 ... 1byte\n *   f('02818003...', 2) ... 8180 ... 2bytes\n *   f('3080....0000', 2) ... 80 ... -1\n *\n *   Requirements:\n *   - ASN.1 type octet length MUST be 1. \n *     (i.e. ASN.1 primitives like SET, SEQUENCE, INTEGER, OCTETSTRING ...)\n */\n\n/**\n * ASN.1 DER encoded hexadecimal string utility class\n * @name ASN1HEX\n * @class ASN.1 DER encoded hexadecimal string utility class\n * @since jsrsasign 1.1\n */\nvar ASN1HEX = new function() {\n    /**\n     * get byte length for ASN.1 L(length) bytes\n     * @name getByteLengthOfL_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} s hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} pos string index\n     * @return byte length for ASN.1 L(length) bytes\n     */\n    this.getByteLengthOfL_AtObj = function(s, pos) {\n\tif (s.substring(pos + 2, pos + 3) != '8') return 1;\n\tvar i = parseInt(s.substring(pos + 3, pos + 4));\n\tif (i == 0) return -1; \t\t// length octet '80' indefinite length\n\tif (0 < i && i < 10) return i + 1;\t// including '8?' octet;\n\treturn -2;\t\t\t\t// malformed format\n    };\n\n    /**\n     * get hexadecimal string for ASN.1 L(length) bytes\n     * @name getHexOfL_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} s hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} pos string index\n     * @return {String} hexadecimal string for ASN.1 L(length) bytes\n     */\n    this.getHexOfL_AtObj = function(s, pos) {\n\tvar len = this.getByteLengthOfL_AtObj(s, pos);\n\tif (len < 1) return '';\n\treturn s.substring(pos + 2, pos + 2 + len * 2);\n    };\n\n    //   getting ASN.1 length value at the position 'idx' of\n    //   hexa decimal string 's'.\n    //\n    //   f('3082025b02...', 0) ... 82025b ... ???\n    //   f('020100', 0) ... 01 ... 1\n    //   f('0203001...', 0) ... 03 ... 3\n    //   f('02818003...', 0) ... 8180 ... 128\n    /**\n     * get integer value of ASN.1 length for ASN.1 data\n     * @name getIntOfL_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} s hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} pos string index\n     * @return ASN.1 L(length) integer value\n     */\n    this.getIntOfL_AtObj = function(s, pos) {\n\tvar hLength = this.getHexOfL_AtObj(s, pos);\n\tif (hLength == '') return -1;\n\tvar bi;\n\tif (parseInt(hLength.substring(0, 1)) < 8) {\n\t    bi = new BigInteger(hLength, 16);\n\t} else {\n\t    bi = new BigInteger(hLength.substring(2), 16);\n\t}\n\treturn bi.intValue();\n    };\n\n    /**\n     * get ASN.1 value starting string position for ASN.1 object refered by index 'idx'.\n     * @name getStartPosOfV_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} s hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} pos string index\n     */\n    this.getStartPosOfV_AtObj = function(s, pos) {\n\tvar l_len = this.getByteLengthOfL_AtObj(s, pos);\n\tif (l_len < 0) return l_len;\n\treturn pos + (l_len + 1) * 2;\n    };\n\n    /**\n     * get hexadecimal string of ASN.1 V(value)\n     * @name getHexOfV_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} s hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} pos string index\n     * @return {String} hexadecimal string of ASN.1 value.\n     */\n    this.getHexOfV_AtObj = function(s, pos) {\n\tvar pos1 = this.getStartPosOfV_AtObj(s, pos);\n\tvar len = this.getIntOfL_AtObj(s, pos);\n\treturn s.substring(pos1, pos1 + len * 2);\n    };\n\n    /**\n     * get hexadecimal string of ASN.1 TLV at\n     * @name getHexOfTLV_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} s hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} pos string index\n     * @return {String} hexadecimal string of ASN.1 TLV.\n     * @since 1.1\n     */\n    this.getHexOfTLV_AtObj = function(s, pos) {\n\tvar hT = s.substr(pos, 2);\n\tvar hL = this.getHexOfL_AtObj(s, pos);\n\tvar hV = this.getHexOfV_AtObj(s, pos);\n\treturn hT + hL + hV;\n    };\n\n    /**\n     * get next sibling starting index for ASN.1 object string\n     * @name getPosOfNextSibling_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} s hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} pos string index\n     * @return next sibling starting index for ASN.1 object string\n     */\n    this.getPosOfNextSibling_AtObj = function(s, pos) {\n\tvar pos1 = this.getStartPosOfV_AtObj(s, pos);\n\tvar len = this.getIntOfL_AtObj(s, pos);\n\treturn pos1 + len * 2;\n    };\n\n    /**\n     * get array of indexes of child ASN.1 objects\n     * @name getPosArrayOfChildren_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} s hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} start string index of ASN.1 object\n     * @return {Array of Number} array of indexes for childen of ASN.1 objects\n     */\n    this.getPosArrayOfChildren_AtObj = function(h, pos) {\n\tvar a = new Array();\n\tvar p0 = this.getStartPosOfV_AtObj(h, pos);\n\ta.push(p0);\n\n\tvar len = this.getIntOfL_AtObj(h, pos);\n\tvar p = p0;\n\tvar k = 0;\n\twhile (1) {\n\t    var pNext = this.getPosOfNextSibling_AtObj(h, p);\n\t    if (pNext == null || (pNext - p0  >= (len * 2))) break;\n\t    if (k >= 200) break;\n\t    \n\t    a.push(pNext);\n\t    p = pNext;\n\t    \n\t    k++;\n\t}\n\t\n\treturn a;\n    };\n\n    /**\n     * get string index of nth child object of ASN.1 object refered by h, idx\n     * @name getNthChildIndex_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} h hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} idx start string index of ASN.1 object\n     * @param {Number} nth for child\n     * @return {Number} string index of nth child.\n     * @since 1.1\n     */\n    this.getNthChildIndex_AtObj = function(h, idx, nth) {\n\tvar a = this.getPosArrayOfChildren_AtObj(h, idx);\n\treturn a[nth];\n    };\n\n    // ========== decendant methods ==============================\n    /**\n     * get string index of nth child object of ASN.1 object refered by h, idx\n     * @name getDecendantIndexByNthList\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} h hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} currentIndex start string index of ASN.1 object\n     * @param {Array of Number} nthList array list of nth\n     * @return {Number} string index refered by nthList\n     * @since 1.1\n     * @example\n     * The \"nthList\" is a index list of structured ASN.1 object\n     * reference. Here is a sample structure and \"nthList\"s which\n     * refers each objects.\n     *\n     * SQUENCE               - [0]\n     *   SEQUENCE            - [0, 0]\n     *     IA5STRING 000     - [0, 0, 0]\n     *     UTF8STRING 001    - [0, 0, 1]\n     *   SET                 - [0, 1]\n     *     IA5STRING 010     - [0, 1, 0]\n     *     UTF8STRING 011    - [0, 1, 1]\n     */\n    this.getDecendantIndexByNthList = function(h, currentIndex, nthList) {\n\tif (nthList.length == 0) {\n\t    return currentIndex;\n\t}\n\tvar firstNth = nthList.shift();\n\tvar a = this.getPosArrayOfChildren_AtObj(h, currentIndex);\n\treturn this.getDecendantIndexByNthList(h, a[firstNth], nthList);\n    };\n\n    /**\n     * get hexadecimal string of ASN.1 TLV refered by current index and nth index list.\n     * @name getDecendantHexTLVByNthList\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} h hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} currentIndex start string index of ASN.1 object\n     * @param {Array of Number} nthList array list of nth\n     * @return {Number} hexadecimal string of ASN.1 TLV refered by nthList\n     * @since 1.1\n     */\n    this.getDecendantHexTLVByNthList = function(h, currentIndex, nthList) {\n\tvar idx = this.getDecendantIndexByNthList(h, currentIndex, nthList);\n\treturn this.getHexOfTLV_AtObj(h, idx);\n    };\n\n    /**\n     * get hexadecimal string of ASN.1 V refered by current index and nth index list.\n     * @name getDecendantHexVByNthList\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} h hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} currentIndex start string index of ASN.1 object\n     * @param {Array of Number} nthList array list of nth\n     * @return {Number} hexadecimal string of ASN.1 V refered by nthList\n     * @since 1.1\n     */\n    this.getDecendantHexVByNthList = function(h, currentIndex, nthList) {\n\tvar idx = this.getDecendantIndexByNthList(h, currentIndex, nthList);\n\treturn this.getHexOfV_AtObj(h, idx);\n    };\n};\n\n/*\n * @since asn1hex 1.1.4\n */\nASN1HEX.getVbyList = function(h, currentIndex, nthList, checkingTag) {\n    var idx = this.getDecendantIndexByNthList(h, currentIndex, nthList);\n    if (idx === undefined) {\n\tthrow \"can't find nthList object\";\n    }\n    if (checkingTag !== undefined) {\n\tif (h.substr(idx, 2) != checkingTag) {\n\t    throw \"checking tag doesn't match: \" + h.substr(idx,2) + \"!=\" + checkingTag;\n\t}\n    }\n    return this.getHexOfV_AtObj(h, idx);\n};\n\n"
  },
  {
    "path": "JavaScript/demo/js/asn1x509-1.0.js",
    "content": "/*! asn1x509-1.0.7.js (c) 2013 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n/*\n * asn1x509.js - ASN.1 DER encoder classes for X.509 certificate\n *\n * Copyright (c) 2013 Kenji Urushima (kenji.urushima@gmail.com)\n *\n * This software is licensed under the terms of the MIT License.\n * http://kjur.github.com/jsrsasign/license\n *\n * The above copyright and license notice shall be \n * included in all copies or substantial portions of the Software.\n */\n\n/**\n * @fileOverview\n * @name asn1x509-1.0.js\n * @author Kenji Urushima kenji.urushima@gmail.com\n * @version 1.0.7 (2013-Oct-11)\n * @since jsrsasign 2.1\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\n */\n\n/** \n * kjur's class library name space\n * // already documented in asn1-1.0.js\n * @name KJUR\n * @namespace kjur's class library name space\n */\nif (typeof KJUR == \"undefined\" || !KJUR) KJUR = {};\n\n/**\n * kjur's ASN.1 class library name space\n * // already documented in asn1-1.0.js\n * @name KJUR.asn1\n * @namespace\n */\nif (typeof KJUR.asn1 == \"undefined\" || !KJUR.asn1) KJUR.asn1 = {};\n\n/**\n * kjur's ASN.1 class for X.509 certificate library name space\n * <p>\n * <h4>FEATURES</h4>\n * <ul>\n * <li>easily issue any kind of certificate</li>\n * <li>APIs are very similar to BouncyCastle library ASN.1 classes. So easy to learn.</li>\n * </ul>\n * </p>\n * <h4>PROVIDED CLASSES</h4>\n * <ul>\n * <li>{@link KJUR.asn1.x509.Certificate}</li>\n * <li>{@link KJUR.asn1.x509.TBSCertificate}</li>\n * <li>{@link KJUR.asn1.x509.Extension}</li>\n * <li>{@link KJUR.asn1.x509.X500Name}</li>\n * <li>{@link KJUR.asn1.x509.RDN}</li>\n * <li>{@link KJUR.asn1.x509.AttributeTypeAndValue}</li>\n * <li>{@link KJUR.asn1.x509.SubjectPublicKeyInfo}</li>\n * <li>{@link KJUR.asn1.x509.AlgorithmIdentifier}</li>\n * <li>{@link KJUR.asn1.x509.GeneralName}</li>\n * <li>{@link KJUR.asn1.x509.GeneralNames}</li>\n * <li>{@link KJUR.asn1.x509.DistributionPointName}</li>\n * <li>{@link KJUR.asn1.x509.DistributionPoint}</li>\n * <li>{@link KJUR.asn1.x509.CRL}</li>\n * <li>{@link KJUR.asn1.x509.TBSCertList}</li>\n * <li>{@link KJUR.asn1.x509.CRLEntry}</li>\n * <li>{@link KJUR.asn1.x509.OID}</li>\n * </ul>\n * <h4>SUPPORTED EXTENSIONS</h4>\n * <ul>\n * <li>{@link KJUR.asn1.x509.BasicConstraints}</li>\n * <li>{@link KJUR.asn1.x509.KeyUsage}</li>\n * <li>{@link KJUR.asn1.x509.CRLDistributionPoints}</li>\n * <li>{@link KJUR.asn1.x509.ExtKeyUsage}</li>\n * </ul>\n * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.\n * @name KJUR.asn1.x509\n * @namespace\n */\nif (typeof KJUR.asn1.x509 == \"undefined\" || !KJUR.asn1.x509) KJUR.asn1.x509 = {};\n\n// === BEGIN Certificate ===================================================\n\n/**\n * X.509 Certificate class to sign and generate hex encoded certificate\n * @name KJUR.asn1.x509.Certificate\n * @class X.509 Certificate class to sign and generate hex encoded certificate\n * @param {Array} params associative array of parameters (ex. {'tbscertobj': obj, 'prvkeyobj': key})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>tbscertobj - specify {@link KJUR.asn1.x509.TBSCertificate} object</li>\n * <li>prvkeyobj - specify {@link RSAKey}, {@link KJUR.crypto.ECDSA} or {@link KJUR.crypto.DSA} object for CA private key to sign the certificate</li>\n * <li>(DEPRECATED)rsaprvkey - specify {@link RSAKey} object CA private key</li>\n * <li>(DEPRECATED)rsaprvpem - specify PEM string of RSA CA private key</li>\n * </ul>\n * NOTE1: 'params' can be omitted.<br/>\n * NOTE2: DSA/ECDSA is also supported for CA signging key from asn1x509 1.0.6.\n * @example\n * var caKey = KEYUTIL.getKey(caKeyPEM); // CA's private key\n * var cert = new KJUR.asn1x509.Certificate({'tbscertobj': tbs, 'prvkeyobj': caKey});\n * cert.sign(); // issue certificate by CA's private key\n * var certPEM = cert.getPEMString();\n *\n * // Certificate  ::=  SEQUENCE  {\n * //     tbsCertificate       TBSCertificate,\n * //     signatureAlgorithm   AlgorithmIdentifier,\n * //     signature            BIT STRING  }\t    \n */\nKJUR.asn1.x509.Certificate = function(params) {\n    KJUR.asn1.x509.Certificate.superclass.constructor.call(this);\n    var asn1TBSCert = null;\n    var asn1SignatureAlg = null;\n    var asn1Sig = null;\n    var hexSig = null;\n    var prvKey = null;\n    var rsaPrvKey = null; // DEPRECATED\n\n    \n    /**\n     * set PKCS#5 encrypted RSA PEM private key as CA key\n     * @name setRsaPrvKeyByPEMandPass\n     * @memberOf KJUR.asn1.x509.Certificate\n     * @function\n     * @param {String} rsaPEM string of PKCS#5 encrypted RSA PEM private key\n     * @param {String} passPEM passcode string to decrypt private key\n     * @since 1.0.1\n     * @description\n     * <br/>\n     * <h4>EXAMPLES</h4>\n     * @example\n     * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs});\n     * cert.setRsaPrvKeyByPEMandPass(\"-----BEGIN RSA PRIVATE..(snip)\", \"password\");\n     */\n    this.setRsaPrvKeyByPEMandPass = function(rsaPEM, passPEM) {\n\tvar caKeyHex = PKCS5PKEY.getDecryptedKeyHex(rsaPEM, passPEM);\n\tvar caKey = new RSAKey();\n\tcaKey.readPrivateKeyFromASN1HexString(caKeyHex);  \n\tthis.prvKey = caKey;\n    };\n\n    /**\n     * sign TBSCertificate and set signature value internally\n     * @name sign\n     * @memberOf KJUR.asn1.x509.Certificate\n     * @function\n     * @description\n     * @example\n     * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs, 'rsaprvkey': prvKey});\n     * cert.sign();\n     */\n    this.sign = function() {\n\tthis.asn1SignatureAlg = this.asn1TBSCert.asn1SignatureAlg;\n\n\tsig = new KJUR.crypto.Signature({'alg': 'SHA1withRSA'});\n\tsig.init(this.prvKey);\n\tsig.updateHex(this.asn1TBSCert.getEncodedHex());\n\tthis.hexSig = sig.sign();\n\n\tthis.asn1Sig = new KJUR.asn1.DERBitString({'hex': '00' + this.hexSig});\n\t\n\tvar seq = new KJUR.asn1.DERSequence({'array': [this.asn1TBSCert,\n\t\t\t\t\t\t       this.asn1SignatureAlg,\n\t\t\t\t\t\t       this.asn1Sig]});\n\tthis.hTLV = seq.getEncodedHex();\n\tthis.isModified = false;\n    };\n\n    this.getEncodedHex = function() {\n\tif (this.isModified == false && this.hTLV != null) return this.hTLV;\n\tthrow \"not signed yet\";\n    };\n\n    /**\n     * get PEM formatted certificate string after signed\n     * @name getPEMString\n     * @memberOf KJUR.asn1.x509.Certificate\n     * @function\n     * @return PEM formatted string of certificate\n     * @description\n     * @example\n     * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs, 'rsaprvkey': prvKey});\n     * cert.sign();\n     * var sPEM =  cert.getPEMString();\n     */\n    this.getPEMString = function() {\n\tvar hCert = this.getEncodedHex();\n\tvar wCert = CryptoJS.enc.Hex.parse(hCert);\n\tvar b64Cert = CryptoJS.enc.Base64.stringify(wCert);\n\tvar pemBody = b64Cert.replace(/(.{64})/g, \"$1\\r\\n\");\n\treturn \"-----BEGIN CERTIFICATE-----\\r\\n\" + pemBody + \"\\r\\n-----END CERTIFICATE-----\\r\\n\";\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['tbscertobj'] != \"undefined\") {\n\t    this.asn1TBSCert = params['tbscertobj'];\n\t}\n\tif (typeof params['prvkeyobj'] != \"undefined\") {\n\t    this.prvKey = params['prvkeyobj'];\n\t} else if (typeof params['rsaprvkey'] != \"undefined\") {\n\t    this.prvKey = params['rsaprvkey'];\n        } else if ((typeof params['rsaprvpem'] != \"undefined\") &&\n\t    (typeof params['rsaprvpas'] != \"undefined\")) {\n\t    this.setRsaPrvKeyByPEMandPass(params['rsaprvpem'], params['rsaprvpas']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.Certificate, KJUR.asn1.ASN1Object);\n\n/**\n * ASN.1 TBSCertificate structure class\n * @name KJUR.asn1.x509.TBSCertificate\n * @class ASN.1 TBSCertificate structure class\n * @param {Array} params associative array of parameters (ex. {})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * <br/>\n * <h4>EXAMPLE</h4>\n * @example\n *  var o = new KJUR.asn1.x509.TBSCertificate();\n *  o.setSerialNumberByParam({'int': 4});\n *  o.setSignatureAlgByParam({'name': 'SHA1withRSA'});\n *  o.setIssuerByParam({'str': '/C=US/O=a'});\n *  o.setNotBeforeByParam({'str': '130504235959Z'});\n *  o.setNotAfterByParam({'str': '140504235959Z'});\n *  o.setSubjectByParam({'str': '/C=US/CN=b'});\n *  o.setSubjectPublicKeyByParam({'rsakey': rsaKey});\n *  o.appendExtension(new KJUR.asn1.x509.BasicConstraints({'cA':true}));\n *  o.appendExtension(new KJUR.asn1.x509.KeyUsage({'bin':'11'}));\n */\nKJUR.asn1.x509.TBSCertificate = function(params) {\n    KJUR.asn1.x509.TBSCertificate.superclass.constructor.call(this);\n\n    this._initialize = function() {\n\tthis.asn1Array = new Array();\n\n\tthis.asn1Version = \n\t    new KJUR.asn1.DERTaggedObject({'obj': new KJUR.asn1.DERInteger({'int': 2})});\n\tthis.asn1SerialNumber = null;\n\tthis.asn1SignatureAlg = null;\n\tthis.asn1Issuer = null;\n\tthis.asn1NotBefore = null;\n\tthis.asn1NotAfter = null;\n\tthis.asn1Subject = null;\n\tthis.asn1SubjPKey = null;\n\tthis.extensionsArray = new Array();\n    };\n\n    /**\n     * set serial number field by parameter\n     * @name setSerialNumberByParam\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Array} intParam DERInteger param\n     * @description\n     * @example\n     * tbsc.setSerialNumberByParam({'int': 3});\n     */\n    this.setSerialNumberByParam = function(intParam) {\n\tthis.asn1SerialNumber = new KJUR.asn1.DERInteger(intParam);\n    };\n\n    /**\n     * set signature algorithm field by parameter\n     * @name setSignatureAlgByParam\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Array} algIdParam AlgorithmIdentifier parameter\n     * @description\n     * @example\n     * tbsc.setSignatureAlgByParam({'name': 'SHA1withRSA'});\n     */\n    this.setSignatureAlgByParam = function(algIdParam) {\n\tthis.asn1SignatureAlg = new KJUR.asn1.x509.AlgorithmIdentifier(algIdParam);\n    };\n\n    /**\n     * set issuer name field by parameter\n     * @name setIssuerByParam\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Array} x500NameParam X500Name parameter\n     * @description\n     * @example\n     * tbsc.setIssuerParam({'str': '/C=US/CN=b'});\n     * @see KJUR.asn1.x509.X500Name\n     */\n    this.setIssuerByParam = function(x500NameParam) {\n\tthis.asn1Issuer = new KJUR.asn1.x509.X500Name(x500NameParam);\n    };\n\n    /**\n     * set notBefore field by parameter\n     * @name setNotBeforeByParam\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Array} timeParam Time parameter\n     * @description\n     * @example\n     * tbsc.setNotBeforeByParam({'str': '130508235959Z'});\n     * @see KJUR.asn1.x509.Time\n     */\n    this.setNotBeforeByParam = function(timeParam) {\n\tthis.asn1NotBefore = new KJUR.asn1.x509.Time(timeParam);\n    };\n    \n    /**\n     * set notAfter field by parameter\n     * @name setNotAfterByParam\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Array} timeParam Time parameter\n     * @description\n     * @example\n     * tbsc.setNotAfterByParam({'str': '130508235959Z'});\n     * @see KJUR.asn1.x509.Time\n     */\n    this.setNotAfterByParam = function(timeParam) {\n\tthis.asn1NotAfter = new KJUR.asn1.x509.Time(timeParam);\n    };\n\n    /**\n     * set subject name field by parameter\n     * @name setSubjectByParam\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Array} x500NameParam X500Name parameter\n     * @description\n     * @example\n     * tbsc.setSubjectParam({'str': '/C=US/CN=b'});\n     * @see KJUR.asn1.x509.X500Name\n     */\n    this.setSubjectByParam = function(x500NameParam) {\n\tthis.asn1Subject = new KJUR.asn1.x509.X500Name(x500NameParam);\n    };\n\n    /**\n     * (DEPRECATED) set subject public key info field by RSA key parameter\n     * @name setSubjectPublicKeyByParam\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Array} subjPKeyParam SubjectPublicKeyInfo parameter of RSA\n     * @deprecated\n     * @description\n     * @example\n     * tbsc.setSubjectPublicKeyByParam({'rsakey': pubKey});\n     * @see KJUR.asn1.x509.SubjectPublicKeyInfo\n     */\n    this.setSubjectPublicKeyByParam = function(subjPKeyParam) {\n\tthis.asn1SubjPKey = new KJUR.asn1.x509.SubjectPublicKeyInfo(subjPKeyParam);\n    };\n\n    /**\n     * set subject public key info by RSA/ECDSA/DSA key parameter\n     * @name setSubjectPublicKeyByGetKey\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Object} keyParam public key parameter which passed to {@link KEYUTIL.getKey} argument\n     * @description\n     * @example\n     * tbsc.setSubjectPublicKeyByGetKeyParam(certPEMString); // or \n     * tbsc.setSubjectPublicKeyByGetKeyParam(pkcs8PublicKeyPEMString); // or \n     * tbsc.setSubjectPublicKeyByGetKeyParam(kjurCryptoECDSAKeyObject); // et.al.\n     * @see KJUR.asn1.x509.SubjectPublicKeyInfo\n     * @see KEYUTIL.getKey\n     * @since asn1x509 1.0.6\n     */\n    this.setSubjectPublicKeyByGetKey = function(keyParam) {\n\tvar keyObj = KEYUTIL.getKey(keyParam);\n\tthis.asn1SubjPKey = new KJUR.asn1.x509.SubjectPublicKeyInfo(keyObj);\n    };\n\n    /**\n     * append X.509v3 extension to this object\n     * @name appendExtension\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Extension} extObj X.509v3 Extension object\n     * @description\n     * @example\n     * tbsc.appendExtension(new KJUR.asn1.x509.BasicConstraints({'cA':true, 'critical': true}));\n     * tbsc.appendExtension(new KJUR.asn1.x509.KeyUsage({'bin':'11'}));\n     * @see KJUR.asn1.x509.Extension\n     */\n    this.appendExtension = function(extObj) {\n\tthis.extensionsArray.push(extObj);\n    };\n\n    /**\n     * append X.509v3 extension to this object by name and parameters\n     * @name appendExtensionByName\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {name} name name of X.509v3 Extension object\n     * @param {Array} extParams parameters as argument of Extension constructor.\n     * @description\n     * @example\n     * tbsc.appendExtensionByName('BasicConstraints', {'cA':true, 'critical': true});\n     * tbsc.appendExtensionByName('KeyUsage', {'bin':'11'});\n     * tbsc.appendExtensionByName('CRLDistributionPoints', {uri: 'http://aaa.com/a.crl'});\n     * tbsc.appendExtensionByName('ExtKeyUsage', {array: [{name: 'clientAuth'}]});\n     * @see KJUR.asn1.x509.Extension\n     */\n    this.appendExtensionByName = function(name, extParams) {\n\tif (name.toLowerCase() == \"basicconstraints\") {\n\t    var extObj = new KJUR.asn1.x509.BasicConstraints(extParams);\n\t    this.appendExtension(extObj);\n\t} else if (name.toLowerCase() == \"keyusage\") {\n\t    var extObj = new KJUR.asn1.x509.KeyUsage(extParams);\n\t    this.appendExtension(extObj);\n\t} else if (name.toLowerCase() == \"crldistributionpoints\") {\n\t    var extObj = new KJUR.asn1.x509.CRLDistributionPoints(extParams);\n\t    this.appendExtension(extObj);\n\t} else if (name.toLowerCase() == \"extkeyusage\") {\n\t    var extObj = new KJUR.asn1.x509.ExtKeyUsage(extParams);\n\t    this.appendExtension(extObj);\n\t} else {\n\t    throw \"unsupported extension name: \" + name;\n\t}\n    };\n\n    this.getEncodedHex = function() {\n\tif (this.asn1NotBefore == null || this.asn1NotAfter == null)\n\t    throw \"notBefore and/or notAfter not set\";\n\tvar asn1Validity = \n\t    new KJUR.asn1.DERSequence({'array':[this.asn1NotBefore, this.asn1NotAfter]});\n\n\tthis.asn1Array = new Array();\n\n\tthis.asn1Array.push(this.asn1Version);\n\tthis.asn1Array.push(this.asn1SerialNumber);\n\tthis.asn1Array.push(this.asn1SignatureAlg);\n\tthis.asn1Array.push(this.asn1Issuer);\n\tthis.asn1Array.push(asn1Validity);\n\tthis.asn1Array.push(this.asn1Subject);\n\tthis.asn1Array.push(this.asn1SubjPKey);\n\n\tif (this.extensionsArray.length > 0) {\n\t    var extSeq = new KJUR.asn1.DERSequence({\"array\": this.extensionsArray});\n\t    var extTagObj = new KJUR.asn1.DERTaggedObject({'explicit': true,\n\t\t\t\t\t\t\t   'tag': 'a3',\n\t\t\t\t\t\t\t   'obj': extSeq});\n\t    this.asn1Array.push(extTagObj);\n\t}\n\n\tvar o = new KJUR.asn1.DERSequence({\"array\": this.asn1Array});\n\tthis.hTLV = o.getEncodedHex();\n\tthis.isModified = false;\n\treturn this.hTLV;\n    };\n\n    this._initialize();\n};\nYAHOO.lang.extend(KJUR.asn1.x509.TBSCertificate, KJUR.asn1.ASN1Object);\n\n// === END   TBSCertificate ===================================================\n\n// === BEGIN X.509v3 Extensions Related =======================================\n\n/**\n * base Extension ASN.1 structure class\n * @name KJUR.asn1.x509.Extension\n * @class base Extension ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'critical': true})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @example\n * // Extension  ::=  SEQUENCE  {\n * //     extnID      OBJECT IDENTIFIER,\n * //     critical    BOOLEAN DEFAULT FALSE,\n * //     extnValue   OCTET STRING  }\n */\nKJUR.asn1.x509.Extension = function(params) {\n    KJUR.asn1.x509.Extension.superclass.constructor.call(this);\n    var asn1ExtnValue = null;\n\n    this.getEncodedHex = function() {\n\tvar asn1Oid = new KJUR.asn1.DERObjectIdentifier({'oid': this.oid});\n\tvar asn1EncapExtnValue = \n\t    new KJUR.asn1.DEROctetString({'hex': this.getExtnValueHex()});\n\n\tvar asn1Array = new Array();\n\tasn1Array.push(asn1Oid);\n\tif (this.critical) asn1Array.push(new KJUR.asn1.DERBoolean());\n\tasn1Array.push(asn1EncapExtnValue);\n\n\tvar asn1Seq = new KJUR.asn1.DERSequence({'array': asn1Array});\n\treturn asn1Seq.getEncodedHex();\n    };\n\n    this.critical = false;\n    if (typeof params != \"undefined\") {\n\tif (typeof params['critical'] != \"undefined\") {\n\t    this.critical = params['critical'];\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.Extension, KJUR.asn1.ASN1Object);\n\n/**\n * KeyUsage ASN.1 structure class\n * @name KJUR.asn1.x509.KeyUsage\n * @class KeyUsage ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'bin': '11', 'critical': true})\n * @extends KJUR.asn1.x509.Extension\n * @description\n * @example\n */\nKJUR.asn1.x509.KeyUsage = function(params) {\n    KJUR.asn1.x509.KeyUsage.superclass.constructor.call(this, params);\n\n    this.getExtnValueHex = function() {\n\treturn this.asn1ExtnValue.getEncodedHex();\n    };\n\n    this.oid = \"2.5.29.15\";\n    if (typeof params != \"undefined\") {\n\tif (typeof params['bin'] != \"undefined\") {\n\t    this.asn1ExtnValue = new KJUR.asn1.DERBitString(params);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.KeyUsage, KJUR.asn1.x509.Extension);\n\n/**\n * BasicConstraints ASN.1 structure class\n * @name KJUR.asn1.x509.BasicConstraints\n * @class BasicConstraints ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'cA': true, 'critical': true})\n * @extends KJUR.asn1.x509.Extension\n * @description\n * @example\n */\nKJUR.asn1.x509.BasicConstraints = function(params) {\n    KJUR.asn1.x509.BasicConstraints.superclass.constructor.call(this, params);\n    var cA = false;\n    var pathLen = -1;\n\n    this.getExtnValueHex = function() {\n\tvar asn1Array = new Array();\n\tif (this.cA) asn1Array.push(new KJUR.asn1.DERBoolean());\n\tif (this.pathLen > -1) \n\t    asn1Array.push(new KJUR.asn1.DERInteger({'int': this.pathLen}));\n\tvar asn1Seq = new KJUR.asn1.DERSequence({'array': asn1Array});\n\tthis.asn1ExtnValue = asn1Seq;\n\treturn this.asn1ExtnValue.getEncodedHex();\n    };\n\n    this.oid = \"2.5.29.19\";\n    this.cA = false;\n    this.pathLen = -1;\n    if (typeof params != \"undefined\") {\n\tif (typeof params['cA'] != \"undefined\") {\n\t    this.cA = params['cA'];\n\t}\n\tif (typeof params['pathLen'] != \"undefined\") {\n\t    this.pathLen = params['pathLen'];\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.BasicConstraints, KJUR.asn1.x509.Extension);\n\n/**\n * CRLDistributionPoints ASN.1 structure class\n * @name KJUR.asn1.x509.CRLDistributionPoints\n * @class CRLDistributionPoints ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'uri': 'http://a.com/', 'critical': true})\n * @extends KJUR.asn1.x509.Extension\n * @description\n * @example\n */\nKJUR.asn1.x509.CRLDistributionPoints = function(params) {\n    KJUR.asn1.x509.CRLDistributionPoints.superclass.constructor.call(this, params);\n\n    this.getExtnValueHex = function() {\n\treturn this.asn1ExtnValue.getEncodedHex();\n    };\n\n    this.setByDPArray = function(dpArray) {\n\tthis.asn1ExtnValue = new KJUR.asn1.DERSequence({'array': dpArray});\n    };\n\n    this.setByOneURI = function(uri) {\n\tvar gn1 = new KJUR.asn1.x509.GeneralNames([{'uri': uri}]);\n\tvar dpn1 = new KJUR.asn1.x509.DistributionPointName(gn1);\n\tvar dp1 = new KJUR.asn1.x509.DistributionPoint({'dpobj': dpn1});\n\tthis.setByDPArray([dp1]);\n    };\n\n    this.oid = \"2.5.29.31\";\n    if (typeof params != \"undefined\") {\n\tif (typeof params['array'] != \"undefined\") {\n\t    this.setByDPArray(params['array']);\n\t} else if (typeof params['uri'] != \"undefined\") {\n\t    this.setByOneURI(params['uri']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.CRLDistributionPoints, KJUR.asn1.x509.Extension);\n\n/**\n * KeyUsage ASN.1 structure class\n * @name KJUR.asn1.x509.ExtKeyUsage\n * @class ExtKeyUsage ASN.1 structure class\n * @param {Array} params associative array of parameters\n * @extends KJUR.asn1.x509.Extension\n * @description\n * @example\n * var e1 = \n *     new KJUR.asn1.x509.ExtKeyUsage({'critical': true,\n *                                     'array':\n *                                     [{'oid': '2.5.29.37.0',  // anyExtendedKeyUsage\n *                                       'name': 'clientAuth'}]});\n *\n * // id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }\n * // ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId\n * // KeyPurposeId ::= OBJECT IDENTIFIER\n */\nKJUR.asn1.x509.ExtKeyUsage = function(params) {\n    KJUR.asn1.x509.ExtKeyUsage.superclass.constructor.call(this, params);\n\n    this.setPurposeArray = function(purposeArray) {\n\tthis.asn1ExtnValue = new KJUR.asn1.DERSequence();\n\tfor (var i = 0; i < purposeArray.length; i++) {\n\t    var o = new KJUR.asn1.DERObjectIdentifier(purposeArray[i]);\n\t    this.asn1ExtnValue.appendASN1Object(o);\n\t}\n    };\n\n    this.getExtnValueHex = function() {\n\treturn this.asn1ExtnValue.getEncodedHex();\n    };\n\n    this.oid = \"2.5.29.37\";\n    if (typeof params != \"undefined\") {\n\tif (typeof params['array'] != \"undefined\") {\n            this.setPurposeArray(params['array']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.ExtKeyUsage, KJUR.asn1.x509.Extension);\n\n\n// === END   X.509v3 Extensions Related =======================================\n\n// === BEGIN CRL Related ===================================================\n/**\n * X.509 CRL class to sign and generate hex encoded CRL\n * @name KJUR.asn1.x509.CRL\n * @class X.509 CRL class to sign and generate hex encoded certificate\n * @param {Array} params associative array of parameters (ex. {'tbsobj': obj, 'rsaprvkey': key})\n * @extends KJUR.asn1.ASN1Object\n * @since 1.0.3\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>tbsobj - specify {@link KJUR.asn1.x509.TBSCertList} object to be signed</li>\n * <li>rsaprvkey - specify {@link RSAKey} object CA private key</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n * <h4>EXAMPLE</h4>\n * @example\n * var prvKey = new RSAKey(); // CA's private key\n * prvKey.readPrivateKeyFromASN1HexString(\"3080...\");\n * var crl = new KJUR.asn1x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey});\n * crl.sign(); // issue CRL by CA's private key\n * var hCRL = crl.getEncodedHex();\n *\n * // CertificateList  ::=  SEQUENCE  {\n * //     tbsCertList          TBSCertList,\n * //     signatureAlgorithm   AlgorithmIdentifier,\n * //     signatureValue       BIT STRING  }\n */\nKJUR.asn1.x509.CRL = function(params) {\n    KJUR.asn1.x509.CRL.superclass.constructor.call(this);\n\n    var asn1TBSCertList = null;\n    var asn1SignatureAlg = null;\n    var asn1Sig = null;\n    var hexSig = null;\n    var rsaPrvKey = null;\n    \n    /**\n     * set PKCS#5 encrypted RSA PEM private key as CA key\n     * @name setRsaPrvKeyByPEMandPass\n     * @memberOf KJUR.asn1.x509.CRL\n     * @function\n     * @param {String} rsaPEM string of PKCS#5 encrypted RSA PEM private key\n     * @param {String} passPEM passcode string to decrypt private key\n     * @description\n     * <br/>\n     * <h4>EXAMPLES</h4>\n     * @example\n     */\n    this.setRsaPrvKeyByPEMandPass = function(rsaPEM, passPEM) {\n\tvar caKeyHex = PKCS5PKEY.getDecryptedKeyHex(rsaPEM, passPEM);\n\tvar caKey = new RSAKey();\n\tcaKey.readPrivateKeyFromASN1HexString(caKeyHex);  \n\tthis.rsaPrvKey = caKey;\n    };\n\n    /**\n     * sign TBSCertList and set signature value internally\n     * @name sign\n     * @memberOf KJUR.asn1.x509.CRL\n     * @function\n     * @description\n     * @example\n     * var cert = new KJUR.asn1.x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey});\n     * cert.sign();\n     */\n    this.sign = function() {\n\tthis.asn1SignatureAlg = this.asn1TBSCertList.asn1SignatureAlg;\n\n\tsig = new KJUR.crypto.Signature({'alg': 'SHA1withRSA', 'prov': 'cryptojs/jsrsa'});\n\tsig.initSign(this.rsaPrvKey);\n\tsig.updateHex(this.asn1TBSCertList.getEncodedHex());\n\tthis.hexSig = sig.sign();\n\n\tthis.asn1Sig = new KJUR.asn1.DERBitString({'hex': '00' + this.hexSig});\n\t\n\tvar seq = new KJUR.asn1.DERSequence({'array': [this.asn1TBSCertList,\n\t\t\t\t\t\t       this.asn1SignatureAlg,\n\t\t\t\t\t\t       this.asn1Sig]});\n\tthis.hTLV = seq.getEncodedHex();\n\tthis.isModified = false;\n    };\n\n    this.getEncodedHex = function() {\n\tif (this.isModified == false && this.hTLV != null) return this.hTLV;\n\tthrow \"not signed yet\";\n    };\n\n    /**\n     * get PEM formatted CRL string after signed\n     * @name getPEMString\n     * @memberOf KJUR.asn1.x509.CRL\n     * @function\n     * @return PEM formatted string of certificate\n     * @description\n     * @example\n     * var cert = new KJUR.asn1.x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey});\n     * cert.sign();\n     * var sPEM =  cert.getPEMString();\n     */\n    this.getPEMString = function() {\n\tvar hCert = this.getEncodedHex();\n\tvar wCert = CryptoJS.enc.Hex.parse(hCert);\n\tvar b64Cert = CryptoJS.enc.Base64.stringify(wCert);\n\tvar pemBody = b64Cert.replace(/(.{64})/g, \"$1\\r\\n\");\n\treturn \"-----BEGIN X509 CRL-----\\r\\n\" + pemBody + \"\\r\\n-----END X509 CRL-----\\r\\n\";\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['tbsobj'] != \"undefined\") {\n\t    this.asn1TBSCertList = params['tbsobj'];\n\t}\n\tif (typeof params['rsaprvkey'] != \"undefined\") {\n\t    this.rsaPrvKey = params['rsaprvkey'];\n\t}\n\tif ((typeof params['rsaprvpem'] != \"undefined\") &&\n\t    (typeof params['rsaprvpas'] != \"undefined\")) {\n\t    this.setRsaPrvKeyByPEMandPass(params['rsaprvpem'], params['rsaprvpas']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.CRL, KJUR.asn1.ASN1Object);\n\n/**\n * ASN.1 TBSCertList structure class for CRL\n * @name KJUR.asn1.x509.TBSCertList\n * @class ASN.1 TBSCertList structure class for CRL\n * @param {Array} params associative array of parameters (ex. {})\n * @extends KJUR.asn1.ASN1Object\n * @since 1.0.3\n * @description\n * <br/>\n * <h4>EXAMPLE</h4>\n * @example\n *  var o = new KJUR.asn1.x509.TBSCertList();\n *  o.setSignatureAlgByParam({'name': 'SHA1withRSA'});\n *  o.setIssuerByParam({'str': '/C=US/O=a'});\n *  o.setNotThisUpdateByParam({'str': '130504235959Z'});\n *  o.setNotNextUpdateByParam({'str': '140504235959Z'});\n *  o.addRevokedCert({'int': 4}, {'str':'130514235959Z'}));\n *  o.addRevokedCert({'hex': '0f34dd'}, {'str':'130514235959Z'}));\n * \n * // TBSCertList  ::=  SEQUENCE  {\n * //        version                 Version OPTIONAL,\n * //                                     -- if present, MUST be v2\n * //        signature               AlgorithmIdentifier,\n * //        issuer                  Name,\n * //        thisUpdate              Time,\n * //        nextUpdate              Time OPTIONAL,\n * //        revokedCertificates     SEQUENCE OF SEQUENCE  {\n * //             userCertificate         CertificateSerialNumber,\n * //             revocationDate          Time,\n * //             crlEntryExtensions      Extensions OPTIONAL\n * //                                      -- if present, version MUST be v2\n * //                                  }  OPTIONAL,\n * //        crlExtensions           [0]  EXPLICIT Extensions OPTIONAL\n */\nKJUR.asn1.x509.TBSCertList = function(params) {\n    KJUR.asn1.x509.TBSCertList.superclass.constructor.call(this);\n    var aRevokedCert = null;\n\n    /**\n     * set signature algorithm field by parameter\n     * @name setSignatureAlgByParam\n     * @memberOf KJUR.asn1.x509.TBSCertList\n     * @function\n     * @param {Array} algIdParam AlgorithmIdentifier parameter\n     * @description\n     * @example\n     * tbsc.setSignatureAlgByParam({'name': 'SHA1withRSA'});\n     */\n    this.setSignatureAlgByParam = function(algIdParam) {\n\tthis.asn1SignatureAlg = new KJUR.asn1.x509.AlgorithmIdentifier(algIdParam);\n    };\n\n    /**\n     * set issuer name field by parameter\n     * @name setIssuerByParam\n     * @memberOf KJUR.asn1.x509.TBSCertList\n     * @function\n     * @param {Array} x500NameParam X500Name parameter\n     * @description\n     * @example\n     * tbsc.setIssuerParam({'str': '/C=US/CN=b'});\n     * @see KJUR.asn1.x509.X500Name\n     */\n    this.setIssuerByParam = function(x500NameParam) {\n\tthis.asn1Issuer = new KJUR.asn1.x509.X500Name(x500NameParam);\n    };\n\n    /**\n     * set thisUpdate field by parameter\n     * @name setThisUpdateByParam\n     * @memberOf KJUR.asn1.x509.TBSCertList\n     * @function\n     * @param {Array} timeParam Time parameter\n     * @description\n     * @example\n     * tbsc.setThisUpdateByParam({'str': '130508235959Z'});\n     * @see KJUR.asn1.x509.Time\n     */\n    this.setThisUpdateByParam = function(timeParam) {\n\tthis.asn1ThisUpdate = new KJUR.asn1.x509.Time(timeParam);\n    };\n\n    /**\n     * set nextUpdate field by parameter\n     * @name setNextUpdateByParam\n     * @memberOf KJUR.asn1.x509.TBSCertList\n     * @function\n     * @param {Array} timeParam Time parameter\n     * @description\n     * @example\n     * tbsc.setNextUpdateByParam({'str': '130508235959Z'});\n     * @see KJUR.asn1.x509.Time\n     */\n    this.setNextUpdateByParam = function(timeParam) {\n\tthis.asn1NextUpdate = new KJUR.asn1.x509.Time(timeParam);\n    };\n\n    /**\n     * add revoked certficate by parameter\n     * @name addRevokedCert\n     * @memberOf KJUR.asn1.x509.TBSCertList\n     * @function\n     * @param {Array} snParam DERInteger parameter for certificate serial number\n     * @param {Array} timeParam Time parameter for revocation date\n     * @description\n     * @example\n     * tbsc.addRevokedCert({'int': 3}, {'str': '130508235959Z'});\n     * @see KJUR.asn1.x509.Time\n     */\n    this.addRevokedCert = function(snParam, timeParam) {\n\tvar param = {};\n\tif (snParam != undefined && snParam != null) param['sn'] = snParam;\n\tif (timeParam != undefined && timeParam != null) param['time'] = timeParam;\n\tvar o = new KJUR.asn1.x509.CRLEntry(param);\n\tthis.aRevokedCert.push(o);\n    };\n\n    this.getEncodedHex = function() {\n\tthis.asn1Array = new Array();\n\n\tif (this.asn1Version != null) this.asn1Array.push(this.asn1Version);\n\tthis.asn1Array.push(this.asn1SignatureAlg);\n\tthis.asn1Array.push(this.asn1Issuer);\n\tthis.asn1Array.push(this.asn1ThisUpdate);\n\tif (this.asn1NextUpdate != null) this.asn1Array.push(this.asn1NextUpdate);\n\n\tif (this.aRevokedCert.length > 0) {\n\t    var seq = new KJUR.asn1.DERSequence({'array': this.aRevokedCert});\n\t    this.asn1Array.push(seq);\n\t}\n\n\tvar o = new KJUR.asn1.DERSequence({\"array\": this.asn1Array});\n\tthis.hTLV = o.getEncodedHex();\n\tthis.isModified = false;\n\treturn this.hTLV;\n    };\n\n    this._initialize = function() {\n\tthis.asn1Version = null;\n\tthis.asn1SignatureAlg = null;\n\tthis.asn1Issuer = null;\n\tthis.asn1ThisUpdate = null;\n\tthis.asn1NextUpdate = null;\n\tthis.aRevokedCert = new Array();\n    };\n\n    this._initialize();\n};\nYAHOO.lang.extend(KJUR.asn1.x509.TBSCertList, KJUR.asn1.ASN1Object);\n\n/**\n * ASN.1 CRLEntry structure class for CRL\n * @name KJUR.asn1.x509.CRLEntry\n * @class ASN.1 CRLEntry structure class for CRL\n * @param {Array} params associative array of parameters (ex. {})\n * @extends KJUR.asn1.ASN1Object\n * @since 1.0.3\n * @description\n * @example\n * var e = new KJUR.asn1.x509.CRLEntry({'time': {'str': '130514235959Z'}, 'sn': {'int': 234}});\n * \n * // revokedCertificates     SEQUENCE OF SEQUENCE  {\n * //     userCertificate         CertificateSerialNumber,\n * //     revocationDate          Time,\n * //     crlEntryExtensions      Extensions OPTIONAL\n * //                             -- if present, version MUST be v2 }\n */\nKJUR.asn1.x509.CRLEntry = function(params) {\n    KJUR.asn1.x509.CRLEntry.superclass.constructor.call(this);\n    var sn = null;\n    var time = null;\n\n    /**\n     * set DERInteger parameter for serial number of revoked certificate \n     * @name setCertSerial\n     * @memberOf KJUR.asn1.x509.CRLEntry\n     * @function\n     * @param {Array} intParam DERInteger parameter for certificate serial number\n     * @description\n     * @example\n     * entry.setCertSerial({'int': 3});\n     */\n    this.setCertSerial = function(intParam) {\n\tthis.sn = new KJUR.asn1.DERInteger(intParam);\n    };\n\n    /**\n     * set Time parameter for revocation date\n     * @name setRevocationDate\n     * @memberOf KJUR.asn1.x509.CRLEntry\n     * @function\n     * @param {Array} timeParam Time parameter for revocation date\n     * @description\n     * @example\n     * entry.setRevocationDate({'str': '130508235959Z'});\n     */\n    this.setRevocationDate = function(timeParam) {\n\tthis.time = new KJUR.asn1.x509.Time(timeParam);\n    };\n\n    this.getEncodedHex = function() {\n\tvar o = new KJUR.asn1.DERSequence({\"array\": [this.sn, this.time]});\n\tthis.TLV = o.getEncodedHex();\n\treturn this.TLV;\n    };\n    \n    if (typeof params != \"undefined\") {\n\tif (typeof params['time'] != \"undefined\") {\n\t    this.setRevocationDate(params['time']);\n\t}\n\tif (typeof params['sn'] != \"undefined\") {\n\t    this.setCertSerial(params['sn']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.CRLEntry, KJUR.asn1.ASN1Object);\n\n// === END   CRL Related ===================================================\n\n// === BEGIN X500Name Related =================================================\n/**\n * X500Name ASN.1 structure class\n * @name KJUR.asn1.x509.X500Name\n * @class X500Name ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'str': '/C=US/O=a'})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @example\n */\nKJUR.asn1.x509.X500Name = function(params) {\n    KJUR.asn1.x509.X500Name.superclass.constructor.call(this);\n    this.asn1Array = new Array();\n\n    this.setByString = function(dnStr) {\n\tvar a = dnStr.split('/');\n\ta.shift();\n\tfor (var i = 0; i < a.length; i++) {\n\t    this.asn1Array.push(new KJUR.asn1.x509.RDN({'str':a[i]}));\n\t}\n    };\n\n    this.getEncodedHex = function() {\n\tvar o = new KJUR.asn1.DERSequence({\"array\": this.asn1Array});\n\tthis.TLV = o.getEncodedHex();\n\treturn this.TLV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['str'] != \"undefined\") {\n\t    this.setByString(params['str']);\n\t}\n    }\n\n};\nYAHOO.lang.extend(KJUR.asn1.x509.X500Name, KJUR.asn1.ASN1Object);\n\n/**\n * RDN (Relative Distinguish Name) ASN.1 structure class\n * @name KJUR.asn1.x509.RDN\n * @class RDN (Relative Distinguish Name) ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'str': 'C=US'})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @example\n */\nKJUR.asn1.x509.RDN = function(params) {\n    KJUR.asn1.x509.RDN.superclass.constructor.call(this);\n    this.asn1Array = new Array();\n\n    this.addByString = function(rdnStr) {\n\tthis.asn1Array.push(new KJUR.asn1.x509.AttributeTypeAndValue({'str':rdnStr}));\n    };\n\n    this.getEncodedHex = function() {\n\tvar o = new KJUR.asn1.DERSet({\"array\": this.asn1Array});\n\tthis.TLV = o.getEncodedHex();\n\treturn this.TLV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['str'] != \"undefined\") {\n\t    this.addByString(params['str']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.RDN, KJUR.asn1.ASN1Object);\n\n/**\n * AttributeTypeAndValue ASN.1 structure class\n * @name KJUR.asn1.x509.AttributeTypeAndValue\n * @class AttributeTypeAndValue ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'str': 'C=US'})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @example\n */\nKJUR.asn1.x509.AttributeTypeAndValue = function(params) {\n    KJUR.asn1.x509.AttributeTypeAndValue.superclass.constructor.call(this);\n    var typeObj = null;\n    var valueObj = null;\n    var defaultDSType = \"utf8\";\n\n    this.setByString = function(attrTypeAndValueStr) {\n\tif (attrTypeAndValueStr.match(/^([^=]+)=(.+)$/)) {\n\t    this.setByAttrTypeAndValueStr(RegExp.$1, RegExp.$2);\n\t} else {\n\t    throw \"malformed attrTypeAndValueStr: \" + attrTypeAndValueStr;\n\t}\n    };\n\n    this.setByAttrTypeAndValueStr = function(shortAttrType, valueStr) {\n\tthis.typeObj = KJUR.asn1.x509.OID.atype2obj(shortAttrType);\n\tvar dsType = defaultDSType;\n\tif (shortAttrType == \"C\") dsType = \"prn\";\n\tthis.valueObj = this.getValueObj(dsType, valueStr);\n    };\n\n    this.getValueObj = function(dsType, valueStr) {\n\tif (dsType == \"utf8\")\treturn new KJUR.asn1.DERUTF8String({\"str\": valueStr});\n\tif (dsType == \"prn\")\treturn new KJUR.asn1.DERPrintableString({\"str\": valueStr});\n\tif (dsType == \"tel\")\treturn new KJUR.asn1.DERTeletexString({\"str\": valueStr});\n\tif (dsType == \"ia5\")\treturn new KJUR.asn1.DERIA5String({\"str\": valueStr});\n\tthrow \"unsupported directory string type: type=\" + dsType + \" value=\" + valueStr;\n    };\n\n    this.getEncodedHex = function() {\n\tvar o = new KJUR.asn1.DERSequence({\"array\": [this.typeObj, this.valueObj]});\n\tthis.TLV = o.getEncodedHex();\n\treturn this.TLV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['str'] != \"undefined\") {\n\t    this.setByString(params['str']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.AttributeTypeAndValue, KJUR.asn1.ASN1Object);\n\n// === END   X500Name Related =================================================\n\n// === BEGIN Other ASN1 structure class  ======================================\n\n/**\n * SubjectPublicKeyInfo ASN.1 structure class\n * @name KJUR.asn1.x509.SubjectPublicKeyInfo\n * @class SubjectPublicKeyInfo ASN.1 structure class\n * @param {Object} params parameter for subject public key\n * @extends KJUR.asn1.ASN1Object\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>{@link RSAKey} object</li>\n * <li>{@link KJUR.crypto.ECDSA} object</li>\n * <li>{@link KJUR.crypto.DSA} object</li>\n * <li>(DEPRECATED)rsakey - specify {@link RSAKey} object of subject public key</li>\n * <li>(DEPRECATED)rsapem - specify a string of PEM public key of RSA key</li>\n * </ul>\n * NOTE1: 'params' can be omitted.<br/>\n * NOTE2: DSA/ECDSA key object is also supported since asn1x509 1.0.6.<br/>\n * <h4>EXAMPLE</h4>\n * @example\n * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(RSAKey_object);\n * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoECDSA_object);\n * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoDSA_object);\n */\nKJUR.asn1.x509.SubjectPublicKeyInfo = function(params) {\n    KJUR.asn1.x509.SubjectPublicKeyInfo.superclass.constructor.call(this);\n    var asn1AlgId = null;\n    var asn1SubjPKey = null;\n    var rsaKey = null;\n\n    /**\n     * (DEPRECATED) set RSAKey object as subject public key\n     * @name setRSAKey\n     * @memberOf KJUR.asn1.x509.SubjectPublicKeyInfo\n     * @function\n     * @param {RSAKey} rsaKey {@link RSAKey} object for RSA public key\n     * @description\n     * @deprecated\n     * @example\n     * spki.setRSAKey(rsaKey);\n     */\n    this.setRSAKey = function(rsaKey) {\n\tif (! RSAKey.prototype.isPrototypeOf(rsaKey))\n\t    throw \"argument is not RSAKey instance\";\n        this.rsaKey = rsaKey;\n\tvar asn1RsaN = new KJUR.asn1.DERInteger({'bigint': rsaKey.n});\n\tvar asn1RsaE = new KJUR.asn1.DERInteger({'int': rsaKey.e});\n\tvar asn1RsaPub = new KJUR.asn1.DERSequence({'array': [asn1RsaN, asn1RsaE]});\n\tvar rsaKeyHex = asn1RsaPub.getEncodedHex();\n\tthis.asn1AlgId = new KJUR.asn1.x509.AlgorithmIdentifier({'name':'rsaEncryption'});\n\tthis.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex':'00'+rsaKeyHex});\n    };\n\n    /**\n     * (DEPRECATED) set a PEM formatted RSA public key string as RSA public key\n     * @name setRSAPEM\n     * @memberOf KJUR.asn1.x509.SubjectPublicKeyInfo\n     * @function\n     * @param {String} rsaPubPEM PEM formatted RSA public key string\n     * @deprecated\n     * @description\n     * @example\n     * spki.setRSAPEM(rsaPubPEM);\n     */\n    this.setRSAPEM = function(rsaPubPEM) {\n\tif (rsaPubPEM.match(/-----BEGIN PUBLIC KEY-----/)) {\n\t    var s = rsaPubPEM;\n\t    s = s.replace(/^-----[^-]+-----/, '');\n\t    s = s.replace(/-----[^-]+-----\\s*$/, '');\n\t    var rsaB64 = s.replace(/\\s+/g, '');\n\t    var rsaWA = CryptoJS.enc.Base64.parse(rsaB64);\n\t    var rsaP8Hex = CryptoJS.enc.Hex.stringify(rsaWA);\n\t    var a = _rsapem_getHexValueArrayOfChildrenFromHex(rsaP8Hex);\n\t    var hBitStrVal = a[1];\n\t    var rsaHex = hBitStrVal.substr(2);\n\t    var a3 = _rsapem_getHexValueArrayOfChildrenFromHex(rsaHex);\n\t    var rsaKey = new RSAKey();\n\t    rsaKey.setPublic(a3[0], a3[1]);\n\t    this.setRSAKey(rsaKey);\n\t} else {\n\t    throw \"key not supported\";\n\t}\n    };\n\n    /*\n     * @since asn1x509 1.0.7\n     */\n    this.getASN1Object = function() {\n\tif (this.asn1AlgId == null || this.asn1SubjPKey == null)\n\t    throw \"algId and/or subjPubKey not set\";\n\tvar o = new KJUR.asn1.DERSequence({'array':\n\t\t\t\t\t   [this.asn1AlgId, this.asn1SubjPKey]});\n\treturn o;\n    };\n\n    this.getEncodedHex = function() {\n\tvar o = this.getASN1Object();\n\tthis.hTLV = o.getEncodedHex();\n\treturn this.hTLV;\n    };\n\n    this._setRSAKey = function(key) {\n\tvar asn1RsaPub = KJUR.asn1.ASN1Util.newObject({\n\t\t'seq': [{'int': {'bigint': key.n}}, {'int': {'int': key.e}}]\n\t    });\n\tvar rsaKeyHex = asn1RsaPub.getEncodedHex();\n\tthis.asn1AlgId = new KJUR.asn1.x509.AlgorithmIdentifier({'name':'rsaEncryption'});\n\tthis.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex':'00'+rsaKeyHex});\n    };\n\n    this._setEC = function(key) {\n\tvar asn1Params = new KJUR.asn1.DERObjectIdentifier({'name': key.curveName});\n\tthis.asn1AlgId = \n\t    new KJUR.asn1.x509.AlgorithmIdentifier({'name': 'ecPublicKey',\n\t\t\t\t\t\t    'asn1params': asn1Params});\n\tthis.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex': '00' + key.pubKeyHex});\n    };\n\n    this._setDSA = function(key) {\n\tvar asn1Params = new KJUR.asn1.ASN1Util.newObject({\n\t\t'seq': [{'int': {'bigint': key.p}},\n\t                {'int': {'bigint': key.q}},\n\t                {'int': {'bigint': key.g}}]\n\t    });\n\tthis.asn1AlgId = \n\t    new KJUR.asn1.x509.AlgorithmIdentifier({'name': 'dsa',\n\t\t\t\t\t\t    'asn1params': asn1Params});\n\tvar pubInt = new KJUR.asn1.DERInteger({'bigint': key.y});\n\tthis.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex': '00' + pubInt.getEncodedHex()});\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof RSAKey != 'undefined' && params instanceof RSAKey) {\n\t    this._setRSAKey(params);\n\t} else if (typeof KJUR.crypto.ECDSA != 'undefined' &&\n\t\t   params instanceof KJUR.crypto.ECDSA) {\n\t    this._setEC(params);\n\t} else if (typeof KJUR.crypto.DSA != 'undefined' &&\n\t\t   params instanceof KJUR.crypto.DSA) {\n\t    this._setDSA(params);\n\t} else if (typeof params['rsakey'] != \"undefined\") {\n\t    this.setRSAKey(params['rsakey']);\n\t} else if (typeof params['rsapem'] != \"undefined\") {\n\t    this.setRSAPEM(params['rsapem']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.SubjectPublicKeyInfo, KJUR.asn1.ASN1Object);\n\n/**\n * Time ASN.1 structure class\n * @name KJUR.asn1.x509.Time\n * @class Time ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'str': '130508235959Z'})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * <br/>\n * <h4>EXAMPLES</h4>\n * @example\n * var t1 = new KJUR.asn1.x509.Time{'str': '130508235959Z'} // UTCTime by default\n * var t2 = new KJUR.asn1.x509.Time{'type': 'gen',  'str': '20130508235959Z'} // GeneralizedTime\n */\nKJUR.asn1.x509.Time = function(params) {\n    KJUR.asn1.x509.Time.superclass.constructor.call(this);\n    var type = null;\n    var timeParams = null;\n\n    this.setTimeParams = function(timeParams) {\n\tthis.timeParams = timeParams;\n    }\n\n    this.getEncodedHex = function() {\n\tif (this.timeParams == null) {\n\t    throw \"timeParams shall be specified. ({'str':'130403235959Z'}}\";\n\t}\n\tvar o = null;\n\tif (this.type == \"utc\") {\n\t    o = new KJUR.asn1.DERUTCTime(this.timeParams);\n\t} else {\n\t    o = new KJUR.asn1.DERGeneralizedTime(this.timeParams);\n\t}\n\tthis.TLV = o.getEncodedHex();\n\treturn this.TLV;\n    };\n \n    this.type = \"utc\";\n    if (typeof params != \"undefined\") {\n\tif (typeof params['type'] != \"undefined\") {\n\t    this.type = params['type'];\n\t}\n\tthis.timeParams = params;\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.Time, KJUR.asn1.ASN1Object);\n\n/**\n * AlgorithmIdentifier ASN.1 structure class\n * @name KJUR.asn1.x509.AlgorithmIdentifier\n * @class AlgorithmIdentifier ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'name': 'SHA1withRSA'})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @example\n */\nKJUR.asn1.x509.AlgorithmIdentifier = function(params) {\n    KJUR.asn1.x509.AlgorithmIdentifier.superclass.constructor.call(this);\n    var nameAlg = null;\n    var asn1Alg = null;\n    var asn1Params = null;\n    var paramEmpty = false;\n\n    this.getEncodedHex = function() {\n\tif (this.nameAlg == null && this.asn1Alg == null) {\n\t    throw \"algorithm not specified\";\n\t}\n\tif (this.nameAlg != null && this.asn1Alg == null) {\n\t    this.asn1Alg = KJUR.asn1.x509.OID.name2obj(this.nameAlg);\n\t}\n\tvar a = [this.asn1Alg];\n\tif (! this.paramEmpty) a.push(this.asn1Params);\n\tvar o = new KJUR.asn1.DERSequence({'array': a});\n\tthis.hTLV = o.getEncodedHex();\n\treturn this.hTLV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['name'] != \"undefined\") {\n\t    this.nameAlg = params['name'];\n\t}\n\tif (typeof params['asn1params'] != \"undefined\") {\n\t    this.asn1Params = params['asn1params'];\n\t}\n\tif (typeof params['paramempty'] != \"undefined\") {\n\t    this.paramEmpty = params['paramempty'];\n\t}\n    }\n    if (this.asn1Params == null) {\n\tthis.asn1Params = new KJUR.asn1.DERNull();\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.AlgorithmIdentifier, KJUR.asn1.ASN1Object);\n\n/**\n * GeneralName ASN.1 structure class\n * @name KJUR.asn1.x509.GeneralName\n * @class GeneralName ASN.1 structure class\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>rfc822 - rfc822Name[1] (ex. user1@foo.com)</li>\n * <li>dns - dNSName[2] (ex. foo.com)</li>\n * <li>uri - uniformResourceIdentifier[6] (ex. http://foo.com/)</li>\n * </ul>\n * NOTE: Currently this only supports 'uniformResourceIdentifier'.\n * <h4>EXAMPLE AND ASN.1 SYNTAX</h4>\n * @example\n * var gn = new KJUR.asn1.x509.GeneralName({'uri': 'http://aaa.com/'});\n *\n * GeneralName ::= CHOICE {\n *         otherName                       [0]     OtherName,\n *         rfc822Name                      [1]     IA5String,\n *         dNSName                         [2]     IA5String,\n *         x400Address                     [3]     ORAddress,\n *         directoryName                   [4]     Name,\n *         ediPartyName                    [5]     EDIPartyName,\n *         uniformResourceIdentifier       [6]     IA5String,\n *         iPAddress                       [7]     OCTET STRING,\n *         registeredID                    [8]     OBJECT IDENTIFIER } \n */\nKJUR.asn1.x509.GeneralName = function(params) {\n    KJUR.asn1.x509.GeneralName.superclass.constructor.call(this);\n    var asn1Obj = null;\n    var type = null;\n    var pTag = {'rfc822': '81', 'dns': '82', 'uri': '86'};\n\n    this.setByParam = function(params) {\n\tvar str = null;\n\tvar v = null;\n\n\tif (typeof params['rfc822'] != \"undefined\") {\n\t    this.type = 'rfc822';\n\t    v = new KJUR.asn1.DERIA5String({'str': params[this.type]});\n\t}\n\tif (typeof params['dns'] != \"undefined\") {\n\t    this.type = 'dns';\n\t    v = new KJUR.asn1.DERIA5String({'str': params[this.type]});\n\t}\n\tif (typeof params['uri'] != \"undefined\") {\n\t    this.type = 'uri';\n\t    v = new KJUR.asn1.DERIA5String({'str': params[this.type]});\n\t}\n\n\tif (this.type == null)\n\t    throw \"unsupported type in params=\" + params;\n        this.asn1Obj = new KJUR.asn1.DERTaggedObject({'explicit': false,\n\t\t\t\t\t\t      'tag': pTag[this.type],\n\t\t\t\t\t\t      'obj': v});\n    };\n\n    this.getEncodedHex = function() {\n\treturn this.asn1Obj.getEncodedHex();\n    }\n\n    if (typeof params != \"undefined\") {\n\tthis.setByParam(params);\n    }\n\n};\nYAHOO.lang.extend(KJUR.asn1.x509.GeneralName, KJUR.asn1.ASN1Object);\n\n/**\n * GeneralNames ASN.1 structure class\n * @name KJUR.asn1.x509.GeneralNames\n * @class GeneralNames ASN.1 structure class\n * @description\n * <br/>\n * <h4>EXAMPLE AND ASN.1 SYNTAX</h4>\n * @example\n * var gns = new KJUR.asn1.x509.GeneralNames([{'uri': 'http://aaa.com/'}, {'uri': 'http://bbb.com/'}]); \n *\n * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName\n */\nKJUR.asn1.x509.GeneralNames = function(paramsArray) {\n    KJUR.asn1.x509.GeneralNames.superclass.constructor.call(this);\n    var asn1Array = null;\n\n    /**\n     * set a array of {@link KJUR.asn1.x509.GeneralName} parameters\n     * @name setByParamArray\n     * @memberOf KJUR.asn1.x509.GeneralNames\n     * @function\n     * @param {Array} paramsArray Array of {@link KJUR.asn1.x509.GeneralNames}\n     * @description\n     * <br/>\n     * <h4>EXAMPLES</h4>\n     * @example\n     * var gns = new KJUR.asn1.x509.GeneralNames();\n     * gns.setByParamArray([{'uri': 'http://aaa.com/'}, {'uri': 'http://bbb.com/'}]);\n     */\n    this.setByParamArray = function(paramsArray) {\n\tfor (var i = 0; i < paramsArray.length; i++) {\n\t    var o = new KJUR.asn1.x509.GeneralName(paramsArray[i]);\n\t    this.asn1Array.push(o);\n\t}\n    };\n\n    this.getEncodedHex = function() {\n\tvar o = new KJUR.asn1.DERSequence({'array': this.asn1Array});\n\treturn o.getEncodedHex();\n    };\n\n    this.asn1Array = new Array();\n    if (typeof paramsArray != \"undefined\") {\n\tthis.setByParamArray(paramsArray);\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.GeneralNames, KJUR.asn1.ASN1Object);\n\n/**\n * DistributionPointName ASN.1 structure class\n * @name KJUR.asn1.x509.DistributionPointName\n * @class DistributionPointName ASN.1 structure class\n * @description\n * @example\n */\nKJUR.asn1.x509.DistributionPointName = function(gnOrRdn) {\n    KJUR.asn1.x509.DistributionPointName.superclass.constructor.call(this);\n    var asn1Obj = null;\n    var type = null;\n    var tag = null;\n    var asn1V = null;\n\n    this.getEncodedHex = function() {\n\tif (this.type != \"full\")\n\t    throw \"currently type shall be 'full': \" + this.type;\n\tthis.asn1Obj = new KJUR.asn1.DERTaggedObject({'explicit': false,\n\t\t\t\t\t\t      'tag': this.tag,\n\t\t\t\t\t\t      'obj': this.asn1V});\n\tthis.hTLV = this.asn1Obj.getEncodedHex();\n\treturn this.hTLV;\n    };\n\n    if (typeof gnOrRdn != \"undefined\") {\n\tif (KJUR.asn1.x509.GeneralNames.prototype.isPrototypeOf(gnOrRdn)) {\n\t    this.type = \"full\";\n\t    this.tag = \"a0\";\n\t    this.asn1V = gnOrRdn;\n\t} else {\n\t    throw \"This class supports GeneralNames only as argument\";\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.DistributionPointName, KJUR.asn1.ASN1Object);\n\n/**\n * DistributionPoint ASN.1 structure class\n * @name KJUR.asn1.x509.DistributionPoint\n * @class DistributionPoint ASN.1 structure class\n * @description\n * @example\n */\nKJUR.asn1.x509.DistributionPoint = function(params) {\n    KJUR.asn1.x509.DistributionPoint.superclass.constructor.call(this);\n    var asn1DP = null;\n\n    this.getEncodedHex = function() {\n\tvar seq = new KJUR.asn1.DERSequence();\n\tif (this.asn1DP != null) {\n\t    var o1 = new KJUR.asn1.DERTaggedObject({'explicit': true,\n\t\t\t\t\t\t    'tag': 'a0',\n\t\t\t\t\t\t    'obj': this.asn1DP});\n\t    seq.appendASN1Object(o1);\n\t}\n\tthis.hTLV = seq.getEncodedHex();\n\treturn this.hTLV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['dpobj'] != \"undefined\") {\n\t    this.asn1DP = params['dpobj'];\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.DistributionPoint, KJUR.asn1.ASN1Object);\n\n/**\n * static object for OID\n * @name KJUR.asn1.x509.OID\n * @class static object for OID\n * @property {Assoc Array} atype2oidList for short attribyte type name and oid (i.e. 'C' and '2.5.4.6')\n * @property {Assoc Array} name2oidList for oid name and oid (i.e. 'keyUsage' and '2.5.29.15')\n * @property {Assoc Array} objCache for caching name and DERObjectIdentifier object \n * @description\n * <dl>\n * <dt><b>atype2oidList</b>\n * <dd>currently supports 'C', 'O', 'OU', 'ST', 'L' and 'CN' only.\n * <dt><b>name2oidList</b>\n * <dd>currently supports 'SHA1withRSA', 'rsaEncryption' and some extension OIDs\n * </dl>\n * @example\n */\nKJUR.asn1.x509.OID = new function(params) {\n    this.atype2oidList = {\n\t'C':\t'2.5.4.6',\n\t'O':\t'2.5.4.10',\n\t'OU':\t'2.5.4.11',\n\t'ST':\t'2.5.4.8',\n\t'L':\t'2.5.4.7',\n\t'CN':\t'2.5.4.3',\n    };\n    this.name2oidList = {\n\t'sha384':\t\t\t'2.16.840.1.101.3.4.2.2',\n\t'sha224':\t\t\t'2.16.840.1.101.3.4.2.4',\n\n\t'MD2withRSA':\t\t\t'1.2.840.113549.1.1.2',\n\t'MD4withRSA':\t\t\t'1.2.840.113549.1.1.3',\n\t'MD5withRSA':\t\t\t'1.2.840.113549.1.1.4',\n\t'SHA1withRSA':\t\t\t'1.2.840.113549.1.1.5',\n\t'SHA224withRSA':\t\t'1.2.840.113549.1.1.14',\n\t'SHA256withRSA':\t\t'1.2.840.113549.1.1.11',\n\t'SHA384withRSA':\t\t'1.2.840.113549.1.1.12',\n\t'SHA512withRSA':\t\t'1.2.840.113549.1.1.13',\n\n\t'SHA1withECDSA':\t\t'1.2.840.10045.4.1',\n\t'SHA224withECDSA':\t\t'1.2.840.10045.4.3.1',\n\t'SHA256withECDSA':\t\t'1.2.840.10045.4.3.2',\n\t'SHA384withECDSA':\t\t'1.2.840.10045.4.3.3',\n\t'SHA512withECDSA':\t\t'1.2.840.10045.4.3.4',\n\n\t'dsa':\t\t\t\t'1.2.840.10040.4.1',\n\t'SHA1withDSA':\t\t\t'1.2.840.10040.4.3',\n\t'SHA224withDSA':\t\t'2.16.840.1.101.3.4.3.1',\n\t'SHA256withDSA':\t\t'2.16.840.1.101.3.4.3.2',\n\n        'rsaEncryption':\t\t'1.2.840.113549.1.1.1',\n\t'subjectKeyIdentifier':\t\t'2.5.29.14',\n\n\t'countryName':\t\t\t'2.5.4.6',\n\t'organization':\t\t\t'2.5.4.10',\n\t'organizationalUnit':\t\t'2.5.4.11',\n\t'stateOrProvinceName':\t\t'2.5.4.8',\n\t'locality':\t\t\t'2.5.4.7',\n\t'commonName':\t\t\t'2.5.4.3',\n\n\t'keyUsage':\t\t\t'2.5.29.15',\n\t'basicConstraints':\t\t'2.5.29.19',\n\t'cRLDistributionPoints':\t'2.5.29.31',\n\t'certificatePolicies':\t\t'2.5.29.32',\n\t'authorityKeyIdentifier':\t'2.5.29.35',\n\t'extKeyUsage':\t\t\t'2.5.29.37',\n\n\t'anyExtendedKeyUsage':\t\t'2.5.29.37.0',\n\t'serverAuth':\t\t\t'1.3.6.1.5.5.7.3.1',\n\t'clientAuth':\t\t\t'1.3.6.1.5.5.7.3.2',\n\t'codeSigning':\t\t\t'1.3.6.1.5.5.7.3.3',\n\t'emailProtection':\t\t'1.3.6.1.5.5.7.3.4',\n\t'timeStamping':\t\t\t'1.3.6.1.5.5.7.3.8',\n\t'ocspSigning':\t\t\t'1.3.6.1.5.5.7.3.9',\n\n\t'ecPublicKey':\t\t\t'1.2.840.10045.2.1',\n\t'secp256r1':\t\t\t'1.2.840.10045.3.1.7',\n\t'secp256k1':\t\t\t'1.3.132.0.10',\n\t'secp384r1':\t\t\t'1.3.132.0.34',\n\n\t'pkcs5PBES2':\t\t\t'1.2.840.113549.1.5.13',\n\t'pkcs5PBKDF2':\t\t\t'1.2.840.113549.1.5.12',\n\n\t'des-EDE3-CBC':\t\t\t'1.2.840.113549.3.7',\n    };\n\n    this.objCache = {};\n\n    /**\n     * get DERObjectIdentifier by registered OID name\n     * @name name2obj\n     * @memberOf KJUR.asn1.x509.OID\n     * @function\n     * @param {String} name OID\n     * @description\n     * @example\n     * var asn1ObjOID = OID.name2obj('SHA1withRSA');\n     */\n    this.name2obj = function(name) {\n\tif (typeof this.objCache[name] != \"undefined\")\n\t    return this.objCache[name];\n\tif (typeof this.name2oidList[name] == \"undefined\")\n\t    throw \"Name of ObjectIdentifier not defined: \" + name;\n\tvar oid = this.name2oidList[name];\n\tvar obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid});\n\tthis.objCache[name] = obj;\n\treturn obj;\n    };\n\n    /**\n     * get DERObjectIdentifier by registered attribyte type name such like 'C' or 'CN'\n     * @name atype2obj\n     * @memberOf KJUR.asn1.x509.OID\n     * @function\n     * @param {String} atype short attribute type name such like 'C' or 'CN'\n     * @description\n     * @example\n     * var asn1ObjOID = OID.atype2obj('CN');\n     */\n    this.atype2obj = function(atype) {\n\tif (typeof this.objCache[atype] != \"undefined\")\n\t    return this.objCache[atype];\n\tif (typeof this.atype2oidList[atype] == \"undefined\")\n\t    throw \"AttributeType name undefined: \" + atype;\n\tvar oid = this.atype2oidList[atype];\n\tvar obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid});\n\tthis.objCache[atype] = obj;\n\treturn obj;\n    };\n};\n\n/**\n * X.509 certificate and CRL utilities class\n * @name KJUR.asn1.x509.X509Util\n * @class X.509 certificate and CRL utilities class\n */\nKJUR.asn1.x509.X509Util = new function() {\n    /**\n     * get PKCS#8 PEM public key string from RSAKey object\n     * @name getPKCS8PubKeyPEMfromRSAKey\n     * @memberOf KJUR.asn1.x509.X509Util\n     * @function\n     * @param {RSAKey} rsaKey RSA public key of {@link RSAKey} object\n     * @description\n     * @example\n     * var pem = KJUR.asn1.x509.X509Util.getPKCS8PubKeyPEMfromRSAKey(pubKey);\n     */\n   this.getPKCS8PubKeyPEMfromRSAKey = function(rsaKey) {\n       var pem = null;\n       var hN = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(rsaKey.n);\n       var hE = KJUR.asn1.ASN1Util.integerToByteHex(rsaKey.e);\n       var iN = new KJUR.asn1.DERInteger({hex: hN});\n       var iE = new KJUR.asn1.DERInteger({hex: hE});\n       var asn1PubKey = new KJUR.asn1.DERSequence({array: [iN, iE]});\n       var hPubKey = asn1PubKey.getEncodedHex();\n       var o1 = new KJUR.asn1.x509.AlgorithmIdentifier({name: 'rsaEncryption'});\n       var o2 = new KJUR.asn1.DERBitString({hex: '00' + hPubKey});\n       var seq = new KJUR.asn1.DERSequence({array: [o1, o2]});\n       var hP8 = seq.getEncodedHex();\n       var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(hP8, \"PUBLIC KEY\");\n       return pem;\n   };\n};\n/**\n * issue a certificate in PEM format\n * @name newCertPEM\n * @memberOf KJUR.asn1.x509.X509Util\n * @function\n * @param {Array} param parameter to issue a certificate\n * @since asn1x509 1.0.6\n * @description\n * This method can issue a certificate by a simple\n * JSON object.\n * NOTE: When using DSA or ECDSA CA signing key,\n * use 'paramempty' in 'sigalg' to ommit parameter field\n * of AlgorithmIdentifer. In case of RSA, parameter\n * NULL will be specified by default.\n * @example\n * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM(\n * { serial: {int: 4},\n *   sigalg: {name: 'SHA1withECDSA', paramempty: true},\n *   issuer: {str: '/C=US/O=a'},\n *   notbefore: {'str': '130504235959Z'},\n *   notafter: {'str': '140504235959Z'},\n *   subject: {str: '/C=US/O=b'},\n *   sbjpubkey: pubKeyPEM,\n *   ext: [\n *     {basicConstraints: {cA: true, critical: true}},\n *     {keyUsage: {bin: '11'}},\n *   ],\n *   cakey: [prvkey, pass]}\n * );\n */\nKJUR.asn1.x509.X509Util.newCertPEM = function(param) {\n    var ns1 = KJUR.asn1.x509;\n    var o = new ns1.TBSCertificate();\n\n    if (param.serial !== undefined)\n\to.setSerialNumberByParam(param.serial);\n    else\n\tthrow \"serial number undefined.\";\n\n    if (typeof param.sigalg.name == 'string')\n\to.setSignatureAlgByParam(param.sigalg);\n    else \n\tthrow \"unproper signature algorithm name\";\n\n    if (param.issuer !== undefined)\n\to.setIssuerByParam(param.issuer);\n    else\n\tthrow \"issuer name undefined.\";\n    \n    if (param.notbefore !== undefined)\n\to.setNotBeforeByParam(param.notbefore);\n    else\n\tthrow \"notbefore undefined.\";\n\n    if (param.notafter !== undefined)\n\to.setNotAfterByParam(param.notafter);\n    else\n\tthrow \"notafter undefined.\";\n\n    if (param.subject !== undefined)\n\to.setSubjectByParam(param.subject);\n    else\n\tthrow \"subject name undefined.\";\n\n    if (param.sbjpubkey !== undefined)\n\to.setSubjectPublicKeyByGetKey(param.sbjpubkey);\n    else\n\tthrow \"subject public key undefined.\";\n\n    if (param.ext.length !== undefined) {\n\tfor (var i = 0; i < param.ext.length; i++) {\n\t    for (key in param.ext[i]) {\n\t\to.appendExtensionByName(key, param.ext[i][key]);\n\t    }\n\t}\n    }\n\n    var caKey = null;\n    if (param.cakey)\n\tcaKey = KEYUTIL.getKey.apply(null, param.cakey);\n    else\n\tthrow \"ca key undefined\";\n\n    var cert = new ns1.Certificate({'tbscertobj': o, 'prvkeyobj': caKey});\n    cert.sign();\n    return cert.getPEMString();\n};\n\n/*\norg.bouncycastle.asn1.x500\nAttributeTypeAndValue\nDirectoryString\nRDN\nX500Name\nX500NameBuilder\n\norg.bouncycastleasn1.x509\nTBSCertificate\n */\n"
  },
  {
    "path": "JavaScript/demo/js/base64.js",
    "content": "/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nvar b64map=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nvar b64pad=\"=\";\n\nfunction hex2b64(h) {\n  var i;\n  var c;\n  var ret = \"\";\n  for(i = 0; i+3 <= h.length; i+=3) {\n    c = parseInt(h.substring(i,i+3),16);\n    ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);\n  }\n  if(i+1 == h.length) {\n    c = parseInt(h.substring(i,i+1),16);\n    ret += b64map.charAt(c << 2);\n  }\n  else if(i+2 == h.length) {\n    c = parseInt(h.substring(i,i+2),16);\n    ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);\n  }\n  if (b64pad) while((ret.length & 3) > 0) ret += b64pad;\n  return ret;\n}\n\n// convert a base64 string to hex\nfunction b64tohex(s) {\n  var ret = \"\"\n  var i;\n  var k = 0; // b64 state, 0-3\n  var slop;\n  var v;\n  for(i = 0; i < s.length; ++i) {\n    if(s.charAt(i) == b64pad) break;\n    v = b64map.indexOf(s.charAt(i));\n    if(v < 0) continue;\n    if(k == 0) {\n      ret += int2char(v >> 2);\n      slop = v & 3;\n      k = 1;\n    }\n    else if(k == 1) {\n      ret += int2char((slop << 2) | (v >> 4));\n      slop = v & 0xf;\n      k = 2;\n    }\n    else if(k == 2) {\n      ret += int2char(slop);\n      ret += int2char(v >> 2);\n      slop = v & 3;\n      k = 3;\n    }\n    else {\n      ret += int2char((slop << 2) | (v >> 4));\n      ret += int2char(v & 0xf);\n      k = 0;\n    }\n  }\n  if(k == 1)\n    ret += int2char(slop << 2);\n  return ret;\n}\n\n// convert a base64 string to a byte/number array\nfunction b64toBA(s) {\n  //piggyback on b64tohex for now, optimize later\n  var h = b64tohex(s);\n  var i;\n  var a = new Array();\n  for(i = 0; 2*i < h.length; ++i) {\n    a[i] = parseInt(h.substring(2*i,2*i+2),16);\n  }\n  return a;\n}\n"
  },
  {
    "path": "JavaScript/demo/js/cipher-core.js",
    "content": "/*\nCryptoJS v3.1.2\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n/**\r\n * Cipher core components.\r\n */\r\nCryptoJS.lib.Cipher || (function (undefined) {\r\n    // Shortcuts\r\n    var C = CryptoJS;\r\n    var C_lib = C.lib;\r\n    var Base = C_lib.Base;\r\n    var WordArray = C_lib.WordArray;\r\n    var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm;\r\n    var C_enc = C.enc;\r\n    var Utf8 = C_enc.Utf8;\r\n    var Base64 = C_enc.Base64;\r\n    var C_algo = C.algo;\r\n    var EvpKDF = C_algo.EvpKDF;\r\n\r\n    /**\r\n     * Abstract base cipher template.\r\n     *\r\n     * @property {number} keySize This cipher's key size. Default: 4 (128 bits)\r\n     * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits)\r\n     * @property {number} _ENC_XFORM_MODE A constant representing encryption mode.\r\n     * @property {number} _DEC_XFORM_MODE A constant representing decryption mode.\r\n     */\r\n    var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({\r\n        /**\r\n         * Configuration options.\r\n         *\r\n         * @property {WordArray} iv The IV to use for this operation.\r\n         */\r\n        cfg: Base.extend(),\r\n\r\n        /**\r\n         * Creates this cipher in encryption mode.\r\n         *\r\n         * @param {WordArray} key The key.\r\n         * @param {Object} cfg (Optional) The configuration options to use for this operation.\r\n         *\r\n         * @return {Cipher} A cipher instance.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });\r\n         */\r\n        createEncryptor: function (key, cfg) {\r\n            return this.create(this._ENC_XFORM_MODE, key, cfg);\r\n        },\r\n\r\n        /**\r\n         * Creates this cipher in decryption mode.\r\n         *\r\n         * @param {WordArray} key The key.\r\n         * @param {Object} cfg (Optional) The configuration options to use for this operation.\r\n         *\r\n         * @return {Cipher} A cipher instance.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });\r\n         */\r\n        createDecryptor: function (key, cfg) {\r\n            return this.create(this._DEC_XFORM_MODE, key, cfg);\r\n        },\r\n\r\n        /**\r\n         * Initializes a newly created cipher.\r\n         *\r\n         * @param {number} xformMode Either the encryption or decryption transormation mode constant.\r\n         * @param {WordArray} key The key.\r\n         * @param {Object} cfg (Optional) The configuration options to use for this operation.\r\n         *\r\n         * @example\r\n         *\r\n         *     var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });\r\n         */\r\n        init: function (xformMode, key, cfg) {\r\n            // Apply config defaults\r\n            this.cfg = this.cfg.extend(cfg);\r\n\r\n            // Store transform mode and key\r\n            this._xformMode = xformMode;\r\n            this._key = key;\r\n\r\n            // Set initial values\r\n            this.reset();\r\n        },\r\n\r\n        /**\r\n         * Resets this cipher to its initial state.\r\n         *\r\n         * @example\r\n         *\r\n         *     cipher.reset();\r\n         */\r\n        reset: function () {\r\n            // Reset data buffer\r\n            BufferedBlockAlgorithm.reset.call(this);\r\n\r\n            // Perform concrete-cipher logic\r\n            this._doReset();\r\n        },\r\n\r\n        /**\r\n         * Adds data to be encrypted or decrypted.\r\n         *\r\n         * @param {WordArray|string} dataUpdate The data to encrypt or decrypt.\r\n         *\r\n         * @return {WordArray} The data after processing.\r\n         *\r\n         * @example\r\n         *\r\n         *     var encrypted = cipher.process('data');\r\n         *     var encrypted = cipher.process(wordArray);\r\n         */\r\n        process: function (dataUpdate) {\r\n            // Append\r\n            this._append(dataUpdate);\r\n\r\n            // Process available blocks\r\n            return this._process();\r\n        },\r\n\r\n        /**\r\n         * Finalizes the encryption or decryption process.\r\n         * Note that the finalize operation is effectively a destructive, read-once operation.\r\n         *\r\n         * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt.\r\n         *\r\n         * @return {WordArray} The data after final processing.\r\n         *\r\n         * @example\r\n         *\r\n         *     var encrypted = cipher.finalize();\r\n         *     var encrypted = cipher.finalize('data');\r\n         *     var encrypted = cipher.finalize(wordArray);\r\n         */\r\n        finalize: function (dataUpdate) {\r\n            // Final data update\r\n            if (dataUpdate) {\r\n                this._append(dataUpdate);\r\n            }\r\n\r\n            // Perform concrete-cipher logic\r\n            var finalProcessedData = this._doFinalize();\r\n\r\n            return finalProcessedData;\r\n        },\r\n\r\n        keySize: 128/32,\r\n\r\n        ivSize: 128/32,\r\n\r\n        _ENC_XFORM_MODE: 1,\r\n\r\n        _DEC_XFORM_MODE: 2,\r\n\r\n        /**\r\n         * Creates shortcut functions to a cipher's object interface.\r\n         *\r\n         * @param {Cipher} cipher The cipher to create a helper for.\r\n         *\r\n         * @return {Object} An object with encrypt and decrypt shortcut functions.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);\r\n         */\r\n        _createHelper: (function () {\r\n            function selectCipherStrategy(key) {\r\n                if (typeof key == 'string') {\r\n                    return PasswordBasedCipher;\r\n                } else {\r\n                    return SerializableCipher;\r\n                }\r\n            }\r\n\r\n            return function (cipher) {\r\n                return {\r\n                    encrypt: function (message, key, cfg) {\r\n                        return selectCipherStrategy(key).encrypt(cipher, message, key, cfg);\r\n                    },\r\n\r\n                    decrypt: function (ciphertext, key, cfg) {\r\n                        return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg);\r\n                    }\r\n                };\r\n            };\r\n        }())\r\n    });\r\n\r\n    /**\r\n     * Abstract base stream cipher template.\r\n     *\r\n     * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits)\r\n     */\r\n    var StreamCipher = C_lib.StreamCipher = Cipher.extend({\r\n        _doFinalize: function () {\r\n            // Process partial blocks\r\n            var finalProcessedBlocks = this._process(!!'flush');\r\n\r\n            return finalProcessedBlocks;\r\n        },\r\n\r\n        blockSize: 1\r\n    });\r\n\r\n    /**\r\n     * Mode namespace.\r\n     */\r\n    var C_mode = C.mode = {};\r\n\r\n    /**\r\n     * Abstract base block cipher mode template.\r\n     */\r\n    var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({\r\n        /**\r\n         * Creates this mode for encryption.\r\n         *\r\n         * @param {Cipher} cipher A block cipher instance.\r\n         * @param {Array} iv The IV words.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);\r\n         */\r\n        createEncryptor: function (cipher, iv) {\r\n            return this.Encryptor.create(cipher, iv);\r\n        },\r\n\r\n        /**\r\n         * Creates this mode for decryption.\r\n         *\r\n         * @param {Cipher} cipher A block cipher instance.\r\n         * @param {Array} iv The IV words.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words);\r\n         */\r\n        createDecryptor: function (cipher, iv) {\r\n            return this.Decryptor.create(cipher, iv);\r\n        },\r\n\r\n        /**\r\n         * Initializes a newly created mode.\r\n         *\r\n         * @param {Cipher} cipher A block cipher instance.\r\n         * @param {Array} iv The IV words.\r\n         *\r\n         * @example\r\n         *\r\n         *     var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words);\r\n         */\r\n        init: function (cipher, iv) {\r\n            this._cipher = cipher;\r\n            this._iv = iv;\r\n        }\r\n    });\r\n\r\n    /**\r\n     * Cipher Block Chaining mode.\r\n     */\r\n    var CBC = C_mode.CBC = (function () {\r\n        /**\r\n         * Abstract base CBC mode.\r\n         */\r\n        var CBC = BlockCipherMode.extend();\r\n\r\n        /**\r\n         * CBC encryptor.\r\n         */\r\n        CBC.Encryptor = CBC.extend({\r\n            /**\r\n             * Processes the data block at offset.\r\n             *\r\n             * @param {Array} words The data words to operate on.\r\n             * @param {number} offset The offset where the block starts.\r\n             *\r\n             * @example\r\n             *\r\n             *     mode.processBlock(data.words, offset);\r\n             */\r\n            processBlock: function (words, offset) {\r\n                // Shortcuts\r\n                var cipher = this._cipher;\r\n                var blockSize = cipher.blockSize;\r\n\r\n                // XOR and encrypt\r\n                xorBlock.call(this, words, offset, blockSize);\r\n                cipher.encryptBlock(words, offset);\r\n\r\n                // Remember this block to use with next block\r\n                this._prevBlock = words.slice(offset, offset + blockSize);\r\n            }\r\n        });\r\n\r\n        /**\r\n         * CBC decryptor.\r\n         */\r\n        CBC.Decryptor = CBC.extend({\r\n            /**\r\n             * Processes the data block at offset.\r\n             *\r\n             * @param {Array} words The data words to operate on.\r\n             * @param {number} offset The offset where the block starts.\r\n             *\r\n             * @example\r\n             *\r\n             *     mode.processBlock(data.words, offset);\r\n             */\r\n            processBlock: function (words, offset) {\r\n                // Shortcuts\r\n                var cipher = this._cipher;\r\n                var blockSize = cipher.blockSize;\r\n\r\n                // Remember this block to use with next block\r\n                var thisBlock = words.slice(offset, offset + blockSize);\r\n\r\n                // Decrypt and XOR\r\n                cipher.decryptBlock(words, offset);\r\n                xorBlock.call(this, words, offset, blockSize);\r\n\r\n                // This block becomes the previous block\r\n                this._prevBlock = thisBlock;\r\n            }\r\n        });\r\n\r\n        function xorBlock(words, offset, blockSize) {\r\n            // Shortcut\r\n            var iv = this._iv;\r\n\r\n            // Choose mixing block\r\n            if (iv) {\r\n                var block = iv;\r\n\r\n                // Remove IV for subsequent blocks\r\n                this._iv = undefined;\r\n            } else {\r\n                var block = this._prevBlock;\r\n            }\r\n\r\n            // XOR blocks\r\n            for (var i = 0; i < blockSize; i++) {\r\n                words[offset + i] ^= block[i];\r\n            }\r\n        }\r\n\r\n        return CBC;\r\n    }());\r\n\r\n    /**\r\n     * Padding namespace.\r\n     */\r\n    var C_pad = C.pad = {};\r\n\r\n    /**\r\n     * PKCS #5/7 padding strategy.\r\n     */\r\n    var Pkcs7 = C_pad.Pkcs7 = {\r\n        /**\r\n         * Pads data using the algorithm defined in PKCS #5/7.\r\n         *\r\n         * @param {WordArray} data The data to pad.\r\n         * @param {number} blockSize The multiple that the data should be padded to.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     CryptoJS.pad.Pkcs7.pad(wordArray, 4);\r\n         */\r\n        pad: function (data, blockSize) {\r\n            // Shortcut\r\n            var blockSizeBytes = blockSize * 4;\r\n\r\n            // Count padding bytes\r\n            var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;\r\n\r\n            // Create padding word\r\n            var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes;\r\n\r\n            // Create padding\r\n            var paddingWords = [];\r\n            for (var i = 0; i < nPaddingBytes; i += 4) {\r\n                paddingWords.push(paddingWord);\r\n            }\r\n            var padding = WordArray.create(paddingWords, nPaddingBytes);\r\n\r\n            // Add padding\r\n            data.concat(padding);\r\n        },\r\n\r\n        /**\r\n         * Unpads data that had been padded using the algorithm defined in PKCS #5/7.\r\n         *\r\n         * @param {WordArray} data The data to unpad.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     CryptoJS.pad.Pkcs7.unpad(wordArray);\r\n         */\r\n        unpad: function (data) {\r\n            // Get number of padding bytes from last byte\r\n            var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;\r\n\r\n            // Remove padding\r\n            data.sigBytes -= nPaddingBytes;\r\n        }\r\n    };\r\n\r\n    /**\r\n     * Abstract base block cipher template.\r\n     *\r\n     * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits)\r\n     */\r\n    var BlockCipher = C_lib.BlockCipher = Cipher.extend({\r\n        /**\r\n         * Configuration options.\r\n         *\r\n         * @property {Mode} mode The block mode to use. Default: CBC\r\n         * @property {Padding} padding The padding strategy to use. Default: Pkcs7\r\n         */\r\n        cfg: Cipher.cfg.extend({\r\n            mode: CBC,\r\n            padding: Pkcs7\r\n        }),\r\n\r\n        reset: function () {\r\n            // Reset cipher\r\n            Cipher.reset.call(this);\r\n\r\n            // Shortcuts\r\n            var cfg = this.cfg;\r\n            var iv = cfg.iv;\r\n            var mode = cfg.mode;\r\n\r\n            // Reset block mode\r\n            if (this._xformMode == this._ENC_XFORM_MODE) {\r\n                var modeCreator = mode.createEncryptor;\r\n            } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {\r\n                var modeCreator = mode.createDecryptor;\r\n\r\n                // Keep at least one block in the buffer for unpadding\r\n                this._minBufferSize = 1;\r\n            }\r\n            this._mode = modeCreator.call(mode, this, iv && iv.words);\r\n        },\r\n\r\n        _doProcessBlock: function (words, offset) {\r\n            this._mode.processBlock(words, offset);\r\n        },\r\n\r\n        _doFinalize: function () {\r\n            // Shortcut\r\n            var padding = this.cfg.padding;\r\n\r\n            // Finalize\r\n            if (this._xformMode == this._ENC_XFORM_MODE) {\r\n                // Pad data\r\n                padding.pad(this._data, this.blockSize);\r\n\r\n                // Process final blocks\r\n                var finalProcessedBlocks = this._process(!!'flush');\r\n            } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {\r\n                // Process final blocks\r\n                var finalProcessedBlocks = this._process(!!'flush');\r\n\r\n                // Unpad data\r\n                padding.unpad(finalProcessedBlocks);\r\n            }\r\n\r\n            return finalProcessedBlocks;\r\n        },\r\n\r\n        blockSize: 128/32\r\n    });\r\n\r\n    /**\r\n     * A collection of cipher parameters.\r\n     *\r\n     * @property {WordArray} ciphertext The raw ciphertext.\r\n     * @property {WordArray} key The key to this ciphertext.\r\n     * @property {WordArray} iv The IV used in the ciphering operation.\r\n     * @property {WordArray} salt The salt used with a key derivation function.\r\n     * @property {Cipher} algorithm The cipher algorithm.\r\n     * @property {Mode} mode The block mode used in the ciphering operation.\r\n     * @property {Padding} padding The padding scheme used in the ciphering operation.\r\n     * @property {number} blockSize The block size of the cipher.\r\n     * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string.\r\n     */\r\n    var CipherParams = C_lib.CipherParams = Base.extend({\r\n        /**\r\n         * Initializes a newly created cipher params object.\r\n         *\r\n         * @param {Object} cipherParams An object with any of the possible cipher parameters.\r\n         *\r\n         * @example\r\n         *\r\n         *     var cipherParams = CryptoJS.lib.CipherParams.create({\r\n         *         ciphertext: ciphertextWordArray,\r\n         *         key: keyWordArray,\r\n         *         iv: ivWordArray,\r\n         *         salt: saltWordArray,\r\n         *         algorithm: CryptoJS.algo.AES,\r\n         *         mode: CryptoJS.mode.CBC,\r\n         *         padding: CryptoJS.pad.PKCS7,\r\n         *         blockSize: 4,\r\n         *         formatter: CryptoJS.format.OpenSSL\r\n         *     });\r\n         */\r\n        init: function (cipherParams) {\r\n            this.mixIn(cipherParams);\r\n        },\r\n\r\n        /**\r\n         * Converts this cipher params object to a string.\r\n         *\r\n         * @param {Format} formatter (Optional) The formatting strategy to use.\r\n         *\r\n         * @return {string} The stringified cipher params.\r\n         *\r\n         * @throws Error If neither the formatter nor the default formatter is set.\r\n         *\r\n         * @example\r\n         *\r\n         *     var string = cipherParams + '';\r\n         *     var string = cipherParams.toString();\r\n         *     var string = cipherParams.toString(CryptoJS.format.OpenSSL);\r\n         */\r\n        toString: function (formatter) {\r\n            return (formatter || this.formatter).stringify(this);\r\n        }\r\n    });\r\n\r\n    /**\r\n     * Format namespace.\r\n     */\r\n    var C_format = C.format = {};\r\n\r\n    /**\r\n     * OpenSSL formatting strategy.\r\n     */\r\n    var OpenSSLFormatter = C_format.OpenSSL = {\r\n        /**\r\n         * Converts a cipher params object to an OpenSSL-compatible string.\r\n         *\r\n         * @param {CipherParams} cipherParams The cipher params object.\r\n         *\r\n         * @return {string} The OpenSSL-compatible string.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams);\r\n         */\r\n        stringify: function (cipherParams) {\r\n            // Shortcuts\r\n            var ciphertext = cipherParams.ciphertext;\r\n            var salt = cipherParams.salt;\r\n\r\n            // Format\r\n            if (salt) {\r\n                var wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);\r\n            } else {\r\n                var wordArray = ciphertext;\r\n            }\r\n\r\n            return wordArray.toString(Base64);\r\n        },\r\n\r\n        /**\r\n         * Converts an OpenSSL-compatible string to a cipher params object.\r\n         *\r\n         * @param {string} openSSLStr The OpenSSL-compatible string.\r\n         *\r\n         * @return {CipherParams} The cipher params object.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString);\r\n         */\r\n        parse: function (openSSLStr) {\r\n            // Parse base64\r\n            var ciphertext = Base64.parse(openSSLStr);\r\n\r\n            // Shortcut\r\n            var ciphertextWords = ciphertext.words;\r\n\r\n            // Test for salt\r\n            if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) {\r\n                // Extract salt\r\n                var salt = WordArray.create(ciphertextWords.slice(2, 4));\r\n\r\n                // Remove salt from ciphertext\r\n                ciphertextWords.splice(0, 4);\r\n                ciphertext.sigBytes -= 16;\r\n            }\r\n\r\n            return CipherParams.create({ ciphertext: ciphertext, salt: salt });\r\n        }\r\n    };\r\n\r\n    /**\r\n     * A cipher wrapper that returns ciphertext as a serializable cipher params object.\r\n     */\r\n    var SerializableCipher = C_lib.SerializableCipher = Base.extend({\r\n        /**\r\n         * Configuration options.\r\n         *\r\n         * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL\r\n         */\r\n        cfg: Base.extend({\r\n            format: OpenSSLFormatter\r\n        }),\r\n\r\n        /**\r\n         * Encrypts a message.\r\n         *\r\n         * @param {Cipher} cipher The cipher algorithm to use.\r\n         * @param {WordArray|string} message The message to encrypt.\r\n         * @param {WordArray} key The key.\r\n         * @param {Object} cfg (Optional) The configuration options to use for this operation.\r\n         *\r\n         * @return {CipherParams} A cipher params object.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key);\r\n         *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv });\r\n         *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL });\r\n         */\r\n        encrypt: function (cipher, message, key, cfg) {\r\n            // Apply config defaults\r\n            cfg = this.cfg.extend(cfg);\r\n\r\n            // Encrypt\r\n            var encryptor = cipher.createEncryptor(key, cfg);\r\n            var ciphertext = encryptor.finalize(message);\r\n\r\n            // Shortcut\r\n            var cipherCfg = encryptor.cfg;\r\n\r\n            // Create and return serializable cipher params\r\n            return CipherParams.create({\r\n                ciphertext: ciphertext,\r\n                key: key,\r\n                iv: cipherCfg.iv,\r\n                algorithm: cipher,\r\n                mode: cipherCfg.mode,\r\n                padding: cipherCfg.padding,\r\n                blockSize: cipher.blockSize,\r\n                formatter: cfg.format\r\n            });\r\n        },\r\n\r\n        /**\r\n         * Decrypts serialized ciphertext.\r\n         *\r\n         * @param {Cipher} cipher The cipher algorithm to use.\r\n         * @param {CipherParams|string} ciphertext The ciphertext to decrypt.\r\n         * @param {WordArray} key The key.\r\n         * @param {Object} cfg (Optional) The configuration options to use for this operation.\r\n         *\r\n         * @return {WordArray} The plaintext.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL });\r\n         *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL });\r\n         */\r\n        decrypt: function (cipher, ciphertext, key, cfg) {\r\n            // Apply config defaults\r\n            cfg = this.cfg.extend(cfg);\r\n\r\n            // Convert string to CipherParams\r\n            ciphertext = this._parse(ciphertext, cfg.format);\r\n\r\n            // Decrypt\r\n            var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext);\r\n\r\n            return plaintext;\r\n        },\r\n\r\n        /**\r\n         * Converts serialized ciphertext to CipherParams,\r\n         * else assumed CipherParams already and returns ciphertext unchanged.\r\n         *\r\n         * @param {CipherParams|string} ciphertext The ciphertext.\r\n         * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext.\r\n         *\r\n         * @return {CipherParams} The unserialized ciphertext.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format);\r\n         */\r\n        _parse: function (ciphertext, format) {\r\n            if (typeof ciphertext == 'string') {\r\n                return format.parse(ciphertext, this);\r\n            } else {\r\n                return ciphertext;\r\n            }\r\n        }\r\n    });\r\n\r\n    /**\r\n     * Key derivation function namespace.\r\n     */\r\n    var C_kdf = C.kdf = {};\r\n\r\n    /**\r\n     * OpenSSL key derivation function.\r\n     */\r\n    var OpenSSLKdf = C_kdf.OpenSSL = {\r\n        /**\r\n         * Derives a key and IV from a password.\r\n         *\r\n         * @param {string} password The password to derive from.\r\n         * @param {number} keySize The size in words of the key to generate.\r\n         * @param {number} ivSize The size in words of the IV to generate.\r\n         * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly.\r\n         *\r\n         * @return {CipherParams} A cipher params object with the key, IV, and salt.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32);\r\n         *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt');\r\n         */\r\n        execute: function (password, keySize, ivSize, salt) {\r\n            // Generate random salt\r\n            if (!salt) {\r\n                salt = WordArray.random(64/8);\r\n            }\r\n\r\n            // Derive key and IV\r\n            var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);\r\n\r\n            // Separate key and IV\r\n            var iv = WordArray.create(key.words.slice(keySize), ivSize * 4);\r\n            key.sigBytes = keySize * 4;\r\n\r\n            // Return params\r\n            return CipherParams.create({ key: key, iv: iv, salt: salt });\r\n        }\r\n    };\r\n\r\n    /**\r\n     * A serializable cipher wrapper that derives the key from a password,\r\n     * and returns ciphertext as a serializable cipher params object.\r\n     */\r\n    var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({\r\n        /**\r\n         * Configuration options.\r\n         *\r\n         * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL\r\n         */\r\n        cfg: SerializableCipher.cfg.extend({\r\n            kdf: OpenSSLKdf\r\n        }),\r\n\r\n        /**\r\n         * Encrypts a message using a password.\r\n         *\r\n         * @param {Cipher} cipher The cipher algorithm to use.\r\n         * @param {WordArray|string} message The message to encrypt.\r\n         * @param {string} password The password.\r\n         * @param {Object} cfg (Optional) The configuration options to use for this operation.\r\n         *\r\n         * @return {CipherParams} A cipher params object.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password');\r\n         *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL });\r\n         */\r\n        encrypt: function (cipher, message, password, cfg) {\r\n            // Apply config defaults\r\n            cfg = this.cfg.extend(cfg);\r\n\r\n            // Derive key and other params\r\n            var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize);\r\n\r\n            // Add IV to config\r\n            cfg.iv = derivedParams.iv;\r\n\r\n            // Encrypt\r\n            var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);\r\n\r\n            // Mix in derived params\r\n            ciphertext.mixIn(derivedParams);\r\n\r\n            return ciphertext;\r\n        },\r\n\r\n        /**\r\n         * Decrypts serialized ciphertext using a password.\r\n         *\r\n         * @param {Cipher} cipher The cipher algorithm to use.\r\n         * @param {CipherParams|string} ciphertext The ciphertext to decrypt.\r\n         * @param {string} password The password.\r\n         * @param {Object} cfg (Optional) The configuration options to use for this operation.\r\n         *\r\n         * @return {WordArray} The plaintext.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL });\r\n         *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL });\r\n         */\r\n        decrypt: function (cipher, ciphertext, password, cfg) {\r\n            // Apply config defaults\r\n            cfg = this.cfg.extend(cfg);\r\n\r\n            // Convert string to CipherParams\r\n            ciphertext = this._parse(ciphertext, cfg.format);\r\n\r\n            // Derive key and other params\r\n            var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt);\r\n\r\n            // Add IV to config\r\n            cfg.iv = derivedParams.iv;\r\n\r\n            // Decrypt\r\n            var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg);\r\n\r\n            return plaintext;\r\n        }\r\n    });\r\n}());\r\n"
  },
  {
    "path": "JavaScript/demo/js/core.js",
    "content": "/*\nCryptoJS v3.1.2\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n/**\r\n * CryptoJS core components.\r\n */\r\nvar CryptoJS = CryptoJS || (function (Math, undefined) {\r\n    /**\r\n     * CryptoJS namespace.\r\n     */\r\n    var C = {};\r\n\r\n    /**\r\n     * Library namespace.\r\n     */\r\n    var C_lib = C.lib = {};\r\n\r\n    /**\r\n     * Base object for prototypal inheritance.\r\n     */\r\n    var Base = C_lib.Base = (function () {\r\n        function F() {}\r\n\r\n        return {\r\n            /**\r\n             * Creates a new object that inherits from this object.\r\n             *\r\n             * @param {Object} overrides Properties to copy into the new object.\r\n             *\r\n             * @return {Object} The new object.\r\n             *\r\n             * @static\r\n             *\r\n             * @example\r\n             *\r\n             *     var MyType = CryptoJS.lib.Base.extend({\r\n             *         field: 'value',\r\n             *\r\n             *         method: function () {\r\n             *         }\r\n             *     });\r\n             */\r\n            extend: function (overrides) {\r\n                // Spawn\r\n                F.prototype = this;\r\n                var subtype = new F();\r\n\r\n                // Augment\r\n                if (overrides) {\r\n                    subtype.mixIn(overrides);\r\n                }\r\n\r\n                // Create default initializer\r\n                if (!subtype.hasOwnProperty('init')) {\r\n                    subtype.init = function () {\r\n                        subtype.$super.init.apply(this, arguments);\r\n                    };\r\n                }\r\n\r\n                // Initializer's prototype is the subtype object\r\n                subtype.init.prototype = subtype;\r\n\r\n                // Reference supertype\r\n                subtype.$super = this;\r\n\r\n                return subtype;\r\n            },\r\n\r\n            /**\r\n             * Extends this object and runs the init method.\r\n             * Arguments to create() will be passed to init().\r\n             *\r\n             * @return {Object} The new object.\r\n             *\r\n             * @static\r\n             *\r\n             * @example\r\n             *\r\n             *     var instance = MyType.create();\r\n             */\r\n            create: function () {\r\n                var instance = this.extend();\r\n                instance.init.apply(instance, arguments);\r\n\r\n                return instance;\r\n            },\r\n\r\n            /**\r\n             * Initializes a newly created object.\r\n             * Override this method to add some logic when your objects are created.\r\n             *\r\n             * @example\r\n             *\r\n             *     var MyType = CryptoJS.lib.Base.extend({\r\n             *         init: function () {\r\n             *             // ...\r\n             *         }\r\n             *     });\r\n             */\r\n            init: function () {\r\n            },\r\n\r\n            /**\r\n             * Copies properties into this object.\r\n             *\r\n             * @param {Object} properties The properties to mix in.\r\n             *\r\n             * @example\r\n             *\r\n             *     MyType.mixIn({\r\n             *         field: 'value'\r\n             *     });\r\n             */\r\n            mixIn: function (properties) {\r\n                for (var propertyName in properties) {\r\n                    if (properties.hasOwnProperty(propertyName)) {\r\n                        this[propertyName] = properties[propertyName];\r\n                    }\r\n                }\r\n\r\n                // IE won't copy toString using the loop above\r\n                if (properties.hasOwnProperty('toString')) {\r\n                    this.toString = properties.toString;\r\n                }\r\n            },\r\n\r\n            /**\r\n             * Creates a copy of this object.\r\n             *\r\n             * @return {Object} The clone.\r\n             *\r\n             * @example\r\n             *\r\n             *     var clone = instance.clone();\r\n             */\r\n            clone: function () {\r\n                return this.init.prototype.extend(this);\r\n            }\r\n        };\r\n    }());\r\n\r\n    /**\r\n     * An array of 32-bit words.\r\n     *\r\n     * @property {Array} words The array of 32-bit words.\r\n     * @property {number} sigBytes The number of significant bytes in this word array.\r\n     */\r\n    var WordArray = C_lib.WordArray = Base.extend({\r\n        /**\r\n         * Initializes a newly created word array.\r\n         *\r\n         * @param {Array} words (Optional) An array of 32-bit words.\r\n         * @param {number} sigBytes (Optional) The number of significant bytes in the words.\r\n         *\r\n         * @example\r\n         *\r\n         *     var wordArray = CryptoJS.lib.WordArray.create();\r\n         *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);\r\n         *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);\r\n         */\r\n        init: function (words, sigBytes) {\r\n            words = this.words = words || [];\r\n\r\n            if (sigBytes != undefined) {\r\n                this.sigBytes = sigBytes;\r\n            } else {\r\n                this.sigBytes = words.length * 4;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Converts this word array to a string.\r\n         *\r\n         * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex\r\n         *\r\n         * @return {string} The stringified word array.\r\n         *\r\n         * @example\r\n         *\r\n         *     var string = wordArray + '';\r\n         *     var string = wordArray.toString();\r\n         *     var string = wordArray.toString(CryptoJS.enc.Utf8);\r\n         */\r\n        toString: function (encoder) {\r\n            return (encoder || Hex).stringify(this);\r\n        },\r\n\r\n        /**\r\n         * Concatenates a word array to this word array.\r\n         *\r\n         * @param {WordArray} wordArray The word array to append.\r\n         *\r\n         * @return {WordArray} This word array.\r\n         *\r\n         * @example\r\n         *\r\n         *     wordArray1.concat(wordArray2);\r\n         */\r\n        concat: function (wordArray) {\r\n            // Shortcuts\r\n            var thisWords = this.words;\r\n            var thatWords = wordArray.words;\r\n            var thisSigBytes = this.sigBytes;\r\n            var thatSigBytes = wordArray.sigBytes;\r\n\r\n            // Clamp excess bits\r\n            this.clamp();\r\n\r\n            // Concat\r\n            if (thisSigBytes % 4) {\r\n                // Copy one byte at a time\r\n                for (var i = 0; i < thatSigBytes; i++) {\r\n                    var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;\r\n                    thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);\r\n                }\r\n            } else if (thatWords.length > 0xffff) {\r\n                // Copy one word at a time\r\n                for (var i = 0; i < thatSigBytes; i += 4) {\r\n                    thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2];\r\n                }\r\n            } else {\r\n                // Copy all words at once\r\n                thisWords.push.apply(thisWords, thatWords);\r\n            }\r\n            this.sigBytes += thatSigBytes;\r\n\r\n            // Chainable\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Removes insignificant bits.\r\n         *\r\n         * @example\r\n         *\r\n         *     wordArray.clamp();\r\n         */\r\n        clamp: function () {\r\n            // Shortcuts\r\n            var words = this.words;\r\n            var sigBytes = this.sigBytes;\r\n\r\n            // Clamp\r\n            words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);\r\n            words.length = Math.ceil(sigBytes / 4);\r\n        },\r\n\r\n        /**\r\n         * Creates a copy of this word array.\r\n         *\r\n         * @return {WordArray} The clone.\r\n         *\r\n         * @example\r\n         *\r\n         *     var clone = wordArray.clone();\r\n         */\r\n        clone: function () {\r\n            var clone = Base.clone.call(this);\r\n            clone.words = this.words.slice(0);\r\n\r\n            return clone;\r\n        },\r\n\r\n        /**\r\n         * Creates a word array filled with random bytes.\r\n         *\r\n         * @param {number} nBytes The number of random bytes to generate.\r\n         *\r\n         * @return {WordArray} The random word array.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var wordArray = CryptoJS.lib.WordArray.random(16);\r\n         */\r\n        random: function (nBytes) {\r\n            var words = [];\r\n            for (var i = 0; i < nBytes; i += 4) {\r\n                words.push((Math.random() * 0x100000000) | 0);\r\n            }\r\n\r\n            return new WordArray.init(words, nBytes);\r\n        }\r\n    });\r\n\r\n    /**\r\n     * Encoder namespace.\r\n     */\r\n    var C_enc = C.enc = {};\r\n\r\n    /**\r\n     * Hex encoding strategy.\r\n     */\r\n    var Hex = C_enc.Hex = {\r\n        /**\r\n         * Converts a word array to a hex string.\r\n         *\r\n         * @param {WordArray} wordArray The word array.\r\n         *\r\n         * @return {string} The hex string.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var hexString = CryptoJS.enc.Hex.stringify(wordArray);\r\n         */\r\n        stringify: function (wordArray) {\r\n            // Shortcuts\r\n            var words = wordArray.words;\r\n            var sigBytes = wordArray.sigBytes;\r\n\r\n            // Convert\r\n            var hexChars = [];\r\n            for (var i = 0; i < sigBytes; i++) {\r\n                var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;\r\n                hexChars.push((bite >>> 4).toString(16));\r\n                hexChars.push((bite & 0x0f).toString(16));\r\n            }\r\n\r\n            return hexChars.join('');\r\n        },\r\n\r\n        /**\r\n         * Converts a hex string to a word array.\r\n         *\r\n         * @param {string} hexStr The hex string.\r\n         *\r\n         * @return {WordArray} The word array.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var wordArray = CryptoJS.enc.Hex.parse(hexString);\r\n         */\r\n        parse: function (hexStr) {\r\n            // Shortcut\r\n            var hexStrLength = hexStr.length;\r\n\r\n            // Convert\r\n            var words = [];\r\n            for (var i = 0; i < hexStrLength; i += 2) {\r\n                words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);\r\n            }\r\n\r\n            return new WordArray.init(words, hexStrLength / 2);\r\n        }\r\n    };\r\n\r\n    /**\r\n     * Latin1 encoding strategy.\r\n     */\r\n    var Latin1 = C_enc.Latin1 = {\r\n        /**\r\n         * Converts a word array to a Latin1 string.\r\n         *\r\n         * @param {WordArray} wordArray The word array.\r\n         *\r\n         * @return {string} The Latin1 string.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);\r\n         */\r\n        stringify: function (wordArray) {\r\n            // Shortcuts\r\n            var words = wordArray.words;\r\n            var sigBytes = wordArray.sigBytes;\r\n\r\n            // Convert\r\n            var latin1Chars = [];\r\n            for (var i = 0; i < sigBytes; i++) {\r\n                var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;\r\n                latin1Chars.push(String.fromCharCode(bite));\r\n            }\r\n\r\n            return latin1Chars.join('');\r\n        },\r\n\r\n        /**\r\n         * Converts a Latin1 string to a word array.\r\n         *\r\n         * @param {string} latin1Str The Latin1 string.\r\n         *\r\n         * @return {WordArray} The word array.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var wordArray = CryptoJS.enc.Latin1.parse(latin1String);\r\n         */\r\n        parse: function (latin1Str) {\r\n            // Shortcut\r\n            var latin1StrLength = latin1Str.length;\r\n\r\n            // Convert\r\n            var words = [];\r\n            for (var i = 0; i < latin1StrLength; i++) {\r\n                words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);\r\n            }\r\n\r\n            return new WordArray.init(words, latin1StrLength);\r\n        }\r\n    };\r\n\r\n    /**\r\n     * UTF-8 encoding strategy.\r\n     */\r\n    var Utf8 = C_enc.Utf8 = {\r\n        /**\r\n         * Converts a word array to a UTF-8 string.\r\n         *\r\n         * @param {WordArray} wordArray The word array.\r\n         *\r\n         * @return {string} The UTF-8 string.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);\r\n         */\r\n        stringify: function (wordArray) {\r\n            try {\r\n                return decodeURIComponent(escape(Latin1.stringify(wordArray)));\r\n            } catch (e) {\r\n                throw new Error('Malformed UTF-8 data');\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Converts a UTF-8 string to a word array.\r\n         *\r\n         * @param {string} utf8Str The UTF-8 string.\r\n         *\r\n         * @return {WordArray} The word array.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var wordArray = CryptoJS.enc.Utf8.parse(utf8String);\r\n         */\r\n        parse: function (utf8Str) {\r\n            return Latin1.parse(unescape(encodeURIComponent(utf8Str)));\r\n        }\r\n    };\r\n\r\n    /**\r\n     * Abstract buffered block algorithm template.\r\n     *\r\n     * The property blockSize must be implemented in a concrete subtype.\r\n     *\r\n     * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0\r\n     */\r\n    var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({\r\n        /**\r\n         * Resets this block algorithm's data buffer to its initial state.\r\n         *\r\n         * @example\r\n         *\r\n         *     bufferedBlockAlgorithm.reset();\r\n         */\r\n        reset: function () {\r\n            // Initial values\r\n            this._data = new WordArray.init();\r\n            this._nDataBytes = 0;\r\n        },\r\n\r\n        /**\r\n         * Adds new data to this block algorithm's buffer.\r\n         *\r\n         * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.\r\n         *\r\n         * @example\r\n         *\r\n         *     bufferedBlockAlgorithm._append('data');\r\n         *     bufferedBlockAlgorithm._append(wordArray);\r\n         */\r\n        _append: function (data) {\r\n            // Convert string to WordArray, else assume WordArray already\r\n            if (typeof data == 'string') {\r\n                data = Utf8.parse(data);\r\n            }\r\n\r\n            // Append\r\n            this._data.concat(data);\r\n            this._nDataBytes += data.sigBytes;\r\n        },\r\n\r\n        /**\r\n         * Processes available data blocks.\r\n         *\r\n         * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.\r\n         *\r\n         * @param {boolean} doFlush Whether all blocks and partial blocks should be processed.\r\n         *\r\n         * @return {WordArray} The processed data.\r\n         *\r\n         * @example\r\n         *\r\n         *     var processedData = bufferedBlockAlgorithm._process();\r\n         *     var processedData = bufferedBlockAlgorithm._process(!!'flush');\r\n         */\r\n        _process: function (doFlush) {\r\n            // Shortcuts\r\n            var data = this._data;\r\n            var dataWords = data.words;\r\n            var dataSigBytes = data.sigBytes;\r\n            var blockSize = this.blockSize;\r\n            var blockSizeBytes = blockSize * 4;\r\n\r\n            // Count blocks ready\r\n            var nBlocksReady = dataSigBytes / blockSizeBytes;\r\n            if (doFlush) {\r\n                // Round up to include partial blocks\r\n                nBlocksReady = Math.ceil(nBlocksReady);\r\n            } else {\r\n                // Round down to include only full blocks,\r\n                // less the number of blocks that must remain in the buffer\r\n                nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);\r\n            }\r\n\r\n            // Count words ready\r\n            var nWordsReady = nBlocksReady * blockSize;\r\n\r\n            // Count bytes ready\r\n            var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);\r\n\r\n            // Process blocks\r\n            if (nWordsReady) {\r\n                for (var offset = 0; offset < nWordsReady; offset += blockSize) {\r\n                    // Perform concrete-algorithm logic\r\n                    this._doProcessBlock(dataWords, offset);\r\n                }\r\n\r\n                // Remove processed words\r\n                var processedWords = dataWords.splice(0, nWordsReady);\r\n                data.sigBytes -= nBytesReady;\r\n            }\r\n\r\n            // Return processed words\r\n            return new WordArray.init(processedWords, nBytesReady);\r\n        },\r\n\r\n        /**\r\n         * Creates a copy of this object.\r\n         *\r\n         * @return {Object} The clone.\r\n         *\r\n         * @example\r\n         *\r\n         *     var clone = bufferedBlockAlgorithm.clone();\r\n         */\r\n        clone: function () {\r\n            var clone = Base.clone.call(this);\r\n            clone._data = this._data.clone();\r\n\r\n            return clone;\r\n        },\r\n\r\n        _minBufferSize: 0\r\n    });\r\n\r\n    /**\r\n     * Abstract hasher template.\r\n     *\r\n     * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)\r\n     */\r\n    var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({\r\n        /**\r\n         * Configuration options.\r\n         */\r\n        cfg: Base.extend(),\r\n\r\n        /**\r\n         * Initializes a newly created hasher.\r\n         *\r\n         * @param {Object} cfg (Optional) The configuration options to use for this hash computation.\r\n         *\r\n         * @example\r\n         *\r\n         *     var hasher = CryptoJS.algo.SHA256.create();\r\n         */\r\n        init: function (cfg) {\r\n            // Apply config defaults\r\n            this.cfg = this.cfg.extend(cfg);\r\n\r\n            // Set initial values\r\n            this.reset();\r\n        },\r\n\r\n        /**\r\n         * Resets this hasher to its initial state.\r\n         *\r\n         * @example\r\n         *\r\n         *     hasher.reset();\r\n         */\r\n        reset: function () {\r\n            // Reset data buffer\r\n            BufferedBlockAlgorithm.reset.call(this);\r\n\r\n            // Perform concrete-hasher logic\r\n            this._doReset();\r\n        },\r\n\r\n        /**\r\n         * Updates this hasher with a message.\r\n         *\r\n         * @param {WordArray|string} messageUpdate The message to append.\r\n         *\r\n         * @return {Hasher} This hasher.\r\n         *\r\n         * @example\r\n         *\r\n         *     hasher.update('message');\r\n         *     hasher.update(wordArray);\r\n         */\r\n        update: function (messageUpdate) {\r\n            // Append\r\n            this._append(messageUpdate);\r\n\r\n            // Update the hash\r\n            this._process();\r\n\r\n            // Chainable\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Finalizes the hash computation.\r\n         * Note that the finalize operation is effectively a destructive, read-once operation.\r\n         *\r\n         * @param {WordArray|string} messageUpdate (Optional) A final message update.\r\n         *\r\n         * @return {WordArray} The hash.\r\n         *\r\n         * @example\r\n         *\r\n         *     var hash = hasher.finalize();\r\n         *     var hash = hasher.finalize('message');\r\n         *     var hash = hasher.finalize(wordArray);\r\n         */\r\n        finalize: function (messageUpdate) {\r\n            // Final message update\r\n            if (messageUpdate) {\r\n                this._append(messageUpdate);\r\n            }\r\n\r\n            // Perform concrete-hasher logic\r\n            var hash = this._doFinalize();\r\n\r\n            return hash;\r\n        },\r\n\r\n        blockSize: 512/32,\r\n\r\n        /**\r\n         * Creates a shortcut function to a hasher's object interface.\r\n         *\r\n         * @param {Hasher} hasher The hasher to create a helper for.\r\n         *\r\n         * @return {Function} The shortcut function.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);\r\n         */\r\n        _createHelper: function (hasher) {\r\n            return function (message, cfg) {\r\n                return new hasher.init(cfg).finalize(message);\r\n            };\r\n        },\r\n\r\n        /**\r\n         * Creates a shortcut function to the HMAC's object interface.\r\n         *\r\n         * @param {Hasher} hasher The hasher to use in this HMAC helper.\r\n         *\r\n         * @return {Function} The shortcut function.\r\n         *\r\n         * @static\r\n         *\r\n         * @example\r\n         *\r\n         *     var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);\r\n         */\r\n        _createHmacHelper: function (hasher) {\r\n            return function (message, key) {\r\n                return new C_algo.HMAC.init(hasher, key).finalize(message);\r\n            };\r\n        }\r\n    });\r\n\r\n    /**\r\n     * Algorithm namespace.\r\n     */\r\n    var C_algo = C.algo = {};\r\n\r\n    return C;\r\n}(Math));\r\n"
  },
  {
    "path": "JavaScript/demo/js/crypto-1.1.js",
    "content": "/*! crypto-1.1.5.js (c) 2013 Kenji Urushima | kjur.github.com/jsrsasign/license\r\n */\r\n/*\r\n * crypto.js - Cryptographic Algorithm Provider class\r\n *\r\n * Copyright (c) 2013 Kenji Urushima (kenji.urushima@gmail.com)\r\n *\r\n * This software is licensed under the terms of the MIT License.\r\n * http://kjur.github.com/jsrsasign/license\r\n *\r\n * The above copyright and license notice shall be \r\n * included in all copies or substantial portions of the Software.\r\n */\r\n\r\n/**\r\n * @fileOverview\r\n * @name crypto-1.1.js\r\n * @author Kenji Urushima kenji.urushima@gmail.com\r\n * @version 1.1.5 (2013-Oct-06)\r\n * @since jsrsasign 2.2\r\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\r\n */\r\n\r\n/** \r\n * kjur's class library name space\r\n * @name KJUR\r\n * @namespace kjur's class library name space\r\n */\r\nif (typeof KJUR == \"undefined\" || !KJUR) KJUR = {};\r\n/**\r\n * kjur's cryptographic algorithm provider library name space\r\n * <p>\r\n * This namespace privides following crytpgrahic classes.\r\n * <ul>\r\n * <li>{@link KJUR.crypto.MessageDigest} - Java JCE(cryptograhic extension) style MessageDigest class</li>\r\n * <li>{@link KJUR.crypto.Signature} - Java JCE(cryptograhic extension) style Signature class</li>\r\n * <li>{@link KJUR.crypto.Util} - cryptographic utility functions and properties</li>\r\n * </ul>\r\n * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.\r\n * </p>\r\n * @name KJUR.crypto\r\n * @namespace\r\n */\r\nif (typeof KJUR.crypto == \"undefined\" || !KJUR.crypto) KJUR.crypto = {};\r\n\r\n/**\r\n * static object for cryptographic function utilities\r\n * @name KJUR.crypto.Util\r\n * @class static object for cryptographic function utilities\r\n * @property {Array} DIGESTINFOHEAD PKCS#1 DigestInfo heading hexadecimal bytes for each hash algorithms\r\n * @property {Array} DEFAULTPROVIDER associative array of default provider name for each hash and signature algorithms\r\n * @description\r\n */\r\nKJUR.crypto.Util = new function() {\r\n    this.DIGESTINFOHEAD = {\r\n\t'sha1':      \"3021300906052b0e03021a05000414\",\r\n    'sha224':    \"302d300d06096086480165030402040500041c\",\r\n\t'sha256':    \"3031300d060960864801650304020105000420\",\r\n\t'sha384':    \"3041300d060960864801650304020205000430\",\r\n\t'sha512':    \"3051300d060960864801650304020305000440\",\r\n\t'md2':       \"3020300c06082a864886f70d020205000410\",\r\n\t'md5':       \"3020300c06082a864886f70d020505000410\",\r\n\t'ripemd160': \"3021300906052b2403020105000414\",\r\n    };\r\n\r\n    /*\r\n     * @since crypto 1.1.1\r\n     */\r\n    this.DEFAULTPROVIDER = {\r\n\t'md5':\t\t\t'cryptojs',\r\n\t'sha1':\t\t\t'cryptojs',\r\n\t'sha224':\t\t'cryptojs',\r\n\t'sha256':\t\t'cryptojs',\r\n\t'sha384':\t\t'cryptojs',\r\n\t'sha512':\t\t'cryptojs',\r\n\t'ripemd160':\t\t'cryptojs',\r\n\t'hmacmd5':\t\t'cryptojs',\r\n\t'hmacsha1':\t\t'cryptojs',\r\n\t'hmacsha224':\t\t'cryptojs',\r\n\t'hmacsha256':\t\t'cryptojs',\r\n\t'hmacsha384':\t\t'cryptojs',\r\n\t'hmacsha512':\t\t'cryptojs',\r\n\t'hmacripemd160':\t'cryptojs',\r\n\t'sm3':\t            'cryptojs',\r\n\r\n\t'MD5withRSA':\t\t'cryptojs/jsrsa',\r\n\t'SHA1withRSA':\t\t'cryptojs/jsrsa',\r\n\t'SHA224withRSA':\t'cryptojs/jsrsa',\r\n\t'SHA256withRSA':\t'cryptojs/jsrsa',\r\n\t'SHA384withRSA':\t'cryptojs/jsrsa',\r\n\t'SHA512withRSA':\t'cryptojs/jsrsa',\r\n\t'RIPEMD160withRSA':\t'cryptojs/jsrsa',\r\n\r\n\t'MD5withECDSA':\t\t'cryptojs/jsrsa',\r\n\t'SHA1withECDSA':\t'cryptojs/jsrsa',\r\n\t'SHA224withECDSA':\t'cryptojs/jsrsa',\r\n\t'SHA256withECDSA':\t'cryptojs/jsrsa',\r\n\t'SHA384withECDSA':\t'cryptojs/jsrsa',\r\n\t'SHA512withECDSA':\t'cryptojs/jsrsa',\r\n\t'RIPEMD160withECDSA':\t'cryptojs/jsrsa',\r\n\r\n\t'SHA1withDSA':\t\t'cryptojs/jsrsa',\r\n\t'SHA224withDSA':\t'cryptojs/jsrsa',\r\n\t'SHA256withDSA':\t'cryptojs/jsrsa',\r\n\r\n\t'MD5withRSAandMGF1':\t\t'cryptojs/jsrsa',\r\n\t'SHA1withRSAandMGF1':\t\t'cryptojs/jsrsa',\r\n\t'SHA224withRSAandMGF1':\t\t'cryptojs/jsrsa',\r\n\t'SHA256withRSAandMGF1':\t\t'cryptojs/jsrsa',\r\n\t'SHA384withRSAandMGF1':\t\t'cryptojs/jsrsa',\r\n\t'SHA512withRSAandMGF1':\t\t'cryptojs/jsrsa',\r\n\t'RIPEMD160withRSAandMGF1':\t'cryptojs/jsrsa',\r\n    };\r\n\r\n    /*\r\n     * @since crypto 1.1.2\r\n     */\r\n    this.CRYPTOJSMESSAGEDIGESTNAME = {\r\n\t'md5':\t\t'CryptoJS.algo.MD5',\r\n\t'sha1':\t\t'CryptoJS.algo.SHA1',\r\n\t'sha224':\t'CryptoJS.algo.SHA224',\r\n\t'sha256':\t'CryptoJS.algo.SHA256',\r\n\t'sha384':\t'CryptoJS.algo.SHA384',\r\n\t'sha512':\t'CryptoJS.algo.SHA512',\r\n\t'ripemd160':'CryptoJS.algo.RIPEMD160',\r\n\t'sm3':      'CryptoJS.algo.SM3'\r\n    };\r\n\r\n    /**\r\n     * get hexadecimal DigestInfo\r\n     * @name getDigestInfoHex\r\n     * @memberOf KJUR.crypto.Util\r\n     * @function\r\n     * @param {String} hHash hexadecimal hash value\r\n     * @param {String} alg hash algorithm name (ex. 'sha1')\r\n     * @return {String} hexadecimal string DigestInfo ASN.1 structure\r\n     */\r\n    this.getDigestInfoHex = function(hHash, alg) {\r\n\tif (typeof this.DIGESTINFOHEAD[alg] == \"undefined\")\r\n\t    throw \"alg not supported in Util.DIGESTINFOHEAD: \" + alg;\r\n\treturn this.DIGESTINFOHEAD[alg] + hHash;\r\n    };\r\n\r\n    /**\r\n     * get PKCS#1 padded hexadecimal DigestInfo\r\n     * @name getPaddedDigestInfoHex\r\n     * @memberOf KJUR.crypto.Util\r\n     * @function\r\n     * @param {String} hHash hexadecimal hash value of message to be signed\r\n     * @param {String} alg hash algorithm name (ex. 'sha1')\r\n     * @param {Integer} keySize key bit length (ex. 1024)\r\n     * @return {String} hexadecimal string of PKCS#1 padded DigestInfo\r\n     */\r\n    this.getPaddedDigestInfoHex = function(hHash, alg, keySize) {\r\n\tvar hDigestInfo = this.getDigestInfoHex(hHash, alg);\r\n\tvar pmStrLen = keySize / 4; // minimum PM length\r\n\r\n\tif (hDigestInfo.length + 22 > pmStrLen) // len(0001+ff(*8)+00+hDigestInfo)=22\r\n\t    throw \"key is too short for SigAlg: keylen=\" + keySize + \",\" + alg;\r\n\r\n\tvar hHead = \"0001\";\r\n\tvar hTail = \"00\" + hDigestInfo;\r\n\tvar hMid = \"\";\r\n\tvar fLen = pmStrLen - hHead.length - hTail.length;\r\n\tfor (var i = 0; i < fLen; i += 2) {\r\n\t    hMid += \"ff\";\r\n\t}\r\n\tvar hPaddedMessage = hHead + hMid + hTail;\r\n\treturn hPaddedMessage;\r\n    };\r\n\r\n    /**\r\n     * get hexadecimal hash of string with specified algorithm\r\n     * @name hashString\r\n     * @memberOf KJUR.crypto.Util\r\n     * @function\r\n     * @param {String} s input string to be hashed\r\n     * @param {String} alg hash algorithm name\r\n     * @return {String} hexadecimal string of hash value\r\n     * @since 1.1.1\r\n     */\r\n    this.hashString = function(s, alg) {\r\n        var md = new KJUR.crypto.MessageDigest({'alg': alg});\r\n        return md.digestString(s);\r\n    };\r\n\r\n    /**\r\n     * get hexadecimal hash of hexadecimal string with specified algorithm\r\n     * @name hashHex\r\n     * @memberOf KJUR.crypto.Util\r\n     * @function\r\n     * @param {String} sHex input hexadecimal string to be hashed\r\n     * @param {String} alg hash algorithm name\r\n     * @return {String} hexadecimal string of hash value\r\n     * @since 1.1.1\r\n     */\r\n    this.hashHex = function(sHex, alg) {\r\n        var md = new KJUR.crypto.MessageDigest({'alg': alg});\r\n        return md.digestHex(sHex);\r\n    };\r\n\r\n    /**\r\n     * get hexadecimal SHA1 hash of string\r\n     * @name sha1\r\n     * @memberOf KJUR.crypto.Util\r\n     * @function\r\n     * @param {String} s input string to be hashed\r\n     * @return {String} hexadecimal string of hash value\r\n     * @since 1.0.3\r\n     */\r\n    this.sha1 = function(s) {\r\n        var md = new KJUR.crypto.MessageDigest({'alg':'sha1', 'prov':'cryptojs'});\r\n        return md.digestString(s);\r\n    };\r\n\r\n    /**\r\n     * get hexadecimal SHA256 hash of string\r\n     * @name sha256\r\n     * @memberOf KJUR.crypto.Util\r\n     * @function\r\n     * @param {String} s input string to be hashed\r\n     * @return {String} hexadecimal string of hash value\r\n     * @since 1.0.3\r\n     */\r\n    this.sha256 = function(s) {\r\n        var md = new KJUR.crypto.MessageDigest({'alg':'sha256', 'prov':'cryptojs'});\r\n        return md.digestString(s);\r\n    };\r\n\r\n    this.sha256Hex = function(s) {\r\n        var md = new KJUR.crypto.MessageDigest({'alg':'sha256', 'prov':'cryptojs'});\r\n        return md.digestHex(s);\r\n    };\r\n\r\n    /**\r\n     * get hexadecimal SHA512 hash of string\r\n     * @name sha512\r\n     * @memberOf KJUR.crypto.Util\r\n     * @function\r\n     * @param {String} s input string to be hashed\r\n     * @return {String} hexadecimal string of hash value\r\n     * @since 1.0.3\r\n     */\r\n    this.sha512 = function(s) {\r\n        var md = new KJUR.crypto.MessageDigest({'alg':'sha512', 'prov':'cryptojs'});\r\n        return md.digestString(s);\r\n    };\r\n\r\n    this.sha512Hex = function(s) {\r\n        var md = new KJUR.crypto.MessageDigest({'alg':'sha512', 'prov':'cryptojs'});\r\n        return md.digestHex(s);\r\n    };\r\n\r\n    /**\r\n     * get hexadecimal MD5 hash of string\r\n     * @name md5\r\n     * @memberOf KJUR.crypto.Util\r\n     * @function\r\n     * @param {String} s input string to be hashed\r\n     * @return {String} hexadecimal string of hash value\r\n     * @since 1.0.3\r\n     */\r\n    this.md5 = function(s) {\r\n        var md = new KJUR.crypto.MessageDigest({'alg':'md5', 'prov':'cryptojs'});\r\n        return md.digestString(s);\r\n    };\r\n\r\n    /**\r\n     * get hexadecimal RIPEMD160 hash of string\r\n     * @name ripemd160\r\n     * @memberOf KJUR.crypto.Util\r\n     * @function\r\n     * @param {String} s input string to be hashed\r\n     * @return {String} hexadecimal string of hash value\r\n     * @since 1.0.3\r\n     */\r\n    this.ripemd160 = function(s) {\r\n        var md = new KJUR.crypto.MessageDigest({'alg':'ripemd160', 'prov':'cryptojs'});\r\n        return md.digestString(s);\r\n    };\r\n\r\n    /*\r\n     * @since 1.1.2\r\n     */\r\n    this.getCryptoJSMDByName = function(s) {\r\n\t\r\n    };\r\n};\r\n\r\n/**\r\n * MessageDigest class which is very similar to java.security.MessageDigest class\r\n * @name KJUR.crypto.MessageDigest\r\n * @class MessageDigest class which is very similar to java.security.MessageDigest class\r\n * @param {Array} params parameters for constructor\r\n * @description\r\n * <br/>\r\n * Currently this supports following algorithm and providers combination:\r\n * <ul>\r\n * <li>md5 - cryptojs</li>\r\n * <li>sha1 - cryptojs</li>\r\n * <li>sha224 - cryptojs</li>\r\n * <li>sha256 - cryptojs</li>\r\n * <li>sha384 - cryptojs</li>\r\n * <li>sha512 - cryptojs</li>\r\n * <li>ripemd160 - cryptojs</li>\r\n * <li>sha256 - sjcl (NEW from crypto.js 1.0.4)</li>\r\n * </ul>\r\n * @example\r\n * // CryptoJS provider sample\r\n * &lt;script src=\"http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/core.js\"&gt;&lt;/script&gt;\r\n * &lt;script src=\"http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/sha1.js\"&gt;&lt;/script&gt;\r\n * &lt;script src=\"crypto-1.0.js\"&gt;&lt;/script&gt;\r\n * var md = new KJUR.crypto.MessageDigest({alg: \"sha1\", prov: \"cryptojs\"});\r\n * md.updateString('aaa')\r\n * var mdHex = md.digest()\r\n *\r\n * // SJCL(Stanford JavaScript Crypto Library) provider sample\r\n * &lt;script src=\"http://bitwiseshiftleft.github.io/sjcl/sjcl.js\"&gt;&lt;/script&gt;\r\n * &lt;script src=\"crypto-1.0.js\"&gt;&lt;/script&gt;\r\n * var md = new KJUR.crypto.MessageDigest({alg: \"sha256\", prov: \"sjcl\"}); // sjcl supports sha256 only\r\n * md.updateString('aaa')\r\n * var mdHex = md.digest()\r\n */\r\nKJUR.crypto.MessageDigest = function(params) {\r\n    var md = null;\r\n    var algName = null;\r\n    var provName = null;\r\n\r\n    /**\r\n     * set hash algorithm and provider\r\n     * @name setAlgAndProvider\r\n     * @memberOf KJUR.crypto.MessageDigest\r\n     * @function\r\n     * @param {String} alg hash algorithm name\r\n     * @param {String} prov provider name\r\n     * @description\r\n     * @example\r\n     * // for SHA1\r\n     * md.setAlgAndProvider('sha1', 'cryptojs');\r\n     * // for RIPEMD160\r\n     * md.setAlgAndProvider('ripemd160', 'cryptojs');\r\n     */\r\n    this.setAlgAndProvider = function(alg, prov) {\r\n\tif (alg != null && prov === undefined) prov = KJUR.crypto.Util.DEFAULTPROVIDER[alg];\r\n\r\n\t// for cryptojs\r\n\tif (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:sm3:'.indexOf(alg) != -1 &&\r\n\t    prov == 'cryptojs') {\r\n\t    try {\r\n\t\tthis.md = eval(KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[alg]).create();\r\n\t    } catch (ex) {\r\n\t\tthrow \"setAlgAndProvider hash alg set fail alg=\" + alg + \"/\" + ex;\r\n\t    }\r\n\t    this.updateString = function(str) {\r\n\t\tthis.md.update(str);\r\n\t    };\r\n\t    this.updateHex = function(hex) {\r\n\t\tvar wHex = CryptoJS.enc.Hex.parse(hex);\r\n\t\tthis.md.update(wHex);\r\n\t    };\r\n\t    this.digest = function() {\r\n\t\tvar hash = this.md.finalize();\r\n\t\treturn hash.toString(CryptoJS.enc.Hex);\r\n\t    };\r\n\t    this.digestString = function(str) {\r\n\t\tthis.updateString(str);\r\n\t\treturn this.digest();\r\n\t    };\r\n\t    this.digestHex = function(hex) {\r\n\t\tthis.updateHex(hex);\r\n\t\treturn this.digest();\r\n\t    };\r\n\t}\r\n\tif (':sha256:'.indexOf(alg) != -1 &&\r\n\t    prov == 'sjcl') {\r\n\t    try {\r\n\t\tthis.md = new sjcl.hash.sha256();\r\n\t    } catch (ex) {\r\n\t\tthrow \"setAlgAndProvider hash alg set fail alg=\" + alg + \"/\" + ex;\r\n\t    }\r\n\t    this.updateString = function(str) {\r\n\t\tthis.md.update(str);\r\n\t    };\r\n\t    this.updateHex = function(hex) {\r\n\t\tvar baHex = sjcl.codec.hex.toBits(hex);\r\n\t\tthis.md.update(baHex);\r\n\t    };\r\n\t    this.digest = function() {\r\n\t\tvar hash = this.md.finalize();\r\n\t\treturn sjcl.codec.hex.fromBits(hash);\r\n\t    };\r\n\t    this.digestString = function(str) {\r\n\t\tthis.updateString(str);\r\n\t\treturn this.digest();\r\n\t    };\r\n\t    this.digestHex = function(hex) {\r\n\t\tthis.updateHex(hex);\r\n\t\treturn this.digest();\r\n\t    };\r\n\t}\r\n    };\r\n\r\n    /**\r\n     * update digest by specified string\r\n     * @name updateString\r\n     * @memberOf KJUR.crypto.MessageDigest\r\n     * @function\r\n     * @param {String} str string to update\r\n     * @description\r\n     * @example\r\n     * md.updateString('New York');\r\n     */\r\n    this.updateString = function(str) {\r\n\tthrow \"updateString(str) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\r\n    };\r\n\r\n    /**\r\n     * update digest by specified hexadecimal string\r\n     * @name updateHex\r\n     * @memberOf KJUR.crypto.MessageDigest\r\n     * @function\r\n     * @param {String} hex hexadecimal string to update\r\n     * @description\r\n     * @example\r\n     * md.updateHex('0afe36');\r\n     */\r\n    this.updateHex = function(hex) {\r\n\tthrow \"updateHex(hex) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\r\n    };\r\n\r\n    /**\r\n     * completes hash calculation and returns hash result\r\n     * @name digest\r\n     * @memberOf KJUR.crypto.MessageDigest\r\n     * @function\r\n     * @description\r\n     * @example\r\n     * md.digest()\r\n     */\r\n    this.digest = function() {\r\n\tthrow \"digest() not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\r\n    };\r\n\r\n    /**\r\n     * performs final update on the digest using string, then completes the digest computation\r\n     * @name digestString\r\n     * @memberOf KJUR.crypto.MessageDigest\r\n     * @function\r\n     * @param {String} str string to final update\r\n     * @description\r\n     * @example\r\n     * md.digestString('aaa')\r\n     */\r\n    this.digestString = function(str) {\r\n\tthrow \"digestString(str) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\r\n    };\r\n\r\n    /**\r\n     * performs final update on the digest using hexadecimal string, then completes the digest computation\r\n     * @name digestHex\r\n     * @memberOf KJUR.crypto.MessageDigest\r\n     * @function\r\n     * @param {String} hex hexadecimal string to final update\r\n     * @description\r\n     * @example\r\n     * md.digestHex('0f2abd')\r\n     */\r\n    this.digestHex = function(hex) {\r\n\tthrow \"digestHex(hex) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\r\n    };\r\n\r\n    if (params !== undefined) {\r\n\tif (params['alg'] !== undefined) {\r\n\t    this.algName = params['alg'];\r\n\t    if (params['prov'] === undefined)\r\n\t\tthis.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];\r\n\t    this.setAlgAndProvider(this.algName, this.provName);\r\n\t}\r\n    }\r\n};\r\n\r\n/**\r\n * Mac(Message Authentication Code) class which is very similar to java.security.Mac class \r\n * @name KJUR.crypto.Mac\r\n * @class Mac class which is very similar to java.security.Mac class\r\n * @param {Array} params parameters for constructor\r\n * @description\r\n * <br/>\r\n * Currently this supports following algorithm and providers combination:\r\n * <ul>\r\n * <li>hmacmd5 - cryptojs</li>\r\n * <li>hmacsha1 - cryptojs</li>\r\n * <li>hmacsha224 - cryptojs</li>\r\n * <li>hmacsha256 - cryptojs</li>\r\n * <li>hmacsha384 - cryptojs</li>\r\n * <li>hmacsha512 - cryptojs</li>\r\n * </ul>\r\n * NOTE: HmacSHA224 and HmacSHA384 issue was fixed since jsrsasign 4.1.4.\r\n * Please use 'ext/cryptojs-312-core-fix*.js' instead of 'core.js' of original CryptoJS\r\n * to avoid those issue.\r\n * @example\r\n * var mac = new KJUR.crypto.Mac({alg: \"HmacSHA1\", prov: \"cryptojs\", \"pass\": \"pass\"});\r\n * mac.updateString('aaa')\r\n * var macHex = md.doFinal()\r\n */\r\nKJUR.crypto.Mac = function(params) {\r\n    var mac = null;\r\n    var pass = null;\r\n    var algName = null;\r\n    var provName = null;\r\n    var algProv = null;\r\n\r\n    this.setAlgAndProvider = function(alg, prov) {\r\n\tif (alg == null) alg = \"hmacsha1\";\r\n\r\n\talg = alg.toLowerCase();\r\n        if (alg.substr(0, 4) != \"hmac\") {\r\n\t    throw \"setAlgAndProvider unsupported HMAC alg: \" + alg;\r\n\t}\r\n\r\n\tif (prov === undefined) prov = KJUR.crypto.Util.DEFAULTPROVIDER[alg];\r\n\tthis.algProv = alg + \"/\" + prov;\r\n\r\n\tvar hashAlg = alg.substr(4);\r\n\r\n\t// for cryptojs\r\n\tif (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:'.indexOf(hashAlg) != -1 &&\r\n\t    prov == 'cryptojs') {\r\n\t    try {\r\n\t\tvar mdObj = eval(KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[hashAlg]);\r\n\t\tthis.mac = CryptoJS.algo.HMAC.create(mdObj, this.pass);\r\n\t    } catch (ex) {\r\n\t\tthrow \"setAlgAndProvider hash alg set fail hashAlg=\" + hashAlg + \"/\" + ex;\r\n\t    }\r\n\t    this.updateString = function(str) {\r\n\t\tthis.mac.update(str);\r\n\t    };\r\n\t    this.updateHex = function(hex) {\r\n\t\tvar wHex = CryptoJS.enc.Hex.parse(hex);\r\n\t\tthis.mac.update(wHex);\r\n\t    };\r\n\t    this.doFinal = function() {\r\n\t\tvar hash = this.mac.finalize();\r\n\t\treturn hash.toString(CryptoJS.enc.Hex);\r\n\t    };\r\n\t    this.doFinalString = function(str) {\r\n\t\tthis.updateString(str);\r\n\t\treturn this.doFinal();\r\n\t    };\r\n\t    this.doFinalHex = function(hex) {\r\n\t\tthis.updateHex(hex);\r\n\t\treturn this.doFinal();\r\n\t    };\r\n\t}\r\n    };\r\n\r\n    /**\r\n     * update digest by specified string\r\n     * @name updateString\r\n     * @memberOf KJUR.crypto.Mac\r\n     * @function\r\n     * @param {String} str string to update\r\n     * @description\r\n     * @example\r\n     * md.updateString('New York');\r\n     */\r\n    this.updateString = function(str) {\r\n\tthrow \"updateString(str) not supported for this alg/prov: \" + this.algProv;\r\n    };\r\n\r\n    /**\r\n     * update digest by specified hexadecimal string\r\n     * @name updateHex\r\n     * @memberOf KJUR.crypto.Mac\r\n     * @function\r\n     * @param {String} hex hexadecimal string to update\r\n     * @description\r\n     * @example\r\n     * md.updateHex('0afe36');\r\n     */\r\n    this.updateHex = function(hex) {\r\n\tthrow \"updateHex(hex) not supported for this alg/prov: \" + this.algProv;\r\n    };\r\n\r\n    /**\r\n     * completes hash calculation and returns hash result\r\n     * @name doFinal\r\n     * @memberOf KJUR.crypto.Mac\r\n     * @function\r\n     * @description\r\n     * @example\r\n     * md.digest()\r\n     */\r\n    this.doFinal = function() {\r\n\tthrow \"digest() not supported for this alg/prov: \" + this.algProv;\r\n    };\r\n\r\n    /**\r\n     * performs final update on the digest using string, then completes the digest computation\r\n     * @name doFinalString\r\n     * @memberOf KJUR.crypto.Mac\r\n     * @function\r\n     * @param {String} str string to final update\r\n     * @description\r\n     * @example\r\n     * md.digestString('aaa')\r\n     */\r\n    this.doFinalString = function(str) {\r\n\tthrow \"digestString(str) not supported for this alg/prov: \" + this.algProv;\r\n    };\r\n\r\n    /**\r\n     * performs final update on the digest using hexadecimal string, \r\n     * then completes the digest computation\r\n     * @name doFinalHex\r\n     * @memberOf KJUR.crypto.Mac\r\n     * @function\r\n     * @param {String} hex hexadecimal string to final update\r\n     * @description\r\n     * @example\r\n     * md.digestHex('0f2abd')\r\n     */\r\n    this.doFinalHex = function(hex) {\r\n\tthrow \"digestHex(hex) not supported for this alg/prov: \" + this.algProv;\r\n    };\r\n\r\n    if (params !== undefined) {\r\n\tif (params['pass'] !== undefined) {\r\n\t    this.pass = params['pass'];\r\n\t}\r\n\tif (params['alg'] !== undefined) {\r\n\t    this.algName = params['alg'];\r\n\t    if (params['prov'] === undefined)\r\n\t\tthis.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];\r\n\t    this.setAlgAndProvider(this.algName, this.provName);\r\n\t}\r\n    }\r\n};\r\n\r\n/**\r\n * Signature class which is very similar to java.security.Signature class\r\n * @name KJUR.crypto.Signature\r\n * @class Signature class which is very similar to java.security.Signature class\r\n * @param {Array} params parameters for constructor\r\n * @property {String} state Current state of this signature object whether 'SIGN', 'VERIFY' or null\r\n * @description\r\n * <br/>\r\n * As for params of constructor's argument, it can be specify following attributes:\r\n * <ul>\r\n * <li>alg - signature algorithm name (ex. {MD5,SHA1,SHA224,SHA256,SHA384,SHA512,RIPEMD160}with{RSA,ECDSA,DSA})</li>\r\n * <li>provider - currently 'cryptojs/jsrsa' only</li>\r\n * </ul>\r\n * <h4>SUPPORTED ALGORITHMS AND PROVIDERS</h4>\r\n * This Signature class supports following signature algorithm and provider names:\r\n * <ul>\r\n * <li>MD5withRSA - cryptojs/jsrsa</li>\r\n * <li>SHA1withRSA - cryptojs/jsrsa</li>\r\n * <li>SHA224withRSA - cryptojs/jsrsa</li>\r\n * <li>SHA256withRSA - cryptojs/jsrsa</li>\r\n * <li>SHA384withRSA - cryptojs/jsrsa</li>\r\n * <li>SHA512withRSA - cryptojs/jsrsa</li>\r\n * <li>RIPEMD160withRSA - cryptojs/jsrsa</li>\r\n * <li>MD5withECDSA - cryptojs/jsrsa</li>\r\n * <li>SHA1withECDSA - cryptojs/jsrsa</li>\r\n * <li>SHA224withECDSA - cryptojs/jsrsa</li>\r\n * <li>SHA256withECDSA - cryptojs/jsrsa</li>\r\n * <li>SHA384withECDSA - cryptojs/jsrsa</li>\r\n * <li>SHA512withECDSA - cryptojs/jsrsa</li>\r\n * <li>RIPEMD160withECDSA - cryptojs/jsrsa</li>\r\n * <li>MD5withRSAandMGF1 - cryptojs/jsrsa</li>\r\n * <li>SHA1withRSAandMGF1 - cryptojs/jsrsa</li>\r\n * <li>SHA224withRSAandMGF1 - cryptojs/jsrsa</li>\r\n * <li>SHA256withRSAandMGF1 - cryptojs/jsrsa</li>\r\n * <li>SHA384withRSAandMGF1 - cryptojs/jsrsa</li>\r\n * <li>SHA512withRSAandMGF1 - cryptojs/jsrsa</li>\r\n * <li>RIPEMD160withRSAandMGF1 - cryptojs/jsrsa</li>\r\n * <li>SHA1withDSA - cryptojs/jsrsa</li>\r\n * <li>SHA224withDSA - cryptojs/jsrsa</li>\r\n * <li>SHA256withDSA - cryptojs/jsrsa</li>\r\n * </ul>\r\n * Here are supported elliptic cryptographic curve names and their aliases for ECDSA:\r\n * <ul>\r\n * <li>secp256k1</li>\r\n * <li>secp256r1, NIST P-256, P-256, prime256v1</li>\r\n * <li>secp384r1, NIST P-384, P-384</li>\r\n * </ul>\r\n * NOTE1: DSA signing algorithm is also supported since crypto 1.1.5.\r\n * <h4>EXAMPLES</h4>\r\n * @example\r\n * // RSA signature generation\r\n * var sig = new KJUR.crypto.Signature({\"alg\": \"SHA1withRSA\"});\r\n * sig.init(prvKeyPEM);\r\n * sig.updateString('aaa');\r\n * var hSigVal = sig.sign();\r\n *\r\n * // DSA signature validation\r\n * var sig2 = new KJUR.crypto.Signature({\"alg\": \"SHA1withDSA\"});\r\n * sig2.init(certPEM);\r\n * sig.updateString('aaa');\r\n * var isValid = sig2.verify(hSigVal);\r\n * \r\n * // ECDSA signing\r\n * var sig = new KJUR.crypto.Signature({'alg':'SHA1withECDSA'});\r\n * sig.init(prvKeyPEM);\r\n * sig.updateString('aaa');\r\n * var sigValueHex = sig.sign();\r\n *\r\n * // ECDSA verifying\r\n * var sig2 = new KJUR.crypto.Signature({'alg':'SHA1withECDSA'});\r\n * sig.init(certPEM);\r\n * sig.updateString('aaa');\r\n * var isValid = sig.verify(sigValueHex);\r\n */\r\nKJUR.crypto.Signature = function(params) {\r\n    var prvKey = null; // RSAKey/KJUR.crypto.{ECDSA,DSA} object for signing\r\n    var pubKey = null; // RSAKey/KJUR.crypto.{ECDSA,DSA} object for verifying\r\n\r\n    var md = null; // KJUR.crypto.MessageDigest object\r\n    var sig = null;\r\n    var algName = null;\r\n    var provName = null;\r\n    var algProvName = null;\r\n    var mdAlgName = null;\r\n    var pubkeyAlgName = null;\t// rsa,ecdsa,rsaandmgf1(=rsapss)\r\n    var state = null;\r\n    var pssSaltLen = -1;\r\n    var initParams = null;\r\n\r\n    var sHashHex = null; // hex hash value for hex\r\n    var hDigestInfo = null;\r\n    var hPaddedDigestInfo = null;\r\n    var hSign = null;\r\n\r\n    this._setAlgNames = function() {\r\n\tif (this.algName.match(/^(.+)with(.+)$/)) {\r\n\t    this.mdAlgName = RegExp.$1.toLowerCase();\r\n\t    this.pubkeyAlgName = RegExp.$2.toLowerCase();\r\n\t}\r\n    };\r\n\r\n    this._zeroPaddingOfSignature = function(hex, bitLength) {\r\n\tvar s = \"\";\r\n\tvar nZero = bitLength / 4 - hex.length;\r\n\tfor (var i = 0; i < nZero; i++) {\r\n\t    s = s + \"0\";\r\n\t}\r\n\treturn s + hex;\r\n    };\r\n\r\n    /**\r\n     * set signature algorithm and provider\r\n     * @name setAlgAndProvider\r\n     * @memberOf KJUR.crypto.Signature\r\n     * @function\r\n     * @param {String} alg signature algorithm name\r\n     * @param {String} prov provider name\r\n     * @description\r\n     * @example\r\n     * md.setAlgAndProvider('SHA1withRSA', 'cryptojs/jsrsa');\r\n     */\r\n    this.setAlgAndProvider = function(alg, prov) {\r\n\tthis._setAlgNames();\r\n\tif (prov != 'cryptojs/jsrsa')\r\n\t    throw \"provider not supported: \" + prov;\r\n\r\n\tif (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:sm3:'.indexOf(this.mdAlgName) != -1) {\r\n\t    try {\r\n\t\tthis.md = new KJUR.crypto.MessageDigest({'alg':this.mdAlgName});\r\n\t    } catch (ex) {\r\n\t\tthrow \"setAlgAndProvider hash alg set fail alg=\" +\r\n                      this.mdAlgName + \"/\" + ex;\r\n\t    }\r\n\r\n\t    this.init = function(keyparam, pass) {\r\n\t\tvar keyObj = null;\r\n\t\ttry {\r\n\t\t    if (pass === undefined) {\r\n\t\t\tkeyObj = KEYUTIL.getKey(keyparam);\r\n\t\t    } else {\r\n\t\t\tkeyObj = KEYUTIL.getKey(keyparam, pass);\r\n\t\t    }\r\n\t\t} catch (ex) {\r\n\t\t    throw \"init failed:\" + ex;\r\n\t\t}\r\n\r\n\t\tif (keyObj.isPrivate === true) {\r\n\t\t    this.prvKey = keyObj;\r\n\t\t    this.state = \"SIGN\";\r\n\t\t} else if (keyObj.isPublic === true) {\r\n\t\t    this.pubKey = keyObj;\r\n\t\t    this.state = \"VERIFY\";\r\n\t\t} else {\r\n\t\t    throw \"init failed.:\" + keyObj;\r\n\t\t}\r\n\t    };\r\n\r\n\t    this.initSign = function(params) {\r\n\t\tif (typeof params['ecprvhex'] == 'string' &&\r\n                    typeof params['eccurvename'] == 'string') {\r\n\t\t    this.ecprvhex = params['ecprvhex'];\r\n\t\t    this.eccurvename = params['eccurvename'];\r\n\t\t} else {\r\n\t\t    this.prvKey = params;\r\n\t\t}\r\n\t\tthis.state = \"SIGN\";\r\n\t    };\r\n\r\n\t    this.initVerifyByPublicKey = function(params) {\r\n\t\tif (typeof params['ecpubhex'] == 'string' &&\r\n\t\t    typeof params['eccurvename'] == 'string') {\r\n\t\t    this.ecpubhex = params['ecpubhex'];\r\n\t\t    this.eccurvename = params['eccurvename'];\r\n\t\t} else if (params instanceof KJUR.crypto.ECDSA) {\r\n\t\t    this.pubKey = params;\r\n\t\t} else if (params instanceof RSAKey) {\r\n\t\t    this.pubKey = params;\r\n\t\t}\r\n\t\tthis.state = \"VERIFY\";\r\n\t    };\r\n\r\n\t    this.initVerifyByCertificatePEM = function(certPEM) {\r\n\t\tvar x509 = new X509();\r\n\t\tx509.readCertPEM(certPEM);\r\n\t\tthis.pubKey = x509.subjectPublicKeyRSA;\r\n\t\tthis.state = \"VERIFY\";\r\n\t    };\r\n\r\n\t    this.updateString = function(str) {\r\n\t\tthis.md.updateString(str);\r\n\t    };\r\n\t    this.updateHex = function(hex) {\r\n\t\tthis.md.updateHex(hex);\r\n\t    };\r\n\r\n\t    this.sign = function() {\r\n\t    \r\n\t    if(this.eccurvename != \"sm2\") {\r\n\t\t    this.sHashHex = this.md.digest();\r\n\t\t}\r\n\t\t\r\n\t\tif (typeof this.ecprvhex != \"undefined\" &&\r\n\t\t    typeof this.eccurvename != \"undefined\") {\r\n\t\t\tif(this.eccurvename == \"sm2\")\r\n\t\t\t{\r\n\t\t\t\tvar ec = new KJUR.crypto.SM3withSM2({curve: this.eccurvename});\r\n\t\t\t\t\r\n\t\t\t\tvar G = ec.ecparams['G'];\r\n\t\t\t\tvar Q = G.multiply(new BigInteger(this.ecprvhex, 16));\r\n\t\t\t\t\r\n\t\t\t\tvar pubKeyHex = Q.getX().toBigInteger().toRadix(16) + Q.getY().toBigInteger().toRadix(16);\r\n\t\t\t\t\r\n\t\t\t\tvar smDigest = new SM3Digest();\r\n\t\t\t\t\r\n\t\t\t\tvar z = new SM3Digest().GetZ(G, pubKeyHex);\r\n\t\t\t\tvar zValue = smDigest.GetWords(smDigest.GetHex(z).toString());\r\n\t\t\t\t\r\n\t\t\t\tvar rawData = CryptoJS.enc.Utf8.stringify(this.md.md._data);\r\n\t\t\t\trawData = CryptoJS.enc.Utf8.parse(rawData).toString();\r\n\t\t\t\trawData = smDigest.GetWords(rawData);\r\n\t\t\t\t\t\t\t\t\r\n                var smHash = new Array(smDigest.GetDigestSize());\r\n                smDigest.BlockUpdate(zValue, 0, zValue.length);\r\n                smDigest.BlockUpdate(rawData, 0, rawData.length);\r\n                smDigest.DoFinal(smHash, 0);\r\n\r\n                var hashHex = smDigest.GetHex(smHash).toString();\r\n\t\t\t\t\r\n\t\t\t\tthis.sHashHex = hashHex;\r\n\t\t\t\t\r\n\t\t    \tthis.hSign = ec.signHex(this.sHashHex, this.ecprvhex);\r\n\t\t\t}else {\r\n\t\t    \tvar ec = new KJUR.crypto.ECDSA({'curve': this.eccurvename});\r\n\t\t    \tthis.hSign = ec.signHex(this.sHashHex, this.ecprvhex);\r\n\t\t\t}\r\n\t\t} else if (this.pubkeyAlgName == \"rsaandmgf1\") {\r\n\t\t    this.hSign = this.prvKey.signWithMessageHashPSS(this.sHashHex,\r\n\t\t\t\t\t\t\t\t    this.mdAlgName,\r\n\t\t\t\t\t\t\t\t    this.pssSaltLen);\r\n\t\t} else if (this.pubkeyAlgName == \"rsa\") {\r\n\t\t    this.hSign = this.prvKey.signWithMessageHash(this.sHashHex,\r\n\t\t\t\t\t\t\t\t this.mdAlgName);\r\n\t\t} else if (this.prvKey instanceof KJUR.crypto.ECDSA) {\r\n\t\t    this.hSign = this.prvKey.signWithMessageHash(this.sHashHex);\r\n\t\t} else if (this.prvKey instanceof KJUR.crypto.DSA) {\r\n\t\t    this.hSign = this.prvKey.signWithMessageHash(this.sHashHex);\r\n\t\t} else {\r\n\t\t    throw \"Signature: unsupported public key alg: \" + this.pubkeyAlgName;\r\n\t\t}\r\n\t\treturn this.hSign;\r\n\t    };\r\n\t    this.signString = function(str) {\r\n\t\tthis.updateString(str);\r\n\t\tthis.sign();\r\n\t    };\r\n\t    this.signHex = function(hex) {\r\n\t\tthis.updateHex(hex);\r\n\t\tthis.sign();\r\n\t    };\r\n\t    this.verify = function(hSigVal) {\r\n\t    \r\n\t    if(this.eccurvename != \"sm2\") {\r\n\t        this.sHashHex = this.md.digest();\r\n\t    }\r\n\t    \r\n\t\tif (typeof this.ecpubhex != \"undefined\" &&\r\n\t\t    typeof this.eccurvename != \"undefined\") {\r\n\t\t\tif(this.eccurvename == \"sm2\")\r\n\t\t\t{\r\n\t\t\t\tvar ec = new KJUR.crypto.SM3withSM2({curve: this.eccurvename});\r\n\t\t\t\t\r\n\t\t\t\tvar G = ec.ecparams['G'];\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\tvar pubKeyHex = this.ecpubhex.substr(2, 128);\r\n\t\t\t\t\r\n\t\t\t\tvar smDigest = new SM3Digest();\r\n\t\t\t\t\r\n\t\t\t\tvar z = new SM3Digest().GetZ(G, pubKeyHex);\r\n\t\t\t\tvar zValue = smDigest.GetWords(smDigest.GetHex(z).toString());\r\n\t\t\t\t\r\n\t\t\t\tvar rawData = CryptoJS.enc.Utf8.stringify(this.md.md._data);\r\n\t\t\t\trawData = CryptoJS.enc.Utf8.parse(rawData).toString();\r\n\t\t\t\trawData = smDigest.GetWords(rawData);\r\n\t\t\t\t\r\n                var smHash = new Array(smDigest.GetDigestSize());\r\n                smDigest.BlockUpdate(zValue, 0, zValue.length);\r\n                smDigest.BlockUpdate(rawData, 0, rawData.length);\r\n                smDigest.DoFinal(smHash, 0);\r\n\r\n                var hashHex = smDigest.GetHex(smHash).toString();\r\n\t\t\t\t\r\n\t\t\t\tthis.sHashHex = hashHex;\r\n\t\t\t\t\r\n\t\t\t\t\r\n\t\t    \treturn ec.verifyHex(this.sHashHex, hSigVal, this.ecpubhex);\r\n\t\t\t}else {\r\n\t\t    \tvar ec = new KJUR.crypto.ECDSA({curve: this.eccurvename});\r\n\t\t    \treturn ec.verifyHex(this.sHashHex, hSigVal, this.ecpubhex);\r\n\t\t\t}\r\n\t\t} else if (this.pubkeyAlgName == \"rsaandmgf1\") {\r\n\t\t    return this.pubKey.verifyWithMessageHashPSS(this.sHashHex, hSigVal, \r\n\t\t\t\t\t\t\t\tthis.mdAlgName,\r\n\t\t\t\t\t\t\t\tthis.pssSaltLen);\r\n\t\t} else if (this.pubkeyAlgName == \"rsa\") {\r\n\t\t    return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal);\r\n\t\t} else if (this.pubKey instanceof KJUR.crypto.ECDSA) {\r\n\t\t    return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal);\r\n\t\t} else if (this.pubKey instanceof KJUR.crypto.DSA) {\r\n\t\t    return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal);\r\n\t\t} else {\r\n\t\t    throw \"Signature: unsupported public key alg: \" + this.pubkeyAlgName;\r\n\t\t}\r\n\t    };\r\n\t}\r\n    };\r\n\r\n    /**\r\n     * Initialize this object for signing or verifying depends on key\r\n     * @name init\r\n     * @memberOf KJUR.crypto.Signature\r\n     * @function\r\n     * @param {Object} key specifying public or private key as plain/encrypted PKCS#5/8 PEM file, certificate PEM or {@link RSAKey}, {@link KJUR.crypto.DSA} or {@link KJUR.crypto.ECDSA} object\r\n     * @param {String} pass (OPTION) passcode for encrypted private key\r\n     * @since crypto 1.1.3\r\n     * @description\r\n     * This method is very useful initialize method for Signature class since\r\n     * you just specify key then this method will automatically initialize it\r\n     * using {@link KEYUTIL.getKey} method.\r\n     * As for 'key',  following argument type are supported:\r\n     * <h5>signing</h5>\r\n     * <ul>\r\n     * <li>PEM formatted PKCS#8 encrypted RSA/ECDSA private key concluding \"BEGIN ENCRYPTED PRIVATE KEY\"</li>\r\n     * <li>PEM formatted PKCS#5 encrypted RSA/DSA private key concluding \"BEGIN RSA/DSA PRIVATE KEY\" and \",ENCRYPTED\"</li>\r\n     * <li>PEM formatted PKCS#8 plain RSA/ECDSA private key concluding \"BEGIN PRIVATE KEY\"</li>\r\n     * <li>PEM formatted PKCS#5 plain RSA/DSA private key concluding \"BEGIN RSA/DSA PRIVATE KEY\" without \",ENCRYPTED\"</li>\r\n     * <li>RSAKey object of private key</li>\r\n     * <li>KJUR.crypto.ECDSA object of private key</li>\r\n     * <li>KJUR.crypto.DSA object of private key</li>\r\n     * </ul>\r\n     * <h5>verification</h5>\r\n     * <ul>\r\n     * <li>PEM formatted PKCS#8 RSA/EC/DSA public key concluding \"BEGIN PUBLIC KEY\"</li>\r\n     * <li>PEM formatted X.509 certificate with RSA/EC/DSA public key concluding\r\n     *     \"BEGIN CERTIFICATE\", \"BEGIN X509 CERTIFICATE\" or \"BEGIN TRUSTED CERTIFICATE\".</li>\r\n     * <li>RSAKey object of public key</li>\r\n     * <li>KJUR.crypto.ECDSA object of public key</li>\r\n     * <li>KJUR.crypto.DSA object of public key</li>\r\n     * </ul>\r\n     * @example\r\n     * sig.init(sCertPEM)\r\n     */\r\n    this.init = function(key, pass) {\r\n\tthrow \"init(key, pass) not supported for this alg:prov=\" +\r\n\t      this.algProvName;\r\n    };\r\n\r\n    /**\r\n     * Initialize this object for verifying with a public key\r\n     * @name initVerifyByPublicKey\r\n     * @memberOf KJUR.crypto.Signature\r\n     * @function\r\n     * @param {Object} param RSAKey object of public key or associative array for ECDSA\r\n     * @since 1.0.2\r\n     * @deprecated from crypto 1.1.5. please use init() method instead.\r\n     * @description\r\n     * Public key information will be provided as 'param' parameter and the value will be\r\n     * following:\r\n     * <ul>\r\n     * <li>{@link RSAKey} object for RSA verification</li>\r\n     * <li>associative array for ECDSA verification\r\n     *     (ex. <code>{'ecpubhex': '041f..', 'eccurvename': 'secp256r1'}</code>)\r\n     * </li>\r\n     * </ul>\r\n     * @example\r\n     * sig.initVerifyByPublicKey(rsaPrvKey)\r\n     */\r\n    this.initVerifyByPublicKey = function(rsaPubKey) {\r\n\tthrow \"initVerifyByPublicKey(rsaPubKeyy) not supported for this alg:prov=\" +\r\n\t      this.algProvName;\r\n    };\r\n\r\n    /**\r\n     * Initialize this object for verifying with a certficate\r\n     * @name initVerifyByCertificatePEM\r\n     * @memberOf KJUR.crypto.Signature\r\n     * @function\r\n     * @param {String} certPEM PEM formatted string of certificate\r\n     * @since 1.0.2\r\n     * @deprecated from crypto 1.1.5. please use init() method instead.\r\n     * @description\r\n     * @example\r\n     * sig.initVerifyByCertificatePEM(certPEM)\r\n     */\r\n    this.initVerifyByCertificatePEM = function(certPEM) {\r\n\tthrow \"initVerifyByCertificatePEM(certPEM) not supported for this alg:prov=\" +\r\n\t    this.algProvName;\r\n    };\r\n\r\n    /**\r\n     * Initialize this object for signing\r\n     * @name initSign\r\n     * @memberOf KJUR.crypto.Signature\r\n     * @function\r\n     * @param {Object} param RSAKey object of public key or associative array for ECDSA\r\n     * @deprecated from crypto 1.1.5. please use init() method instead.\r\n     * @description\r\n     * Private key information will be provided as 'param' parameter and the value will be\r\n     * following:\r\n     * <ul>\r\n     * <li>{@link RSAKey} object for RSA signing</li>\r\n     * <li>associative array for ECDSA signing\r\n     *     (ex. <code>{'ecprvhex': '1d3f..', 'eccurvename': 'secp256r1'}</code>)</li>\r\n     * </ul>\r\n     * @example\r\n     * sig.initSign(prvKey)\r\n     */\r\n    this.initSign = function(prvKey) {\r\n\tthrow \"initSign(prvKey) not supported for this alg:prov=\" + this.algProvName;\r\n    };\r\n\r\n    /**\r\n     * Updates the data to be signed or verified by a string\r\n     * @name updateString\r\n     * @memberOf KJUR.crypto.Signature\r\n     * @function\r\n     * @param {String} str string to use for the update\r\n     * @description\r\n     * @example\r\n     * sig.updateString('aaa')\r\n     */\r\n    this.updateString = function(str) {\r\n\tthrow \"updateString(str) not supported for this alg:prov=\" + this.algProvName;\r\n    };\r\n\r\n    /**\r\n     * Updates the data to be signed or verified by a hexadecimal string\r\n     * @name updateHex\r\n     * @memberOf KJUR.crypto.Signature\r\n     * @function\r\n     * @param {String} hex hexadecimal string to use for the update\r\n     * @description\r\n     * @example\r\n     * sig.updateHex('1f2f3f')\r\n     */\r\n    this.updateHex = function(hex) {\r\n\tthrow \"updateHex(hex) not supported for this alg:prov=\" + this.algProvName;\r\n    };\r\n\r\n    /**\r\n     * Returns the signature bytes of all data updates as a hexadecimal string\r\n     * @name sign\r\n     * @memberOf KJUR.crypto.Signature\r\n     * @function\r\n     * @return the signature bytes as a hexadecimal string\r\n     * @description\r\n     * @example\r\n     * var hSigValue = sig.sign()\r\n     */\r\n    this.sign = function() {\r\n\tthrow \"sign() not supported for this alg:prov=\" + this.algProvName;\r\n    };\r\n\r\n    /**\r\n     * performs final update on the sign using string, then returns the signature bytes of all data updates as a hexadecimal string\r\n     * @name signString\r\n     * @memberOf KJUR.crypto.Signature\r\n     * @function\r\n     * @param {String} str string to final update\r\n     * @return the signature bytes of a hexadecimal string\r\n     * @description\r\n     * @example\r\n     * var hSigValue = sig.signString('aaa')\r\n     */\r\n    this.signString = function(str) {\r\n\tthrow \"digestString(str) not supported for this alg:prov=\" + this.algProvName;\r\n    };\r\n\r\n    /**\r\n     * performs final update on the sign using hexadecimal string, then returns the signature bytes of all data updates as a hexadecimal string\r\n     * @name signHex\r\n     * @memberOf KJUR.crypto.Signature\r\n     * @function\r\n     * @param {String} hex hexadecimal string to final update\r\n     * @return the signature bytes of a hexadecimal string\r\n     * @description\r\n     * @example\r\n     * var hSigValue = sig.signHex('1fdc33')\r\n     */\r\n    this.signHex = function(hex) {\r\n\tthrow \"digestHex(hex) not supported for this alg:prov=\" + this.algProvName;\r\n    };\r\n\r\n    /**\r\n     * verifies the passed-in signature.\r\n     * @name verify\r\n     * @memberOf KJUR.crypto.Signature\r\n     * @function\r\n     * @param {String} str string to final update\r\n     * @return {Boolean} true if the signature was verified, otherwise false\r\n     * @description\r\n     * @example\r\n     * var isValid = sig.verify('1fbcefdca4823a7(snip)')\r\n     */\r\n    this.verify = function(hSigVal) {\r\n\tthrow \"verify(hSigVal) not supported for this alg:prov=\" + this.algProvName;\r\n    };\r\n\r\n    this.initParams = params;\r\n\r\n    if (params !== undefined) {\r\n\tif (params['alg'] !== undefined) {\r\n\t    this.algName = params['alg'];\r\n\t    if (params['prov'] === undefined) {\r\n\t\tthis.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];\r\n\t    } else {\r\n\t\tthis.provName = params['prov'];\r\n\t    }\r\n\t    this.algProvName = this.algName + \":\" + this.provName;\r\n\t    this.setAlgAndProvider(this.algName, this.provName);\r\n\t    this._setAlgNames();\r\n\t}\r\n\r\n\tif (params['psssaltlen'] !== undefined) this.pssSaltLen = params['psssaltlen'];\r\n\r\n\tif (params['prvkeypem'] !== undefined) {\r\n\t    if (params['prvkeypas'] !== undefined) {\r\n\t\tthrow \"both prvkeypem and prvkeypas parameters not supported\";\r\n\t    } else {\r\n\t\ttry {\r\n\t\t    var prvKey = new RSAKey();\r\n\t\t    prvKey.readPrivateKeyFromPEMString(params['prvkeypem']);\r\n\t\t    this.initSign(prvKey);\r\n\t\t} catch (ex) {\r\n\t\t    throw \"fatal error to load pem private key: \" + ex;\r\n\t\t}\r\n\t    }\r\n\t}\r\n    }\r\n};\r\n\r\n/**\r\n * static object for cryptographic function utilities\r\n * @name KJUR.crypto.OID\r\n * @class static object for cryptography related OIDs\r\n * @property {Array} oidhex2name key value of hexadecimal OID and its name\r\n *           (ex. '2a8648ce3d030107' and 'secp256r1')\r\n * @since crypto 1.1.3\r\n * @description\r\n */\r\n\r\n\r\nKJUR.crypto.OID = new function() {\r\n    this.oidhex2name = {\r\n\t'2a864886f70d010101': 'rsaEncryption',\r\n\t'2a8648ce3d0201': 'ecPublicKey',\r\n\t'2a8648ce380401': 'dsa',\r\n\t'2a8648ce3d030107': 'secp256r1',\r\n\t'2b8104001f': 'secp192k1',\r\n\t'2b81040021': 'secp224r1',\r\n\t'2b8104000a': 'secp256k1',\r\n\t'2b81040023': 'secp521r1',\r\n\t'2b81040022': 'secp384r1',\r\n\t'2a8648ce380403': 'SHA1withDSA', // 1.2.840.10040.4.3\r\n\t'608648016503040301': 'SHA224withDSA', // 2.16.840.1.101.3.4.3.1\r\n\t'608648016503040302': 'SHA256withDSA', // 2.16.840.1.101.3.4.3.2\r\n    };\r\n};\r\n"
  },
  {
    "path": "JavaScript/demo/js/ec-patch.js",
    "content": "/*! (c) Stefan Thomas | https://github.com/bitcoinjs/bitcoinjs-lib\r\n */\r\n/*\r\n * splitted from bitcoin-lib/ecdsa.js\r\n *\r\n * version 1.0.0 is the original of bitcoin-lib/ecdsa.js\r\n */\r\nECFieldElementFp.prototype.getByteLength = function () {\r\n  return Math.floor((this.toBigInteger().bitLength() + 7) / 8);\r\n};\r\n\r\nECPointFp.prototype.getEncoded = function (compressed) {\r\n  var integerToBytes = function(i, len) {\r\n    var bytes = i.toByteArrayUnsigned();\r\n\r\n    if (len < bytes.length) {\r\n      bytes = bytes.slice(bytes.length-len);\r\n    } else while (len > bytes.length) {\r\n      bytes.unshift(0);\r\n    }\r\n    return bytes;\r\n  };\r\n\r\n  var x = this.getX().toBigInteger();\r\n  var y = this.getY().toBigInteger();\r\n\r\n  // Get value as a 32-byte Buffer\r\n  // Fixed length based on a patch by bitaddress.org and Casascius\r\n  var enc = integerToBytes(x, 32);\r\n\r\n  if (compressed) {\r\n    if (y.isEven()) {\r\n      // Compressed even pubkey\r\n      // M = 02 || X\r\n      enc.unshift(0x02);\r\n    } else {\r\n      // Compressed uneven pubkey\r\n      // M = 03 || X\r\n      enc.unshift(0x03);\r\n    }\r\n  } else {\r\n    // Uncompressed pubkey\r\n    // M = 04 || X || Y\r\n    enc.unshift(0x04);\r\n    enc = enc.concat(integerToBytes(y, 32));\r\n  }\r\n  return enc;\r\n};\r\n\r\nECPointFp.decodeFrom = function (curve, enc) {\r\n  var type = enc[0];\r\n  var dataLen = enc.length-1;\r\n\r\n  // Extract x and y as byte arrays\r\n  var xBa = enc.slice(1, 1 + dataLen/2);\r\n  var yBa = enc.slice(1 + dataLen/2, 1 + dataLen);\r\n\r\n  // Prepend zero byte to prevent interpretation as negative integer\r\n  xBa.unshift(0);\r\n  yBa.unshift(0);\r\n\r\n  // Convert to BigIntegers\r\n  var x = new BigInteger(xBa);\r\n  var y = new BigInteger(yBa);\r\n\r\n  // Return point\r\n  return new ECPointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y));\r\n};\r\n\r\n/*\r\n * @since ec-patch.js 1.0.1\r\n */\r\nECPointFp.decodeFromHex = function (curve, encHex) {\r\n  var type = encHex.substr(0, 2); // shall be \"04\"\r\n  var dataLen = encHex.length - 2;\r\n\r\n  // Extract x and y as byte arrays\r\n  var xHex = encHex.substr(2, dataLen / 2);\r\n  var yHex = encHex.substr(2 + dataLen / 2, dataLen / 2);\r\n\r\n  // Convert to BigIntegers\r\n  var x = new BigInteger(xHex, 16);\r\n  var y = new BigInteger(yHex, 16);\r\n\r\n  // Return point\r\n  return new ECPointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y));\r\n};\r\n\r\nECPointFp.prototype.add2D = function (b) {\r\n  if(this.isInfinity()) return b;\r\n  if(b.isInfinity()) return this;\r\n\r\n  if (this.x.equals(b.x)) {\r\n    if (this.y.equals(b.y)) {\r\n      // this = b, i.e. this must be doubled\r\n      return this.twice();\r\n    }\r\n    // this = -b, i.e. the result is the point at infinity\r\n    return this.curve.getInfinity();\r\n  }\r\n\r\n  var x_x = b.x.subtract(this.x);\r\n  var y_y = b.y.subtract(this.y);\r\n  var gamma = y_y.divide(x_x);\r\n\r\n  var x3 = gamma.square().subtract(this.x).subtract(b.x);\r\n  var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y);\r\n\r\n  return new ECPointFp(this.curve, x3, y3);\r\n};\r\n\r\nECPointFp.prototype.twice2D = function () {\r\n  if (this.isInfinity()) return this;\r\n  if (this.y.toBigInteger().signum() == 0) {\r\n    // if y1 == 0, then (x1, y1) == (x1, -y1)\r\n    // and hence this = -this and thus 2(x1, y1) == infinity\r\n    return this.curve.getInfinity();\r\n  }\r\n\r\n  var TWO = this.curve.fromBigInteger(BigInteger.valueOf(2));\r\n  var THREE = this.curve.fromBigInteger(BigInteger.valueOf(3));\r\n  var gamma = this.x.square().multiply(THREE).add(this.curve.a).divide(this.y.multiply(TWO));\r\n\r\n  var x3 = gamma.square().subtract(this.x.multiply(TWO));\r\n  var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y);\r\n\r\n  return new ECPointFp(this.curve, x3, y3);\r\n};\r\n\r\nECPointFp.prototype.multiply2D = function (k) {\r\n  if(this.isInfinity()) return this;\r\n  if(k.signum() == 0) return this.curve.getInfinity();\r\n\r\n  var e = k;\r\n  var h = e.multiply(new BigInteger(\"3\"));\r\n\r\n  var neg = this.negate();\r\n  var R = this;\r\n\r\n  var i;\r\n  for (i = h.bitLength() - 2; i > 0; --i) {\r\n    R = R.twice();\r\n\r\n    var hBit = h.testBit(i);\r\n    var eBit = e.testBit(i);\r\n\r\n    if (hBit != eBit) {\r\n      R = R.add2D(hBit ? this : neg);\r\n    }\r\n  }\r\n\r\n  return R;\r\n};\r\n\r\nECPointFp.prototype.isOnCurve = function () {\r\n  var x = this.getX().toBigInteger();\r\n  var y = this.getY().toBigInteger();\r\n  var a = this.curve.getA().toBigInteger();\r\n  var b = this.curve.getB().toBigInteger();\r\n  var n = this.curve.getQ();\r\n  var lhs = y.multiply(y).mod(n);\r\n  var rhs = x.multiply(x).multiply(x)\r\n    .add(a.multiply(x)).add(b).mod(n);\r\n  return lhs.equals(rhs);\r\n};\r\n\r\nECPointFp.prototype.toString = function () {\r\n  return '('+this.getX().toBigInteger().toString()+','+\r\n    this.getY().toBigInteger().toString()+')';\r\n};\r\n\r\n/**\r\n * Validate an elliptic curve point.\r\n *\r\n * See SEC 1, section 3.2.2.1: Elliptic Curve Public Key Validation Primitive\r\n */\r\nECPointFp.prototype.validate = function () {\r\n  var n = this.curve.getQ();\r\n\r\n  // Check Q != O\r\n  if (this.isInfinity()) {\r\n    throw new Error(\"Point is at infinity.\");\r\n  }\r\n\r\n  // Check coordinate bounds\r\n  var x = this.getX().toBigInteger();\r\n  var y = this.getY().toBigInteger();\r\n  if (x.compareTo(BigInteger.ONE) < 0 ||\r\n      x.compareTo(n.subtract(BigInteger.ONE)) > 0) {\r\n    throw new Error('x coordinate out of bounds');\r\n  }\r\n  if (y.compareTo(BigInteger.ONE) < 0 ||\r\n      y.compareTo(n.subtract(BigInteger.ONE)) > 0) {\r\n    throw new Error('y coordinate out of bounds');\r\n  }\r\n\r\n  // Check y^2 = x^3 + ax + b (mod n)\r\n  if (!this.isOnCurve()) {\r\n    throw new Error(\"Point is not on the curve.\");\r\n  }\r\n\r\n  // Check nQ = 0 (Q is a scalar multiple of G)\r\n  if (this.multiply(n).isInfinity()) {\r\n    // TODO: This check doesn't work - fix.\r\n    throw new Error(\"Point is not a scalar multiple of G.\");\r\n  }\r\n\r\n  return true;\r\n};\r\n"
  },
  {
    "path": "JavaScript/demo/js/ec.js",
    "content": "/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\n// Basic Javascript Elliptic Curve implementation\n// Ported loosely from BouncyCastle's Java EC code\n// Only Fp curves implemented for now\n\n// Requires jsbn.js and jsbn2.js\n\n// ----------------\n// ECFieldElementFp\n\n// constructor\nfunction ECFieldElementFp(q,x) {\n    this.x = x;\n    // TODO if(x.compareTo(q) >= 0) error\n    this.q = q;\n}\n\nfunction feFpEquals(other) {\n    if(other == this) return true;\n    return (this.q.equals(other.q) && this.x.equals(other.x));\n}\n\nfunction feFpToBigInteger() {\n    return this.x;\n}\n\nfunction feFpNegate() {\n    return new ECFieldElementFp(this.q, this.x.negate().mod(this.q));\n}\n\nfunction feFpAdd(b) {\n    return new ECFieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q));\n}\n\nfunction feFpSubtract(b) {\n    return new ECFieldElementFp(this.q, this.x.subtract(b.toBigInteger()).mod(this.q));\n}\n\nfunction feFpMultiply(b) {\n    return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger()).mod(this.q));\n}\n\nfunction feFpSquare() {\n    return new ECFieldElementFp(this.q, this.x.square().mod(this.q));\n}\n\nfunction feFpDivide(b) {\n    return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q));\n}\n\nECFieldElementFp.prototype.equals = feFpEquals;\nECFieldElementFp.prototype.toBigInteger = feFpToBigInteger;\nECFieldElementFp.prototype.negate = feFpNegate;\nECFieldElementFp.prototype.add = feFpAdd;\nECFieldElementFp.prototype.subtract = feFpSubtract;\nECFieldElementFp.prototype.multiply = feFpMultiply;\nECFieldElementFp.prototype.square = feFpSquare;\nECFieldElementFp.prototype.divide = feFpDivide;\n\n// ----------------\n// ECPointFp\n\n// constructor\nfunction ECPointFp(curve,x,y,z) {\n    this.curve = curve;\n    this.x = x;\n    this.y = y;\n    // Projective coordinates: either zinv == null or z * zinv == 1\n    // z and zinv are just BigIntegers, not fieldElements\n    if(z == null) {\n      this.z = BigInteger.ONE;\n    }\n    else {\n      this.z = z;\n    }\n    this.zinv = null;\n    //TODO: compression flag\n}\n\nfunction pointFpGetX() {\n    if(this.zinv == null) {\n      this.zinv = this.z.modInverse(this.curve.q);\n    }\n    return this.curve.fromBigInteger(this.x.toBigInteger().multiply(this.zinv).mod(this.curve.q));\n}\n\nfunction pointFpGetY() {\n    if(this.zinv == null) {\n      this.zinv = this.z.modInverse(this.curve.q);\n    }\n    return this.curve.fromBigInteger(this.y.toBigInteger().multiply(this.zinv).mod(this.curve.q));\n}\n\nfunction pointFpEquals(other) {\n    if(other == this) return true;\n    if(this.isInfinity()) return other.isInfinity();\n    if(other.isInfinity()) return this.isInfinity();\n    var u, v;\n    // u = Y2 * Z1 - Y1 * Z2\n    u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod(this.curve.q);\n    if(!u.equals(BigInteger.ZERO)) return false;\n    // v = X2 * Z1 - X1 * Z2\n    v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod(this.curve.q);\n    return v.equals(BigInteger.ZERO);\n}\n\nfunction pointFpIsInfinity() {\n    if((this.x == null) && (this.y == null)) return true;\n    return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO);\n}\n\nfunction pointFpNegate() {\n    return new ECPointFp(this.curve, this.x, this.y.negate(), this.z);\n}\n\nfunction pointFpAdd(b) {\n    if(this.isInfinity()) return b;\n    if(b.isInfinity()) return this;\n\n    // u = Y2 * Z1 - Y1 * Z2\n    var u = b.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(b.z)).mod(this.curve.q);\n    // v = X2 * Z1 - X1 * Z2\n    var v = b.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(b.z)).mod(this.curve.q);\n\n    if(BigInteger.ZERO.equals(v)) {\n        if(BigInteger.ZERO.equals(u)) {\n            return this.twice(); // this == b, so double\n        }\n\treturn this.curve.getInfinity(); // this = -b, so infinity\n    }\n\n    var THREE = new BigInteger(\"3\");\n    var x1 = this.x.toBigInteger();\n    var y1 = this.y.toBigInteger();\n    var x2 = b.x.toBigInteger();\n    var y2 = b.y.toBigInteger();\n\n    var v2 = v.square();\n    var v3 = v2.multiply(v);\n    var x1v2 = x1.multiply(v2);\n    var zu2 = u.square().multiply(this.z);\n\n    // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3)\n    var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.q);\n    // y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3\n    var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.curve.q);\n    // z3 = v^3 * z1 * z2\n    var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.q);\n\n    return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3);\n}\n\nfunction pointFpTwice() {\n    if(this.isInfinity()) return this;\n    if(this.y.toBigInteger().signum() == 0) return this.curve.getInfinity();\n\n    // TODO: optimized handling of constants\n    var THREE = new BigInteger(\"3\");\n    var x1 = this.x.toBigInteger();\n    var y1 = this.y.toBigInteger();\n\n    var y1z1 = y1.multiply(this.z);\n    var y1sqz1 = y1z1.multiply(y1).mod(this.curve.q);\n    var a = this.curve.a.toBigInteger();\n\n    // w = 3 * x1^2 + a * z1^2\n    var w = x1.square().multiply(THREE);\n    if(!BigInteger.ZERO.equals(a)) {\n      w = w.add(this.z.square().multiply(a));\n    }\n    w = w.mod(this.curve.q);\n    // x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1)\n    var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.curve.q);\n    // y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3\n    var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.square().multiply(w)).mod(this.curve.q);\n    // z3 = 8 * (y1 * z1)^3\n    var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.q);\n\n    return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3);\n}\n\n// Simple NAF (Non-Adjacent Form) multiplication algorithm\n// TODO: modularize the multiplication algorithm\nfunction pointFpMultiply(k) {\n    if(this.isInfinity()) return this;\n    if(k.signum() == 0) return this.curve.getInfinity();\n\n    var e = k;\n    var h = e.multiply(new BigInteger(\"3\"));\n\n    var neg = this.negate();\n    var R = this;\n\n    var i;\n    for(i = h.bitLength() - 2; i > 0; --i) {\n\tR = R.twice();\n\n\tvar hBit = h.testBit(i);\n\tvar eBit = e.testBit(i);\n\n\tif (hBit != eBit) {\n\t    R = R.add(hBit ? this : neg);\n\t}\n    }\n\n    return R;\n}\n\n// Compute this*j + x*k (simultaneous multiplication)\nfunction pointFpMultiplyTwo(j,x,k) {\n  var i;\n  if(j.bitLength() > k.bitLength())\n    i = j.bitLength() - 1;\n  else\n    i = k.bitLength() - 1;\n\n  var R = this.curve.getInfinity();\n  var both = this.add(x);\n  while(i >= 0) {\n    R = R.twice();\n    if(j.testBit(i)) {\n      if(k.testBit(i)) {\n        R = R.add(both);\n      }\n      else {\n        R = R.add(this);\n      }\n    }\n    else {\n      if(k.testBit(i)) {\n        R = R.add(x);\n      }\n    }\n    --i;\n  }\n\n  return R;\n}\n\nECPointFp.prototype.getX = pointFpGetX;\nECPointFp.prototype.getY = pointFpGetY;\nECPointFp.prototype.equals = pointFpEquals;\nECPointFp.prototype.isInfinity = pointFpIsInfinity;\nECPointFp.prototype.negate = pointFpNegate;\nECPointFp.prototype.add = pointFpAdd;\nECPointFp.prototype.twice = pointFpTwice;\nECPointFp.prototype.multiply = pointFpMultiply;\nECPointFp.prototype.multiplyTwo = pointFpMultiplyTwo;\n\n// ----------------\n// ECCurveFp\n\n// constructor\nfunction ECCurveFp(q,a,b) {\n    this.q = q;\n    this.a = this.fromBigInteger(a);\n    this.b = this.fromBigInteger(b);\n    this.infinity = new ECPointFp(this, null, null);\n}\n\nfunction curveFpGetQ() {\n    return this.q;\n}\n\nfunction curveFpGetA() {\n    return this.a;\n}\n\nfunction curveFpGetB() {\n    return this.b;\n}\n\nfunction curveFpEquals(other) {\n    if(other == this) return true;\n    return(this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b));\n}\n\nfunction curveFpGetInfinity() {\n    return this.infinity;\n}\n\nfunction curveFpFromBigInteger(x) {\n    return new ECFieldElementFp(this.q, x);\n}\n\n// for now, work with hex strings because they're easier in JS\nfunction curveFpDecodePointHex(s) {\n    switch(parseInt(s.substr(0,2), 16)) { // first byte\n    case 0:\n\treturn this.infinity;\n    case 2:\n    case 3:\n\t// point compression not supported yet\n\treturn null;\n    case 4:\n    case 6:\n    case 7:\n\tvar len = (s.length - 2) / 2;\n\tvar xHex = s.substr(2, len);\n\tvar yHex = s.substr(len+2, len);\n\n\treturn new ECPointFp(this,\n\t\t\t     this.fromBigInteger(new BigInteger(xHex, 16)),\n\t\t\t     this.fromBigInteger(new BigInteger(yHex, 16)));\n\n    default: // unsupported\n\treturn null;\n    }\n}\n\nECCurveFp.prototype.getQ = curveFpGetQ;\nECCurveFp.prototype.getA = curveFpGetA;\nECCurveFp.prototype.getB = curveFpGetB;\nECCurveFp.prototype.equals = curveFpEquals;\nECCurveFp.prototype.getInfinity = curveFpGetInfinity;\nECCurveFp.prototype.fromBigInteger = curveFpFromBigInteger;\nECCurveFp.prototype.decodePointHex = curveFpDecodePointHex;\n"
  },
  {
    "path": "JavaScript/demo/js/ecdsa-modified-1.0.js",
    "content": "/*! ecdsa-modified-1.0.4.js (c) Stephan Thomas, Kenji Urushima | github.com/bitcoinjs/bitcoinjs-lib/blob/master/LICENSE\n */\n/*\n * ecdsa-modified.js - modified Bitcoin.ECDSA class\n * \n * Copyright (c) 2013 Stefan Thomas (github.com/justmoon)\n *                    Kenji Urushima (kenji.urushima@gmail.com)\n * LICENSE\n *   https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/LICENSE\n */\n\n/**\n * @fileOverview\n * @name ecdsa-modified-1.0.js\n * @author Stefan Thomas (github.com/justmoon) and Kenji Urushima (kenji.urushima@gmail.com)\n * @version 1.0.4 (2013-Oct-06)\n * @since jsrsasign 4.0\n * @license <a href=\"https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/LICENSE\">MIT License</a>\n */\n\nif (typeof KJUR == \"undefined\" || !KJUR) KJUR = {};\nif (typeof KJUR.crypto == \"undefined\" || !KJUR.crypto) KJUR.crypto = {};\n\n/**\n * class for EC key generation,  ECDSA signing and verifcation\n * @name KJUR.crypto.ECDSA\n * @class class for EC key generation,  ECDSA signing and verifcation\n * @description\n * <p>\n * CAUTION: Most of the case, you don't need to use this class except\n * for generating an EC key pair. Please use {@link KJUR.crypto.Signature} class instead.\n * </p>\n * <p>\n * This class was originally developped by Stefan Thomas for Bitcoin JavaScript library.\n * (See {@link https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/ecdsa.js})\n * Currently this class supports following named curves and their aliases.\n * <ul>\n * <li>secp256r1, NIST P-256, P-256, prime256v1 (*)</li>\n * <li>secp256k1 (*)</li>\n * <li>secp384r1, NIST P-384, P-384 (*)</li>\n * </ul>\n * </p>\n */\nKJUR.crypto.ECDSA = function(params) {\n    var curveName = \"secp256r1\";\t// curve name default\n    var ecparams = null;\n    var prvKeyHex = null;\n    var pubKeyHex = null;\n\n    var rng = new SecureRandom();\n\n    var P_OVER_FOUR = null;\n\n    this.type = \"EC\";\n\n    function implShamirsTrick(P, k, Q, l) {\n\tvar m = Math.max(k.bitLength(), l.bitLength());\n\tvar Z = P.add2D(Q);\n\tvar R = P.curve.getInfinity();\n\n\tfor (var i = m - 1; i >= 0; --i) {\n\t    R = R.twice2D();\n\n\t    R.z = BigInteger.ONE;\n\n\t    if (k.testBit(i)) {\n\t\tif (l.testBit(i)) {\n\t\t    R = R.add2D(Z);\n\t\t} else {\n\t\t    R = R.add2D(P);\n\t\t}\n\t    } else {\n\t\tif (l.testBit(i)) {\n\t\t    R = R.add2D(Q);\n\t\t}\n\t    }\n\t}\n\t\n\treturn R;\n    };\n\n    //===========================\n    // PUBLIC METHODS\n    //===========================\n    this.getBigRandom = function (limit) {\n\treturn new BigInteger(limit.bitLength(), rng)\n\t.mod(limit.subtract(BigInteger.ONE))\n\t.add(BigInteger.ONE)\n\t;\n    };\n\n    this.setNamedCurve = function(curveName) {\n\tthis.ecparams = KJUR.crypto.ECParameterDB.getByName(curveName);\n\tthis.prvKeyHex = null;\n\tthis.pubKeyHex = null;\n\tthis.curveName = curveName;\n    }\n\n    this.setPrivateKeyHex = function(prvKeyHex) {\n        this.isPrivate = true;\n\tthis.prvKeyHex = prvKeyHex;\n    }\n\n    this.setPublicKeyHex = function(pubKeyHex) {\n        this.isPublic = true;\n\tthis.pubKeyHex = pubKeyHex;\n    }\n\n    /**\n     * generate a EC key pair\n     * @name generateKeyPairHex\n     * @memberOf KJUR.crypto.ECDSA\n     * @function\n     * @return {Array} associative array of hexadecimal string of private and public key\n     * @since ecdsa-modified 1.0.1\n     * @example\n     * var ec = KJUR.crypto.ECDSA({'curve': 'secp256r1'});\n     * var keypair = ec.generateKeyPairHex();\n     * var pubhex = keypair.ecpubhex; // hexadecimal string of EC private key (=d)\n     * var prvhex = keypair.ecprvhex; // hexadecimal string of EC public key\n     */\n    this.generateKeyPairHex = function() {\n\tvar biN = this.ecparams['n'];\n\tvar biPrv = this.getBigRandom(biN);\n\tvar epPub = this.ecparams['G'].multiply(biPrv);\n\tvar biX = epPub.getX().toBigInteger();\n\tvar biY = epPub.getY().toBigInteger();\n\n\tvar charlen = this.ecparams['keylen'] / 4;\n\tvar hPrv = (\"0000000000\" + biPrv.toString(16)).slice(- charlen);\n\tvar hX   = (\"0000000000\" + biX.toString(16)).slice(- charlen);\n\tvar hY   = (\"0000000000\" + biY.toString(16)).slice(- charlen);\n\tvar hPub = \"04\" + hX + hY;\n\n\tthis.setPrivateKeyHex(hPrv);\n\tthis.setPublicKeyHex(hPub);\n\treturn {'ecprvhex': hPrv, 'ecpubhex': hPub};\n    };\n\n    this.signWithMessageHash = function(hashHex) {\n\treturn this.signHex(hashHex, this.prvKeyHex);\n    };\n\n    /**\n     * signing to message hash\n     * @name signHex\n     * @memberOf KJUR.crypto.ECDSA\n     * @function\n     * @param {String} hashHex hexadecimal string of hash value of signing message\n     * @param {String} privHex hexadecimal string of EC private key\n     * @return {String} hexadecimal string of ECDSA signature\n     * @since ecdsa-modified 1.0.1\n     * @example\n     * var ec = KJUR.crypto.ECDSA({'curve': 'secp256r1'});\n     * var sigValue = ec.signHex(hash, prvKey);\n     */\n    this.signHex = function (hashHex, privHex) {\n\tvar d = new BigInteger(privHex, 16);\n\tvar n = this.ecparams['n'];\n\tvar e = new BigInteger(hashHex, 16);\n\n\tdo {\n\t    var k = this.getBigRandom(n);\n\t    var G = this.ecparams['G'];\n\t    var Q = G.multiply(k);\n\t    var r = Q.getX().toBigInteger().mod(n);\n\t} while (r.compareTo(BigInteger.ZERO) <= 0);\n\n\tvar s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);\n\n\treturn KJUR.crypto.ECDSA.biRSSigToASN1Sig(r, s);\n    };\n\n    this.sign = function (hash, priv) {\n\tvar d = priv;\n\tvar n = this.ecparams['n'];\n\tvar e = BigInteger.fromByteArrayUnsigned(hash);\n\n\tdo {\n\t    var k = this.getBigRandom(n);\n\t    var G = this.ecparams['G'];\n\t    var Q = G.multiply(k);\n\t    var r = Q.getX().toBigInteger().mod(n);\n\t} while (r.compareTo(BigInteger.ZERO) <= 0);\n\n\tvar s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);\n\treturn this.serializeSig(r, s);\n    };\n\n    this.verifyWithMessageHash = function(hashHex, sigHex) {\n\treturn this.verifyHex(hashHex, sigHex, this.pubKeyHex);\n    };\n\n    /**\n     * verifying signature with message hash and public key\n     * @name verifyHex\n     * @memberOf KJUR.crypto.ECDSA\n     * @function\n     * @param {String} hashHex hexadecimal string of hash value of signing message\n     * @param {String} sigHex hexadecimal string of signature value\n     * @param {String} pubkeyHex hexadecimal string of public key\n     * @return {Boolean} true if the signature is valid, otherwise false\n     * @since ecdsa-modified 1.0.1\n     * @example\n     * var ec = KJUR.crypto.ECDSA({'curve': 'secp256r1'});\n     * var result = ec.verifyHex(msgHashHex, sigHex, pubkeyHex);\n     */\n    this.verifyHex = function(hashHex, sigHex, pubkeyHex) {\n\tvar r,s;\n\n\tvar obj = KJUR.crypto.ECDSA.parseSigHex(sigHex);\n\tr = obj.r;\n\ts = obj.s;\n\n\tvar Q;\n\tQ = ECPointFp.decodeFromHex(this.ecparams['curve'], pubkeyHex);\n\tvar e = new BigInteger(hashHex, 16);\n\n\treturn this.verifyRaw(e, r, s, Q);\n    };\n\n    this.verify = function (hash, sig, pubkey) {\n\tvar r,s;\n\tif (Bitcoin.Util.isArray(sig)) {\n\t    var obj = this.parseSig(sig);\n\t    r = obj.r;\n\t    s = obj.s;\n\t} else if (\"object\" === typeof sig && sig.r && sig.s) {\n\t    r = sig.r;\n\t    s = sig.s;\n\t} else {\n\t    throw \"Invalid value for signature\";\n\t}\n\n\tvar Q;\n\tif (pubkey instanceof ECPointFp) {\n\t    Q = pubkey;\n\t} else if (Bitcoin.Util.isArray(pubkey)) {\n\t    Q = ECPointFp.decodeFrom(this.ecparams['curve'], pubkey);\n\t} else {\n\t    throw \"Invalid format for pubkey value, must be byte array or ECPointFp\";\n\t}\n\tvar e = BigInteger.fromByteArrayUnsigned(hash);\n\n\treturn this.verifyRaw(e, r, s, Q);\n    };\n\n    this.verifyRaw = function (e, r, s, Q) {\n\tvar n = this.ecparams['n'];\n\tvar G = this.ecparams['G'];\n\n\tif (r.compareTo(BigInteger.ONE) < 0 ||\n\t    r.compareTo(n) >= 0)\n\t    return false;\n\n\tif (s.compareTo(BigInteger.ONE) < 0 ||\n\t    s.compareTo(n) >= 0)\n\t    return false;\n\n\tvar c = s.modInverse(n);\n\n\tvar u1 = e.multiply(c).mod(n);\n\tvar u2 = r.multiply(c).mod(n);\n\n\t// TODO(!!!): For some reason Shamir's trick isn't working with\n\t// signed message verification!? Probably an implementation\n\t// error!\n\t//var point = implShamirsTrick(G, u1, Q, u2);\n\tvar point = G.multiply(u1).add(Q.multiply(u2));\n\n\tvar v = point.getX().toBigInteger().mod(n);\n\n\treturn v.equals(r);\n    };\n\n    /**\n     * Serialize a signature into DER format.\n     *\n     * Takes two BigIntegers representing r and s and returns a byte array.\n     */\n    this.serializeSig = function (r, s) {\n\tvar rBa = r.toByteArraySigned();\n\tvar sBa = s.toByteArraySigned();\n\n\tvar sequence = [];\n\tsequence.push(0x02); // INTEGER\n\tsequence.push(rBa.length);\n\tsequence = sequence.concat(rBa);\n\n\tsequence.push(0x02); // INTEGER\n\tsequence.push(sBa.length);\n\tsequence = sequence.concat(sBa);\n\n\tsequence.unshift(sequence.length);\n\tsequence.unshift(0x30); // SEQUENCE\n\treturn sequence;\n    };\n\n    /**\n     * Parses a byte array containing a DER-encoded signature.\n     *\n     * This function will return an object of the form:\n     *\n     * {\n     *   r: BigInteger,\n     *   s: BigInteger\n     * }\n     */\n    this.parseSig = function (sig) {\n\tvar cursor;\n\tif (sig[0] != 0x30)\n\t    throw new Error(\"Signature not a valid DERSequence\");\n\n\tcursor = 2;\n\tif (sig[cursor] != 0x02)\n\t    throw new Error(\"First element in signature must be a DERInteger\");;\n\tvar rBa = sig.slice(cursor+2, cursor+2+sig[cursor+1]);\n\n\tcursor += 2+sig[cursor+1];\n\tif (sig[cursor] != 0x02)\n\t    throw new Error(\"Second element in signature must be a DERInteger\");\n\tvar sBa = sig.slice(cursor+2, cursor+2+sig[cursor+1]);\n\n\tcursor += 2+sig[cursor+1];\n\n\t//if (cursor != sig.length)\n\t//  throw new Error(\"Extra bytes in signature\");\n\n\tvar r = BigInteger.fromByteArrayUnsigned(rBa);\n\tvar s = BigInteger.fromByteArrayUnsigned(sBa);\n\n\treturn {r: r, s: s};\n    };\n\n    this.parseSigCompact = function (sig) {\n\tif (sig.length !== 65) {\n\t    throw \"Signature has the wrong length\";\n\t}\n\n\t// Signature is prefixed with a type byte storing three bits of\n\t// information.\n\tvar i = sig[0] - 27;\n\tif (i < 0 || i > 7) {\n\t    throw \"Invalid signature type\";\n\t}\n\n\tvar n = this.ecparams['n'];\n\tvar r = BigInteger.fromByteArrayUnsigned(sig.slice(1, 33)).mod(n);\n\tvar s = BigInteger.fromByteArrayUnsigned(sig.slice(33, 65)).mod(n);\n\n\treturn {r: r, s: s, i: i};\n    };\n\n    /*\n     * Recover a public key from a signature.\n     *\n     * See SEC 1: Elliptic Curve Cryptography, section 4.1.6, \"Public\n     * Key Recovery Operation\".\n     *\n     * http://www.secg.org/download/aid-780/sec1-v2.pdf\n     */\n    /*\n    recoverPubKey: function (r, s, hash, i) {\n\t// The recovery parameter i has two bits.\n\ti = i & 3;\n\n\t// The less significant bit specifies whether the y coordinate\n\t// of the compressed point is even or not.\n\tvar isYEven = i & 1;\n\n\t// The more significant bit specifies whether we should use the\n\t// first or second candidate key.\n\tvar isSecondKey = i >> 1;\n\n\tvar n = this.ecparams['n'];\n\tvar G = this.ecparams['G'];\n\tvar curve = this.ecparams['curve'];\n\tvar p = curve.getQ();\n\tvar a = curve.getA().toBigInteger();\n\tvar b = curve.getB().toBigInteger();\n\n\t// We precalculate (p + 1) / 4 where p is if the field order\n\tif (!P_OVER_FOUR) {\n\t    P_OVER_FOUR = p.add(BigInteger.ONE).divide(BigInteger.valueOf(4));\n\t}\n\n\t// 1.1 Compute x\n\tvar x = isSecondKey ? r.add(n) : r;\n\n\t// 1.3 Convert x to point\n\tvar alpha = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(p);\n\tvar beta = alpha.modPow(P_OVER_FOUR, p);\n\n\tvar xorOdd = beta.isEven() ? (i % 2) : ((i+1) % 2);\n\t// If beta is even, but y isn't or vice versa, then convert it,\n\t// otherwise we're done and y == beta.\n\tvar y = (beta.isEven() ? !isYEven : isYEven) ? beta : p.subtract(beta);\n\n\t// 1.4 Check that nR is at infinity\n\tvar R = new ECPointFp(curve,\n\t\t\t      curve.fromBigInteger(x),\n\t\t\t      curve.fromBigInteger(y));\n\tR.validate();\n\n\t// 1.5 Compute e from M\n\tvar e = BigInteger.fromByteArrayUnsigned(hash);\n\tvar eNeg = BigInteger.ZERO.subtract(e).mod(n);\n\n\t// 1.6 Compute Q = r^-1 (sR - eG)\n\tvar rInv = r.modInverse(n);\n\tvar Q = implShamirsTrick(R, s, G, eNeg).multiply(rInv);\n\n\tQ.validate();\n\tif (!this.verifyRaw(e, r, s, Q)) {\n\t    throw \"Pubkey recovery unsuccessful\";\n\t}\n\n\tvar pubKey = new Bitcoin.ECKey();\n\tpubKey.pub = Q;\n\treturn pubKey;\n    },\n    */\n\n    /*\n     * Calculate pubkey extraction parameter.\n     *\n     * When extracting a pubkey from a signature, we have to\n     * distinguish four different cases. Rather than putting this\n     * burden on the verifier, Bitcoin includes a 2-bit value with the\n     * signature.\n     *\n     * This function simply tries all four cases and returns the value\n     * that resulted in a successful pubkey recovery.\n     */\n    /*\n    calcPubkeyRecoveryParam: function (address, r, s, hash) {\n\tfor (var i = 0; i < 4; i++) {\n\t    try {\n\t\tvar pubkey = Bitcoin.ECDSA.recoverPubKey(r, s, hash, i);\n\t\tif (pubkey.getBitcoinAddress().toString() == address) {\n\t\t    return i;\n\t\t}\n\t    } catch (e) {}\n\t}\n\tthrow \"Unable to find valid recovery factor\";\n    }\n    */\n\n    if (params !== undefined) {\n\tif (params['curve'] !== undefined) {\n\t    this.curveName = params['curve'];\n\t}\n    }\n    if (this.curveName === undefined) this.curveName = curveName;\n    this.setNamedCurve(this.curveName);\n    if (params !== undefined) {\n\tif (params['prv'] !== undefined) this.setPrivateKeyHex(params['prv']);\n\tif (params['pub'] !== undefined) this.setPublicKeyHex(params['pub']);\n    }\n};\n\n/**\n * parse ASN.1 DER encoded ECDSA signature\n * @name parseSigHex\n * @memberOf KJUR.crypto.ECDSA\n * @function\n * @static\n * @param {String} sigHex hexadecimal string of ECDSA signature value\n * @return {Array} associative array of signature field r and s of BigInteger\n * @since ecdsa-modified 1.0.1\n * @example\n * var ec = KJUR.crypto.ECDSA({'curve': 'secp256r1'});\n * var sig = ec.parseSigHex('30...');\n * var biR = sig.r; // BigInteger object for 'r' field of signature.\n * var biS = sig.s; // BigInteger object for 's' field of signature.\n */\nKJUR.crypto.ECDSA.parseSigHex = function(sigHex) {\n    var p = KJUR.crypto.ECDSA.parseSigHexInHexRS(sigHex);\n    var biR = new BigInteger(p.r, 16);\n    var biS = new BigInteger(p.s, 16);\n    \n    return {'r': biR, 's': biS};\n};\n\n/**\n * parse ASN.1 DER encoded ECDSA signature\n * @name parseSigHexInHexRS\n * @memberOf KJUR.crypto.ECDSA\n * @function\n * @static\n * @param {String} sigHex hexadecimal string of ECDSA signature value\n * @return {Array} associative array of signature field r and s in hexadecimal\n * @since ecdsa-modified 1.0.3\n * @example\n * var ec = KJUR.crypto.ECDSA({'curve': 'secp256r1'});\n * var sig = ec.parseSigHexInHexRS('30...');\n * var hR = sig.r; // hexadecimal string for 'r' field of signature.\n * var hS = sig.s; // hexadecimal string for 's' field of signature.\n */\nKJUR.crypto.ECDSA.parseSigHexInHexRS = function(sigHex) {\n    // 1. ASN.1 Sequence Check\n    if (sigHex.substr(0, 2) != \"30\")\n\tthrow \"signature is not a ASN.1 sequence\";\n\n    // 2. Items of ASN.1 Sequence Check\n    var a = ASN1HEX.getPosArrayOfChildren_AtObj(sigHex, 0);\n    if (a.length != 2)\n\tthrow \"number of signature ASN.1 sequence elements seem wrong\";\n    \n    // 3. Integer check\n    var iTLV1 = a[0];\n    var iTLV2 = a[1];\n    if (sigHex.substr(iTLV1, 2) != \"02\")\n\tthrow \"1st item of sequene of signature is not ASN.1 integer\";\n    if (sigHex.substr(iTLV2, 2) != \"02\")\n\tthrow \"2nd item of sequene of signature is not ASN.1 integer\";\n\n    // 4. getting value\n    var hR = ASN1HEX.getHexOfV_AtObj(sigHex, iTLV1);\n    var hS = ASN1HEX.getHexOfV_AtObj(sigHex, iTLV2);\n    \n    return {'r': hR, 's': hS};\n};\n\n/**\n * convert hexadecimal ASN.1 encoded signature to concatinated signature\n * @name asn1SigToConcatSig\n * @memberOf KJUR.crypto.ECDSA\n * @function\n * @static\n * @param {String} asn1Hex hexadecimal string of ASN.1 encoded ECDSA signature value\n * @return {String} r-s concatinated format of ECDSA signature value\n * @since ecdsa-modified 1.0.3\n */\nKJUR.crypto.ECDSA.asn1SigToConcatSig = function(asn1Sig) {\n    var pSig = KJUR.crypto.ECDSA.parseSigHexInHexRS(asn1Sig);\n    var hR = pSig.r;\n    var hS = pSig.s;\n\n    if (hR.substr(0, 2) == \"00\" && (((hR.length / 2) * 8) % (16 * 8)) == 8) \n\thR = hR.substr(2);\n\n    if (hS.substr(0, 2) == \"00\" && (((hS.length / 2) * 8) % (16 * 8)) == 8) \n\thS = hS.substr(2);\n\n    if ((((hR.length / 2) * 8) % (16 * 8)) != 0)\n\tthrow \"unknown ECDSA sig r length error\";\n\n    if ((((hS.length / 2) * 8) % (16 * 8)) != 0)\n\tthrow \"unknown ECDSA sig s length error\";\n\n    return hR + hS;\n};\n\n/**\n * convert hexadecimal concatinated signature to ASN.1 encoded signature\n * @name concatSigToASN1Sig\n * @memberOf KJUR.crypto.ECDSA\n * @function\n * @static\n * @param {String} concatSig r-s concatinated format of ECDSA signature value\n * @return {String} hexadecimal string of ASN.1 encoded ECDSA signature value\n * @since ecdsa-modified 1.0.3\n */\nKJUR.crypto.ECDSA.concatSigToASN1Sig = function(concatSig) {\n    if ((((concatSig.length / 2) * 8) % (16 * 8)) != 0)\n\tthrow \"unknown ECDSA concatinated r-s sig  length error\";\n\n    var hR = concatSig.substr(0, concatSig.length / 2);\n    var hS = concatSig.substr(concatSig.length / 2);\n    return KJUR.crypto.ECDSA.hexRSSigToASN1Sig(hR, hS);\n};\n\n/**\n * convert hexadecimal R and S value of signature to ASN.1 encoded signature\n * @name hexRSSigToASN1Sig\n * @memberOf KJUR.crypto.ECDSA\n * @function\n * @static\n * @param {String} hR hexadecimal string of R field of ECDSA signature value\n * @param {String} hS hexadecimal string of S field of ECDSA signature value\n * @return {String} hexadecimal string of ASN.1 encoded ECDSA signature value\n * @since ecdsa-modified 1.0.3\n */\nKJUR.crypto.ECDSA.hexRSSigToASN1Sig = function(hR, hS) {\n    var biR = new BigInteger(hR, 16);\n    var biS = new BigInteger(hS, 16);\n    return KJUR.crypto.ECDSA.biRSSigToASN1Sig(biR, biS);\n};\n\n/**\n * convert R and S BigInteger object of signature to ASN.1 encoded signature\n * @name biRSSigToASN1Sig\n * @memberOf KJUR.crypto.ECDSA\n * @function\n * @static\n * @param {BigInteger} biR BigInteger object of R field of ECDSA signature value\n * @param {BigInteger} biS BIgInteger object of S field of ECDSA signature value\n * @return {String} hexadecimal string of ASN.1 encoded ECDSA signature value\n * @since ecdsa-modified 1.0.3\n */\nKJUR.crypto.ECDSA.biRSSigToASN1Sig = function(biR, biS) {\n    var derR = new KJUR.asn1.DERInteger({'bigint': biR});\n    var derS = new KJUR.asn1.DERInteger({'bigint': biS});\n    var derSeq = new KJUR.asn1.DERSequence({'array': [derR, derS]});\n    return derSeq.getEncodedHex();\n};\n\n"
  },
  {
    "path": "JavaScript/demo/js/ecparam-1.0.js",
    "content": "/*! ecparam-1.0.0.js (c) 2013 Kenji Urushima | kjur.github.com/jsrsasign/license\r\n */\r\n/*\r\n * ecparam.js - Elliptic Curve Cryptography Curve Parameter Definition class\r\n *\r\n * Copyright (c) 2013 Kenji Urushima (kenji.urushima@gmail.com)\r\n *\r\n * This software is licensed under the terms of the MIT License.\r\n * http://kjur.github.com/jsrsasign/license\r\n *\r\n * The above copyright and license notice shall be \r\n * included in all copies or substantial portions of the Software.\r\n */\r\n\r\n/**\r\n * @fileOverview\r\n * @name ecparam-1.1.js\r\n * @author Kenji Urushima kenji.urushima@gmail.com\r\n * @version 1.0.0 (2013-Jul-17)\r\n * @since jsrsasign 4.0\r\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\r\n */\r\n\r\nif (typeof KJUR == \"undefined\" || !KJUR) KJUR = {};\r\nif (typeof KJUR.crypto == \"undefined\" || !KJUR.crypto) KJUR.crypto = {};\r\n\r\n/**\r\n * static object for elliptic curve names and parameters\r\n * @name KJUR.crypto.ECParameterDB\r\n * @class static object for elliptic curve names and parameters\r\n * @description\r\n * This class provides parameters for named elliptic curves.\r\n * Currently it supoprts following curve names and aliases however \r\n * the name marked (*) are available for {@link KJUR.crypto.ECDSA} and\r\n * {@link KJUR.crypto.Signature} classes.\r\n * <ul>\r\n * <li>secp128r1</li>\r\n * <li>secp160r1</li>\r\n * <li>secp160k1</li>\r\n * <li>secp192r1</li>\r\n * <li>secp192k1</li>\r\n * <li>secp224r1</li>\r\n * <li>secp256r1, NIST P-256, P-256, prime256v1 (*)</li>\r\n * <li>secp256k1 (*)</li>\r\n * <li>secp384r1, NIST P-384, P-384 (*)</li>\r\n * <li>secp521r1, NIST P-521, P-521</li>\r\n * </ul>\r\n * You can register new curves by using 'register' method.\r\n */\r\nKJUR.crypto.ECParameterDB = new function() {\r\n    var db = {};\r\n    var aliasDB = {};\r\n\r\n    function hex2bi(hex) {\r\n        return new BigInteger(hex, 16);\r\n    }\r\n    \r\n    /**\r\n     * get curve inforamtion associative array for curve name or alias\r\n     * @name getByName\r\n     * @memberOf KJUR.crypto.ECParameterDB\r\n     * @function\r\n     * @param {String} nameOrAlias curve name or alias name\r\n     * @return {Array} associative array of curve parameters\r\n     * @example\r\n     * var param = KJUR.crypto.ECParameterDB.getByName('prime256v1');\r\n     * var keylen = param['keylen'];\r\n     * var n = param['n'];\r\n     */\r\n    this.getByName = function(nameOrAlias) {\r\n\tvar name = nameOrAlias;\r\n\tif (typeof aliasDB[name] != \"undefined\") {\r\n\t    name = aliasDB[nameOrAlias];\r\n        }\r\n\tif (typeof db[name] != \"undefined\") {\r\n\t    return db[name];\r\n\t}\r\n\tthrow \"unregistered EC curve name: \" + name;\r\n    };\r\n\r\n    /**\r\n     * register new curve\r\n     * @name regist\r\n     * @memberOf KJUR.crypto.ECParameterDB\r\n     * @function\r\n     * @param {String} name name of curve\r\n     * @param {Integer} keylen key length\r\n     * @param {String} pHex hexadecimal value of p\r\n     * @param {String} aHex hexadecimal value of a\r\n     * @param {String} bHex hexadecimal value of b\r\n     * @param {String} nHex hexadecimal value of n\r\n     * @param {String} hHex hexadecimal value of h\r\n     * @param {String} gxHex hexadecimal value of Gx\r\n     * @param {String} gyHex hexadecimal value of Gy\r\n     * @param {Array} aliasList array of string for curve names aliases\r\n     * @param {String} oid Object Identifier for the curve\r\n     * @param {String} info information string for the curve\r\n     */\r\n    this.regist = function(name, keylen, pHex, aHex, bHex, nHex, hHex, gxHex, gyHex, aliasList, oid, info) {\r\n        db[name] = {};\r\n\tvar p = hex2bi(pHex);\r\n\tvar a = hex2bi(aHex);\r\n\tvar b = hex2bi(bHex);\r\n\tvar n = hex2bi(nHex);\r\n\tvar h = hex2bi(hHex);\r\n        var curve = new ECCurveFp(p, a, b);\r\n        var G = curve.decodePointHex(\"04\" + gxHex + gyHex);\r\n\tdb[name]['name'] = name;\r\n\tdb[name]['keylen'] = keylen;\r\n        db[name]['curve'] = curve;\r\n        db[name]['G'] = G;\r\n        db[name]['n'] = n;\r\n        db[name]['h'] = h;\r\n        db[name]['oid'] = oid;\r\n        db[name]['info'] = info;\r\n\r\n        for (var i = 0; i < aliasList.length; i++) {\r\n\t    aliasDB[aliasList[i]] = name;\r\n        }\r\n    };\r\n};\r\n\r\nKJUR.crypto.ECParameterDB.regist(\r\n  \"secp128r1\", // name / p = 2^128 - 2^97 - 1\r\n  128,\r\n  \"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF\", // p\r\n  \"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC\", // a\r\n  \"E87579C11079F43DD824993C2CEE5ED3\", // b\r\n  \"FFFFFFFE0000000075A30D1B9038A115\", // n\r\n  \"1\", // h\r\n  \"161FF7528B899B2D0C28607CA52C5B86\", // gx\r\n  \"CF5AC8395BAFEB13C02DA292DDED7A83\", // gy\r\n  [], // alias\r\n  \"\", // oid (underconstruction)\r\n  \"secp128r1 : SECG curve over a 128 bit prime field\"); // info\r\n\r\nKJUR.crypto.ECParameterDB.regist(\r\n  \"secp160k1\", // name / p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1\r\n  160,\r\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73\", // p\r\n  \"0\", // a\r\n  \"7\", // b\r\n  \"0100000000000000000001B8FA16DFAB9ACA16B6B3\", // n\r\n  \"1\", // h\r\n  \"3B4C382CE37AA192A4019E763036F4F5DD4D7EBB\", // gx\r\n  \"938CF935318FDCED6BC28286531733C3F03C4FEE\", // gy\r\n  [], // alias\r\n  \"\", // oid\r\n  \"secp160k1 : SECG curve over a 160 bit prime field\"); // info\r\n\r\nKJUR.crypto.ECParameterDB.regist(\r\n  \"secp160r1\", // name / p = 2^160 - 2^31 - 1\r\n  160,\r\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF\", // p\r\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC\", // a\r\n  \"1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45\", // b\r\n  \"0100000000000000000001F4C8F927AED3CA752257\", // n\r\n  \"1\", // h\r\n  \"4A96B5688EF573284664698968C38BB913CBFC82\", // gx\r\n  \"23A628553168947D59DCC912042351377AC5FB32\", // gy\r\n  [], // alias\r\n  \"\", // oid\r\n  \"secp160r1 : SECG curve over a 160 bit prime field\"); // info\r\n\r\nKJUR.crypto.ECParameterDB.regist(\r\n  \"secp192k1\", // name / p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1\r\n  192,\r\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37\", // p\r\n  \"0\", // a\r\n  \"3\", // b\r\n  \"FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D\", // n\r\n  \"1\", // h\r\n  \"DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D\", // gx\r\n  \"9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D\", // gy\r\n  []); // alias\r\n\r\nKJUR.crypto.ECParameterDB.regist(\r\n  \"secp192r1\", // name / p = 2^192 - 2^64 - 1\r\n  192,\r\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF\", // p\r\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC\", // a\r\n  \"64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1\", // b\r\n  \"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831\", // n\r\n  \"1\", // h\r\n  \"188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012\", // gx\r\n  \"07192B95FFC8DA78631011ED6B24CDD573F977A11E794811\", // gy\r\n  []); // alias\r\n\r\nKJUR.crypto.ECParameterDB.regist(\r\n  \"secp224r1\", // name / p = 2^224 - 2^96 + 1\r\n  224,\r\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001\", // p\r\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE\", // a\r\n  \"B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4\", // b\r\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D\", // n\r\n  \"1\", // h\r\n  \"B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21\", // gx\r\n  \"BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34\", // gy\r\n  []); // alias\r\n\r\nKJUR.crypto.ECParameterDB.regist(\r\n  \"secp256k1\", // name / p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1\r\n  256,\r\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F\", // p\r\n  \"0\", // a\r\n  \"7\", // b\r\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141\", // n\r\n  \"1\", // h\r\n  \"79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798\", // gx\r\n  \"483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8\", // gy\r\n  []); // alias\r\n\r\nKJUR.crypto.ECParameterDB.regist(\r\n  \"secp256r1\", // name / p = 2^224 (2^32 - 1) + 2^192 + 2^96 - 1\r\n  256,\r\n  \"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\", // p\r\n  \"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC\", // a\r\n  \"5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B\", // b\r\n  \"FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551\", // n\r\n  \"1\", // h\r\n  \"6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296\", // gx\r\n  \"4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5\", // gy\r\n  [\"NIST P-256\", \"P-256\", \"prime256v1\"]); // alias\r\n\r\nKJUR.crypto.ECParameterDB.regist(\r\n  \"secp384r1\", // name\r\n  384,\r\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF\", // p\r\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC\", // a\r\n  \"B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF\", // b\r\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973\", // n\r\n  \"1\", // h\r\n  \"AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7\", // gx\r\n  \"3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f\", // gy\r\n  [\"NIST P-384\", \"P-384\"]); // alias\r\n\r\nKJUR.crypto.ECParameterDB.regist(\r\n  \"secp521r1\", // name\r\n  521,\r\n  \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\", // p\r\n  \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC\", // a\r\n  \"051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00\", // b\r\n  \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409\", // n\r\n  \"1\", // h\r\n  \"C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66\", // gx\r\n  \"011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650\", // gy\r\n  [\"NIST P-521\", \"P-521\"]); // alias\r\n\r\nKJUR.crypto.ECParameterDB.regist(\r\n  \"sm2\", // name\r\n  256,\r\n  \"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF\", // p\r\n  \"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC\", // a\r\n  \"28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93\", // b\r\n  \"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123\", // n\r\n  \"1\", // h\r\n  \"32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7\", // gx\r\n  \"BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0\", // gy\r\n  [\"sm2\", \"SM2\"]); // alias\r\n"
  },
  {
    "path": "JavaScript/demo/js/enc-base64.js",
    "content": "/*\nCryptoJS v3.1.2\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function () {\n    // Shortcuts\n    var C = CryptoJS;\n    var C_lib = C.lib;\n    var WordArray = C_lib.WordArray;\n    var C_enc = C.enc;\n\n    /**\n     * Base64 encoding strategy.\n     */\n    var Base64 = C_enc.Base64 = {\n        /**\n         * Converts a word array to a Base64 string.\n         *\n         * @param {WordArray} wordArray The word array.\n         *\n         * @return {string} The Base64 string.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var base64String = CryptoJS.enc.Base64.stringify(wordArray);\n         */\n        stringify: function (wordArray) {\n            // Shortcuts\n            var words = wordArray.words;\n            var sigBytes = wordArray.sigBytes;\n            var map = this._map;\n\n            // Clamp excess bits\n            wordArray.clamp();\n\n            // Convert\n            var base64Chars = [];\n            for (var i = 0; i < sigBytes; i += 3) {\n                var byte1 = (words[i >>> 2]       >>> (24 - (i % 4) * 8))       & 0xff;\n                var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;\n                var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;\n\n                var triplet = (byte1 << 16) | (byte2 << 8) | byte3;\n\n                for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) {\n                    base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));\n                }\n            }\n\n            // Add padding\n            var paddingChar = map.charAt(64);\n            if (paddingChar) {\n                while (base64Chars.length % 4) {\n                    base64Chars.push(paddingChar);\n                }\n            }\n\n            return base64Chars.join('');\n        },\n\n        /**\n         * Converts a Base64 string to a word array.\n         *\n         * @param {string} base64Str The Base64 string.\n         *\n         * @return {WordArray} The word array.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var wordArray = CryptoJS.enc.Base64.parse(base64String);\n         */\n        parse: function (base64Str) {\n            // Shortcuts\n            var base64StrLength = base64Str.length;\n            var map = this._map;\n\n            // Ignore padding\n            var paddingChar = map.charAt(64);\n            if (paddingChar) {\n                var paddingIndex = base64Str.indexOf(paddingChar);\n                if (paddingIndex != -1) {\n                    base64StrLength = paddingIndex;\n                }\n            }\n\n            // Convert\n            var words = [];\n            var nBytes = 0;\n            for (var i = 0; i < base64StrLength; i++) {\n                if (i % 4) {\n                    var bits1 = map.indexOf(base64Str.charAt(i - 1)) << ((i % 4) * 2);\n                    var bits2 = map.indexOf(base64Str.charAt(i)) >>> (6 - (i % 4) * 2);\n                    words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8);\n                    nBytes++;\n                }\n            }\n\n            return WordArray.create(words, nBytes);\n        },\n\n        _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='\n    };\n}());\n"
  },
  {
    "path": "JavaScript/demo/js/fingerprint.js",
    "content": "/*\n* fingerprintJS 0.5.4 - Fast browser fingerprint library\n* https://github.com/Valve/fingerprintjs\n* Copyright (c) 2013 Valentin Vasilyev (valentin.vasilyev@outlook.com)\n* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.\n*\n* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n* ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\n* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n;(function (name, context, definition) {\n  if (typeof module !== 'undefined' && module.exports) { module.exports = definition(); }\n  else if (typeof define === 'function' && define.amd) { define(definition); }\n  else { context[name] = definition(); }\n})('Fingerprint', this, function () {\n  'use strict';\n\n  var Fingerprint = function (options) {\n    var nativeForEach, nativeMap;\n    nativeForEach = Array.prototype.forEach;\n    nativeMap = Array.prototype.map;\n\n    this.each = function (obj, iterator, context) {\n      if (obj === null) {\n        return;\n      }\n      if (nativeForEach && obj.forEach === nativeForEach) {\n        obj.forEach(iterator, context);\n      } else if (obj.length === +obj.length) {\n        for (var i = 0, l = obj.length; i < l; i++) {\n          if (iterator.call(context, obj[i], i, obj) === {}) return;\n        }\n      } else {\n        for (var key in obj) {\n          if (obj.hasOwnProperty(key)) {\n            if (iterator.call(context, obj[key], key, obj) === {}) return;\n          }\n        }\n      }\n    };\n\n    this.map = function(obj, iterator, context) {\n      var results = [];\n      // Not using strict equality so that this acts as a\n      // shortcut to checking for `null` and `undefined`.\n      if (obj == null) return results;\n      if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);\n      this.each(obj, function(value, index, list) {\n        results[results.length] = iterator.call(context, value, index, list);\n      });\n      return results;\n    };\n\n    if (typeof options == 'object'){\n      this.hasher = options.hasher;\n      this.screen_resolution = options.screen_resolution;\n      this.screen_orientation = options.screen_orientation;\n      this.canvas = options.canvas;\n      this.ie_activex = options.ie_activex;\n    } else if(typeof options == 'function'){\n      this.hasher = options;\n    }\n  };\n\n  Fingerprint.prototype = {\n    get: function(){\n      var keys = [];\n      keys.push(navigator.userAgent);\n      keys.push(navigator.language);\n      keys.push(screen.colorDepth);\n      if (this.screen_resolution) {\n        var resolution = this.getScreenResolution();\n        if (typeof resolution !== 'undefined'){ // headless browsers, such as phantomjs\n          keys.push(resolution.join('x'));\n        }\n      }\n      keys.push(new Date().getTimezoneOffset());\n      keys.push(this.hasSessionStorage());\n      keys.push(this.hasLocalStorage());\n      keys.push(!!window.indexedDB);\n      //body might not be defined at this point or removed programmatically\n      if(document.body){\n        keys.push(typeof(document.body.addBehavior));\n      } else {\n        keys.push(typeof undefined);\n      }\n      keys.push(typeof(window.openDatabase));\n      keys.push(navigator.cpuClass);\n      keys.push(navigator.platform);\n      keys.push(navigator.doNotTrack);\n      keys.push(this.getPluginsString());\n      if(this.canvas && this.isCanvasSupported()){\n        keys.push(this.getCanvasFingerprint());\n      }\n      if(this.hasher){\n        return this.hasher(keys.join('###'), 31);\n      } else {\n        return this.murmurhash3_32_gc(keys.join('###'), 31);\n      }\n    },\n\n    /**\n     * JS Implementation of MurmurHash3 (r136) (as of May 20, 2011)\n     *\n     * @author <a href=\"mailto:gary.court@gmail.com\">Gary Court</a>\n     * @see http://github.com/garycourt/murmurhash-js\n     * @author <a href=\"mailto:aappleby@gmail.com\">Austin Appleby</a>\n     * @see http://sites.google.com/site/murmurhash/\n     *\n     * @param {string} key ASCII only\n     * @param {number} seed Positive integer only\n     * @return {number} 32-bit positive integer hash\n     */\n\n    murmurhash3_32_gc: function(key, seed) {\n      var remainder, bytes, h1, h1b, c1, c2, k1, i;\n\n      remainder = key.length & 3; // key.length % 4\n      bytes = key.length - remainder;\n      h1 = seed;\n      c1 = 0xcc9e2d51;\n      c2 = 0x1b873593;\n      i = 0;\n\n      while (i < bytes) {\n          k1 =\n            ((key.charCodeAt(i) & 0xff)) |\n            ((key.charCodeAt(++i) & 0xff) << 8) |\n            ((key.charCodeAt(++i) & 0xff) << 16) |\n            ((key.charCodeAt(++i) & 0xff) << 24);\n        ++i;\n\n        k1 = ((((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16))) & 0xffffffff;\n        k1 = (k1 << 15) | (k1 >>> 17);\n        k1 = ((((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16))) & 0xffffffff;\n\n        h1 ^= k1;\n            h1 = (h1 << 13) | (h1 >>> 19);\n        h1b = ((((h1 & 0xffff) * 5) + ((((h1 >>> 16) * 5) & 0xffff) << 16))) & 0xffffffff;\n        h1 = (((h1b & 0xffff) + 0x6b64) + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16));\n      }\n\n      k1 = 0;\n\n      switch (remainder) {\n        case 3: k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;\n        case 2: k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;\n        case 1: k1 ^= (key.charCodeAt(i) & 0xff);\n\n        k1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;\n        k1 = (k1 << 15) | (k1 >>> 17);\n        k1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;\n        h1 ^= k1;\n      }\n\n      h1 ^= key.length;\n\n      h1 ^= h1 >>> 16;\n      h1 = (((h1 & 0xffff) * 0x85ebca6b) + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;\n      h1 ^= h1 >>> 13;\n      h1 = ((((h1 & 0xffff) * 0xc2b2ae35) + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16))) & 0xffffffff;\n      h1 ^= h1 >>> 16;\n\n      return h1 >>> 0;\n    },\n\n    // https://bugzilla.mozilla.org/show_bug.cgi?id=781447\n    hasLocalStorage: function () {\n      try{\n        return !!window.localStorage;\n      } catch(e) {\n        return true; // SecurityError when referencing it means it exists\n      }\n    },\n\n    hasSessionStorage: function () {\n      try{\n        return !!window.sessionStorage;\n      } catch(e) {\n        return true; // SecurityError when referencing it means it exists\n      }\n    },\n\n    isCanvasSupported: function () {\n      var elem = document.createElement('canvas');\n      return !!(elem.getContext && elem.getContext('2d'));\n    },\n\n    isIE: function () {\n      if(navigator.appName === 'Microsoft Internet Explorer') {\n        return true;\n      } else if(navigator.appName === 'Netscape' && /Trident/.test(navigator.userAgent)){// IE 11\n        return true;\n      }\n      return false;\n    },\n\n    getPluginsString: function () {\n      if(this.isIE() && this.ie_activex){\n        return this.getIEPluginsString();\n      } else {\n        return this.getRegularPluginsString();\n      }\n    },\n\n    getRegularPluginsString: function () {\n      return this.map(navigator.plugins, function (p) {\n        var mimeTypes = this.map(p, function(mt){\n          return [mt.type, mt.suffixes].join('~');\n        }).join(',');\n        return [p.name, p.description, mimeTypes].join('::');\n      }, this).join(';');\n    },\n\n    getIEPluginsString: function () {\n      if(window.ActiveXObject){\n        var names = ['ShockwaveFlash.ShockwaveFlash',//flash plugin\n          'AcroPDF.PDF', // Adobe PDF reader 7+\n          'PDF.PdfCtrl', // Adobe PDF reader 6 and earlier, brrr\n          'QuickTime.QuickTime', // QuickTime\n          // 5 versions of real players\n          'rmocx.RealPlayer G2 Control',\n          'rmocx.RealPlayer G2 Control.1',\n          'RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)',\n          'RealVideo.RealVideo(tm) ActiveX Control (32-bit)',\n          'RealPlayer',\n          'SWCtl.SWCtl', // ShockWave player\n          'WMPlayer.OCX', // Windows media player\n          'AgControl.AgControl', // Silverlight\n          'Skype.Detection'];\n\n        // starting to detect plugins in IE\n        return this.map(names, function(name){\n          try{\n            new ActiveXObject(name);\n            return name;\n          } catch(e){\n            return null;\n          }\n        }).join(';');\n      } else {\n        return \"\"; // behavior prior version 0.5.0, not breaking backwards compat.\n      }\n    },\n\n    getScreenResolution: function () {\n      var resolution;\n       if(this.screen_orientation){\n         resolution = (screen.height > screen.width) ? [screen.height, screen.width] : [screen.width, screen.height];\n       }else{\n         resolution = [screen.height, screen.width];\n       }\n       return resolution;\n    },\n\n    getCanvasFingerprint: function () {\n      var canvas = document.createElement('canvas');\n      var ctx = canvas.getContext('2d');\n      // https://www.browserleaks.com/canvas#how-does-it-work\n      var txt = 'http://valve.github.io';\n      ctx.textBaseline = \"top\";\n      ctx.font = \"14px 'Arial'\";\n      ctx.textBaseline = \"alphabetic\";\n      ctx.fillStyle = \"#f60\";\n      ctx.fillRect(125,1,62,20);\n      ctx.fillStyle = \"#069\";\n      ctx.fillText(txt, 2, 15);\n      ctx.fillStyle = \"rgba(102, 204, 0, 0.7)\";\n      ctx.fillText(txt, 4, 17);\n      return canvas.toDataURL();\n    }\n  };\n\n\n  return Fingerprint;\n\n});\n"
  },
  {
    "path": "JavaScript/demo/js/fingerprint2.js",
    "content": "/*\r\n* Fingerprintjs2 1.4.2 - Modern & flexible browser fingerprint library v2\r\n* https://github.com/Valve/fingerprintjs2\r\n* Copyright (c) 2015 Valentin Vasilyev (valentin.vasilyev@outlook.com)\r\n* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.\r\n*\r\n* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\r\n* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r\n* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r\n* ARE DISCLAIMED. IN NO EVENT SHALL VALENTIN VASILYEV BE LIABLE FOR ANY\r\n* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r\n* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r\n* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r\n* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r\n* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n*/\r\n\r\n(function (name, context, definition) {\r\n  \"use strict\";\r\n  if (typeof define === \"function\" && define.amd) { define(definition); }\r\n  else if (typeof module !== \"undefined\" && module.exports) { module.exports = definition(); }\r\n  else if (context.exports) { context.exports = definition(); }\r\n  else { context[name] = definition(); }\r\n})(\"Fingerprint2\", this, function() {\r\n  \"use strict\";\r\n  // This will only be polyfilled for IE8 and older\r\n  // Taken from Mozilla MDC\r\n  if (!Array.prototype.indexOf) {\r\n    Array.prototype.indexOf = function(searchElement, fromIndex) {\r\n      var k;\r\n      if (this == null) {\r\n        throw new TypeError(\"'this' is null or undefined\");\r\n      }\r\n      var O = Object(this);\r\n      var len = O.length >>> 0;\r\n      if (len === 0) {\r\n        return -1;\r\n      }\r\n      var n = +fromIndex || 0;\r\n      if (Math.abs(n) === Infinity) {\r\n        n = 0;\r\n      }\r\n      if (n >= len) {\r\n        return -1;\r\n      }\r\n      k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);\r\n      while (k < len) {\r\n        if (k in O && O[k] === searchElement) {\r\n          return k;\r\n        }\r\n        k++;\r\n      }\r\n      return -1;\r\n    };\r\n  }\r\n  var Fingerprint2 = function(options) {\r\n\r\n    if (!(this instanceof Fingerprint2)) {\r\n      return new Fingerprint2(options);\r\n    }\r\n\r\n    var defaultOptions = {\r\n      swfContainerId: \"fingerprintjs2\",\r\n      swfPath: \"flash/compiled/FontList.swf\",\r\n      detectScreenOrientation: true,\r\n      sortPluginsFor: [/palemoon/i],\r\n      userDefinedFonts: []\r\n    };\r\n    this.options = this.extend(options, defaultOptions);\r\n    this.nativeForEach = Array.prototype.forEach;\r\n    this.nativeMap = Array.prototype.map;\r\n  };\r\n  Fingerprint2.prototype = {\r\n    extend: function(source, target) {\r\n      if (source == null) { return target; }\r\n      for (var k in source) {\r\n        if(source[k] != null && target[k] !== source[k]) {\r\n          target[k] = source[k];\r\n        }\r\n      }\r\n      return target;\r\n    },\r\n    log: function(msg){\r\n      if(window.console){\r\n        console.log(msg);\r\n      }\r\n    },\r\n    get: function(done){\r\n      var keys = [];\r\n      keys = this.userAgentKey(keys);\r\n      keys = this.languageKey(keys);\r\n      keys = this.colorDepthKey(keys);\r\n      keys = this.pixelRatioKey(keys);\r\n      keys = this.screenResolutionKey(keys);\r\n      keys = this.availableScreenResolutionKey(keys);\r\n      keys = this.timezoneOffsetKey(keys);\r\n      keys = this.sessionStorageKey(keys);\r\n      keys = this.localStorageKey(keys);\r\n      keys = this.indexedDbKey(keys);\r\n      keys = this.addBehaviorKey(keys);\r\n      keys = this.openDatabaseKey(keys);\r\n      keys = this.cpuClassKey(keys);\r\n      keys = this.platformKey(keys);\r\n      keys = this.doNotTrackKey(keys);\r\n      keys = this.pluginsKey(keys);\r\n      keys = this.canvasKey(keys);\r\n      keys = this.webglKey(keys);\r\n      keys = this.adBlockKey(keys);\r\n      keys = this.hasLiedLanguagesKey(keys);\r\n      keys = this.hasLiedResolutionKey(keys);\r\n      keys = this.hasLiedOsKey(keys);\r\n      keys = this.hasLiedBrowserKey(keys);\r\n      keys = this.touchSupportKey(keys);\r\n      var that = this;\r\n      this.fontsKey(keys, function(newKeys){\r\n        var values = [];\r\n        that.each(newKeys, function(pair) {\r\n          var value = pair.value;\r\n          if (typeof pair.value.join !== \"undefined\") {\r\n            value = pair.value.join(\";\");\r\n          }\r\n          values.push(value);\r\n        });\r\n        var murmur = that.x64hash128(values.join(\"~~~\"), 31);\r\n        return done(murmur, newKeys);\r\n      });\r\n    },\r\n    userAgentKey: function(keys) {\r\n      if(!this.options.excludeUserAgent) {\r\n        keys.push({key: \"user_agent\", value: this.getUserAgent()});\r\n      }\r\n      return keys;\r\n    },\r\n    // for tests\r\n    getUserAgent: function(){\r\n      return navigator.userAgent;\r\n    },\r\n    languageKey: function(keys) {\r\n      if(!this.options.excludeLanguage) {\r\n        // IE 9,10 on Windows 10 does not have the `navigator.language` property any longer\r\n        keys.push({ key: \"language\", value: navigator.language || navigator.userLanguage || navigator.browserLanguage || navigator.systemLanguage || \"\" });\r\n      }\r\n      return keys;\r\n    },\r\n    colorDepthKey: function(keys) {\r\n      if(!this.options.excludeColorDepth) {\r\n        keys.push({key: \"color_depth\", value: screen.colorDepth || -1});\r\n      }\r\n      return keys;\r\n    },\r\n    pixelRatioKey: function(keys) {\r\n      if(!this.options.excludePixelRatio) {\r\n        keys.push({key: \"pixel_ratio\", value: this.getPixelRatio()});\r\n      }\r\n      return keys;\r\n    },\r\n    getPixelRatio: function() {\r\n      return window.devicePixelRatio || \"\";\r\n    },\r\n    screenResolutionKey: function(keys) {\r\n      if(!this.options.excludeScreenResolution) {\r\n        return this.getScreenResolution(keys);\r\n      }\r\n      return keys;\r\n    },\r\n    getScreenResolution: function(keys) {\r\n      var resolution;\r\n      if(this.options.detectScreenOrientation) {\r\n        resolution = (screen.height > screen.width) ? [screen.height, screen.width] : [screen.width, screen.height];\r\n      } else {\r\n        resolution = [screen.width, screen.height];\r\n      }\r\n      if(typeof resolution !== \"undefined\") { // headless browsers\r\n        keys.push({key: \"resolution\", value: resolution});\r\n      }\r\n      return keys;\r\n    },\r\n    availableScreenResolutionKey: function(keys) {\r\n      if (!this.options.excludeAvailableScreenResolution) {\r\n        return this.getAvailableScreenResolution(keys);\r\n      }\r\n      return keys;\r\n    },\r\n    getAvailableScreenResolution: function(keys) {\r\n      var available;\r\n      if(screen.availWidth && screen.availHeight) {\r\n        if(this.options.detectScreenOrientation) {\r\n          available = (screen.availHeight > screen.availWidth) ? [screen.availHeight, screen.availWidth] : [screen.availWidth, screen.availHeight];\r\n        } else {\r\n          available = [screen.availHeight, screen.availWidth];\r\n        }\r\n      }\r\n      if(typeof available !== \"undefined\") { // headless browsers\r\n        keys.push({key: \"available_resolution\", value: available});\r\n      }\r\n      return keys;\r\n    },\r\n    timezoneOffsetKey: function(keys) {\r\n      if(!this.options.excludeTimezoneOffset) {\r\n        keys.push({key: \"timezone_offset\", value: new Date().getTimezoneOffset()});\r\n      }\r\n      return keys;\r\n    },\r\n    sessionStorageKey: function(keys) {\r\n      if(!this.options.excludeSessionStorage && this.hasSessionStorage()) {\r\n        keys.push({key: \"session_storage\", value: 1});\r\n      }\r\n      return keys;\r\n    },\r\n    localStorageKey: function(keys) {\r\n      if(!this.options.excludeSessionStorage && this.hasLocalStorage()) {\r\n        keys.push({key: \"local_storage\", value: 1});\r\n      }\r\n      return keys;\r\n    },\r\n    indexedDbKey: function(keys) {\r\n      if(!this.options.excludeIndexedDB && this.hasIndexedDB()) {\r\n        keys.push({key: \"indexed_db\", value: 1});\r\n      }\r\n      return keys;\r\n    },\r\n    addBehaviorKey: function(keys) {\r\n      //body might not be defined at this point or removed programmatically\r\n      if(document.body && !this.options.excludeAddBehavior && document.body.addBehavior) {\r\n        keys.push({key: \"add_behavior\", value: 1});\r\n      }\r\n      return keys;\r\n    },\r\n    openDatabaseKey: function(keys) {\r\n      if(!this.options.excludeOpenDatabase && window.openDatabase) {\r\n        keys.push({key: \"open_database\", value: 1});\r\n      }\r\n      return keys;\r\n    },\r\n    cpuClassKey: function(keys) {\r\n      if(!this.options.excludeCpuClass) {\r\n        keys.push({key: \"cpu_class\", value: this.getNavigatorCpuClass()});\r\n      }\r\n      return keys;\r\n    },\r\n    platformKey: function(keys) {\r\n      if(!this.options.excludePlatform) {\r\n        keys.push({key: \"navigator_platform\", value: this.getNavigatorPlatform()});\r\n      }\r\n      return keys;\r\n    },\r\n    doNotTrackKey: function(keys) {\r\n      if(!this.options.excludeDoNotTrack) {\r\n        keys.push({key: \"do_not_track\", value: this.getDoNotTrack()});\r\n      }\r\n      return keys;\r\n    },\r\n    canvasKey: function(keys) {\r\n      if(!this.options.excludeCanvas && this.isCanvasSupported()) {\r\n        keys.push({key: \"canvas\", value: this.getCanvasFp()});\r\n      }\r\n      return keys;\r\n    },\r\n    webglKey: function(keys) {\r\n      if(this.options.excludeWebGL) {\r\n        if(typeof NODEBUG === \"undefined\"){\r\n          this.log(\"Skipping WebGL fingerprinting per excludeWebGL configuration option\");\r\n        }\r\n        return keys;\r\n      }\r\n      if(!this.isWebGlSupported()) {\r\n        if(typeof NODEBUG === \"undefined\"){\r\n          this.log(\"Skipping WebGL fingerprinting because it is not supported in this browser\");\r\n        }\r\n        return keys;\r\n      }\r\n      keys.push({key: \"webgl\", value: this.getWebglFp()});\r\n      return keys;\r\n    },\r\n    adBlockKey: function(keys){\r\n      if(!this.options.excludeAdBlock) {\r\n        keys.push({key: \"adblock\", value: this.getAdBlock()});\r\n      }\r\n      return keys;\r\n    },\r\n    hasLiedLanguagesKey: function(keys){\r\n      if(!this.options.excludeHasLiedLanguages){\r\n        keys.push({key: \"has_lied_languages\", value: this.getHasLiedLanguages()});\r\n      }\r\n      return keys;\r\n    },\r\n    hasLiedResolutionKey: function(keys){\r\n      if(!this.options.excludeHasLiedResolution){\r\n        keys.push({key: \"has_lied_resolution\", value: this.getHasLiedResolution()});\r\n      }\r\n      return keys;\r\n    },\r\n    hasLiedOsKey: function(keys){\r\n      if(!this.options.excludeHasLiedOs){\r\n        keys.push({key: \"has_lied_os\", value: this.getHasLiedOs()});\r\n      }\r\n      return keys;\r\n    },\r\n    hasLiedBrowserKey: function(keys){\r\n      if(!this.options.excludeHasLiedBrowser){\r\n        keys.push({key: \"has_lied_browser\", value: this.getHasLiedBrowser()});\r\n      }\r\n      return keys;\r\n    },\r\n    fontsKey: function(keys, done) {\r\n      if (this.options.excludeJsFonts) {\r\n        return this.flashFontsKey(keys, done);\r\n      }\r\n      return this.jsFontsKey(keys, done);\r\n    },\r\n    // flash fonts (will increase fingerprinting time 20X to ~ 130-150ms)\r\n    flashFontsKey: function(keys, done) {\r\n      if(this.options.excludeFlashFonts) {\r\n        if(typeof NODEBUG === \"undefined\"){\r\n          this.log(\"Skipping flash fonts detection per excludeFlashFonts configuration option\");\r\n        }\r\n        return done(keys);\r\n      }\r\n      // we do flash if swfobject is loaded\r\n      if(!this.hasSwfObjectLoaded()){\r\n        if(typeof NODEBUG === \"undefined\"){\r\n          this.log(\"Swfobject is not detected, Flash fonts enumeration is skipped\");\r\n        }\r\n        return done(keys);\r\n      }\r\n      if(!this.hasMinFlashInstalled()){\r\n        if(typeof NODEBUG === \"undefined\"){\r\n          this.log(\"Flash is not installed, skipping Flash fonts enumeration\");\r\n        }\r\n        return done(keys);\r\n      }\r\n      if(typeof this.options.swfPath === \"undefined\"){\r\n        if(typeof NODEBUG === \"undefined\"){\r\n          this.log(\"To use Flash fonts detection, you must pass a valid swfPath option, skipping Flash fonts enumeration\");\r\n        }\r\n        return done(keys);\r\n      }\r\n      this.loadSwfAndDetectFonts(function(fonts){\r\n        keys.push({key: \"swf_fonts\", value: fonts.join(\";\")});\r\n        done(keys);\r\n      });\r\n    },\r\n    // kudos to http://www.lalit.org/lab/javascript-css-font-detect/\r\n    jsFontsKey: function(keys, done) {\r\n      var that = this;\r\n      // doing js fonts detection in a pseudo-async fashion\r\n      return setTimeout(function(){\r\n\r\n        // a font will be compared against all the three default fonts.\r\n        // and if it doesn't match all 3 then that font is not available.\r\n        var baseFonts = [\"monospace\", \"sans-serif\", \"serif\"];\r\n\r\n        var fontList = [\r\n                        \"Andale Mono\", \"Arial\", \"Arial Black\", \"Arial Hebrew\", \"Arial MT\", \"Arial Narrow\", \"Arial Rounded MT Bold\", \"Arial Unicode MS\",\r\n                        \"Bitstream Vera Sans Mono\", \"Book Antiqua\", \"Bookman Old Style\",\r\n                        \"Calibri\", \"Cambria\", \"Cambria Math\", \"Century\", \"Century Gothic\", \"Century Schoolbook\", \"Comic Sans\", \"Comic Sans MS\", \"Consolas\", \"Courier\", \"Courier New\",\r\n                        \"Garamond\", \"Geneva\", \"Georgia\",\r\n                        \"Helvetica\", \"Helvetica Neue\",\r\n                        \"Impact\",\r\n                        \"Lucida Bright\", \"Lucida Calligraphy\", \"Lucida Console\", \"Lucida Fax\", \"LUCIDA GRANDE\", \"Lucida Handwriting\", \"Lucida Sans\", \"Lucida Sans Typewriter\", \"Lucida Sans Unicode\",\r\n                        \"Microsoft Sans Serif\", \"Monaco\", \"Monotype Corsiva\", \"MS Gothic\", \"MS Outlook\", \"MS PGothic\", \"MS Reference Sans Serif\", \"MS Sans Serif\", \"MS Serif\", \"MYRIAD\", \"MYRIAD PRO\",\r\n                        \"Palatino\", \"Palatino Linotype\",\r\n                        \"Segoe Print\", \"Segoe Script\", \"Segoe UI\", \"Segoe UI Light\", \"Segoe UI Semibold\", \"Segoe UI Symbol\",\r\n                        \"Tahoma\", \"Times\", \"Times New Roman\", \"Times New Roman PS\", \"Trebuchet MS\",\r\n                        \"Verdana\", \"Wingdings\", \"Wingdings 2\", \"Wingdings 3\"\r\n                      ];\r\n        var extendedFontList = [\r\n                        \"Abadi MT Condensed Light\", \"Academy Engraved LET\", \"ADOBE CASLON PRO\", \"Adobe Garamond\", \"ADOBE GARAMOND PRO\", \"Agency FB\", \"Aharoni\", \"Albertus Extra Bold\", \"Albertus Medium\", \"Algerian\", \"Amazone BT\", \"American Typewriter\",\r\n                        \"American Typewriter Condensed\", \"AmerType Md BT\", \"Andalus\", \"Angsana New\", \"AngsanaUPC\", \"Antique Olive\", \"Aparajita\", \"Apple Chancery\", \"Apple Color Emoji\", \"Apple SD Gothic Neo\", \"Arabic Typesetting\", \"ARCHER\",\r\n                         \"ARNO PRO\", \"Arrus BT\", \"Aurora Cn BT\", \"AvantGarde Bk BT\", \"AvantGarde Md BT\", \"AVENIR\", \"Ayuthaya\", \"Bandy\", \"Bangla Sangam MN\", \"Bank Gothic\", \"BankGothic Md BT\", \"Baskerville\",\r\n                        \"Baskerville Old Face\", \"Batang\", \"BatangChe\", \"Bauer Bodoni\", \"Bauhaus 93\", \"Bazooka\", \"Bell MT\", \"Bembo\", \"Benguiat Bk BT\", \"Berlin Sans FB\", \"Berlin Sans FB Demi\", \"Bernard MT Condensed\", \"BernhardFashion BT\", \"BernhardMod BT\", \"Big Caslon\", \"BinnerD\",\r\n                        \"Blackadder ITC\", \"BlairMdITC TT\", \"Bodoni 72\", \"Bodoni 72 Oldstyle\", \"Bodoni 72 Smallcaps\", \"Bodoni MT\", \"Bodoni MT Black\", \"Bodoni MT Condensed\", \"Bodoni MT Poster Compressed\",\r\n                        \"Bookshelf Symbol 7\", \"Boulder\", \"Bradley Hand\", \"Bradley Hand ITC\", \"Bremen Bd BT\", \"Britannic Bold\", \"Broadway\", \"Browallia New\", \"BrowalliaUPC\", \"Brush Script MT\", \"Californian FB\", \"Calisto MT\", \"Calligrapher\", \"Candara\",\r\n                        \"CaslonOpnface BT\", \"Castellar\", \"Centaur\", \"Cezanne\", \"CG Omega\", \"CG Times\", \"Chalkboard\", \"Chalkboard SE\", \"Chalkduster\", \"Charlesworth\", \"Charter Bd BT\", \"Charter BT\", \"Chaucer\",\r\n                        \"ChelthmITC Bk BT\", \"Chiller\", \"Clarendon\", \"Clarendon Condensed\", \"CloisterBlack BT\", \"Cochin\", \"Colonna MT\", \"Constantia\", \"Cooper Black\", \"Copperplate\", \"Copperplate Gothic\", \"Copperplate Gothic Bold\",\r\n                        \"Copperplate Gothic Light\", \"CopperplGoth Bd BT\", \"Corbel\", \"Cordia New\", \"CordiaUPC\", \"Cornerstone\", \"Coronet\", \"Cuckoo\", \"Curlz MT\", \"DaunPenh\", \"Dauphin\", \"David\", \"DB LCD Temp\", \"DELICIOUS\", \"Denmark\",\r\n                        \"DFKai-SB\", \"Didot\", \"DilleniaUPC\", \"DIN\", \"DokChampa\", \"Dotum\", \"DotumChe\", \"Ebrima\", \"Edwardian Script ITC\", \"Elephant\", \"English 111 Vivace BT\", \"Engravers MT\", \"EngraversGothic BT\", \"Eras Bold ITC\", \"Eras Demi ITC\", \"Eras Light ITC\", \"Eras Medium ITC\",\r\n                        \"EucrosiaUPC\", \"Euphemia\", \"Euphemia UCAS\", \"EUROSTILE\", \"Exotc350 Bd BT\", \"FangSong\", \"Felix Titling\", \"Fixedsys\", \"FONTIN\", \"Footlight MT Light\", \"Forte\",\r\n                        \"FrankRuehl\", \"Fransiscan\", \"Freefrm721 Blk BT\", \"FreesiaUPC\", \"Freestyle Script\", \"French Script MT\", \"FrnkGothITC Bk BT\", \"Fruitger\", \"FRUTIGER\",\r\n                        \"Futura\", \"Futura Bk BT\", \"Futura Lt BT\", \"Futura Md BT\", \"Futura ZBlk BT\", \"FuturaBlack BT\", \"Gabriola\", \"Galliard BT\", \"Gautami\", \"Geeza Pro\", \"Geometr231 BT\", \"Geometr231 Hv BT\", \"Geometr231 Lt BT\", \"GeoSlab 703 Lt BT\",\r\n                        \"GeoSlab 703 XBd BT\", \"Gigi\", \"Gill Sans\", \"Gill Sans MT\", \"Gill Sans MT Condensed\", \"Gill Sans MT Ext Condensed Bold\", \"Gill Sans Ultra Bold\", \"Gill Sans Ultra Bold Condensed\", \"Gisha\", \"Gloucester MT Extra Condensed\", \"GOTHAM\", \"GOTHAM BOLD\",\r\n                        \"Goudy Old Style\", \"Goudy Stout\", \"GoudyHandtooled BT\", \"GoudyOLSt BT\", \"Gujarati Sangam MN\", \"Gulim\", \"GulimChe\", \"Gungsuh\", \"GungsuhChe\", \"Gurmukhi MN\", \"Haettenschweiler\", \"Harlow Solid Italic\", \"Harrington\", \"Heather\", \"Heiti SC\", \"Heiti TC\", \"HELV\",\r\n                        \"Herald\", \"High Tower Text\", \"Hiragino Kaku Gothic ProN\", \"Hiragino Mincho ProN\", \"Hoefler Text\", \"Humanst 521 Cn BT\", \"Humanst521 BT\", \"Humanst521 Lt BT\", \"Imprint MT Shadow\", \"Incised901 Bd BT\", \"Incised901 BT\",\r\n                        \"Incised901 Lt BT\", \"INCONSOLATA\", \"Informal Roman\", \"Informal011 BT\", \"INTERSTATE\", \"IrisUPC\", \"Iskoola Pota\", \"JasmineUPC\", \"Jazz LET\", \"Jenson\", \"Jester\", \"Jokerman\", \"Juice ITC\", \"Kabel Bk BT\", \"Kabel Ult BT\", \"Kailasa\", \"KaiTi\", \"Kalinga\", \"Kannada Sangam MN\",\r\n                        \"Kartika\", \"Kaufmann Bd BT\", \"Kaufmann BT\", \"Khmer UI\", \"KodchiangUPC\", \"Kokila\", \"Korinna BT\", \"Kristen ITC\", \"Krungthep\", \"Kunstler Script\", \"Lao UI\", \"Latha\", \"Leelawadee\", \"Letter Gothic\", \"Levenim MT\", \"LilyUPC\", \"Lithograph\", \"Lithograph Light\", \"Long Island\",\r\n                        \"Lydian BT\", \"Magneto\", \"Maiandra GD\", \"Malayalam Sangam MN\", \"Malgun Gothic\",\r\n                        \"Mangal\", \"Marigold\", \"Marion\", \"Marker Felt\", \"Market\", \"Marlett\", \"Matisse ITC\", \"Matura MT Script Capitals\", \"Meiryo\", \"Meiryo UI\", \"Microsoft Himalaya\", \"Microsoft JhengHei\", \"Microsoft New Tai Lue\", \"Microsoft PhagsPa\", \"Microsoft Tai Le\",\r\n                        \"Microsoft Uighur\", \"Microsoft YaHei\", \"Microsoft Yi Baiti\", \"MingLiU\", \"MingLiU_HKSCS\", \"MingLiU_HKSCS-ExtB\", \"MingLiU-ExtB\", \"Minion\", \"Minion Pro\", \"Miriam\", \"Miriam Fixed\", \"Mistral\", \"Modern\", \"Modern No. 20\", \"Mona Lisa Solid ITC TT\", \"Mongolian Baiti\",\r\n                        \"MONO\", \"MoolBoran\", \"Mrs Eaves\", \"MS LineDraw\", \"MS Mincho\", \"MS PMincho\", \"MS Reference Specialty\", \"MS UI Gothic\", \"MT Extra\", \"MUSEO\", \"MV Boli\",\r\n                        \"Nadeem\", \"Narkisim\", \"NEVIS\", \"News Gothic\", \"News GothicMT\", \"NewsGoth BT\", \"Niagara Engraved\", \"Niagara Solid\", \"Noteworthy\", \"NSimSun\", \"Nyala\", \"OCR A Extended\", \"Old Century\", \"Old English Text MT\", \"Onyx\", \"Onyx BT\", \"OPTIMA\", \"Oriya Sangam MN\",\r\n                        \"OSAKA\", \"OzHandicraft BT\", \"Palace Script MT\", \"Papyrus\", \"Parchment\", \"Party LET\", \"Pegasus\", \"Perpetua\", \"Perpetua Titling MT\", \"PetitaBold\", \"Pickwick\", \"Plantagenet Cherokee\", \"Playbill\", \"PMingLiU\", \"PMingLiU-ExtB\",\r\n                        \"Poor Richard\", \"Poster\", \"PosterBodoni BT\", \"PRINCETOWN LET\", \"Pristina\", \"PTBarnum BT\", \"Pythagoras\", \"Raavi\", \"Rage Italic\", \"Ravie\", \"Ribbon131 Bd BT\", \"Rockwell\", \"Rockwell Condensed\", \"Rockwell Extra Bold\", \"Rod\", \"Roman\", \"Sakkal Majalla\",\r\n                        \"Santa Fe LET\", \"Savoye LET\", \"Sceptre\", \"Script\", \"Script MT Bold\", \"SCRIPTINA\", \"Serifa\", \"Serifa BT\", \"Serifa Th BT\", \"ShelleyVolante BT\", \"Sherwood\",\r\n                        \"Shonar Bangla\", \"Showcard Gothic\", \"Shruti\", \"Signboard\", \"SILKSCREEN\", \"SimHei\", \"Simplified Arabic\", \"Simplified Arabic Fixed\", \"SimSun\", \"SimSun-ExtB\", \"Sinhala Sangam MN\", \"Sketch Rockwell\", \"Skia\", \"Small Fonts\", \"Snap ITC\", \"Snell Roundhand\", \"Socket\",\r\n                        \"Souvenir Lt BT\", \"Staccato222 BT\", \"Steamer\", \"Stencil\", \"Storybook\", \"Styllo\", \"Subway\", \"Swis721 BlkEx BT\", \"Swiss911 XCm BT\", \"Sylfaen\", \"Synchro LET\", \"System\", \"Tamil Sangam MN\", \"Technical\", \"Teletype\", \"Telugu Sangam MN\", \"Tempus Sans ITC\",\r\n                        \"Terminal\", \"Thonburi\", \"Traditional Arabic\", \"Trajan\", \"TRAJAN PRO\", \"Tristan\", \"Tubular\", \"Tunga\", \"Tw Cen MT\", \"Tw Cen MT Condensed\", \"Tw Cen MT Condensed Extra Bold\",\r\n                        \"TypoUpright BT\", \"Unicorn\", \"Univers\", \"Univers CE 55 Medium\", \"Univers Condensed\", \"Utsaah\", \"Vagabond\", \"Vani\", \"Vijaya\", \"Viner Hand ITC\", \"VisualUI\", \"Vivaldi\", \"Vladimir Script\", \"Vrinda\", \"Westminster\", \"WHITNEY\", \"Wide Latin\",\r\n                        \"ZapfEllipt BT\", \"ZapfHumnst BT\", \"ZapfHumnst Dm BT\", \"Zapfino\", \"Zurich BlkEx BT\", \"Zurich Ex BT\", \"ZWAdobeF\"];\r\n\r\n        if(that.options.extendedJsFonts) {\r\n            fontList = fontList.concat(extendedFontList);\r\n        }\r\n\r\n        fontList = fontList.concat(that.options.userDefinedFonts);\r\n\r\n        //we use m or w because these two characters take up the maximum width.\r\n        // And we use a LLi so that the same matching fonts can get separated\r\n        var testString = \"mmmmmmmmmmlli\";\r\n\r\n        //we test using 72px font size, we may use any size. I guess larger the better.\r\n        var testSize = \"72px\";\r\n\r\n        var h = document.getElementsByTagName(\"body\")[0];\r\n\r\n        // div to load spans for the base fonts\r\n        var baseFontsDiv = document.createElement(\"div\");\r\n\r\n        // div to load spans for the fonts to detect\r\n        var fontsDiv = document.createElement(\"div\");\r\n\r\n        var defaultWidth = {};\r\n        var defaultHeight = {};\r\n\r\n        // creates a span where the fonts will be loaded\r\n        var createSpan = function() {\r\n            var s = document.createElement(\"span\");\r\n            /*\r\n             * We need this css as in some weird browser this\r\n             * span elements shows up for a microSec which creates a\r\n             * bad user experience\r\n             */\r\n            s.style.position = \"absolute\";\r\n            s.style.left = \"-9999px\";\r\n            s.style.fontSize = testSize;\r\n            s.style.lineHeight = \"normal\";\r\n            s.innerHTML = testString;\r\n            return s;\r\n        };\r\n\r\n        // creates a span and load the font to detect and a base font for fallback\r\n        var createSpanWithFonts = function(fontToDetect, baseFont) {\r\n            var s = createSpan();\r\n            s.style.fontFamily = \"'\" + fontToDetect + \"',\" + baseFont;\r\n            return s;\r\n        };\r\n\r\n        // creates spans for the base fonts and adds them to baseFontsDiv\r\n        var initializeBaseFontsSpans = function() {\r\n            var spans = [];\r\n            for (var index = 0, length = baseFonts.length; index < length; index++) {\r\n                var s = createSpan();\r\n                s.style.fontFamily = baseFonts[index];\r\n                baseFontsDiv.appendChild(s);\r\n                spans.push(s);\r\n            }\r\n            return spans;\r\n        };\r\n\r\n        // creates spans for the fonts to detect and adds them to fontsDiv\r\n        var initializeFontsSpans = function() {\r\n            var spans = {};\r\n            for(var i = 0, l = fontList.length; i < l; i++) {\r\n                var fontSpans = [];\r\n                for(var j = 0, numDefaultFonts = baseFonts.length; j < numDefaultFonts; j++) {\r\n                    var s = createSpanWithFonts(fontList[i], baseFonts[j]);\r\n                    fontsDiv.appendChild(s);\r\n                    fontSpans.push(s);\r\n                }\r\n                spans[fontList[i]] = fontSpans; // Stores {fontName : [spans for that font]}\r\n            }\r\n            return spans;\r\n        };\r\n\r\n        // checks if a font is available\r\n        var isFontAvailable = function(fontSpans) {\r\n            var detected = false;\r\n            for(var i = 0; i < baseFonts.length; i++) {\r\n                detected = (fontSpans[i].offsetWidth !== defaultWidth[baseFonts[i]] || fontSpans[i].offsetHeight !== defaultHeight[baseFonts[i]]);\r\n                if(detected) {\r\n                    return detected;\r\n                }\r\n            }\r\n            return detected;\r\n        };\r\n\r\n        // create spans for base fonts\r\n        var baseFontsSpans = initializeBaseFontsSpans();\r\n\r\n        // add the spans to the DOM\r\n        h.appendChild(baseFontsDiv);\r\n\r\n        // get the default width for the three base fonts\r\n        for (var index = 0, length = baseFonts.length; index < length; index++) {\r\n            defaultWidth[baseFonts[index]] = baseFontsSpans[index].offsetWidth; // width for the default font\r\n            defaultHeight[baseFonts[index]] = baseFontsSpans[index].offsetHeight; // height for the default font\r\n        }\r\n\r\n        // create spans for fonts to detect\r\n        var fontsSpans = initializeFontsSpans();\r\n\r\n        // add all the spans to the DOM\r\n        h.appendChild(fontsDiv);\r\n\r\n        // check available fonts\r\n        var available = [];\r\n        for(var i = 0, l = fontList.length; i < l; i++) {\r\n            if(isFontAvailable(fontsSpans[fontList[i]])) {\r\n                available.push(fontList[i]);\r\n            }\r\n        }\r\n\r\n        // remove spans from DOM\r\n        h.removeChild(fontsDiv);\r\n        h.removeChild(baseFontsDiv);\r\n\r\n        keys.push({key: \"js_fonts\", value: available});\r\n        done(keys);\r\n      }, 1);\r\n    },\r\n    pluginsKey: function(keys) {\r\n      if(!this.options.excludePlugins){\r\n        if(this.isIE()){\r\n          if(!this.options.excludeIEPlugins) {\r\n            keys.push({key: \"ie_plugins\", value: this.getIEPlugins()});\r\n          }\r\n        } else {\r\n          keys.push({key: \"regular_plugins\", value: this.getRegularPlugins()});\r\n        }\r\n      }\r\n      return keys;\r\n    },\r\n    getRegularPlugins: function () {\r\n      var plugins = [];\r\n      for(var i = 0, l = navigator.plugins.length; i < l; i++) {\r\n        plugins.push(navigator.plugins[i]);\r\n      }\r\n      // sorting plugins only for those user agents, that we know randomize the plugins\r\n      // every time we try to enumerate them\r\n      if(this.pluginsShouldBeSorted()) {\r\n        plugins = plugins.sort(function(a, b) {\r\n          if(a.name > b.name){ return 1; }\r\n          if(a.name < b.name){ return -1; }\r\n          return 0;\r\n        });\r\n      }\r\n      return this.map(plugins, function (p) {\r\n        var mimeTypes = this.map(p, function(mt){\r\n          return [mt.type, mt.suffixes].join(\"~\");\r\n        }).join(\",\");\r\n        return [p.name, p.description, mimeTypes].join(\"::\");\r\n      }, this);\r\n    },\r\n    getIEPlugins: function () {\r\n      var result = [];\r\n      if((Object.getOwnPropertyDescriptor && Object.getOwnPropertyDescriptor(window, \"ActiveXObject\")) || (\"ActiveXObject\" in window)) {\r\n        var names = [\r\n          \"AcroPDF.PDF\", // Adobe PDF reader 7+\r\n          \"Adodb.Stream\",\r\n          \"AgControl.AgControl\", // Silverlight\r\n          \"DevalVRXCtrl.DevalVRXCtrl.1\",\r\n          \"MacromediaFlashPaper.MacromediaFlashPaper\",\r\n          \"Msxml2.DOMDocument\",\r\n          \"Msxml2.XMLHTTP\",\r\n          \"PDF.PdfCtrl\", // Adobe PDF reader 6 and earlier, brrr\r\n          \"QuickTime.QuickTime\", // QuickTime\r\n          \"QuickTimeCheckObject.QuickTimeCheck.1\",\r\n          \"RealPlayer\",\r\n          \"RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)\",\r\n          \"RealVideo.RealVideo(tm) ActiveX Control (32-bit)\",\r\n          \"Scripting.Dictionary\",\r\n          \"SWCtl.SWCtl\", // ShockWave player\r\n          \"Shell.UIHelper\",\r\n          \"ShockwaveFlash.ShockwaveFlash\", //flash plugin\r\n          \"Skype.Detection\",\r\n          \"TDCCtl.TDCCtl\",\r\n          \"WMPlayer.OCX\", // Windows media player\r\n          \"rmocx.RealPlayer G2 Control\",\r\n          \"rmocx.RealPlayer G2 Control.1\"\r\n        ];\r\n        // starting to detect plugins in IE\r\n        result = this.map(names, function(name) {\r\n          try {\r\n            new ActiveXObject(name); // eslint-disable-no-new\r\n            return name;\r\n          } catch(e) {\r\n            return null;\r\n          }\r\n        });\r\n      }\r\n      if(navigator.plugins) {\r\n        result = result.concat(this.getRegularPlugins());\r\n      }\r\n      return result;\r\n    },\r\n    pluginsShouldBeSorted: function () {\r\n      var should = false;\r\n      for(var i = 0, l = this.options.sortPluginsFor.length; i < l; i++) {\r\n        var re = this.options.sortPluginsFor[i];\r\n        if(navigator.userAgent.match(re)) {\r\n          should = true;\r\n          break;\r\n        }\r\n      }\r\n      return should;\r\n    },\r\n    touchSupportKey: function (keys) {\r\n      if(!this.options.excludeTouchSupport){\r\n        keys.push({key: \"touch_support\", value: this.getTouchSupport()});\r\n      }\r\n      return keys;\r\n    },\r\n    hasSessionStorage: function () {\r\n      try {\r\n        return !!window.sessionStorage;\r\n      } catch(e) {\r\n        return true; // SecurityError when referencing it means it exists\r\n      }\r\n    },\r\n    // https://bugzilla.mozilla.org/show_bug.cgi?id=781447\r\n    hasLocalStorage: function () {\r\n      try {\r\n        return !!window.localStorage;\r\n      } catch(e) {\r\n        return true; // SecurityError when referencing it means it exists\r\n      }\r\n    },\r\n    hasIndexedDB: function (){\r\n      return !!window.indexedDB;\r\n    },\r\n    getNavigatorCpuClass: function () {\r\n      if(navigator.cpuClass){\r\n        return navigator.cpuClass;\r\n      } else {\r\n        return \"unknown\";\r\n      }\r\n    },\r\n    getNavigatorPlatform: function () {\r\n      if(navigator.platform) {\r\n        return navigator.platform;\r\n      } else {\r\n        return \"unknown\";\r\n      }\r\n    },\r\n    getDoNotTrack: function () {\r\n      if(navigator.doNotTrack) {\r\n        return navigator.doNotTrack;\r\n      } else if (navigator.msDoNotTrack) {\r\n        return navigator.msDoNotTrack;\r\n      } else if (window.doNotTrack) {\r\n        return window.doNotTrack;\r\n      } else {\r\n        return \"unknown\";\r\n      }\r\n    },\r\n    // This is a crude and primitive touch screen detection.\r\n    // It's not possible to currently reliably detect the  availability of a touch screen\r\n    // with a JS, without actually subscribing to a touch event.\r\n    // http://www.stucox.com/blog/you-cant-detect-a-touchscreen/\r\n    // https://github.com/Modernizr/Modernizr/issues/548\r\n    // method returns an array of 3 values:\r\n    // maxTouchPoints, the success or failure of creating a TouchEvent,\r\n    // and the availability of the 'ontouchstart' property\r\n    getTouchSupport: function () {\r\n      var maxTouchPoints = 0;\r\n      var touchEvent = false;\r\n      if(typeof navigator.maxTouchPoints !== \"undefined\") {\r\n        maxTouchPoints = navigator.maxTouchPoints;\r\n      } else if (typeof navigator.msMaxTouchPoints !== \"undefined\") {\r\n        maxTouchPoints = navigator.msMaxTouchPoints;\r\n      }\r\n      try {\r\n        document.createEvent(\"TouchEvent\");\r\n        touchEvent = true;\r\n      } catch(_) { /* squelch */ }\r\n      var touchStart = \"ontouchstart\" in window;\r\n      return [maxTouchPoints, touchEvent, touchStart];\r\n    },\r\n    // https://www.browserleaks.com/canvas#how-does-it-work\r\n    getCanvasFp: function() {\r\n      var result = [];\r\n      // Very simple now, need to make it more complex (geo shapes etc)\r\n      var canvas = document.createElement(\"canvas\");\r\n      canvas.width = 2000;\r\n      canvas.height = 200;\r\n      canvas.style.display = \"inline\";\r\n      var ctx = canvas.getContext(\"2d\");\r\n      // detect browser support of canvas winding\r\n      // http://blogs.adobe.com/webplatform/2013/01/30/winding-rules-in-canvas/\r\n      // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/canvas/winding.js\r\n      ctx.rect(0, 0, 10, 10);\r\n      ctx.rect(2, 2, 6, 6);\r\n      result.push(\"canvas winding:\" + ((ctx.isPointInPath(5, 5, \"evenodd\") === false) ? \"yes\" : \"no\"));\r\n\r\n      ctx.textBaseline = \"alphabetic\";\r\n      ctx.fillStyle = \"#f60\";\r\n      ctx.fillRect(125, 1, 62, 20);\r\n      ctx.fillStyle = \"#069\";\r\n      // https://github.com/Valve/fingerprintjs2/issues/66\r\n      if(this.options.dontUseFakeFontInCanvas) {\r\n        ctx.font = \"11pt Arial\";\r\n      } else {\r\n        ctx.font = \"11pt no-real-font-123\";\r\n      }\r\n      ctx.fillText(\"Cwm fjordbank glyphs vext quiz, \\ud83d\\ude03\", 2, 15);\r\n      ctx.fillStyle = \"rgba(102, 204, 0, 0.2)\";\r\n      ctx.font = \"18pt Arial\";\r\n      ctx.fillText(\"Cwm fjordbank glyphs vext quiz, \\ud83d\\ude03\", 4, 45);\r\n\r\n      // canvas blending\r\n      // http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\r\n      // http://jsfiddle.net/NDYV8/16/\r\n      ctx.globalCompositeOperation = \"multiply\";\r\n      ctx.fillStyle = \"rgb(255,0,255)\";\r\n      ctx.beginPath();\r\n      ctx.arc(50, 50, 50, 0, Math.PI * 2, true);\r\n      ctx.closePath();\r\n      ctx.fill();\r\n      ctx.fillStyle = \"rgb(0,255,255)\";\r\n      ctx.beginPath();\r\n      ctx.arc(100, 50, 50, 0, Math.PI * 2, true);\r\n      ctx.closePath();\r\n      ctx.fill();\r\n      ctx.fillStyle = \"rgb(255,255,0)\";\r\n      ctx.beginPath();\r\n      ctx.arc(75, 100, 50, 0, Math.PI * 2, true);\r\n      ctx.closePath();\r\n      ctx.fill();\r\n      ctx.fillStyle = \"rgb(255,0,255)\";\r\n      // canvas winding\r\n      // http://blogs.adobe.com/webplatform/2013/01/30/winding-rules-in-canvas/\r\n      // http://jsfiddle.net/NDYV8/19/\r\n      ctx.arc(75, 75, 75, 0, Math.PI * 2, true);\r\n      ctx.arc(75, 75, 25, 0, Math.PI * 2, true);\r\n      ctx.fill(\"evenodd\");\r\n\r\n      result.push(\"canvas fp:\" + canvas.toDataURL());\r\n      return result.join(\"~\");\r\n    },\r\n\r\n    getWebglFp: function() {\r\n      var gl;\r\n      var fa2s = function(fa) {\r\n        gl.clearColor(0.0, 0.0, 0.0, 1.0);\r\n        gl.enable(gl.DEPTH_TEST);\r\n        gl.depthFunc(gl.LEQUAL);\r\n        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\r\n        return \"[\" + fa[0] + \", \" + fa[1] + \"]\";\r\n      };\r\n      var maxAnisotropy = function(gl) {\r\n        var anisotropy, ext = gl.getExtension(\"EXT_texture_filter_anisotropic\") || gl.getExtension(\"WEBKIT_EXT_texture_filter_anisotropic\") || gl.getExtension(\"MOZ_EXT_texture_filter_anisotropic\");\r\n        return ext ? (anisotropy = gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT), 0 === anisotropy && (anisotropy = 2), anisotropy) : null;\r\n      };\r\n      gl = this.getWebglCanvas();\r\n      if(!gl) { return null; }\r\n      // WebGL fingerprinting is a combination of techniques, found in MaxMind antifraud script & Augur fingerprinting.\r\n      // First it draws a gradient object with shaders and convers the image to the Base64 string.\r\n      // Then it enumerates all WebGL extensions & capabilities and appends them to the Base64 string, resulting in a huge WebGL string, potentially very unique on each device\r\n      // Since iOS supports webgl starting from version 8.1 and 8.1 runs on several graphics chips, the results may be different across ios devices, but we need to verify it.\r\n      var result = [];\r\n      var vShaderTemplate = \"attribute vec2 attrVertex;varying vec2 varyinTexCoordinate;uniform vec2 uniformOffset;void main(){varyinTexCoordinate=attrVertex+uniformOffset;gl_Position=vec4(attrVertex,0,1);}\";\r\n      var fShaderTemplate = \"precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}\";\r\n      var vertexPosBuffer = gl.createBuffer();\r\n      gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer);\r\n      var vertices = new Float32Array([-.2, -.9, 0, .4, -.26, 0, 0, .732134444, 0]);\r\n      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\r\n      vertexPosBuffer.itemSize = 3;\r\n      vertexPosBuffer.numItems = 3;\r\n      var program = gl.createProgram(), vshader = gl.createShader(gl.VERTEX_SHADER);\r\n      gl.shaderSource(vshader, vShaderTemplate);\r\n      gl.compileShader(vshader);\r\n      var fshader = gl.createShader(gl.FRAGMENT_SHADER);\r\n      gl.shaderSource(fshader, fShaderTemplate);\r\n      gl.compileShader(fshader);\r\n      gl.attachShader(program, vshader);\r\n      gl.attachShader(program, fshader);\r\n      gl.linkProgram(program);\r\n      gl.useProgram(program);\r\n      program.vertexPosAttrib = gl.getAttribLocation(program, \"attrVertex\");\r\n      program.offsetUniform = gl.getUniformLocation(program, \"uniformOffset\");\r\n      gl.enableVertexAttribArray(program.vertexPosArray);\r\n      gl.vertexAttribPointer(program.vertexPosAttrib, vertexPosBuffer.itemSize, gl.FLOAT, !1, 0, 0);\r\n      gl.uniform2f(program.offsetUniform, 1, 1);\r\n      gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertexPosBuffer.numItems);\r\n      if (gl.canvas != null) { result.push(gl.canvas.toDataURL()); }\r\n      result.push(\"extensions:\" + gl.getSupportedExtensions().join(\";\"));\r\n      result.push(\"webgl aliased line width range:\" + fa2s(gl.getParameter(gl.ALIASED_LINE_WIDTH_RANGE)));\r\n      result.push(\"webgl aliased point size range:\" + fa2s(gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE)));\r\n      result.push(\"webgl alpha bits:\" + gl.getParameter(gl.ALPHA_BITS));\r\n      result.push(\"webgl antialiasing:\" + (gl.getContextAttributes().antialias ? \"yes\" : \"no\"));\r\n      result.push(\"webgl blue bits:\" + gl.getParameter(gl.BLUE_BITS));\r\n      result.push(\"webgl depth bits:\" + gl.getParameter(gl.DEPTH_BITS));\r\n      result.push(\"webgl green bits:\" + gl.getParameter(gl.GREEN_BITS));\r\n      result.push(\"webgl max anisotropy:\" + maxAnisotropy(gl));\r\n      result.push(\"webgl max combined texture image units:\" + gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS));\r\n      result.push(\"webgl max cube map texture size:\" + gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE));\r\n      result.push(\"webgl max fragment uniform vectors:\" + gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS));\r\n      result.push(\"webgl max render buffer size:\" + gl.getParameter(gl.MAX_RENDERBUFFER_SIZE));\r\n      result.push(\"webgl max texture image units:\" + gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS));\r\n      result.push(\"webgl max texture size:\" + gl.getParameter(gl.MAX_TEXTURE_SIZE));\r\n      result.push(\"webgl max varying vectors:\" + gl.getParameter(gl.MAX_VARYING_VECTORS));\r\n      result.push(\"webgl max vertex attribs:\" + gl.getParameter(gl.MAX_VERTEX_ATTRIBS));\r\n      result.push(\"webgl max vertex texture image units:\" + gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS));\r\n      result.push(\"webgl max vertex uniform vectors:\" + gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS));\r\n      result.push(\"webgl max viewport dims:\" + fa2s(gl.getParameter(gl.MAX_VIEWPORT_DIMS)));\r\n      result.push(\"webgl red bits:\" + gl.getParameter(gl.RED_BITS));\r\n      result.push(\"webgl renderer:\" + gl.getParameter(gl.RENDERER));\r\n      result.push(\"webgl shading language version:\" + gl.getParameter(gl.SHADING_LANGUAGE_VERSION));\r\n      result.push(\"webgl stencil bits:\" + gl.getParameter(gl.STENCIL_BITS));\r\n      result.push(\"webgl vendor:\" + gl.getParameter(gl.VENDOR));\r\n      result.push(\"webgl version:\" + gl.getParameter(gl.VERSION));\r\n\r\n      if (!gl.getShaderPrecisionFormat) {\r\n        if (typeof NODEBUG === \"undefined\") {\r\n          this.log(\"WebGL fingerprinting is incomplete, because your browser does not support getShaderPrecisionFormat\");\r\n        }\r\n        return result.join(\"~\");\r\n      }\r\n\r\n      result.push(\"webgl vertex shader high float precision:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision);\r\n      result.push(\"webgl vertex shader high float precision rangeMin:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT ).rangeMin);\r\n      result.push(\"webgl vertex shader high float precision rangeMax:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT ).rangeMax);\r\n      result.push(\"webgl vertex shader medium float precision:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision);\r\n      result.push(\"webgl vertex shader medium float precision rangeMin:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).rangeMin);\r\n      result.push(\"webgl vertex shader medium float precision rangeMax:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).rangeMax);\r\n      result.push(\"webgl vertex shader low float precision:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.LOW_FLOAT ).precision);\r\n      result.push(\"webgl vertex shader low float precision rangeMin:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.LOW_FLOAT ).rangeMin);\r\n      result.push(\"webgl vertex shader low float precision rangeMax:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.LOW_FLOAT ).rangeMax);\r\n      result.push(\"webgl fragment shader high float precision:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision);\r\n      result.push(\"webgl fragment shader high float precision rangeMin:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).rangeMin);\r\n      result.push(\"webgl fragment shader high float precision rangeMax:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).rangeMax);\r\n      result.push(\"webgl fragment shader medium float precision:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision);\r\n      result.push(\"webgl fragment shader medium float precision rangeMin:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).rangeMin);\r\n      result.push(\"webgl fragment shader medium float precision rangeMax:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).rangeMax);\r\n      result.push(\"webgl fragment shader low float precision:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_FLOAT ).precision);\r\n      result.push(\"webgl fragment shader low float precision rangeMin:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_FLOAT ).rangeMin);\r\n      result.push(\"webgl fragment shader low float precision rangeMax:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_FLOAT ).rangeMax);\r\n      result.push(\"webgl vertex shader high int precision:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_INT ).precision);\r\n      result.push(\"webgl vertex shader high int precision rangeMin:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_INT ).rangeMin);\r\n      result.push(\"webgl vertex shader high int precision rangeMax:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_INT ).rangeMax);\r\n      result.push(\"webgl vertex shader medium int precision:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_INT ).precision);\r\n      result.push(\"webgl vertex shader medium int precision rangeMin:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_INT ).rangeMin);\r\n      result.push(\"webgl vertex shader medium int precision rangeMax:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_INT ).rangeMax);\r\n      result.push(\"webgl vertex shader low int precision:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.LOW_INT ).precision);\r\n      result.push(\"webgl vertex shader low int precision rangeMin:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.LOW_INT ).rangeMin);\r\n      result.push(\"webgl vertex shader low int precision rangeMax:\" + gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.LOW_INT ).rangeMax);\r\n      result.push(\"webgl fragment shader high int precision:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_INT ).precision);\r\n      result.push(\"webgl fragment shader high int precision rangeMin:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_INT ).rangeMin);\r\n      result.push(\"webgl fragment shader high int precision rangeMax:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_INT ).rangeMax);\r\n      result.push(\"webgl fragment shader medium int precision:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_INT ).precision);\r\n      result.push(\"webgl fragment shader medium int precision rangeMin:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_INT ).rangeMin);\r\n      result.push(\"webgl fragment shader medium int precision rangeMax:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_INT ).rangeMax);\r\n      result.push(\"webgl fragment shader low int precision:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_INT ).precision);\r\n      result.push(\"webgl fragment shader low int precision rangeMin:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_INT ).rangeMin);\r\n      result.push(\"webgl fragment shader low int precision rangeMax:\" + gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_INT ).rangeMax);\r\n      return result.join(\"~\");\r\n    },\r\n    getAdBlock: function(){\r\n      var ads = document.createElement(\"div\");\r\n      ads.innerHTML = \"&nbsp;\";\r\n      ads.className = \"adsbox\";\r\n      var result = false;\r\n      try {\r\n        // body may not exist, that's why we need try/catch\r\n        document.body.appendChild(ads);\r\n        result = document.getElementsByClassName(\"adsbox\")[0].offsetHeight === 0;\r\n        document.body.removeChild(ads);\r\n      } catch (e) {\r\n        result = false;\r\n      }\r\n      return result;\r\n    },\r\n    getHasLiedLanguages: function(){\r\n      //We check if navigator.language is equal to the first language of navigator.languages\r\n      if(typeof navigator.languages !== \"undefined\"){\r\n        try {\r\n          var firstLanguages = navigator.languages[0].substr(0, 2);\r\n          if(firstLanguages !== navigator.language.substr(0, 2)){\r\n            return true;\r\n          }\r\n        } catch(err) {\r\n          return true;\r\n        }\r\n      }\r\n      return false;\r\n    },\r\n    getHasLiedResolution: function(){\r\n      if(screen.width < screen.availWidth){\r\n        return true;\r\n      }\r\n      if(screen.height < screen.availHeight){\r\n        return true;\r\n      }\r\n      return false;\r\n    },\r\n    getHasLiedOs: function(){\r\n      var userAgent = navigator.userAgent.toLowerCase();\r\n      var oscpu = navigator.oscpu;\r\n      var platform = navigator.platform.toLowerCase();\r\n      var os;\r\n      //We extract the OS from the user agent (respect the order of the if else if statement)\r\n      if(userAgent.indexOf(\"windows phone\") >= 0){\r\n        os = \"Windows Phone\";\r\n      } else if(userAgent.indexOf(\"win\") >= 0){\r\n        os = \"Windows\";\r\n      } else if(userAgent.indexOf(\"android\") >= 0){\r\n        os = \"Android\";\r\n      } else if(userAgent.indexOf(\"linux\") >= 0){\r\n        os = \"Linux\";\r\n      } else if(userAgent.indexOf(\"iphone\") >= 0 || userAgent.indexOf(\"ipad\") >= 0 ){\r\n        os = \"iOS\";\r\n      } else if(userAgent.indexOf(\"mac\") >= 0){\r\n        os = \"Mac\";\r\n      } else{\r\n        os = \"Other\";\r\n      }\r\n      // We detect if the person uses a mobile device\r\n      var mobileDevice;\r\n      if ((\"ontouchstart\" in window) ||\r\n           (navigator.maxTouchPoints > 0) ||\r\n           (navigator.msMaxTouchPoints > 0)) {\r\n            mobileDevice = true;\r\n      } else{\r\n        mobileDevice = false;\r\n      }\r\n\r\n      if(mobileDevice && os !== \"Windows Phone\" && os !== \"Android\" && os !== \"iOS\" && os !== \"Other\"){\r\n        return true;\r\n      }\r\n\r\n      // We compare oscpu with the OS extracted from the UA\r\n      if(typeof oscpu !== \"undefined\"){\r\n        oscpu = oscpu.toLowerCase();\r\n        if(oscpu.indexOf(\"win\") >= 0 && os !== \"Windows\" && os !== \"Windows Phone\"){\r\n          return true;\r\n        } else if(oscpu.indexOf(\"linux\") >= 0 && os !== \"Linux\" && os !== \"Android\"){\r\n          return true;\r\n        } else if(oscpu.indexOf(\"mac\") >= 0 && os !== \"Mac\" && os !== \"iOS\"){\r\n          return true;\r\n        } else if(oscpu.indexOf(\"win\") === 0 && oscpu.indexOf(\"linux\") === 0 && oscpu.indexOf(\"mac\") >= 0 && os !== \"other\"){\r\n          return true;\r\n        }\r\n      }\r\n\r\n      //We compare platform with the OS extracted from the UA\r\n      if(platform.indexOf(\"win\") >= 0 && os !== \"Windows\" && os !== \"Windows Phone\"){\r\n        return true;\r\n      } else if((platform.indexOf(\"linux\") >= 0 || platform.indexOf(\"android\") >= 0 || platform.indexOf(\"pike\") >= 0) && os !== \"Linux\" && os !== \"Android\"){\r\n        return true;\r\n      } else if((platform.indexOf(\"mac\") >= 0 || platform.indexOf(\"ipad\") >= 0 || platform.indexOf(\"ipod\") >= 0 || platform.indexOf(\"iphone\") >= 0) && os !== \"Mac\" && os !== \"iOS\"){\r\n        return true;\r\n      } else if(platform.indexOf(\"win\") === 0 && platform.indexOf(\"linux\") === 0 && platform.indexOf(\"mac\") >= 0 && os !== \"other\"){\r\n        return true;\r\n      }\r\n\r\n      if(typeof navigator.plugins === \"undefined\" && os !== \"Windows\" && os !== \"Windows Phone\"){\r\n        //We are are in the case where the person uses ie, therefore we can infer that it's windows\r\n        return true;\r\n      }\r\n\r\n      return false;\r\n    },\r\n    getHasLiedBrowser: function () {\r\n      var userAgent = navigator.userAgent.toLowerCase();\r\n      var productSub = navigator.productSub;\r\n\r\n      //we extract the browser from the user agent (respect the order of the tests)\r\n      var browser;\r\n      if(userAgent.indexOf(\"firefox\") >= 0){\r\n        browser = \"Firefox\";\r\n      } else if(userAgent.indexOf(\"opera\") >= 0 || userAgent.indexOf(\"opr\") >= 0){\r\n        browser = \"Opera\";\r\n      } else if(userAgent.indexOf(\"chrome\") >= 0){\r\n        browser = \"Chrome\";\r\n      } else if(userAgent.indexOf(\"safari\") >= 0){\r\n        browser = \"Safari\";\r\n      } else if(userAgent.indexOf(\"trident\") >= 0){\r\n        browser = \"Internet Explorer\";\r\n      } else{\r\n        browser = \"Other\";\r\n      }\r\n\r\n      if((browser === \"Chrome\" || browser === \"Safari\" || browser === \"Opera\") && productSub !== \"20030107\"){\r\n        return true;\r\n      }\r\n\r\n      var tempRes = eval.toString().length;\r\n      if(tempRes === 37 && browser !== \"Safari\" && browser !== \"Firefox\" && browser !== \"Other\"){\r\n        return true;\r\n      } else if(tempRes === 39 && browser !== \"Internet Explorer\" && browser !== \"Other\"){\r\n        return true;\r\n      } else if(tempRes === 33 && browser !== \"Chrome\" && browser !== \"Opera\" && browser !== \"Other\"){\r\n        return true;\r\n      }\r\n\r\n      //We create an error to see how it is handled\r\n      var errFirefox;\r\n      try {\r\n        throw \"a\";\r\n      } catch(err){\r\n        try{\r\n          err.toSource();\r\n          errFirefox = true;\r\n        } catch(errOfErr){\r\n          errFirefox = false;\r\n        }\r\n      }\r\n      if(errFirefox && browser !== \"Firefox\" && browser !== \"Other\"){\r\n        return true;\r\n      }\r\n      return false;\r\n    },\r\n    isCanvasSupported: function () {\r\n      var elem = document.createElement(\"canvas\");\r\n      return !!(elem.getContext && elem.getContext(\"2d\"));\r\n    },\r\n    isWebGlSupported: function() {\r\n      // code taken from Modernizr\r\n      if (!this.isCanvasSupported()) {\r\n        return false;\r\n      }\r\n\r\n      var canvas = document.createElement(\"canvas\"),\r\n          glContext;\r\n\r\n      try {\r\n        glContext = canvas.getContext && (canvas.getContext(\"webgl\") || canvas.getContext(\"experimental-webgl\"));\r\n      } catch(e) {\r\n        glContext = false;\r\n      }\r\n\r\n      return !!window.WebGLRenderingContext && !!glContext;\r\n    },\r\n    isIE: function () {\r\n      if(navigator.appName === \"Microsoft Internet Explorer\") {\r\n        return true;\r\n      } else if(navigator.appName === \"Netscape\" && /Trident/.test(navigator.userAgent)) { // IE 11\r\n        return true;\r\n      }\r\n      return false;\r\n    },\r\n    hasSwfObjectLoaded: function(){\r\n      return typeof window.swfobject !== \"undefined\";\r\n    },\r\n    hasMinFlashInstalled: function () {\r\n      return swfobject.hasFlashPlayerVersion(\"9.0.0\");\r\n    },\r\n    addFlashDivNode: function() {\r\n      var node = document.createElement(\"div\");\r\n      node.setAttribute(\"id\", this.options.swfContainerId);\r\n      document.body.appendChild(node);\r\n    },\r\n    loadSwfAndDetectFonts: function(done) {\r\n      var hiddenCallback = \"___fp_swf_loaded\";\r\n      window[hiddenCallback] = function(fonts) {\r\n        done(fonts);\r\n      };\r\n      var id = this.options.swfContainerId;\r\n      this.addFlashDivNode();\r\n      var flashvars = { onReady: hiddenCallback};\r\n      var flashparams = { allowScriptAccess: \"always\", menu: \"false\" };\r\n      swfobject.embedSWF(this.options.swfPath, id, \"1\", \"1\", \"9.0.0\", false, flashvars, flashparams, {});\r\n    },\r\n    getWebglCanvas: function() {\r\n      var canvas = document.createElement(\"canvas\");\r\n      var gl = null;\r\n      try {\r\n        gl = canvas.getContext(\"webgl\") || canvas.getContext(\"experimental-webgl\");\r\n      } catch(e) { /* squelch */ }\r\n      if (!gl) { gl = null; }\r\n      return gl;\r\n    },\r\n    each: function (obj, iterator, context) {\r\n      if (obj === null) {\r\n        return;\r\n      }\r\n      if (this.nativeForEach && obj.forEach === this.nativeForEach) {\r\n        obj.forEach(iterator, context);\r\n      } else if (obj.length === +obj.length) {\r\n        for (var i = 0, l = obj.length; i < l; i++) {\r\n          if (iterator.call(context, obj[i], i, obj) === {}) { return; }\r\n        }\r\n      } else {\r\n        for (var key in obj) {\r\n          if (obj.hasOwnProperty(key)) {\r\n            if (iterator.call(context, obj[key], key, obj) === {}) { return; }\r\n          }\r\n        }\r\n      }\r\n    },\r\n\r\n    map: function(obj, iterator, context) {\r\n      var results = [];\r\n      // Not using strict equality so that this acts as a\r\n      // shortcut to checking for `null` and `undefined`.\r\n      if (obj == null) { return results; }\r\n      if (this.nativeMap && obj.map === this.nativeMap) { return obj.map(iterator, context); }\r\n      this.each(obj, function(value, index, list) {\r\n        results[results.length] = iterator.call(context, value, index, list);\r\n      });\r\n      return results;\r\n    },\r\n\r\n    /// MurmurHash3 related functions\r\n\r\n    //\r\n    // Given two 64bit ints (as an array of two 32bit ints) returns the two\r\n    // added together as a 64bit int (as an array of two 32bit ints).\r\n    //\r\n    x64Add: function(m, n) {\r\n      m = [m[0] >>> 16, m[0] & 0xffff, m[1] >>> 16, m[1] & 0xffff];\r\n      n = [n[0] >>> 16, n[0] & 0xffff, n[1] >>> 16, n[1] & 0xffff];\r\n      var o = [0, 0, 0, 0];\r\n      o[3] += m[3] + n[3];\r\n      o[2] += o[3] >>> 16;\r\n      o[3] &= 0xffff;\r\n      o[2] += m[2] + n[2];\r\n      o[1] += o[2] >>> 16;\r\n      o[2] &= 0xffff;\r\n      o[1] += m[1] + n[1];\r\n      o[0] += o[1] >>> 16;\r\n      o[1] &= 0xffff;\r\n      o[0] += m[0] + n[0];\r\n      o[0] &= 0xffff;\r\n      return [(o[0] << 16) | o[1], (o[2] << 16) | o[3]];\r\n    },\r\n\r\n    //\r\n    // Given two 64bit ints (as an array of two 32bit ints) returns the two\r\n    // multiplied together as a 64bit int (as an array of two 32bit ints).\r\n    //\r\n    x64Multiply: function(m, n) {\r\n      m = [m[0] >>> 16, m[0] & 0xffff, m[1] >>> 16, m[1] & 0xffff];\r\n      n = [n[0] >>> 16, n[0] & 0xffff, n[1] >>> 16, n[1] & 0xffff];\r\n      var o = [0, 0, 0, 0];\r\n      o[3] += m[3] * n[3];\r\n      o[2] += o[3] >>> 16;\r\n      o[3] &= 0xffff;\r\n      o[2] += m[2] * n[3];\r\n      o[1] += o[2] >>> 16;\r\n      o[2] &= 0xffff;\r\n      o[2] += m[3] * n[2];\r\n      o[1] += o[2] >>> 16;\r\n      o[2] &= 0xffff;\r\n      o[1] += m[1] * n[3];\r\n      o[0] += o[1] >>> 16;\r\n      o[1] &= 0xffff;\r\n      o[1] += m[2] * n[2];\r\n      o[0] += o[1] >>> 16;\r\n      o[1] &= 0xffff;\r\n      o[1] += m[3] * n[1];\r\n      o[0] += o[1] >>> 16;\r\n      o[1] &= 0xffff;\r\n      o[0] += (m[0] * n[3]) + (m[1] * n[2]) + (m[2] * n[1]) + (m[3] * n[0]);\r\n      o[0] &= 0xffff;\r\n      return [(o[0] << 16) | o[1], (o[2] << 16) | o[3]];\r\n    },\r\n    //\r\n    // Given a 64bit int (as an array of two 32bit ints) and an int\r\n    // representing a number of bit positions, returns the 64bit int (as an\r\n    // array of two 32bit ints) rotated left by that number of positions.\r\n    //\r\n    x64Rotl: function(m, n) {\r\n      n %= 64;\r\n      if (n === 32) {\r\n        return [m[1], m[0]];\r\n      }\r\n      else if (n < 32) {\r\n        return [(m[0] << n) | (m[1] >>> (32 - n)), (m[1] << n) | (m[0] >>> (32 - n))];\r\n      }\r\n      else {\r\n        n -= 32;\r\n        return [(m[1] << n) | (m[0] >>> (32 - n)), (m[0] << n) | (m[1] >>> (32 - n))];\r\n      }\r\n    },\r\n    //\r\n    // Given a 64bit int (as an array of two 32bit ints) and an int\r\n    // representing a number of bit positions, returns the 64bit int (as an\r\n    // array of two 32bit ints) shifted left by that number of positions.\r\n    //\r\n    x64LeftShift: function(m, n) {\r\n      n %= 64;\r\n      if (n === 0) {\r\n        return m;\r\n      }\r\n      else if (n < 32) {\r\n        return [(m[0] << n) | (m[1] >>> (32 - n)), m[1] << n];\r\n      }\r\n      else {\r\n        return [m[1] << (n - 32), 0];\r\n      }\r\n    },\r\n    //\r\n    // Given two 64bit ints (as an array of two 32bit ints) returns the two\r\n    // xored together as a 64bit int (as an array of two 32bit ints).\r\n    //\r\n    x64Xor: function(m, n) {\r\n      return [m[0] ^ n[0], m[1] ^ n[1]];\r\n    },\r\n    //\r\n    // Given a block, returns murmurHash3's final x64 mix of that block.\r\n    // (`[0, h[0] >>> 1]` is a 33 bit unsigned right shift. This is the\r\n    // only place where we need to right shift 64bit ints.)\r\n    //\r\n    x64Fmix: function(h) {\r\n      h = this.x64Xor(h, [0, h[0] >>> 1]);\r\n      h = this.x64Multiply(h, [0xff51afd7, 0xed558ccd]);\r\n      h = this.x64Xor(h, [0, h[0] >>> 1]);\r\n      h = this.x64Multiply(h, [0xc4ceb9fe, 0x1a85ec53]);\r\n      h = this.x64Xor(h, [0, h[0] >>> 1]);\r\n      return h;\r\n    },\r\n\r\n    //\r\n    // Given a string and an optional seed as an int, returns a 128 bit\r\n    // hash using the x64 flavor of MurmurHash3, as an unsigned hex.\r\n    //\r\n    x64hash128: function (key, seed) {\r\n      key = key || \"\";\r\n      seed = seed || 0;\r\n      var remainder = key.length % 16;\r\n      var bytes = key.length - remainder;\r\n      var h1 = [0, seed];\r\n      var h2 = [0, seed];\r\n      var k1 = [0, 0];\r\n      var k2 = [0, 0];\r\n      var c1 = [0x87c37b91, 0x114253d5];\r\n      var c2 = [0x4cf5ad43, 0x2745937f];\r\n      for (var i = 0; i < bytes; i = i + 16) {\r\n        k1 = [((key.charCodeAt(i + 4) & 0xff)) | ((key.charCodeAt(i + 5) & 0xff) << 8) | ((key.charCodeAt(i + 6) & 0xff) << 16) | ((key.charCodeAt(i + 7) & 0xff) << 24), ((key.charCodeAt(i) & 0xff)) | ((key.charCodeAt(i + 1) & 0xff) << 8) | ((key.charCodeAt(i + 2) & 0xff) << 16) | ((key.charCodeAt(i + 3) & 0xff) << 24)];\r\n        k2 = [((key.charCodeAt(i + 12) & 0xff)) | ((key.charCodeAt(i + 13) & 0xff) << 8) | ((key.charCodeAt(i + 14) & 0xff) << 16) | ((key.charCodeAt(i + 15) & 0xff) << 24), ((key.charCodeAt(i + 8) & 0xff)) | ((key.charCodeAt(i + 9) & 0xff) << 8) | ((key.charCodeAt(i + 10) & 0xff) << 16) | ((key.charCodeAt(i + 11) & 0xff) << 24)];\r\n        k1 = this.x64Multiply(k1, c1);\r\n        k1 = this.x64Rotl(k1, 31);\r\n        k1 = this.x64Multiply(k1, c2);\r\n        h1 = this.x64Xor(h1, k1);\r\n        h1 = this.x64Rotl(h1, 27);\r\n        h1 = this.x64Add(h1, h2);\r\n        h1 = this.x64Add(this.x64Multiply(h1, [0, 5]), [0, 0x52dce729]);\r\n        k2 = this.x64Multiply(k2, c2);\r\n        k2 = this.x64Rotl(k2, 33);\r\n        k2 = this.x64Multiply(k2, c1);\r\n        h2 = this.x64Xor(h2, k2);\r\n        h2 = this.x64Rotl(h2, 31);\r\n        h2 = this.x64Add(h2, h1);\r\n        h2 = this.x64Add(this.x64Multiply(h2, [0, 5]), [0, 0x38495ab5]);\r\n      }\r\n      k1 = [0, 0];\r\n      k2 = [0, 0];\r\n      switch(remainder) {\r\n        case 15:\r\n          k2 = this.x64Xor(k2, this.x64LeftShift([0, key.charCodeAt(i + 14)], 48));\r\n        case 14:\r\n          k2 = this.x64Xor(k2, this.x64LeftShift([0, key.charCodeAt(i + 13)], 40));\r\n        case 13:\r\n          k2 = this.x64Xor(k2, this.x64LeftShift([0, key.charCodeAt(i + 12)], 32));\r\n        case 12:\r\n          k2 = this.x64Xor(k2, this.x64LeftShift([0, key.charCodeAt(i + 11)], 24));\r\n        case 11:\r\n          k2 = this.x64Xor(k2, this.x64LeftShift([0, key.charCodeAt(i + 10)], 16));\r\n        case 10:\r\n          k2 = this.x64Xor(k2, this.x64LeftShift([0, key.charCodeAt(i + 9)], 8));\r\n        case 9:\r\n          k2 = this.x64Xor(k2, [0, key.charCodeAt(i + 8)]);\r\n          k2 = this.x64Multiply(k2, c2);\r\n          k2 = this.x64Rotl(k2, 33);\r\n          k2 = this.x64Multiply(k2, c1);\r\n          h2 = this.x64Xor(h2, k2);\r\n        case 8:\r\n          k1 = this.x64Xor(k1, this.x64LeftShift([0, key.charCodeAt(i + 7)], 56));\r\n        case 7:\r\n          k1 = this.x64Xor(k1, this.x64LeftShift([0, key.charCodeAt(i + 6)], 48));\r\n        case 6:\r\n          k1 = this.x64Xor(k1, this.x64LeftShift([0, key.charCodeAt(i + 5)], 40));\r\n        case 5:\r\n          k1 = this.x64Xor(k1, this.x64LeftShift([0, key.charCodeAt(i + 4)], 32));\r\n        case 4:\r\n          k1 = this.x64Xor(k1, this.x64LeftShift([0, key.charCodeAt(i + 3)], 24));\r\n        case 3:\r\n          k1 = this.x64Xor(k1, this.x64LeftShift([0, key.charCodeAt(i + 2)], 16));\r\n        case 2:\r\n          k1 = this.x64Xor(k1, this.x64LeftShift([0, key.charCodeAt(i + 1)], 8));\r\n        case 1:\r\n          k1 = this.x64Xor(k1, [0, key.charCodeAt(i)]);\r\n          k1 = this.x64Multiply(k1, c1);\r\n          k1 = this.x64Rotl(k1, 31);\r\n          k1 = this.x64Multiply(k1, c2);\r\n          h1 = this.x64Xor(h1, k1);\r\n      }\r\n      h1 = this.x64Xor(h1, [0, key.length]);\r\n      h2 = this.x64Xor(h2, [0, key.length]);\r\n      h1 = this.x64Add(h1, h2);\r\n      h2 = this.x64Add(h2, h1);\r\n      h1 = this.x64Fmix(h1);\r\n      h2 = this.x64Fmix(h2);\r\n      h1 = this.x64Add(h1, h2);\r\n      h2 = this.x64Add(h2, h1);\r\n      return (\"00000000\" + (h1[0] >>> 0).toString(16)).slice(-8) + (\"00000000\" + (h1[1] >>> 0).toString(16)).slice(-8) + (\"00000000\" + (h2[0] >>> 0).toString(16)).slice(-8) + (\"00000000\" + (h2[1] >>> 0).toString(16)).slice(-8);\r\n    }\r\n  };\r\n  Fingerprint2.VERSION = \"1.4.2\";\r\n  return Fingerprint2;\r\n});\r\n"
  },
  {
    "path": "JavaScript/demo/js/jsbn.js",
    "content": "/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\n// Copyright (c) 2005  Tom Wu\n// All Rights Reserved.\n// See \"LICENSE\" for details.\n\n// Basic JavaScript BN library - subset useful for RSA encryption.\n\n// Bits per digit\nvar dbits;\n\n// JavaScript engine analysis\nvar canary = 0xdeadbeefcafe;\nvar j_lm = ((canary&0xffffff)==0xefcafe);\n\n// (public) Constructor\nfunction BigInteger(a,b,c) {\n  if(a != null)\n    if(\"number\" == typeof a) this.fromNumber(a,b,c);\n    else if(b == null && \"string\" != typeof a) this.fromString(a,256);\n    else this.fromString(a,b);\n}\n\n// return new, unset BigInteger\nfunction nbi() { return new BigInteger(null); }\n\n// am: Compute w_j += (x*this_i), propagate carries,\n// c is initial carry, returns final carry.\n// c < 3*dvalue, x < 2*dvalue, this_i < dvalue\n// We need to select the fastest one that works in this environment.\n\n// am1: use a single mult and divide to get the high bits,\n// max digit bits should be 26 because\n// max internal value = 2*dvalue^2-2*dvalue (< 2^53)\nfunction am1(i,x,w,j,c,n) {\n  while(--n >= 0) {\n    var v = x*this[i++]+w[j]+c;\n    c = Math.floor(v/0x4000000);\n    w[j++] = v&0x3ffffff;\n  }\n  return c;\n}\n// am2 avoids a big mult-and-extract completely.\n// Max digit bits should be <= 30 because we do bitwise ops\n// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)\nfunction am2(i,x,w,j,c,n) {\n  var xl = x&0x7fff, xh = x>>15;\n  while(--n >= 0) {\n    var l = this[i]&0x7fff;\n    var h = this[i++]>>15;\n    var m = xh*l+h*xl;\n    l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);\n    c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);\n    w[j++] = l&0x3fffffff;\n  }\n  return c;\n}\n// Alternately, set max digit bits to 28 since some\n// browsers slow down when dealing with 32-bit numbers.\nfunction am3(i,x,w,j,c,n) {\n  var xl = x&0x3fff, xh = x>>14;\n  while(--n >= 0) {\n    var l = this[i]&0x3fff;\n    var h = this[i++]>>14;\n    var m = xh*l+h*xl;\n    l = xl*l+((m&0x3fff)<<14)+w[j]+c;\n    c = (l>>28)+(m>>14)+xh*h;\n    w[j++] = l&0xfffffff;\n  }\n  return c;\n}\nif(j_lm && (navigator.appName == \"Microsoft Internet Explorer\")) {\n  BigInteger.prototype.am = am2;\n  dbits = 30;\n}\nelse if(j_lm && (navigator.appName != \"Netscape\")) {\n  BigInteger.prototype.am = am1;\n  dbits = 26;\n}\nelse { // Mozilla/Netscape seems to prefer am3\n  BigInteger.prototype.am = am3;\n  dbits = 28;\n}\n\nBigInteger.prototype.DB = dbits;\nBigInteger.prototype.DM = ((1<<dbits)-1);\nBigInteger.prototype.DV = (1<<dbits);\n\nvar BI_FP = 52;\nBigInteger.prototype.FV = Math.pow(2,BI_FP);\nBigInteger.prototype.F1 = BI_FP-dbits;\nBigInteger.prototype.F2 = 2*dbits-BI_FP;\n\n// Digit conversions\nvar BI_RM = \"0123456789abcdefghijklmnopqrstuvwxyz\";\nvar BI_RC = new Array();\nvar rr,vv;\nrr = \"0\".charCodeAt(0);\nfor(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;\nrr = \"a\".charCodeAt(0);\nfor(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;\nrr = \"A\".charCodeAt(0);\nfor(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;\n\nfunction int2char(n) { return BI_RM.charAt(n); }\nfunction intAt(s,i) {\n  var c = BI_RC[s.charCodeAt(i)];\n  return (c==null)?-1:c;\n}\n\n// (protected) copy this to r\nfunction bnpCopyTo(r) {\n  for(var i = this.t-1; i >= 0; --i) r[i] = this[i];\n  r.t = this.t;\n  r.s = this.s;\n}\n\n// (protected) set from integer value x, -DV <= x < DV\nfunction bnpFromInt(x) {\n  this.t = 1;\n  this.s = (x<0)?-1:0;\n  if(x > 0) this[0] = x;\n  else if(x < -1) this[0] = x+this.DV;\n  else this.t = 0;\n}\n\n// return bigint initialized to value\nfunction nbv(i) { var r = nbi(); r.fromInt(i); return r; }\n\n// (protected) set from string and radix\nfunction bnpFromString(s,b) {\n  var k;\n  if(b == 16) k = 4;\n  else if(b == 8) k = 3;\n  else if(b == 256) k = 8; // byte array\n  else if(b == 2) k = 1;\n  else if(b == 32) k = 5;\n  else if(b == 4) k = 2;\n  else { this.fromRadix(s,b); return; }\n  this.t = 0;\n  this.s = 0;\n  var i = s.length, mi = false, sh = 0;\n  while(--i >= 0) {\n    var x = (k==8)?s[i]&0xff:intAt(s,i);\n    if(x < 0) {\n      if(s.charAt(i) == \"-\") mi = true;\n      continue;\n    }\n    mi = false;\n    if(sh == 0)\n      this[this.t++] = x;\n    else if(sh+k > this.DB) {\n      this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;\n      this[this.t++] = (x>>(this.DB-sh));\n    }\n    else\n      this[this.t-1] |= x<<sh;\n    sh += k;\n    if(sh >= this.DB) sh -= this.DB;\n  }\n  if(k == 8 && (s[0]&0x80) != 0) {\n    this.s = -1;\n    if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;\n  }\n  this.clamp();\n  if(mi) BigInteger.ZERO.subTo(this,this);\n}\n\n// (protected) clamp off excess high words\nfunction bnpClamp() {\n  var c = this.s&this.DM;\n  while(this.t > 0 && this[this.t-1] == c) --this.t;\n}\n\n// (public) return string representation in given radix\nfunction bnToString(b) {\n  if(this.s < 0) return \"-\"+this.negate().toString(b);\n  var k;\n  if(b == 16) k = 4;\n  else if(b == 8) k = 3;\n  else if(b == 2) k = 1;\n  else if(b == 32) k = 5;\n  else if(b == 4) k = 2;\n  else return this.toRadix(b);\n  var km = (1<<k)-1, d, m = false, r = \"\", i = this.t;\n  var p = this.DB-(i*this.DB)%k;\n  if(i-- > 0) {\n    if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }\n    while(i >= 0) {\n      if(p < k) {\n        d = (this[i]&((1<<p)-1))<<(k-p);\n        d |= this[--i]>>(p+=this.DB-k);\n      }\n      else {\n        d = (this[i]>>(p-=k))&km;\n        if(p <= 0) { p += this.DB; --i; }\n      }\n      if(d > 0) m = true;\n      if(m) r += int2char(d);\n    }\n  }\n  return m?r:\"0\";\n}\n\n// (public) -this\nfunction bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }\n\n// (public) |this|\nfunction bnAbs() { return (this.s<0)?this.negate():this; }\n\n// (public) return + if this > a, - if this < a, 0 if equal\nfunction bnCompareTo(a) {\n  var r = this.s-a.s;\n  if(r != 0) return r;\n  var i = this.t;\n  r = i-a.t;\n  if(r != 0) return (this.s<0)?-r:r;\n  while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;\n  return 0;\n}\n\n// returns bit length of the integer x\nfunction nbits(x) {\n  var r = 1, t;\n  if((t=x>>>16) != 0) { x = t; r += 16; }\n  if((t=x>>8) != 0) { x = t; r += 8; }\n  if((t=x>>4) != 0) { x = t; r += 4; }\n  if((t=x>>2) != 0) { x = t; r += 2; }\n  if((t=x>>1) != 0) { x = t; r += 1; }\n  return r;\n}\n\n// (public) return the number of bits in \"this\"\nfunction bnBitLength() {\n  if(this.t <= 0) return 0;\n  return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));\n}\n\n// (protected) r = this << n*DB\nfunction bnpDLShiftTo(n,r) {\n  var i;\n  for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];\n  for(i = n-1; i >= 0; --i) r[i] = 0;\n  r.t = this.t+n;\n  r.s = this.s;\n}\n\n// (protected) r = this >> n*DB\nfunction bnpDRShiftTo(n,r) {\n  for(var i = n; i < this.t; ++i) r[i-n] = this[i];\n  r.t = Math.max(this.t-n,0);\n  r.s = this.s;\n}\n\n// (protected) r = this << n\nfunction bnpLShiftTo(n,r) {\n  var bs = n%this.DB;\n  var cbs = this.DB-bs;\n  var bm = (1<<cbs)-1;\n  var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;\n  for(i = this.t-1; i >= 0; --i) {\n    r[i+ds+1] = (this[i]>>cbs)|c;\n    c = (this[i]&bm)<<bs;\n  }\n  for(i = ds-1; i >= 0; --i) r[i] = 0;\n  r[ds] = c;\n  r.t = this.t+ds+1;\n  r.s = this.s;\n  r.clamp();\n}\n\n// (protected) r = this >> n\nfunction bnpRShiftTo(n,r) {\n  r.s = this.s;\n  var ds = Math.floor(n/this.DB);\n  if(ds >= this.t) { r.t = 0; return; }\n  var bs = n%this.DB;\n  var cbs = this.DB-bs;\n  var bm = (1<<bs)-1;\n  r[0] = this[ds]>>bs;\n  for(var i = ds+1; i < this.t; ++i) {\n    r[i-ds-1] |= (this[i]&bm)<<cbs;\n    r[i-ds] = this[i]>>bs;\n  }\n  if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;\n  r.t = this.t-ds;\n  r.clamp();\n}\n\n// (protected) r = this - a\nfunction bnpSubTo(a,r) {\n  var i = 0, c = 0, m = Math.min(a.t,this.t);\n  while(i < m) {\n    c += this[i]-a[i];\n    r[i++] = c&this.DM;\n    c >>= this.DB;\n  }\n  if(a.t < this.t) {\n    c -= a.s;\n    while(i < this.t) {\n      c += this[i];\n      r[i++] = c&this.DM;\n      c >>= this.DB;\n    }\n    c += this.s;\n  }\n  else {\n    c += this.s;\n    while(i < a.t) {\n      c -= a[i];\n      r[i++] = c&this.DM;\n      c >>= this.DB;\n    }\n    c -= a.s;\n  }\n  r.s = (c<0)?-1:0;\n  if(c < -1) r[i++] = this.DV+c;\n  else if(c > 0) r[i++] = c;\n  r.t = i;\n  r.clamp();\n}\n\n// (protected) r = this * a, r != this,a (HAC 14.12)\n// \"this\" should be the larger one if appropriate.\nfunction bnpMultiplyTo(a,r) {\n  var x = this.abs(), y = a.abs();\n  var i = x.t;\n  r.t = i+y.t;\n  while(--i >= 0) r[i] = 0;\n  for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);\n  r.s = 0;\n  r.clamp();\n  if(this.s != a.s) BigInteger.ZERO.subTo(r,r);\n}\n\n// (protected) r = this^2, r != this (HAC 14.16)\nfunction bnpSquareTo(r) {\n  var x = this.abs();\n  var i = r.t = 2*x.t;\n  while(--i >= 0) r[i] = 0;\n  for(i = 0; i < x.t-1; ++i) {\n    var c = x.am(i,x[i],r,2*i,0,1);\n    if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {\n      r[i+x.t] -= x.DV;\n      r[i+x.t+1] = 1;\n    }\n  }\n  if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);\n  r.s = 0;\n  r.clamp();\n}\n\n// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)\n// r != q, this != m.  q or r may be null.\nfunction bnpDivRemTo(m,q,r) {\n  var pm = m.abs();\n  if(pm.t <= 0) return;\n  var pt = this.abs();\n  if(pt.t < pm.t) {\n    if(q != null) q.fromInt(0);\n    if(r != null) this.copyTo(r);\n    return;\n  }\n  if(r == null) r = nbi();\n  var y = nbi(), ts = this.s, ms = m.s;\n  var nsh = this.DB-nbits(pm[pm.t-1]);\t// normalize modulus\n  if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }\n  else { pm.copyTo(y); pt.copyTo(r); }\n  var ys = y.t;\n  var y0 = y[ys-1];\n  if(y0 == 0) return;\n  var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);\n  var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;\n  var i = r.t, j = i-ys, t = (q==null)?nbi():q;\n  y.dlShiftTo(j,t);\n  if(r.compareTo(t) >= 0) {\n    r[r.t++] = 1;\n    r.subTo(t,r);\n  }\n  BigInteger.ONE.dlShiftTo(ys,t);\n  t.subTo(y,y);\t// \"negative\" y so we can replace sub with am later\n  while(y.t < ys) y[y.t++] = 0;\n  while(--j >= 0) {\n    // Estimate quotient digit\n    var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);\n    if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) {\t// Try it out\n      y.dlShiftTo(j,t);\n      r.subTo(t,r);\n      while(r[i] < --qd) r.subTo(t,r);\n    }\n  }\n  if(q != null) {\n    r.drShiftTo(ys,q);\n    if(ts != ms) BigInteger.ZERO.subTo(q,q);\n  }\n  r.t = ys;\n  r.clamp();\n  if(nsh > 0) r.rShiftTo(nsh,r);\t// Denormalize remainder\n  if(ts < 0) BigInteger.ZERO.subTo(r,r);\n}\n\n// (public) this mod a\nfunction bnMod(a) {\n  var r = nbi();\n  this.abs().divRemTo(a,null,r);\n  if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);\n  return r;\n}\n\n// Modular reduction using \"classic\" algorithm\nfunction Classic(m) { this.m = m; }\nfunction cConvert(x) {\n  if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);\n  else return x;\n}\nfunction cRevert(x) { return x; }\nfunction cReduce(x) { x.divRemTo(this.m,null,x); }\nfunction cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }\nfunction cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }\n\nClassic.prototype.convert = cConvert;\nClassic.prototype.revert = cRevert;\nClassic.prototype.reduce = cReduce;\nClassic.prototype.mulTo = cMulTo;\nClassic.prototype.sqrTo = cSqrTo;\n\n// (protected) return \"-1/this % 2^DB\"; useful for Mont. reduction\n// justification:\n//         xy == 1 (mod m)\n//         xy =  1+km\n//   xy(2-xy) = (1+km)(1-km)\n// x[y(2-xy)] = 1-k^2m^2\n// x[y(2-xy)] == 1 (mod m^2)\n// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2\n// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.\n// JS multiply \"overflows\" differently from C/C++, so care is needed here.\nfunction bnpInvDigit() {\n  if(this.t < 1) return 0;\n  var x = this[0];\n  if((x&1) == 0) return 0;\n  var y = x&3;\t\t// y == 1/x mod 2^2\n  y = (y*(2-(x&0xf)*y))&0xf;\t// y == 1/x mod 2^4\n  y = (y*(2-(x&0xff)*y))&0xff;\t// y == 1/x mod 2^8\n  y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff;\t// y == 1/x mod 2^16\n  // last step - calculate inverse mod DV directly;\n  // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints\n  y = (y*(2-x*y%this.DV))%this.DV;\t\t// y == 1/x mod 2^dbits\n  // we really want the negative inverse, and -DV < y < DV\n  return (y>0)?this.DV-y:-y;\n}\n\n// Montgomery reduction\nfunction Montgomery(m) {\n  this.m = m;\n  this.mp = m.invDigit();\n  this.mpl = this.mp&0x7fff;\n  this.mph = this.mp>>15;\n  this.um = (1<<(m.DB-15))-1;\n  this.mt2 = 2*m.t;\n}\n\n// xR mod m\nfunction montConvert(x) {\n  var r = nbi();\n  x.abs().dlShiftTo(this.m.t,r);\n  r.divRemTo(this.m,null,r);\n  if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);\n  return r;\n}\n\n// x/R mod m\nfunction montRevert(x) {\n  var r = nbi();\n  x.copyTo(r);\n  this.reduce(r);\n  return r;\n}\n\n// x = x/R mod m (HAC 14.32)\nfunction montReduce(x) {\n  while(x.t <= this.mt2)\t// pad x so am has enough room later\n    x[x.t++] = 0;\n  for(var i = 0; i < this.m.t; ++i) {\n    // faster way of calculating u0 = x[i]*mp mod DV\n    var j = x[i]&0x7fff;\n    var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;\n    // use am to combine the multiply-shift-add into one call\n    j = i+this.m.t;\n    x[j] += this.m.am(0,u0,x,i,0,this.m.t);\n    // propagate carry\n    while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }\n  }\n  x.clamp();\n  x.drShiftTo(this.m.t,x);\n  if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);\n}\n\n// r = \"x^2/R mod m\"; x != r\nfunction montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }\n\n// r = \"xy/R mod m\"; x,y != r\nfunction montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }\n\nMontgomery.prototype.convert = montConvert;\nMontgomery.prototype.revert = montRevert;\nMontgomery.prototype.reduce = montReduce;\nMontgomery.prototype.mulTo = montMulTo;\nMontgomery.prototype.sqrTo = montSqrTo;\n\n// (protected) true iff this is even\nfunction bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }\n\n// (protected) this^e, e < 2^32, doing sqr and mul with \"r\" (HAC 14.79)\nfunction bnpExp(e,z) {\n  if(e > 0xffffffff || e < 1) return BigInteger.ONE;\n  var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;\n  g.copyTo(r);\n  while(--i >= 0) {\n    z.sqrTo(r,r2);\n    if((e&(1<<i)) > 0) z.mulTo(r2,g,r);\n    else { var t = r; r = r2; r2 = t; }\n  }\n  return z.revert(r);\n}\n\n// (public) this^e % m, 0 <= e < 2^32\nfunction bnModPowInt(e,m) {\n  var z;\n  if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);\n  return this.exp(e,z);\n}\n\n// protected\nBigInteger.prototype.copyTo = bnpCopyTo;\nBigInteger.prototype.fromInt = bnpFromInt;\nBigInteger.prototype.fromString = bnpFromString;\nBigInteger.prototype.clamp = bnpClamp;\nBigInteger.prototype.dlShiftTo = bnpDLShiftTo;\nBigInteger.prototype.drShiftTo = bnpDRShiftTo;\nBigInteger.prototype.lShiftTo = bnpLShiftTo;\nBigInteger.prototype.rShiftTo = bnpRShiftTo;\nBigInteger.prototype.subTo = bnpSubTo;\nBigInteger.prototype.multiplyTo = bnpMultiplyTo;\nBigInteger.prototype.squareTo = bnpSquareTo;\nBigInteger.prototype.divRemTo = bnpDivRemTo;\nBigInteger.prototype.invDigit = bnpInvDigit;\nBigInteger.prototype.isEven = bnpIsEven;\nBigInteger.prototype.exp = bnpExp;\n\n// public\nBigInteger.prototype.toString = bnToString;\nBigInteger.prototype.negate = bnNegate;\nBigInteger.prototype.abs = bnAbs;\nBigInteger.prototype.compareTo = bnCompareTo;\nBigInteger.prototype.bitLength = bnBitLength;\nBigInteger.prototype.mod = bnMod;\nBigInteger.prototype.modPowInt = bnModPowInt;\n\n// \"constants\"\nBigInteger.ZERO = nbv(0);\nBigInteger.ONE = nbv(1);\n"
  },
  {
    "path": "JavaScript/demo/js/jsbn2.js",
    "content": "/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\n// Copyright (c) 2005-2009  Tom Wu\n// All Rights Reserved.\n// See \"LICENSE\" for details.\n\n// Extended JavaScript BN functions, required for RSA private ops.\n\n// Version 1.1: new BigInteger(\"0\", 10) returns \"proper\" zero\n// Version 1.2: square() API, isProbablePrime fix\n\n// (public)\nfunction bnClone() { var r = nbi(); this.copyTo(r); return r; }\n\n// (public) return value as integer\nfunction bnIntValue() {\n  if(this.s < 0) {\n    if(this.t == 1) return this[0]-this.DV;\n    else if(this.t == 0) return -1;\n  }\n  else if(this.t == 1) return this[0];\n  else if(this.t == 0) return 0;\n  // assumes 16 < DB < 32\n  return ((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0];\n}\n\n// (public) return value as byte\nfunction bnByteValue() { return (this.t==0)?this.s:(this[0]<<24)>>24; }\n\n// (public) return value as short (assumes DB>=16)\nfunction bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; }\n\n// (protected) return x s.t. r^x < DV\nfunction bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); }\n\n// (public) 0 if this == 0, 1 if this > 0\nfunction bnSigNum() {\n  if(this.s < 0) return -1;\n  else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;\n  else return 1;\n}\n\n// (protected) convert to radix string\nfunction bnpToRadix(b) {\n  if(b == null) b = 10;\n  if(this.signum() == 0 || b < 2 || b > 36) return \"0\";\n  var cs = this.chunkSize(b);\n  var a = Math.pow(b,cs);\n  var d = nbv(a), y = nbi(), z = nbi(), r = \"\";\n  this.divRemTo(d,y,z);\n  while(y.signum() > 0) {\n    r = (a+z.intValue()).toString(b).substr(1) + r;\n    y.divRemTo(d,y,z);\n  }\n  return z.intValue().toString(b) + r;\n}\n\n// (protected) convert from radix string\nfunction bnpFromRadix(s,b) {\n  this.fromInt(0);\n  if(b == null) b = 10;\n  var cs = this.chunkSize(b);\n  var d = Math.pow(b,cs), mi = false, j = 0, w = 0;\n  for(var i = 0; i < s.length; ++i) {\n    var x = intAt(s,i);\n    if(x < 0) {\n      if(s.charAt(i) == \"-\" && this.signum() == 0) mi = true;\n      continue;\n    }\n    w = b*w+x;\n    if(++j >= cs) {\n      this.dMultiply(d);\n      this.dAddOffset(w,0);\n      j = 0;\n      w = 0;\n    }\n  }\n  if(j > 0) {\n    this.dMultiply(Math.pow(b,j));\n    this.dAddOffset(w,0);\n  }\n  if(mi) BigInteger.ZERO.subTo(this,this);\n}\n\n// (protected) alternate constructor\nfunction bnpFromNumber(a,b,c) {\n  if(\"number\" == typeof b) {\n    // new BigInteger(int,int,RNG)\n    if(a < 2) this.fromInt(1);\n    else {\n      this.fromNumber(a,c);\n      if(!this.testBit(a-1))\t// force MSB set\n        this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);\n      if(this.isEven()) this.dAddOffset(1,0); // force odd\n      while(!this.isProbablePrime(b)) {\n        this.dAddOffset(2,0);\n        if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this);\n      }\n    }\n  }\n  else {\n    // new BigInteger(int,RNG)\n    var x = new Array(), t = a&7;\n    x.length = (a>>3)+1;\n    b.nextBytes(x);\n    if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0;\n    this.fromString(x,256);\n  }\n}\n\n// (public) convert to bigendian byte array\nfunction bnToByteArray() {\n  var i = this.t, r = new Array();\n  r[0] = this.s;\n  var p = this.DB-(i*this.DB)%8, d, k = 0;\n  if(i-- > 0) {\n    if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p)\n      r[k++] = d|(this.s<<(this.DB-p));\n    while(i >= 0) {\n      if(p < 8) {\n        d = (this[i]&((1<<p)-1))<<(8-p);\n        d |= this[--i]>>(p+=this.DB-8);\n      }\n      else {\n        d = (this[i]>>(p-=8))&0xff;\n        if(p <= 0) { p += this.DB; --i; }\n      }\n      if((d&0x80) != 0) d |= -256;\n      if(k == 0 && (this.s&0x80) != (d&0x80)) ++k;\n      if(k > 0 || d != this.s) r[k++] = d;\n    }\n  }\n  return r;\n}\n\nfunction bnEquals(a) { return(this.compareTo(a)==0); }\nfunction bnMin(a) { return(this.compareTo(a)<0)?this:a; }\nfunction bnMax(a) { return(this.compareTo(a)>0)?this:a; }\n\n// (protected) r = this op a (bitwise)\nfunction bnpBitwiseTo(a,op,r) {\n  var i, f, m = Math.min(a.t,this.t);\n  for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]);\n  if(a.t < this.t) {\n    f = a.s&this.DM;\n    for(i = m; i < this.t; ++i) r[i] = op(this[i],f);\n    r.t = this.t;\n  }\n  else {\n    f = this.s&this.DM;\n    for(i = m; i < a.t; ++i) r[i] = op(f,a[i]);\n    r.t = a.t;\n  }\n  r.s = op(this.s,a.s);\n  r.clamp();\n}\n\n// (public) this & a\nfunction op_and(x,y) { return x&y; }\nfunction bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; }\n\n// (public) this | a\nfunction op_or(x,y) { return x|y; }\nfunction bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; }\n\n// (public) this ^ a\nfunction op_xor(x,y) { return x^y; }\nfunction bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; }\n\n// (public) this & ~a\nfunction op_andnot(x,y) { return x&~y; }\nfunction bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; }\n\n// (public) ~this\nfunction bnNot() {\n  var r = nbi();\n  for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i];\n  r.t = this.t;\n  r.s = ~this.s;\n  return r;\n}\n\n// (public) this << n\nfunction bnShiftLeft(n) {\n  var r = nbi();\n  if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r);\n  return r;\n}\n\n// (public) this >> n\nfunction bnShiftRight(n) {\n  var r = nbi();\n  if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r);\n  return r;\n}\n\n// return index of lowest 1-bit in x, x < 2^31\nfunction lbit(x) {\n  if(x == 0) return -1;\n  var r = 0;\n  if((x&0xffff) == 0) { x >>= 16; r += 16; }\n  if((x&0xff) == 0) { x >>= 8; r += 8; }\n  if((x&0xf) == 0) { x >>= 4; r += 4; }\n  if((x&3) == 0) { x >>= 2; r += 2; }\n  if((x&1) == 0) ++r;\n  return r;\n}\n\n// (public) returns index of lowest 1-bit (or -1 if none)\nfunction bnGetLowestSetBit() {\n  for(var i = 0; i < this.t; ++i)\n    if(this[i] != 0) return i*this.DB+lbit(this[i]);\n  if(this.s < 0) return this.t*this.DB;\n  return -1;\n}\n\n// return number of 1 bits in x\nfunction cbit(x) {\n  var r = 0;\n  while(x != 0) { x &= x-1; ++r; }\n  return r;\n}\n\n// (public) return number of set bits\nfunction bnBitCount() {\n  var r = 0, x = this.s&this.DM;\n  for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x);\n  return r;\n}\n\n// (public) true iff nth bit is set\nfunction bnTestBit(n) {\n  var j = Math.floor(n/this.DB);\n  if(j >= this.t) return(this.s!=0);\n  return((this[j]&(1<<(n%this.DB)))!=0);\n}\n\n// (protected) this op (1<<n)\nfunction bnpChangeBit(n,op) {\n  var r = BigInteger.ONE.shiftLeft(n);\n  this.bitwiseTo(r,op,r);\n  return r;\n}\n\n// (public) this | (1<<n)\nfunction bnSetBit(n) { return this.changeBit(n,op_or); }\n\n// (public) this & ~(1<<n)\nfunction bnClearBit(n) { return this.changeBit(n,op_andnot); }\n\n// (public) this ^ (1<<n)\nfunction bnFlipBit(n) { return this.changeBit(n,op_xor); }\n\n// (protected) r = this + a\nfunction bnpAddTo(a,r) {\n  var i = 0, c = 0, m = Math.min(a.t,this.t);\n  while(i < m) {\n    c += this[i]+a[i];\n    r[i++] = c&this.DM;\n    c >>= this.DB;\n  }\n  if(a.t < this.t) {\n    c += a.s;\n    while(i < this.t) {\n      c += this[i];\n      r[i++] = c&this.DM;\n      c >>= this.DB;\n    }\n    c += this.s;\n  }\n  else {\n    c += this.s;\n    while(i < a.t) {\n      c += a[i];\n      r[i++] = c&this.DM;\n      c >>= this.DB;\n    }\n    c += a.s;\n  }\n  r.s = (c<0)?-1:0;\n  if(c > 0) r[i++] = c;\n  else if(c < -1) r[i++] = this.DV+c;\n  r.t = i;\n  r.clamp();\n}\n\n// (public) this + a\nfunction bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; }\n\n// (public) this - a\nfunction bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; }\n\n// (public) this * a\nfunction bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; }\n\n// (public) this^2\nfunction bnSquare() { var r = nbi(); this.squareTo(r); return r; }\n\n// (public) this / a\nfunction bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; }\n\n// (public) this % a\nfunction bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; }\n\n// (public) [this/a,this%a]\nfunction bnDivideAndRemainder(a) {\n  var q = nbi(), r = nbi();\n  this.divRemTo(a,q,r);\n  return new Array(q,r);\n}\n\n// (protected) this *= n, this >= 0, 1 < n < DV\nfunction bnpDMultiply(n) {\n  this[this.t] = this.am(0,n-1,this,0,0,this.t);\n  ++this.t;\n  this.clamp();\n}\n\n// (protected) this += n << w words, this >= 0\nfunction bnpDAddOffset(n,w) {\n  if(n == 0) return;\n  while(this.t <= w) this[this.t++] = 0;\n  this[w] += n;\n  while(this[w] >= this.DV) {\n    this[w] -= this.DV;\n    if(++w >= this.t) this[this.t++] = 0;\n    ++this[w];\n  }\n}\n\n// A \"null\" reducer\nfunction NullExp() {}\nfunction nNop(x) { return x; }\nfunction nMulTo(x,y,r) { x.multiplyTo(y,r); }\nfunction nSqrTo(x,r) { x.squareTo(r); }\n\nNullExp.prototype.convert = nNop;\nNullExp.prototype.revert = nNop;\nNullExp.prototype.mulTo = nMulTo;\nNullExp.prototype.sqrTo = nSqrTo;\n\n// (public) this^e\nfunction bnPow(e) { return this.exp(e,new NullExp()); }\n\n// (protected) r = lower n words of \"this * a\", a.t <= n\n// \"this\" should be the larger one if appropriate.\nfunction bnpMultiplyLowerTo(a,n,r) {\n  var i = Math.min(this.t+a.t,n);\n  r.s = 0; // assumes a,this >= 0\n  r.t = i;\n  while(i > 0) r[--i] = 0;\n  var j;\n  for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t);\n  for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i);\n  r.clamp();\n}\n\n// (protected) r = \"this * a\" without lower n words, n > 0\n// \"this\" should be the larger one if appropriate.\nfunction bnpMultiplyUpperTo(a,n,r) {\n  --n;\n  var i = r.t = this.t+a.t-n;\n  r.s = 0; // assumes a,this >= 0\n  while(--i >= 0) r[i] = 0;\n  for(i = Math.max(n-this.t,0); i < a.t; ++i)\n    r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n);\n  r.clamp();\n  r.drShiftTo(1,r);\n}\n\n// Barrett modular reduction\nfunction Barrett(m) {\n  // setup Barrett\n  this.r2 = nbi();\n  this.q3 = nbi();\n  BigInteger.ONE.dlShiftTo(2*m.t,this.r2);\n  this.mu = this.r2.divide(m);\n  this.m = m;\n}\n\nfunction barrettConvert(x) {\n  if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m);\n  else if(x.compareTo(this.m) < 0) return x;\n  else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }\n}\n\nfunction barrettRevert(x) { return x; }\n\n// x = x mod m (HAC 14.42)\nfunction barrettReduce(x) {\n  x.drShiftTo(this.m.t-1,this.r2);\n  if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); }\n  this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);\n  this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);\n  while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1);\n  x.subTo(this.r2,x);\n  while(x.compareTo(this.m) >= 0) x.subTo(this.m,x);\n}\n\n// r = x^2 mod m; x != r\nfunction barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); }\n\n// r = x*y mod m; x,y != r\nfunction barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }\n\nBarrett.prototype.convert = barrettConvert;\nBarrett.prototype.revert = barrettRevert;\nBarrett.prototype.reduce = barrettReduce;\nBarrett.prototype.mulTo = barrettMulTo;\nBarrett.prototype.sqrTo = barrettSqrTo;\n\n// (public) this^e % m (HAC 14.85)\nfunction bnModPow(e,m) {\n  var i = e.bitLength(), k, r = nbv(1), z;\n  if(i <= 0) return r;\n  else if(i < 18) k = 1;\n  else if(i < 48) k = 3;\n  else if(i < 144) k = 4;\n  else if(i < 768) k = 5;\n  else k = 6;\n  if(i < 8)\n    z = new Classic(m);\n  else if(m.isEven())\n    z = new Barrett(m);\n  else\n    z = new Montgomery(m);\n\n  // precomputation\n  var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1;\n  g[1] = z.convert(this);\n  if(k > 1) {\n    var g2 = nbi();\n    z.sqrTo(g[1],g2);\n    while(n <= km) {\n      g[n] = nbi();\n      z.mulTo(g2,g[n-2],g[n]);\n      n += 2;\n    }\n  }\n\n  var j = e.t-1, w, is1 = true, r2 = nbi(), t;\n  i = nbits(e[j])-1;\n  while(j >= 0) {\n    if(i >= k1) w = (e[j]>>(i-k1))&km;\n    else {\n      w = (e[j]&((1<<(i+1))-1))<<(k1-i);\n      if(j > 0) w |= e[j-1]>>(this.DB+i-k1);\n    }\n\n    n = k;\n    while((w&1) == 0) { w >>= 1; --n; }\n    if((i -= n) < 0) { i += this.DB; --j; }\n    if(is1) {\t// ret == 1, don't bother squaring or multiplying it\n      g[w].copyTo(r);\n      is1 = false;\n    }\n    else {\n      while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; }\n      if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; }\n      z.mulTo(r2,g[w],r);\n    }\n\n    while(j >= 0 && (e[j]&(1<<i)) == 0) {\n      z.sqrTo(r,r2); t = r; r = r2; r2 = t;\n      if(--i < 0) { i = this.DB-1; --j; }\n    }\n  }\n  return z.revert(r);\n}\n\n// (public) gcd(this,a) (HAC 14.54)\nfunction bnGCD(a) {\n  var x = (this.s<0)?this.negate():this.clone();\n  var y = (a.s<0)?a.negate():a.clone();\n  if(x.compareTo(y) < 0) { var t = x; x = y; y = t; }\n  var i = x.getLowestSetBit(), g = y.getLowestSetBit();\n  if(g < 0) return x;\n  if(i < g) g = i;\n  if(g > 0) {\n    x.rShiftTo(g,x);\n    y.rShiftTo(g,y);\n  }\n  while(x.signum() > 0) {\n    if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x);\n    if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y);\n    if(x.compareTo(y) >= 0) {\n      x.subTo(y,x);\n      x.rShiftTo(1,x);\n    }\n    else {\n      y.subTo(x,y);\n      y.rShiftTo(1,y);\n    }\n  }\n  if(g > 0) y.lShiftTo(g,y);\n  return y;\n}\n\n// (protected) this % n, n < 2^26\nfunction bnpModInt(n) {\n  if(n <= 0) return 0;\n  var d = this.DV%n, r = (this.s<0)?n-1:0;\n  if(this.t > 0)\n    if(d == 0) r = this[0]%n;\n    else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n;\n  return r;\n}\n\n// (public) 1/this % m (HAC 14.61)\nfunction bnModInverse(m) {\n  var ac = m.isEven();\n  if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;\n  var u = m.clone(), v = this.clone();\n  var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);\n  while(u.signum() != 0) {\n    while(u.isEven()) {\n      u.rShiftTo(1,u);\n      if(ac) {\n        if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); }\n        a.rShiftTo(1,a);\n      }\n      else if(!b.isEven()) b.subTo(m,b);\n      b.rShiftTo(1,b);\n    }\n    while(v.isEven()) {\n      v.rShiftTo(1,v);\n      if(ac) {\n        if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); }\n        c.rShiftTo(1,c);\n      }\n      else if(!d.isEven()) d.subTo(m,d);\n      d.rShiftTo(1,d);\n    }\n    if(u.compareTo(v) >= 0) {\n      u.subTo(v,u);\n      if(ac) a.subTo(c,a);\n      b.subTo(d,b);\n    }\n    else {\n      v.subTo(u,v);\n      if(ac) c.subTo(a,c);\n      d.subTo(b,d);\n    }\n  }\n  if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;\n  if(d.compareTo(m) >= 0) return d.subtract(m);\n  if(d.signum() < 0) d.addTo(m,d); else return d;\n  if(d.signum() < 0) return d.add(m); else return d;\n}\n\nvar lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997];\nvar lplim = (1<<26)/lowprimes[lowprimes.length-1];\n\n// (public) test primality with certainty >= 1-.5^t\nfunction bnIsProbablePrime(t) {\n  var i, x = this.abs();\n  if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) {\n    for(i = 0; i < lowprimes.length; ++i)\n      if(x[0] == lowprimes[i]) return true;\n    return false;\n  }\n  if(x.isEven()) return false;\n  i = 1;\n  while(i < lowprimes.length) {\n    var m = lowprimes[i], j = i+1;\n    while(j < lowprimes.length && m < lplim) m *= lowprimes[j++];\n    m = x.modInt(m);\n    while(i < j) if(m%lowprimes[i++] == 0) return false;\n  }\n  return x.millerRabin(t);\n}\n\n// (protected) true if probably prime (HAC 4.24, Miller-Rabin)\nfunction bnpMillerRabin(t) {\n  var n1 = this.subtract(BigInteger.ONE);\n  var k = n1.getLowestSetBit();\n  if(k <= 0) return false;\n  var r = n1.shiftRight(k);\n  t = (t+1)>>1;\n  if(t > lowprimes.length) t = lowprimes.length;\n  var a = nbi();\n  for(var i = 0; i < t; ++i) {\n    //Pick bases at random, instead of starting at 2\n    a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]);\n    var y = a.modPow(r,this);\n    if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {\n      var j = 1;\n      while(j++ < k && y.compareTo(n1) != 0) {\n        y = y.modPowInt(2,this);\n        if(y.compareTo(BigInteger.ONE) == 0) return false;\n      }\n      if(y.compareTo(n1) != 0) return false;\n    }\n  }\n  return true;\n}\n\n// protected\nBigInteger.prototype.chunkSize = bnpChunkSize;\nBigInteger.prototype.toRadix = bnpToRadix;\nBigInteger.prototype.fromRadix = bnpFromRadix;\nBigInteger.prototype.fromNumber = bnpFromNumber;\nBigInteger.prototype.bitwiseTo = bnpBitwiseTo;\nBigInteger.prototype.changeBit = bnpChangeBit;\nBigInteger.prototype.addTo = bnpAddTo;\nBigInteger.prototype.dMultiply = bnpDMultiply;\nBigInteger.prototype.dAddOffset = bnpDAddOffset;\nBigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;\nBigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;\nBigInteger.prototype.modInt = bnpModInt;\nBigInteger.prototype.millerRabin = bnpMillerRabin;\n\n// public\nBigInteger.prototype.clone = bnClone;\nBigInteger.prototype.intValue = bnIntValue;\nBigInteger.prototype.byteValue = bnByteValue;\nBigInteger.prototype.shortValue = bnShortValue;\nBigInteger.prototype.signum = bnSigNum;\nBigInteger.prototype.toByteArray = bnToByteArray;\nBigInteger.prototype.equals = bnEquals;\nBigInteger.prototype.min = bnMin;\nBigInteger.prototype.max = bnMax;\nBigInteger.prototype.and = bnAnd;\nBigInteger.prototype.or = bnOr;\nBigInteger.prototype.xor = bnXor;\nBigInteger.prototype.andNot = bnAndNot;\nBigInteger.prototype.not = bnNot;\nBigInteger.prototype.shiftLeft = bnShiftLeft;\nBigInteger.prototype.shiftRight = bnShiftRight;\nBigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;\nBigInteger.prototype.bitCount = bnBitCount;\nBigInteger.prototype.testBit = bnTestBit;\nBigInteger.prototype.setBit = bnSetBit;\nBigInteger.prototype.clearBit = bnClearBit;\nBigInteger.prototype.flipBit = bnFlipBit;\nBigInteger.prototype.add = bnAdd;\nBigInteger.prototype.subtract = bnSubtract;\nBigInteger.prototype.multiply = bnMultiply;\nBigInteger.prototype.divide = bnDivide;\nBigInteger.prototype.remainder = bnRemainder;\nBigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;\nBigInteger.prototype.modPow = bnModPow;\nBigInteger.prototype.modInverse = bnModInverse;\nBigInteger.prototype.pow = bnPow;\nBigInteger.prototype.gcd = bnGCD;\nBigInteger.prototype.isProbablePrime = bnIsProbablePrime;\n\n// JSBN-specific extension\nBigInteger.prototype.square = bnSquare;\n\n// BigInteger interfaces not implemented in jsbn:\n\n// BigInteger(int signum, byte[] magnitude)\n// double doubleValue()\n// float floatValue()\n// int hashCode()\n// long longValue()\n// static BigInteger valueOf(long val)\n"
  },
  {
    "path": "JavaScript/demo/js/md5.js",
    "content": "/*\nCryptoJS v3.1.2\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function (Math) {\r\n    // Shortcuts\r\n    var C = CryptoJS;\r\n    var C_lib = C.lib;\r\n    var WordArray = C_lib.WordArray;\r\n    var Hasher = C_lib.Hasher;\r\n    var C_algo = C.algo;\r\n\r\n    // Constants table\r\n    var T = [];\r\n\r\n    // Compute constants\r\n    (function () {\r\n        for (var i = 0; i < 64; i++) {\r\n            T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;\r\n        }\r\n    }());\r\n\r\n    /**\r\n     * MD5 hash algorithm.\r\n     */\r\n    var MD5 = C_algo.MD5 = Hasher.extend({\r\n        _doReset: function () {\r\n            this._hash = new WordArray.init([\r\n                0x67452301, 0xefcdab89,\r\n                0x98badcfe, 0x10325476\r\n            ]);\r\n        },\r\n\r\n        _doProcessBlock: function (M, offset) {\r\n            // Swap endian\r\n            for (var i = 0; i < 16; i++) {\r\n                // Shortcuts\r\n                var offset_i = offset + i;\r\n                var M_offset_i = M[offset_i];\r\n\r\n                M[offset_i] = (\r\n                    (((M_offset_i << 8)  | (M_offset_i >>> 24)) & 0x00ff00ff) |\r\n                    (((M_offset_i << 24) | (M_offset_i >>> 8))  & 0xff00ff00)\r\n                );\r\n            }\r\n\r\n            // Shortcuts\r\n            var H = this._hash.words;\r\n\r\n            var M_offset_0  = M[offset + 0];\r\n            var M_offset_1  = M[offset + 1];\r\n            var M_offset_2  = M[offset + 2];\r\n            var M_offset_3  = M[offset + 3];\r\n            var M_offset_4  = M[offset + 4];\r\n            var M_offset_5  = M[offset + 5];\r\n            var M_offset_6  = M[offset + 6];\r\n            var M_offset_7  = M[offset + 7];\r\n            var M_offset_8  = M[offset + 8];\r\n            var M_offset_9  = M[offset + 9];\r\n            var M_offset_10 = M[offset + 10];\r\n            var M_offset_11 = M[offset + 11];\r\n            var M_offset_12 = M[offset + 12];\r\n            var M_offset_13 = M[offset + 13];\r\n            var M_offset_14 = M[offset + 14];\r\n            var M_offset_15 = M[offset + 15];\r\n\r\n            // Working varialbes\r\n            var a = H[0];\r\n            var b = H[1];\r\n            var c = H[2];\r\n            var d = H[3];\r\n\r\n            // Computation\r\n            a = FF(a, b, c, d, M_offset_0,  7,  T[0]);\r\n            d = FF(d, a, b, c, M_offset_1,  12, T[1]);\r\n            c = FF(c, d, a, b, M_offset_2,  17, T[2]);\r\n            b = FF(b, c, d, a, M_offset_3,  22, T[3]);\r\n            a = FF(a, b, c, d, M_offset_4,  7,  T[4]);\r\n            d = FF(d, a, b, c, M_offset_5,  12, T[5]);\r\n            c = FF(c, d, a, b, M_offset_6,  17, T[6]);\r\n            b = FF(b, c, d, a, M_offset_7,  22, T[7]);\r\n            a = FF(a, b, c, d, M_offset_8,  7,  T[8]);\r\n            d = FF(d, a, b, c, M_offset_9,  12, T[9]);\r\n            c = FF(c, d, a, b, M_offset_10, 17, T[10]);\r\n            b = FF(b, c, d, a, M_offset_11, 22, T[11]);\r\n            a = FF(a, b, c, d, M_offset_12, 7,  T[12]);\r\n            d = FF(d, a, b, c, M_offset_13, 12, T[13]);\r\n            c = FF(c, d, a, b, M_offset_14, 17, T[14]);\r\n            b = FF(b, c, d, a, M_offset_15, 22, T[15]);\r\n\r\n            a = GG(a, b, c, d, M_offset_1,  5,  T[16]);\r\n            d = GG(d, a, b, c, M_offset_6,  9,  T[17]);\r\n            c = GG(c, d, a, b, M_offset_11, 14, T[18]);\r\n            b = GG(b, c, d, a, M_offset_0,  20, T[19]);\r\n            a = GG(a, b, c, d, M_offset_5,  5,  T[20]);\r\n            d = GG(d, a, b, c, M_offset_10, 9,  T[21]);\r\n            c = GG(c, d, a, b, M_offset_15, 14, T[22]);\r\n            b = GG(b, c, d, a, M_offset_4,  20, T[23]);\r\n            a = GG(a, b, c, d, M_offset_9,  5,  T[24]);\r\n            d = GG(d, a, b, c, M_offset_14, 9,  T[25]);\r\n            c = GG(c, d, a, b, M_offset_3,  14, T[26]);\r\n            b = GG(b, c, d, a, M_offset_8,  20, T[27]);\r\n            a = GG(a, b, c, d, M_offset_13, 5,  T[28]);\r\n            d = GG(d, a, b, c, M_offset_2,  9,  T[29]);\r\n            c = GG(c, d, a, b, M_offset_7,  14, T[30]);\r\n            b = GG(b, c, d, a, M_offset_12, 20, T[31]);\r\n\r\n            a = HH(a, b, c, d, M_offset_5,  4,  T[32]);\r\n            d = HH(d, a, b, c, M_offset_8,  11, T[33]);\r\n            c = HH(c, d, a, b, M_offset_11, 16, T[34]);\r\n            b = HH(b, c, d, a, M_offset_14, 23, T[35]);\r\n            a = HH(a, b, c, d, M_offset_1,  4,  T[36]);\r\n            d = HH(d, a, b, c, M_offset_4,  11, T[37]);\r\n            c = HH(c, d, a, b, M_offset_7,  16, T[38]);\r\n            b = HH(b, c, d, a, M_offset_10, 23, T[39]);\r\n            a = HH(a, b, c, d, M_offset_13, 4,  T[40]);\r\n            d = HH(d, a, b, c, M_offset_0,  11, T[41]);\r\n            c = HH(c, d, a, b, M_offset_3,  16, T[42]);\r\n            b = HH(b, c, d, a, M_offset_6,  23, T[43]);\r\n            a = HH(a, b, c, d, M_offset_9,  4,  T[44]);\r\n            d = HH(d, a, b, c, M_offset_12, 11, T[45]);\r\n            c = HH(c, d, a, b, M_offset_15, 16, T[46]);\r\n            b = HH(b, c, d, a, M_offset_2,  23, T[47]);\r\n\r\n            a = II(a, b, c, d, M_offset_0,  6,  T[48]);\r\n            d = II(d, a, b, c, M_offset_7,  10, T[49]);\r\n            c = II(c, d, a, b, M_offset_14, 15, T[50]);\r\n            b = II(b, c, d, a, M_offset_5,  21, T[51]);\r\n            a = II(a, b, c, d, M_offset_12, 6,  T[52]);\r\n            d = II(d, a, b, c, M_offset_3,  10, T[53]);\r\n            c = II(c, d, a, b, M_offset_10, 15, T[54]);\r\n            b = II(b, c, d, a, M_offset_1,  21, T[55]);\r\n            a = II(a, b, c, d, M_offset_8,  6,  T[56]);\r\n            d = II(d, a, b, c, M_offset_15, 10, T[57]);\r\n            c = II(c, d, a, b, M_offset_6,  15, T[58]);\r\n            b = II(b, c, d, a, M_offset_13, 21, T[59]);\r\n            a = II(a, b, c, d, M_offset_4,  6,  T[60]);\r\n            d = II(d, a, b, c, M_offset_11, 10, T[61]);\r\n            c = II(c, d, a, b, M_offset_2,  15, T[62]);\r\n            b = II(b, c, d, a, M_offset_9,  21, T[63]);\r\n\r\n            // Intermediate hash value\r\n            H[0] = (H[0] + a) | 0;\r\n            H[1] = (H[1] + b) | 0;\r\n            H[2] = (H[2] + c) | 0;\r\n            H[3] = (H[3] + d) | 0;\r\n        },\r\n\r\n        _doFinalize: function () {\r\n            // Shortcuts\r\n            var data = this._data;\r\n            var dataWords = data.words;\r\n\r\n            var nBitsTotal = this._nDataBytes * 8;\r\n            var nBitsLeft = data.sigBytes * 8;\r\n\r\n            // Add padding\r\n            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);\r\n\r\n            var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000);\r\n            var nBitsTotalL = nBitsTotal;\r\n            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = (\r\n                (((nBitsTotalH << 8)  | (nBitsTotalH >>> 24)) & 0x00ff00ff) |\r\n                (((nBitsTotalH << 24) | (nBitsTotalH >>> 8))  & 0xff00ff00)\r\n            );\r\n            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (\r\n                (((nBitsTotalL << 8)  | (nBitsTotalL >>> 24)) & 0x00ff00ff) |\r\n                (((nBitsTotalL << 24) | (nBitsTotalL >>> 8))  & 0xff00ff00)\r\n            );\r\n\r\n            data.sigBytes = (dataWords.length + 1) * 4;\r\n\r\n            // Hash final blocks\r\n            this._process();\r\n\r\n            // Shortcuts\r\n            var hash = this._hash;\r\n            var H = hash.words;\r\n\r\n            // Swap endian\r\n            for (var i = 0; i < 4; i++) {\r\n                // Shortcut\r\n                var H_i = H[i];\r\n\r\n                H[i] = (((H_i << 8)  | (H_i >>> 24)) & 0x00ff00ff) |\r\n                       (((H_i << 24) | (H_i >>> 8))  & 0xff00ff00);\r\n            }\r\n\r\n            // Return final computed hash\r\n            return hash;\r\n        },\r\n\r\n        clone: function () {\r\n            var clone = Hasher.clone.call(this);\r\n            clone._hash = this._hash.clone();\r\n\r\n            return clone;\r\n        }\r\n    });\r\n\r\n    function FF(a, b, c, d, x, s, t) {\r\n        var n = a + ((b & c) | (~b & d)) + x + t;\r\n        return ((n << s) | (n >>> (32 - s))) + b;\r\n    }\r\n\r\n    function GG(a, b, c, d, x, s, t) {\r\n        var n = a + ((b & d) | (c & ~d)) + x + t;\r\n        return ((n << s) | (n >>> (32 - s))) + b;\r\n    }\r\n\r\n    function HH(a, b, c, d, x, s, t) {\r\n        var n = a + (b ^ c ^ d) + x + t;\r\n        return ((n << s) | (n >>> (32 - s))) + b;\r\n    }\r\n\r\n    function II(a, b, c, d, x, s, t) {\r\n        var n = a + (c ^ (b | ~d)) + x + t;\r\n        return ((n << s) | (n >>> (32 - s))) + b;\r\n    }\r\n\r\n    /**\r\n     * Shortcut function to the hasher's object interface.\r\n     *\r\n     * @param {WordArray|string} message The message to hash.\r\n     *\r\n     * @return {WordArray} The hash.\r\n     *\r\n     * @static\r\n     *\r\n     * @example\r\n     *\r\n     *     var hash = CryptoJS.MD5('message');\r\n     *     var hash = CryptoJS.MD5(wordArray);\r\n     */\r\n    C.MD5 = Hasher._createHelper(MD5);\r\n\r\n    /**\r\n     * Shortcut function to the HMAC's object interface.\r\n     *\r\n     * @param {WordArray|string} message The message to hash.\r\n     * @param {WordArray|string} key The secret key.\r\n     *\r\n     * @return {WordArray} The HMAC.\r\n     *\r\n     * @static\r\n     *\r\n     * @example\r\n     *\r\n     *     var hmac = CryptoJS.HmacMD5(message, key);\r\n     */\r\n    C.HmacMD5 = Hasher._createHmacHelper(MD5);\r\n}(Math));\r\n"
  },
  {
    "path": "JavaScript/demo/js/pkcs5pkey-1.0.js",
    "content": "/*! pkcs5pkey-1.0.5.js (c) 2013 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n/*\n * pkcs5pkey.js - reading passcode protected PKCS#5 PEM formatted RSA private key\n *\n * Copyright (c) 2013 Kenji Urushima (kenji.urushima@gmail.com)\n *\n * This software is licensed under the terms of the MIT License.\n * http://kjur.github.com/jsrsasign/license\n *\n * The above copyright and license notice shall be \n * included in all copies or substantial portions of the Software.\n */\n/**\n * @fileOverview\n * @name pkcs5pkey-1.0.js\n * @author Kenji Urushima kenji.urushima@gmail.com\n * @version pkcs5pkey 1.0.5 (2013-Aug-20)\n * @since jsrsasign 2.0.0\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\n */\n\n/**\n * @name PKCS5PKEY\n * @class class for PKCS#5 and PKCS#8 private key \n * @deprecated Since jsrsasign 4.1.3. Please use KEYUTIL class.\n * @description \n * <br/>\n * {@link PKCS5PKEY} class has following features:\n * <ul>\n * <li>read and parse PEM formatted encrypted PKCS#5 private key\n * <li>generate PEM formatted encrypted PKCS#5 private key\n * <li>read and parse PEM formatted plain PKCS#8 private key\n * <li>read and parse PEM formatted encrypted PKCS#8 private key by PBKDF2/HmacSHA1/3DES\n * </ul>\n * Currently supports only RSA private key and\n * following symmetric key algorithms to protect private key.\n * <ul>\n * <li>DES-EDE3-CBC</li>\n * <li>AES-256-CBC</li>\n * <li>AES-192-CBC</li>\n * <li>AES-128-CBC</li>\n * </ul>\n * \n * <h5>METHOD SUMMARY</h5>\n * <dl>\n * <dt><b>PKCS8 PRIVATE KEY METHODS</b><dd>\n * <ul>\n * <li>{@link PKCS5PKEY.getRSAKeyFromPlainPKCS8PEM} - convert plain PKCS8 PEM to RSAKey object</li>\n * <li>{@link PKCS5PKEY.getRSAKeyFromPlainPKCS8Hex} - convert plain PKCS8 hexadecimal data to RSAKey object</li>\n * <li>{@link PKCS5PKEY.getRSAKeyFromEncryptedPKCS8PEM} - convert encrypted PKCS8 PEM to RSAKey object</li>\n * <li>{@link PKCS5PKEY.getPlainPKCS8HexFromEncryptedPKCS8PEM} - convert encrypted PKCS8 PEM to plain PKCS8 Hex</li>\n * </ul>\n * <dt><b>PKCS5 PRIVATE KEY METHODS</b><dd>\n * <ul>\n * <li>{@link PKCS5PKEY.getRSAKeyFromEncryptedPKCS5PEM} - convert encrypted PKCS5 PEM to RSAKey object</li>\n * <li>{@link PKCS5PKEY.getEncryptedPKCS5PEMFromRSAKey} - convert RSAKey object to encryped PKCS5 PEM</li>\n * <li>{@link PKCS5PKEY.newEncryptedPKCS5PEM} - generate RSAKey and its encrypted PKCS5 PEM</li>\n * </ul>\n * <dt><b>PKCS8 PUBLIC KEY METHODS</b><dd>\n * <ul>\n * <li>{@link PKCS5PKEY.getKeyFromPublicPKCS8PEM} - convert encrypted PKCS8 PEM to RSAKey/ECDSA object</li>\n * <li>{@link PKCS5PKEY.getKeyFromPublicPKCS8Hex} - convert encrypted PKCS8 Hex to RSAKey/ECDSA object</li>\n * <li>{@link PKCS5PKEY.getRSAKeyFromPublicPKCS8PEM} - convert encrypted PKCS8 PEM to RSAKey object</li>\n * <li>{@link PKCS5PKEY.getRSAKeyFromPublicPKCS8Hex} - convert encrypted PKCS8 Hex to RSAKey object</li>\n * </ul>\n * <dt><b>UTITILIY METHODS</b><dd>\n * <ul>\n * <li>{@link PKCS5PKEY.getHexFromPEM} - convert PEM string to hexadecimal data</li>\n * <li>{@link PKCS5PKEY.getDecryptedKeyHexByKeyIV} - decrypt key by sharedKey and IV</li>\n * </ul>\n * </dl>\n * \n * @example\n * Here is an example of PEM formatted encrypted PKCS#5 private key.\n * -----BEGIN RSA PRIVATE KEY-----\n * Proc-Type: 4,ENCRYPTED\n * DEK-Info: AES-256-CBC,40555967F759530864FE022E257DE34E\n *\n * jV7uXajRw4cccDaliagcqiLOiQEUCe19l761pXRxzgQP+DH4rCi12T4puTdZyy6l\n *          ...(snip)...\n * qxLS+BASmyGm4DME6m+kltZ12LXwPgNU6+d+XQ4NXSA=\n *-----END RSA PRIVATE KEY-----\n */\nvar PKCS5PKEY = function() {\n    // *****************************************************************\n    // *** PRIVATE PROPERTIES AND METHODS *******************************\n    // *****************************************************************\n    // shared key decryption ------------------------------------------\n    var decryptAES = function(dataHex, keyHex, ivHex) {\n\treturn decryptGeneral(CryptoJS.AES, dataHex, keyHex, ivHex);\n    };\n\n    var decrypt3DES = function(dataHex, keyHex, ivHex) {\n\treturn decryptGeneral(CryptoJS.TripleDES, dataHex, keyHex, ivHex);\n    };\n\n    var decryptGeneral = function(f, dataHex, keyHex, ivHex) {\n\tvar data = CryptoJS.enc.Hex.parse(dataHex);\n\tvar key = CryptoJS.enc.Hex.parse(keyHex);\n\tvar iv = CryptoJS.enc.Hex.parse(ivHex);\n\tvar encrypted = {};\n\tencrypted.key = key;\n\tencrypted.iv = iv;\n\tencrypted.ciphertext = data;\n\tvar decrypted = f.decrypt(encrypted, key, { iv: iv });\n\treturn CryptoJS.enc.Hex.stringify(decrypted);\n    };\n\n    // shared key decryption ------------------------------------------\n    var encryptAES = function(dataHex, keyHex, ivHex) {\n\treturn encryptGeneral(CryptoJS.AES, dataHex, keyHex, ivHex);\n    };\n\n    var encrypt3DES = function(dataHex, keyHex, ivHex) {\n\treturn encryptGeneral(CryptoJS.TripleDES, dataHex, keyHex, ivHex);\n    };\n\n    var encryptGeneral = function(f, dataHex, keyHex, ivHex) {\n\tvar data = CryptoJS.enc.Hex.parse(dataHex);\n\tvar key = CryptoJS.enc.Hex.parse(keyHex);\n\tvar iv = CryptoJS.enc.Hex.parse(ivHex);\n\tvar msg = {};\n\tvar encryptedHex = f.encrypt(data, key, { iv: iv });\n        var encryptedWA = CryptoJS.enc.Hex.parse(encryptedHex.toString());\n        var encryptedB64 = CryptoJS.enc.Base64.stringify(encryptedWA);\n\treturn encryptedB64;\n    };\n\n    // other methods and properties ----------------------------------------\n    var ALGLIST = {\n\t'AES-256-CBC': { 'proc': decryptAES, 'eproc': encryptAES, keylen: 32, ivlen: 16 },\n\t'AES-192-CBC': { 'proc': decryptAES, 'eproc': encryptAES, keylen: 24, ivlen: 16 },\n\t'AES-128-CBC': { 'proc': decryptAES, 'eproc': encryptAES, keylen: 16, ivlen: 16 },\n\t'DES-EDE3-CBC': { 'proc': decrypt3DES, 'eproc': encrypt3DES, keylen: 24, ivlen: 8 }\n    };\n\n    var getFuncByName = function(algName) {\n\treturn ALGLIST[algName]['proc'];\n    };\n\n    var _generateIvSaltHex = function(numBytes) {\n\tvar wa = CryptoJS.lib.WordArray.random(numBytes);\n\tvar hex = CryptoJS.enc.Hex.stringify(wa);\n\treturn hex;\n    };\n\n    var _parsePKCS5PEM = function(sPKCS5PEM) {\n\tvar info = {};\n\tif (sPKCS5PEM.match(new RegExp(\"DEK-Info: ([^,]+),([0-9A-Fa-f]+)\", \"m\"))) {\n\t    info.cipher = RegExp.$1;\n\t    info.ivsalt = RegExp.$2;\n\t}\n\tif (sPKCS5PEM.match(new RegExp(\"-----BEGIN ([A-Z]+) PRIVATE KEY-----\"))) {\n\t    info.type = RegExp.$1;\n\t}\n\tvar i1 = -1;\n\tvar lenNEWLINE = 0;\n\tif (sPKCS5PEM.indexOf(\"\\r\\n\\r\\n\") != -1) {\n\t    i1 = sPKCS5PEM.indexOf(\"\\r\\n\\r\\n\");\n\t    lenNEWLINE = 2;\n\t}\n\tif (sPKCS5PEM.indexOf(\"\\n\\n\") != -1) {\n\t    i1 = sPKCS5PEM.indexOf(\"\\n\\n\");\n\t    lenNEWLINE = 1;\n\t}\n\tvar i2 = sPKCS5PEM.indexOf(\"-----END\");\n\tif (i1 != -1 && i2 != -1) {\n\t    var s = sPKCS5PEM.substring(i1 + lenNEWLINE * 2, i2 - lenNEWLINE);\n\t    s = s.replace(/\\s+/g, '');\n\t    info.data = s;\n\t}\n\treturn info;\n    };\n\n    var _getKeyAndUnusedIvByPasscodeAndIvsalt = function(algName, passcode, ivsaltHex) {\n\t//alert(\"ivsaltHex(2) = \" + ivsaltHex);\n\tvar saltHex = ivsaltHex.substring(0, 16);\n\t//alert(\"salt = \" + saltHex);\n\t    \n\tvar salt = CryptoJS.enc.Hex.parse(saltHex);\n\tvar data = CryptoJS.enc.Utf8.parse(passcode);\n\t//alert(\"salt = \" + salt);\n\t//alert(\"data = \" + data);\n\n\tvar nRequiredBytes = ALGLIST[algName]['keylen'] + ALGLIST[algName]['ivlen'];\n\tvar hHexValueJoined = '';\n\tvar hLastValue = null;\n\t//alert(\"nRequiredBytes = \" + nRequiredBytes);\n\tfor (;;) {\n\t    var h = CryptoJS.algo.MD5.create();\n\t    if (hLastValue != null) {\n\t\th.update(hLastValue);\n\t    }\n\t    h.update(data);\n\t    h.update(salt);\n\t    hLastValue = h.finalize();\n\t    hHexValueJoined = hHexValueJoined + CryptoJS.enc.Hex.stringify(hLastValue);\n\t    //alert(\"joined = \" + hHexValueJoined);\n\t    if (hHexValueJoined.length >= nRequiredBytes * 2) {\n\t\tbreak;\n\t    }\n\t}\n\tvar result = {};\n\tresult.keyhex = hHexValueJoined.substr(0, ALGLIST[algName]['keylen'] * 2);\n\tresult.ivhex = hHexValueJoined.substr(ALGLIST[algName]['keylen'] * 2, ALGLIST[algName]['ivlen'] * 2);\n\treturn result;\n    };\n\n    /*\n     * @param {String} privateKeyB64 base64 string of encrypted private key\n     * @param {String} sharedKeyAlgName algorithm name of shared key encryption\n     * @param {String} sharedKeyHex hexadecimal string of shared key to encrypt\n     * @param {String} ivsaltHex hexadecimal string of IV and salt\n     * @param {String} hexadecimal string of decrypted private key\n     */\n    var _decryptKeyB64 = function(privateKeyB64, sharedKeyAlgName, sharedKeyHex, ivsaltHex) {\n\tvar privateKeyWA = CryptoJS.enc.Base64.parse(privateKeyB64);\n\tvar privateKeyHex = CryptoJS.enc.Hex.stringify(privateKeyWA);\n\tvar f = ALGLIST[sharedKeyAlgName]['proc'];\n\tvar decryptedKeyHex = f(privateKeyHex, sharedKeyHex, ivsaltHex);\n\treturn decryptedKeyHex;\n    };\n    \n    /*\n     * @param {String} privateKeyHex hexadecimal string of private key\n     * @param {String} sharedKeyAlgName algorithm name of shared key encryption\n     * @param {String} sharedKeyHex hexadecimal string of shared key to encrypt\n     * @param {String} ivsaltHex hexadecimal string of IV and salt\n     * @param {String} base64 string of encrypted private key\n     */\n    var _encryptKeyHex = function(privateKeyHex, sharedKeyAlgName, sharedKeyHex, ivsaltHex) {\n\tvar f = ALGLIST[sharedKeyAlgName]['eproc'];\n\tvar encryptedKeyB64 = f(privateKeyHex, sharedKeyHex, ivsaltHex);\n\treturn encryptedKeyB64;\n    };\n\n    // *****************************************************************\n    // *** PUBLIC PROPERTIES AND METHODS *******************************\n    // *****************************************************************\n    return {\n        // -- UTILITY METHODS ------------------------------------------------------------\n\t/**\n         * decrypt private key by shared key\n\t * @name version\n\t * @memberOf PKCS5PKEY\n\t * @property {String} version\n\t * @description version string of PKCS5PKEY class\n\t */\n\tversion: \"1.0.5\",\n\n\t/**\n         * get hexacedimal string of PEM format\n\t * @name getHexFromPEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} sPEM PEM formatted string\n\t * @param {String} sHead PEM header string without BEGIN/END\n\t * @return {String} hexadecimal string data of PEM contents\n\t * @since pkcs5pkey 1.0.5\n\t */\n        getHexFromPEM: function(sPEM, sHead) {\n\t    var s = sPEM;\n\t    if (s.indexOf(\"BEGIN \" + sHead) == -1) {\n\t\tthrow \"can't find PEM header: \" + sHead;\n\t    }\n\t    s = s.replace(\"-----BEGIN \" + sHead + \"-----\", \"\");\n\t    s = s.replace(\"-----END \" + sHead + \"-----\", \"\");\n\t    var sB64 = s.replace(/\\s+/g, '');\n            var dataHex = b64tohex(sB64);\n\t    return dataHex;\n\t},\n\n\t/**\n         * decrypt private key by shared key\n\t * @name getDecryptedKeyHexByKeyIV\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} encryptedKeyHex hexadecimal string of encrypted private key\n\t * @param {String} algName name of symmetric key algorithm (ex. 'DES-EBE3-CBC')\n\t * @param {String} sharedKeyHex hexadecimal string of symmetric key\n\t * @param {String} ivHex hexadecimal string of initial vector(IV).\n\t * @return {String} hexadecimal string of decrypted privated key\n\t */\n\tgetDecryptedKeyHexByKeyIV: function(encryptedKeyHex, algName, sharedKeyHex, ivHex) {\n\t    var f1 = getFuncByName(algName);\n\t    return f1(encryptedKeyHex, sharedKeyHex, ivHex);\n\t},\n\n\t/**\n         * parse PEM formatted passcode protected PKCS#5 private key\n\t * @name parsePKCS5PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} sEncryptedPEM PEM formatted protected passcode protected PKCS#5 private key\n\t * @return {Hash} hash of key information\n\t * @description\n         * Resulted hash has following attributes.\n\t * <ul>\n\t * <li>cipher - symmetric key algorithm name (ex. 'DES-EBE3-CBC', 'AES-256-CBC')</li>\n\t * <li>ivsalt - IV used for decrypt. Its heading 8 bytes will be used for passcode salt.</li>\n\t * <li>type - asymmetric key algorithm name of private key described in PEM header.</li>\n\t * <li>data - base64 encoded encrypted private key.</li>\n\t * </ul>\n         *\n\t */\n        parsePKCS5PEM: function(sPKCS5PEM) {\n\t    return _parsePKCS5PEM(sPKCS5PEM);\n\t},\n\n\t/**\n         * the same function as OpenSSL EVP_BytsToKey to generate shared key and IV\n\t * @name getKeyAndUnusedIvByPasscodeAndIvsalt\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} algName name of symmetric key algorithm (ex. 'DES-EBE3-CBC')\n\t * @param {String} passcode passcode to decrypt private key (ex. 'password')\n\t * @param {String} hexadecimal string of IV. heading 8 bytes will be used for passcode salt\n\t * @return {Hash} hash of key and unused IV (ex. {keyhex:2fe3..., ivhex:3fad..})\n\t */\n\tgetKeyAndUnusedIvByPasscodeAndIvsalt: function(algName, passcode, ivsaltHex) {\n\t    return _getKeyAndUnusedIvByPasscodeAndIvsalt(algName, passcode, ivsaltHex);\n\t},\n\n        decryptKeyB64: function(privateKeyB64, sharedKeyAlgName, sharedKeyHex, ivsaltHex) {\n\t    return _decryptKeyB64(privateKeyB64, sharedKeyAlgName, sharedKeyHex, ivsaltHex);\n        },\n\n\t/**\n         * decrypt PEM formatted protected PKCS#5 private key with passcode\n\t * @name getDecryptedKeyHex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} sEncryptedPEM PEM formatted protected passcode protected PKCS#5 private key\n\t * @param {String} passcode passcode to decrypt private key (ex. 'password')\n\t * @return {String} hexadecimal string of decrypted RSA priavte key\n\t */\n\tgetDecryptedKeyHex: function(sEncryptedPEM, passcode) {\n\t    // 1. parse pem\n\t    var info = _parsePKCS5PEM(sEncryptedPEM);\n\t    var publicKeyAlgName = info.type;\n\t    var sharedKeyAlgName = info.cipher;\n\t    var ivsaltHex = info.ivsalt;\n\t    var privateKeyB64 = info.data;\n\t    //alert(\"ivsaltHex = \" + ivsaltHex);\n\n\t    // 2. generate shared key\n\t    var sharedKeyInfo = _getKeyAndUnusedIvByPasscodeAndIvsalt(sharedKeyAlgName, passcode, ivsaltHex);\n\t    var sharedKeyHex = sharedKeyInfo.keyhex;\n\t    //alert(\"sharedKeyHex = \" + sharedKeyHex);\n\n\t    // 3. decrypt private key\n            var decryptedKey = _decryptKeyB64(privateKeyB64, sharedKeyAlgName, sharedKeyHex, ivsaltHex);\n\t    return decryptedKey;\n\t},\n\n\t/**\n         * read PEM formatted encrypted PKCS#5 private key and returns RSAKey object\n\t * @name getRSAKeyFromEncryptedPKCS5PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} sEncryptedP5PEM PEM formatted encrypted PKCS#5 private key\n\t * @param {String} passcode passcode to decrypt private key\n\t * @return {RSAKey} loaded RSAKey object of RSA private key\n         * @since pkcs5pkey 1.0.2\n\t */\n\tgetRSAKeyFromEncryptedPKCS5PEM: function(sEncryptedP5PEM, passcode) {\n\t    var hPKey = this.getDecryptedKeyHex(sEncryptedP5PEM, passcode);\n\t    var rsaKey = new RSAKey();\n\t    rsaKey.readPrivateKeyFromASN1HexString(hPKey);\n\t    return rsaKey;\n\t},\n\n\t/**\n         * get PEM formatted encrypted PKCS#5 private key from hexadecimal string of plain private key\n\t * @name getEryptedPKCS5PEMFromPrvKeyHex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} hPrvKey hexadecimal string of plain private key\n\t * @param {String} passcode pass code to protect private key (ex. password)\n\t * @param {String} sharedKeyAlgName algorithm name to protect private key (ex. AES-256-CBC)\n\t * @param {String} ivsaltHex hexadecimal string of IV and salt\n\t * @return {String} string of PEM formatted encrypted PKCS#5 private key\n         * @since pkcs5pkey 1.0.2\n\t * @description\n\t * <br/>\n\t * generate PEM formatted encrypted PKCS#5 private key by hexadecimal string encoded\n\t * ASN.1 object of plain RSA private key.\n\t * Following arguments can be omitted.\n\t * <ul>\n\t * <li>alg - AES-256-CBC will be used if omitted.</li>\n\t * <li>ivsaltHex - automatically generate IV and salt which length depends on algorithm</li>\n\t * </ul>\n\t * @example\n\t * var pem = \n         *   PKCS5PKEY.getEryptedPKCS5PEMFromPrvKeyHex(plainKeyHex, \"password\");\n\t * var pem2 = \n         *   PKCS5PKEY.getEryptedPKCS5PEMFromPrvKeyHex(plainKeyHex, \"password\", \"AES-128-CBC\");\n\t * var pem3 = \n         *   PKCS5PKEY.getEryptedPKCS5PEMFromPrvKeyHex(plainKeyHex, \"password\", \"AES-128-CBC\", \"1f3d02...\");\n\t */\n\tgetEryptedPKCS5PEMFromPrvKeyHex: function(hPrvKey, passcode, sharedKeyAlgName, ivsaltHex) {\n\t    var sPEM = \"\";\n\n\t    // 1. set sharedKeyAlgName if undefined (default AES-256-CBC)\n\t    if (typeof sharedKeyAlgName == \"undefined\" || sharedKeyAlgName == null) {\n\t\tsharedKeyAlgName = \"AES-256-CBC\";\n\t    }\n\t    if (typeof ALGLIST[sharedKeyAlgName] == \"undefined\")\n\t\tthrow \"PKCS5PKEY unsupported algorithm: \" + sharedKeyAlgName;\n\n\t    // 2. set ivsaltHex if undefined\n\t    if (typeof ivsaltHex == \"undefined\" || ivsaltHex == null) {\n\t\tvar ivlen = ALGLIST[sharedKeyAlgName]['ivlen'];\n\t\tvar randIV = _generateIvSaltHex(ivlen);\n\t\tivsaltHex = randIV.toUpperCase();\n\t    }\n\n\t    // 3. get shared key\n            //alert(\"ivsalthex=\" + ivsaltHex);\n\t    var sharedKeyInfo = _getKeyAndUnusedIvByPasscodeAndIvsalt(sharedKeyAlgName, passcode, ivsaltHex);\n\t    var sharedKeyHex = sharedKeyInfo.keyhex;\n\t    // alert(\"sharedKeyHex = \" + sharedKeyHex);\n\n            // 3. get encrypted Key in Base64\n            var encryptedKeyB64 = _encryptKeyHex(hPrvKey, sharedKeyAlgName, sharedKeyHex, ivsaltHex);\n\n\t    var pemBody = encryptedKeyB64.replace(/(.{64})/g, \"$1\\r\\n\");\n\t    var sPEM = \"-----BEGIN RSA PRIVATE KEY-----\\r\\n\";\n\t    sPEM += \"Proc-Type: 4,ENCRYPTED\\r\\n\";\n\t    sPEM += \"DEK-Info: \" + sharedKeyAlgName + \",\" + ivsaltHex + \"\\r\\n\";\n\t    sPEM += \"\\r\\n\";\n\t    sPEM += pemBody;\n\t    sPEM += \"\\r\\n-----END RSA PRIVATE KEY-----\\r\\n\";\n\n\t    return sPEM;\n        },\n\n\t/**\n         * get PEM formatted encrypted PKCS#5 private key from RSAKey object of private key\n\t * @name getEryptedPKCS5PEMFromRSAKey\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {RSAKey} pKey RSAKey object of private key\n\t * @param {String} passcode pass code to protect private key (ex. password)\n\t * @param {String} alg algorithm name to protect private key (default AES-256-CBC)\n\t * @param {String} ivsaltHex hexadecimal string of IV and salt (default generated random IV)\n\t * @return {String} string of PEM formatted encrypted PKCS#5 private key\n         * @since pkcs5pkey 1.0.2\n\t * @description\n\t * <br/>\n\t * generate PEM formatted encrypted PKCS#5 private key by\n\t * {@link RSAKey} object of RSA private key and passcode.\n\t * Following argument can be omitted.\n\t * <ul>\n\t * <li>alg - AES-256-CBC will be used if omitted.</li>\n\t * <li>ivsaltHex - automatically generate IV and salt which length depends on algorithm</li>\n\t * </ul>\n\t * @example\n\t * var pkey = new RSAKey();\n\t * pkey.generate(1024, '10001'); // generate 1024bit RSA private key with public exponent 'x010001'\n\t * var pem = PKCS5PKEY.getEryptedPKCS5PEMFromRSAKey(pkey, \"password\");\n\t */\n        getEryptedPKCS5PEMFromRSAKey: function(pKey, passcode, alg, ivsaltHex) {\n\t    var version = new KJUR.asn1.DERInteger({'int': 0});\n\t    var n = new KJUR.asn1.DERInteger({'bigint': pKey.n});\n\t    var e = new KJUR.asn1.DERInteger({'int': pKey.e});\n\t    var d = new KJUR.asn1.DERInteger({'bigint': pKey.d});\n\t    var p = new KJUR.asn1.DERInteger({'bigint': pKey.p});\n\t    var q = new KJUR.asn1.DERInteger({'bigint': pKey.q});\n\t    var dmp1 = new KJUR.asn1.DERInteger({'bigint': pKey.dmp1});\n\t    var dmq1 = new KJUR.asn1.DERInteger({'bigint': pKey.dmq1});\n\t    var coeff = new KJUR.asn1.DERInteger({'bigint': pKey.coeff});\n\t    var seq = new KJUR.asn1.DERSequence({'array': [version, n, e, d, p, q, dmp1, dmq1, coeff]});\n\t    var hex = seq.getEncodedHex();\n\t    return this.getEryptedPKCS5PEMFromPrvKeyHex(hex, passcode, alg, ivsaltHex);\n        },\n\n\t/**\n         * generate RSAKey and PEM formatted encrypted PKCS#5 private key\n\t * @name newEncryptedPKCS5PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} passcode pass code to protect private key (ex. password)\n\t * @param {Integer} keyLen key bit length of RSA key to be generated. (default 1024)\n\t * @param {String} hPublicExponent hexadecimal string of public exponent (default 10001)\n\t * @param {String} alg shared key algorithm to encrypt private key (default AES-258-CBC)\n\t * @return {String} string of PEM formatted encrypted PKCS#5 private key\n         * @since pkcs5pkey 1.0.2\n\t * @example\n\t * var pem1 = PKCS5PKEY.newEncryptedPKCS5PEM(\"password\");           // RSA1024bit/10001/AES-256-CBC\n\t * var pem2 = PKCS5PKEY.newEncryptedPKCS5PEM(\"password\", 512);      // RSA 512bit/10001/AES-256-CBC\n\t * var pem3 = PKCS5PKEY.newEncryptedPKCS5PEM(\"password\", 512, '3'); // RSA 512bit/    3/AES-256-CBC\n\t */\n\tnewEncryptedPKCS5PEM: function(passcode, keyLen, hPublicExponent, alg) {\n\t    if (typeof keyLen == \"undefined\" || keyLen == null) {\n\t\tkeyLen = 1024;\n\t    }\n\t    if (typeof hPublicExponent == \"undefined\" || hPublicExponent == null) {\n\t\thPublicExponent = '10001';\n\t    }\n\t    var pKey = new RSAKey();\n\t    pKey.generate(keyLen, hPublicExponent);\n\t    var pem = null;\n\t    if (typeof alg == \"undefined\" || alg == null) {\n\t\tpem = this.getEncryptedPKCS5PEMFromRSAKey(pkey, passcode);\n\t    } else {\n\t\tpem = this.getEncryptedPKCS5PEMFromRSAKey(pkey, passcode, alg);\n\t    }\n\t    return pem;\n        },\n\n\t// === PKCS8 ===============================================================\n\n\t/**\n         * read PEM formatted unencrypted PKCS#8 private key and returns RSAKey object\n\t * @name getRSAKeyFromPlainPKCS8PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PEM PEM formatted unencrypted PKCS#8 private key\n\t * @return {RSAKey} loaded RSAKey object of RSA private key\n         * @since pkcs5pkey 1.0.1\n\t */\n        getRSAKeyFromPlainPKCS8PEM: function(pkcs8PEM) {\n            if (pkcs8PEM.match(/ENCRYPTED/))\n                throw \"pem shall be not ENCRYPTED\";\n            var prvKeyHex = this.getHexFromPEM(pkcs8PEM, \"PRIVATE KEY\");\n            var rsaKey = this.getRSAKeyFromPlainPKCS8Hex(prvKeyHex);\n\t    return rsaKey;\n        },\n\n\t/**\n         * provide hexadecimal string of unencrypted PKCS#8 private key and returns RSAKey object\n\t * @name getRSAKeyFromPlainPKCS8Hex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} prvKeyHex hexadecimal string of unencrypted PKCS#8 private key\n\t * @return {RSAKey} loaded RSAKey object of RSA private key\n         * @since pkcs5pkey 1.0.3\n\t */\n        getRSAKeyFromPlainPKCS8Hex: function(prvKeyHex) {\n\t    var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(prvKeyHex, 0);\n\t    if (a1.length != 3)\n\t\tthrow \"outer DERSequence shall have 3 elements: \" + a1.length;\n            var algIdTLV =ASN1HEX.getHexOfTLV_AtObj(prvKeyHex, a1[1]);\n\t    if (algIdTLV != \"300d06092a864886f70d0101010500\") // AlgId rsaEncryption\n\t\tthrow \"PKCS8 AlgorithmIdentifier is not rsaEnc: \" + algIdTLV;\n            var algIdTLV = ASN1HEX.getHexOfTLV_AtObj(prvKeyHex, a1[1]);\n\t    var octetStr = ASN1HEX.getHexOfTLV_AtObj(prvKeyHex, a1[2]);\n\t    var p5KeyHex = ASN1HEX.getHexOfV_AtObj(octetStr, 0);\n            //alert(p5KeyHex);\n\t    var rsaKey = new RSAKey();\n\t    rsaKey.readPrivateKeyFromASN1HexString(p5KeyHex);\n\t    return rsaKey;\n        },\n\n\t/**\n         * generate PBKDF2 key hexstring with specified passcode and information\n\t * @name parseHexOfEncryptedPKCS8\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} passcode passcode to decrypto private key\n\t * @return {Array} info associative array of PKCS#8 parameters\n         * @since pkcs5pkey 1.0.3\n\t * @description\n\t * The associative array which is returned by this method has following properties:\n\t * <ul>\n\t * <li>info.pbkdf2Salt - hexadecimal string of PBKDF2 salt</li>\n\t * <li>info.pkbdf2Iter - iteration count</li>\n\t * <li>info.ciphertext - hexadecimal string of encrypted private key</li>\n\t * <li>info.encryptionSchemeAlg - encryption algorithm name (currently TripleDES only)</li>\n\t * <li>info.encryptionSchemeIV - initial vector for encryption algorithm</li>\n\t * </ul>\n\t * Currently, this method only supports PKCS#5v2.0 with PBES2/PBDKF2 of HmacSHA1 and TripleDES.\n\t * <ul>\n\t * <li>keyDerivationFunc = pkcs5PBKDF2 with HmacSHA1</li>\n\t * <li>encryptionScheme = des-EDE3-CBC(i.e. TripleDES</li>\n\t * </ul>\n\t * @example\n\t * // to convert plain PKCS#5 private key to encrypted PKCS#8 private\n\t * // key with PBKDF2 with TripleDES\n\t * % openssl pkcs8 -in plain_p5.pem -topk8 -v2 -des3 -out encrypted_p8.pem\n\t */\n        parseHexOfEncryptedPKCS8: function(sHEX) {\n            var info = {};\n\t    \n\t    var a0 = ASN1HEX.getPosArrayOfChildren_AtObj(sHEX, 0);\n\t    if (a0.length != 2)\n\t\tthrow \"malformed format: SEQUENCE(0).items != 2: \" + a0.length;\n\n\t    // 1. ciphertext\n\t    info.ciphertext = ASN1HEX.getHexOfV_AtObj(sHEX, a0[1]);\n\n\t    // 2. pkcs5PBES2\n\t    var a0_0 = ASN1HEX.getPosArrayOfChildren_AtObj(sHEX, a0[0]); \n\t    if (a0_0.length != 2)\n\t\tthrow \"malformed format: SEQUENCE(0.0).items != 2: \" + a0_0.length;\n\n\t    // 2.1 check if pkcs5PBES2(1 2 840 113549 1 5 13)\n\t    if (ASN1HEX.getHexOfV_AtObj(sHEX, a0_0[0]) != \"2a864886f70d01050d\")\n\t\tthrow \"this only supports pkcs5PBES2\";\n\n\t    // 2.2 pkcs5PBES2 param\n            var a0_0_1 = ASN1HEX.getPosArrayOfChildren_AtObj(sHEX, a0_0[1]); \n\t    if (a0_0.length != 2)\n\t\tthrow \"malformed format: SEQUENCE(0.0.1).items != 2: \" + a0_0_1.length;\n\n\t    // 2.2.1 encryptionScheme\n\t    var a0_0_1_1 = ASN1HEX.getPosArrayOfChildren_AtObj(sHEX, a0_0_1[1]); \n\t    if (a0_0_1_1.length != 2)\n\t\tthrow \"malformed format: SEQUENCE(0.0.1.1).items != 2: \" + a0_0_1_1.length;\n\t    if (ASN1HEX.getHexOfV_AtObj(sHEX, a0_0_1_1[0]) != \"2a864886f70d0307\")\n\t\tthrow \"this only supports TripleDES\";\n\t    info.encryptionSchemeAlg = \"TripleDES\";\n\n\t    // 2.2.1.1 IV of encryptionScheme\n\t    info.encryptionSchemeIV = ASN1HEX.getHexOfV_AtObj(sHEX, a0_0_1_1[1]);\n\n\t    // 2.2.2 keyDerivationFunc\n\t    var a0_0_1_0 = ASN1HEX.getPosArrayOfChildren_AtObj(sHEX, a0_0_1[0]); \n\t    if (a0_0_1_0.length != 2)\n\t\tthrow \"malformed format: SEQUENCE(0.0.1.0).items != 2: \" + a0_0_1_0.length;\n\t    if (ASN1HEX.getHexOfV_AtObj(sHEX, a0_0_1_0[0]) != \"2a864886f70d01050c\")\n\t\tthrow \"this only supports pkcs5PBKDF2\";\n\n\t    // 2.2.2.1 pkcs5PBKDF2 param\n\t    var a0_0_1_0_1 = ASN1HEX.getPosArrayOfChildren_AtObj(sHEX, a0_0_1_0[1]); \n\t    if (a0_0_1_0_1.length < 2)\n\t\tthrow \"malformed format: SEQUENCE(0.0.1.0.1).items < 2: \" + a0_0_1_0_1.length;\n\n\t    // 2.2.2.1.1 PBKDF2 salt\n\t    info.pbkdf2Salt = ASN1HEX.getHexOfV_AtObj(sHEX, a0_0_1_0_1[0]);\n\n\t    // 2.2.2.1.2 PBKDF2 iter\n\t    var iterNumHex = ASN1HEX.getHexOfV_AtObj(sHEX, a0_0_1_0_1[1]);\n\t    try {\n\t\tinfo.pbkdf2Iter = parseInt(iterNumHex, 16);\n\t    } catch(ex) {\n\t\tthrow \"malformed format pbkdf2Iter: \" + iterNumHex;\n\t    }\n\n\t    return info;\n\t},\n\n\t/**\n         * generate PBKDF2 key hexstring with specified passcode and information\n\t * @name getPBKDF2KeyHexFromParam\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {Array} info result of {@link parseHexOfEncryptedPKCS8} which has preference of PKCS#8 file\n\t * @param {String} passcode passcode to decrypto private key\n\t * @return {String} hexadecimal string of PBKDF2 key\n         * @since pkcs5pkey 1.0.3\n\t * @description\n\t * As for info, this uses following properties:\n\t * <ul>\n\t * <li>info.pbkdf2Salt - hexadecimal string of PBKDF2 salt</li>\n\t * <li>info.pkbdf2Iter - iteration count</li>\n\t * </ul>\n\t * Currently, this method only supports PKCS#5v2.0 with PBES2/PBDKF2 of HmacSHA1 and TripleDES.\n\t * <ul>\n\t * <li>keyDerivationFunc = pkcs5PBKDF2 with HmacSHA1</li>\n\t * <li>encryptionScheme = des-EDE3-CBC(i.e. TripleDES</li>\n\t * </ul>\n\t * @example\n\t * // to convert plain PKCS#5 private key to encrypted PKCS#8 private\n\t * // key with PBKDF2 with TripleDES\n\t * % openssl pkcs8 -in plain_p5.pem -topk8 -v2 -des3 -out encrypted_p8.pem\n\t */\n\tgetPBKDF2KeyHexFromParam: function(info, passcode) {\n\t    var pbkdf2SaltWS = CryptoJS.enc.Hex.parse(info.pbkdf2Salt);\n\t    var pbkdf2Iter = info.pbkdf2Iter;\n\t    var pbkdf2KeyWS = CryptoJS.PBKDF2(passcode, \n\t\t\t\t\t      pbkdf2SaltWS, \n\t\t\t\t\t      { keySize: 192/32, iterations: pbkdf2Iter });\n\t    var pbkdf2KeyHex = CryptoJS.enc.Hex.stringify(pbkdf2KeyWS);\n\t    return pbkdf2KeyHex;\n\t},\n\n\t/**\n         * read PEM formatted encrypted PKCS#8 private key and returns hexadecimal string of plain PKCS#8 private key\n\t * @name getPlainPKCS8HexFromEncryptedPKCS8PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PEM PEM formatted encrypted PKCS#8 private key\n\t * @param {String} passcode passcode to decrypto private key\n\t * @return {String} hexadecimal string of plain PKCS#8 private key\n         * @since pkcs5pkey 1.0.3\n\t * @description\n\t * Currently, this method only supports PKCS#5v2.0 with PBES2/PBDKF2 of HmacSHA1 and TripleDES.\n\t * <ul>\n\t * <li>keyDerivationFunc = pkcs5PBKDF2 with HmacSHA1</li>\n\t * <li>encryptionScheme = des-EDE3-CBC(i.e. TripleDES</li>\n\t * </ul>\n\t * @example\n\t * // to convert plain PKCS#5 private key to encrypted PKCS#8 private\n\t * // key with PBKDF2 with TripleDES\n\t * % openssl pkcs8 -in plain_p5.pem -topk8 -v2 -des3 -out encrypted_p8.pem\n\t */\n\tgetPlainPKCS8HexFromEncryptedPKCS8PEM: function(pkcs8PEM, passcode) {\n\t    // 1. derHex - PKCS#8 private key encrypted by PBKDF2\n            var derHex = this.getHexFromPEM(pkcs8PEM, \"ENCRYPTED PRIVATE KEY\");\n\t    // 2. info - PKCS#5 PBES info\n\t    var info = this.parseHexOfEncryptedPKCS8(derHex);\n\t    // 3. hKey - PBKDF2 key\n\t    var pbkdf2KeyHex = PKCS5PKEY.getPBKDF2KeyHexFromParam(info, passcode);\n\t    // 4. decrypt ciphertext by PBKDF2 key\n\t    var encrypted = {};\n\t    encrypted.ciphertext = CryptoJS.enc.Hex.parse(info.ciphertext);\n\t    var pbkdf2KeyWS = CryptoJS.enc.Hex.parse(pbkdf2KeyHex);\n\t    var des3IVWS = CryptoJS.enc.Hex.parse(info.encryptionSchemeIV);\n\t    var decWS = CryptoJS.TripleDES.decrypt(encrypted, pbkdf2KeyWS, { iv: des3IVWS });\n\t    var decHex = CryptoJS.enc.Hex.stringify(decWS);\n\t    return decHex;\n\t},\n\n\t/**\n         * read PEM formatted encrypted PKCS#8 private key and returns RSAKey object\n\t * @name getRSAKeyFromEncryptedPKCS8PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PEM PEM formatted encrypted PKCS#8 private key\n\t * @param {String} passcode passcode to decrypto private key\n\t * @return {RSAKey} loaded RSAKey object of RSA private key\n         * @since pkcs5pkey 1.0.3\n\t * @description\n\t * Currently, this method only supports PKCS#5v2.0 with PBES2/PBDKF2 of HmacSHA1 and TripleDES.\n\t * <ul>\n\t * <li>keyDerivationFunc = pkcs5PBKDF2 with HmacSHA1</li>\n\t * <li>encryptionScheme = des-EDE3-CBC(i.e. TripleDES</li>\n\t * </ul>\n\t * @example\n\t * // to convert plain PKCS#5 private key to encrypted PKCS#8 private\n\t * // key with PBKDF2 with TripleDES\n\t * % openssl pkcs8 -in plain_p5.pem -topk8 -v2 -des3 -out encrypted_p8.pem\n\t */\n        getRSAKeyFromEncryptedPKCS8PEM: function(pkcs8PEM, passcode) {\n\t    var prvKeyHex = this.getPlainPKCS8HexFromEncryptedPKCS8PEM(pkcs8PEM, passcode);\n\t    var rsaKey = this.getRSAKeyFromPlainPKCS8Hex(prvKeyHex);\n\t    return rsaKey;\n        },\n\n\t/**\n         * get RSAKey/ECDSA private key object from encrypted PEM PKCS#8 private key\n\t * @name getKeyFromEncryptedPKCS8PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PEM string of PEM formatted PKCS#8 private key\n\t * @param {String} passcode passcode string to decrypt key\n\t * @return {Object} RSAKey or KJUR.crypto.ECDSA private key object\n\t * @since pkcs5pkey 1.0.5\n\t */\n        getKeyFromEncryptedPKCS8PEM: function(pkcs8PEM, passcode) {\n\t    var prvKeyHex = this.getPlainPKCS8HexFromEncryptedPKCS8PEM(pkcs8PEM, passcode);\n\t    var key = this.getKeyFromPlainPrivatePKCS8Hex(prvKeyHex);\n\t    return key;\n        },\n\n\t/**\n         * parse hexadecimal string of plain PKCS#8 private key\n\t * @name parsePlainPrivatePKCS8Hex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PrvHex hexadecimal string of PKCS#8 plain private key\n\t * @return {Array} associative array of parsed key\n\t * @since pkcs5pkey 1.0.5\n\t * @description\n\t * Resulted associative array has following properties:\n\t * <ul>\n\t * <li>algoid - hexadecimal string of OID of asymmetric key algorithm</li>\n\t * <li>algparam - hexadecimal string of OID of ECC curve name or null</li>\n\t * <li>keyidx - string starting index of key in pkcs8PrvHex</li>\n\t * </ul>\n\t */\n\tparsePlainPrivatePKCS8Hex: function(pkcs8PrvHex) {\n\t    var result = {};\n\t    result.algparam = null;\n\n\t    // 1. sequence\n\t    if (pkcs8PrvHex.substr(0, 2) != \"30\")\n\t\tthrow \"malformed plain PKCS8 private key(code:001)\"; // not sequence\n\n\t    var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(pkcs8PrvHex, 0);\n\t    if (a1.length != 3)\n\t\tthrow \"malformed plain PKCS8 private key(code:002)\";\n\n\t    // 2. AlgID\n            if (pkcs8PrvHex.substr(a1[1], 2) != \"30\")\n                throw \"malformed PKCS8 private key(code:003)\"; // AlgId not sequence\n\n            var a2 = ASN1HEX.getPosArrayOfChildren_AtObj(pkcs8PrvHex, a1[1]);\n            if (a2.length != 2)\n                throw \"malformed PKCS8 private key(code:004)\"; // AlgId not have two elements\n\n\t    // 2.1. AlgID OID\n\t    if (pkcs8PrvHex.substr(a2[0], 2) != \"06\")\n\t\tthrow \"malformed PKCS8 private key(code:005)\"; // AlgId.oid is not OID\n\n\t    result.algoid = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a2[0]);\n\n\t    // 2.2. AlgID param\n\t    if (pkcs8PrvHex.substr(a2[1], 2) == \"06\") {\n\t\tresult.algparam = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a2[1]);\n\t    }\n\n\t    // 3. Key index\n\t    if (pkcs8PrvHex.substr(a1[2], 2) != \"04\")\n\t\tthrow \"malformed PKCS8 private key(code:006)\"; // not octet string\n\n\t    result.keyidx = ASN1HEX.getStartPosOfV_AtObj(pkcs8PrvHex, a1[2]);\n\n\t    return result;\n        },\n\n\t/**\n         * get RSAKey/ECDSA private key object from PEM plain PEM PKCS#8 private key\n\t * @name getKeyFromPlainPrivatePKCS8PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PEM string of plain PEM formatted PKCS#8 private key\n\t * @return {Object} RSAKey or KJUR.crypto.ECDSA private key object\n\t * @since pkcs5pkey 1.0.5\n\t */\n\tgetKeyFromPlainPrivatePKCS8PEM: function(prvKeyPEM) {\n\t    var prvKeyHex = this.getHexFromPEM(prvKeyPEM, \"PRIVATE KEY\");\n\t    var key = this.getKeyFromPlainPrivatePKCS8Hex(prvKeyHex);\n\t    return key;\n\t},\n\n\t/**\n         * get RSAKey/ECDSA private key object from HEX plain PEM PKCS#8 private key\n\t * @name getKeyFromPlainPrivatePKCS8Hex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} prvKeyHex hexadecimal string of plain PKCS#8 private key\n\t * @return {Object} RSAKey or KJUR.crypto.ECDSA private key object\n\t * @since pkcs5pkey 1.0.5\n\t */\n\tgetKeyFromPlainPrivatePKCS8Hex: function(prvKeyHex) {\n\t    var p8 = this.parsePlainPrivatePKCS8Hex(prvKeyHex);\n\t    \n\t    if (p8.algoid == \"2a864886f70d010101\") { // RSA\n\t\tthis.parsePrivateRawRSAKeyHexAtObj(prvKeyHex, p8);\n\t\tvar k = p8.key;\n\t\tvar key = new RSAKey();\n\t\tkey.setPrivateEx(k.n, k.e, k.d, k.p, k.q, k.dp, k.dq, k.co);\n\t\treturn key;\n\t    } else if (p8.algoid == \"2a8648ce3d0201\") { // ECC\n\t\tthis.parsePrivateRawECKeyHexAtObj(prvKeyHex, p8);\n\t\tif (KJUR.crypto.OID.oidhex2name[p8.algparam] === undefined)\n\t\t    throw \"KJUR.crypto.OID.oidhex2name undefined: \" + p8.algparam;\n\t\tvar curveName = KJUR.crypto.OID.oidhex2name[p8.algparam];\n\t\tvar key = new KJUR.crypto.ECDSA({'curve': curveName, 'prv': p8.key});\n\t\treturn key;\n\t    } else {\n\t\tthrow \"unsupported private key algorithm\";\n\t    }\n\t},\n\n\t// === PKCS8 RSA Public Key ================================================\n\t/**\n         * read PEM formatted PKCS#8 public key and returns RSAKey object\n\t * @name getRSAKeyFromPublicPKCS8PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PubPEM PEM formatted PKCS#8 public key\n\t * @return {RSAKey} loaded RSAKey object of RSA public key\n         * @since pkcs5pkey 1.0.4\n\t */\n        getRSAKeyFromPublicPKCS8PEM: function(pkcs8PubPEM) {\n            var pubKeyHex = this.getHexFromPEM(pkcs8PubPEM, \"PUBLIC KEY\");\n            var rsaKey = this.getRSAKeyFromPublicPKCS8Hex(pubKeyHex);\n\t    return rsaKey;\n\t},\n\n\t/**\n         * get RSAKey/ECDSA public key object from PEM PKCS#8 public key\n\t * @name getKeyFromPublicPKCS8PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcsPub8PEM string of PEM formatted PKCS#8 public key\n\t * @return {Object} RSAKey or KJUR.crypto.ECDSA private key object\n\t * @since pkcs5pkey 1.0.5\n\t */\n        getKeyFromPublicPKCS8PEM: function(pkcs8PubPEM) {\n            var pubKeyHex = this.getHexFromPEM(pkcs8PubPEM, \"PUBLIC KEY\");\n            var key = this.getKeyFromPublicPKCS8Hex(pubKeyHex);\n\t    return key;\n\t},\n\n\t/**\n         * get RSAKey/ECDSA public key object from hexadecimal string of PKCS#8 public key\n\t * @name getKeyFromPublicPKCS8Hex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcsPub8Hex hexadecimal string of PKCS#8 public key\n\t * @return {Object} RSAKey or KJUR.crypto.ECDSA private key object\n\t * @since pkcs5pkey 1.0.5\n\t */\n        getKeyFromPublicPKCS8Hex: function(pkcs8PubHex) {\n\t    var p8 = this.parsePublicPKCS8Hex(pkcs8PubHex);\n\t    \n\t    if (p8.algoid == \"2a864886f70d010101\") { // RSA\n\t\tvar aRSA = this.parsePublicRawRSAKeyHex(p8.key);\n\t\tvar key = new RSAKey();\n\t\tkey.setPublic(aRSA.n, aRSA.e);\n\t\treturn key;\n\t    } else if (p8.algoid == \"2a8648ce3d0201\") { // ECC\n\t\tif (KJUR.crypto.OID.oidhex2name[p8.algparam] === undefined)\n\t\t    throw \"KJUR.crypto.OID.oidhex2name undefined: \" + p8.algparam;\n\t\tvar curveName = KJUR.crypto.OID.oidhex2name[p8.algparam];\n\t\tvar key = new KJUR.crypto.ECDSA({'curve': curveName, 'pub': p8.key});\n\t\treturn key;\n\t    } else {\n\t\tthrow \"unsupported public key algorithm\";\n\t    }\n\t},\n\n\t/**\n         * parse hexadecimal string of plain PKCS#8 private key\n\t * @name parsePublicRawRSAKeyHex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pubRawRSAHex hexadecimal string of ASN.1 encoded PKCS#8 public key\n\t * @return {Array} associative array of parsed key\n\t * @since pkcs5pkey 1.0.5\n\t * @description\n\t * Resulted associative array has following properties:\n\t * <ul>\n\t * <li>n - hexadecimal string of public key\n\t * <li>e - hexadecimal string of public exponent\n\t * </ul>\n\t */\n\tparsePublicRawRSAKeyHex: function(pubRawRSAHex) {\n\t    var result = {};\n\t    \n\t    // 1. Sequence\n\t    if (pubRawRSAHex.substr(0, 2) != \"30\")\n\t\tthrow \"malformed RSA key(code:001)\"; // not sequence\n\t    \n\t    var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(pubRawRSAHex, 0);\n\t    if (a1.length != 2)\n\t\tthrow \"malformed RSA key(code:002)\"; // not 2 items in seq\n\n\t    // 2. public key \"N\"\n\t    if (pubRawRSAHex.substr(a1[0], 2) != \"02\")\n\t\tthrow \"malformed RSA key(code:003)\"; // 1st item is not integer\n\n\t    result.n = ASN1HEX.getHexOfV_AtObj(pubRawRSAHex, a1[0]);\n\n\t    // 3. public key \"E\"\n\t    if (pubRawRSAHex.substr(a1[1], 2) != \"02\")\n\t\tthrow \"malformed RSA key(code:004)\"; // 2nd item is not integer\n\n\t    result.e = ASN1HEX.getHexOfV_AtObj(pubRawRSAHex, a1[1]);\n\n\t    return result;\n\t},\n\n\t/**\n         * parse hexadecimal string of RSA private key\n\t * @name parsePrivateRawRSAKeyHexAtObj\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PrvHex hexadecimal string of PKCS#8 private key concluding RSA private key\n\t * @return {Array} info associative array to add parsed RSA private key information\n\t * @since pkcs5pkey 1.0.5\n\t * @description\n\t * Following properties are added to associative array 'info'\n\t * <ul>\n\t * <li>n - hexadecimal string of public key\n\t * <li>e - hexadecimal string of public exponent\n\t * <li>d - hexadecimal string of private key\n\t * <li>p - hexadecimal string\n\t * <li>q - hexadecimal string\n\t * <li>dp - hexadecimal string\n\t * <li>dq - hexadecimal string\n\t * <li>co - hexadecimal string\n\t * </ul>\n\t */\n\tparsePrivateRawRSAKeyHexAtObj: function(pkcs8PrvHex, info) {\n\t    var keyIdx = info.keyidx;\n\t    \n\t    // 1. sequence\n\t    if (pkcs8PrvHex.substr(keyIdx, 2) != \"30\")\n\t\tthrow \"malformed RSA private key(code:001)\"; // not sequence\n\n\t    var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(pkcs8PrvHex, keyIdx);\n\t    if (a1.length != 9)\n\t\tthrow \"malformed RSA private key(code:002)\"; // not sequence\n\n\t    // 2. RSA key\n\t    info.key = {};\n\t    info.key.n = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[1]);\n\t    info.key.e = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[2]);\n\t    info.key.d = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[3]);\n\t    info.key.p = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[4]);\n\t    info.key.q = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[5]);\n\t    info.key.dp = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[6]);\n\t    info.key.dq = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[7]);\n\t    info.key.co = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[8]);\n\t},\n\n\t/**\n         * parse hexadecimal string of ECC private key\n\t * @name parsePrivateRawECKeyHexAtObj\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PrvHex hexadecimal string of PKCS#8 private key concluding EC private key\n\t * @return {Array} info associative array to add parsed ECC private key information\n\t * @since pkcs5pkey 1.0.5\n\t * @description\n\t * Following properties are added to associative array 'info'\n\t * <ul>\n\t * <li>key - hexadecimal string of ECC private key\n\t * </ul>\n\t */\n\tparsePrivateRawECKeyHexAtObj: function(pkcs8PrvHex, info) {\n\t    var keyIdx = info.keyidx;\n\t    \n\t    // 1. sequence\n\t    if (pkcs8PrvHex.substr(keyIdx, 2) != \"30\")\n\t\tthrow \"malformed ECC private key(code:001)\"; // not sequence\n\n\t    var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(pkcs8PrvHex, keyIdx);\n\t    if (a1.length != 3)\n\t\tthrow \"malformed ECC private key(code:002)\"; // not sequence\n\n\t    // 2. EC private key\n\t    if (pkcs8PrvHex.substr(a1[1], 2) != \"04\")\n\t\tthrow \"malformed ECC private key(code:003)\"; // not octetstring\n\n\t    info.key = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[1]);\n\t},\n\n\t/**\n         * parse hexadecimal string of PKCS#8 public key\n\t * @name parsePublicPKCS8Hex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PubHex hexadecimal string of PKCS#8 public key\n\t * @return {Hash} hash of key information\n\t * @description\n         * Resulted hash has following attributes.\n\t * <ul>\n\t * <li>algoid - hexadecimal string of OID of asymmetric key algorithm</li>\n\t * <li>algparam - hexadecimal string of OID of ECC curve name or null</li>\n\t * <li>key - hexadecimal string of public key</li>\n\t * </ul>\n\t */\n        parsePublicPKCS8Hex: function(pkcs8PubHex) {\n\t    var result = {};\n\t    result.algparam = null;\n\n            // 1. AlgID and Key bit string\n\t    var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(pkcs8PubHex, 0);\n\t    if (a1.length != 2)\n\t\tthrow \"outer DERSequence shall have 2 elements: \" + a1.length;\n\n            // 2. AlgID\n            var idxAlgIdTLV = a1[0];\n            if (pkcs8PubHex.substr(idxAlgIdTLV, 2) != \"30\")\n                throw \"malformed PKCS8 public key(code:001)\"; // AlgId not sequence\n\n            var a2 = ASN1HEX.getPosArrayOfChildren_AtObj(pkcs8PubHex, idxAlgIdTLV);\n            if (a2.length != 2)\n                throw \"malformed PKCS8 public key(code:002)\"; // AlgId not have two elements\n\n\t    // 2.1. AlgID OID\n\t    if (pkcs8PubHex.substr(a2[0], 2) != \"06\")\n\t\tthrow \"malformed PKCS8 public key(code:003)\"; // AlgId.oid is not OID\n\n\t    result.algoid = ASN1HEX.getHexOfV_AtObj(pkcs8PubHex, a2[0]);\n\n\t    // 2.2. AlgID param\n\t    if (pkcs8PubHex.substr(a2[1], 2) == \"06\") {\n\t\tresult.algparam = ASN1HEX.getHexOfV_AtObj(pkcs8PubHex, a2[1]);\n\t    }\n\n\t    // 3. Key\n\t    if (pkcs8PubHex.substr(a1[1], 2) != \"03\")\n\t\tthrow \"malformed PKCS8 public key(code:004)\"; // Key is not bit string\n\n\t    result.key = ASN1HEX.getHexOfV_AtObj(pkcs8PubHex, a1[1]).substr(2);\n            \n\t    // 4. return result assoc array\n\t    return result;\n        },\n\n\t/**\n         * provide hexadecimal string of unencrypted PKCS#8 private key and returns RSAKey object\n\t * @name getRSAKeyFromPublicPKCS8Hex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PubHex hexadecimal string of unencrypted PKCS#8 public key\n\t * @return {RSAKey} loaded RSAKey object of RSA public key\n         * @since pkcs5pkey 1.0.4\n\t */\n        getRSAKeyFromPublicPKCS8Hex: function(pkcs8PubHex) {\n\t    var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(pkcs8PubHex, 0);\n\t    if (a1.length != 2)\n\t\tthrow \"outer DERSequence shall have 2 elements: \" + a1.length;\n\n            var algIdTLV =ASN1HEX.getHexOfTLV_AtObj(pkcs8PubHex, a1[0]);\n\t    if (algIdTLV != \"300d06092a864886f70d0101010500\") // AlgId rsaEncryption\n\t\tthrow \"PKCS8 AlgorithmId is not rsaEncryption\";\n\t    \n\t    if (pkcs8PubHex.substr(a1[1], 2) != \"03\")\n\t\tthrow \"PKCS8 Public Key is not BITSTRING encapslated.\";\n\n\t    var idxPub = ASN1HEX.getStartPosOfV_AtObj(pkcs8PubHex, a1[1]) + 2; // 2 for unused bit\n\t    \n\t    if (pkcs8PubHex.substr(idxPub, 2) != \"30\")\n\t\tthrow \"PKCS8 Public Key is not SEQUENCE.\";\n\n\t    var a2 = ASN1HEX.getPosArrayOfChildren_AtObj(pkcs8PubHex, idxPub);\n\t    if (a2.length != 2)\n\t\tthrow \"inner DERSequence shall have 2 elements: \" + a2.length;\n\n\t    if (pkcs8PubHex.substr(a2[0], 2) != \"02\") \n\t\tthrow \"N is not ASN.1 INTEGER\";\n\t    if (pkcs8PubHex.substr(a2[1], 2) != \"02\") \n\t\tthrow \"E is not ASN.1 INTEGER\";\n\t\t\n\t    var hN = ASN1HEX.getHexOfV_AtObj(pkcs8PubHex, a2[0]);\n\t    var hE = ASN1HEX.getHexOfV_AtObj(pkcs8PubHex, a2[1]);\n\n\t    var pubKey = new RSAKey();\n\t    pubKey.setPublic(hN, hE);\n\t    \n\t    return pubKey;\n\t},\n\n\t//addAlgorithm: function(functionObject, algName, keyLen, ivLen) {\n\t//}\n    };\n}();\n"
  },
  {
    "path": "JavaScript/demo/js/prng4.js",
    "content": "/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\n// prng4.js - uses Arcfour as a PRNG\n\nfunction Arcfour() {\n  this.i = 0;\n  this.j = 0;\n  this.S = new Array();\n}\n\n// Initialize arcfour context from key, an array of ints, each from [0..255]\nfunction ARC4init(key) {\n  var i, j, t;\n  for(i = 0; i < 256; ++i)\n    this.S[i] = i;\n  j = 0;\n  for(i = 0; i < 256; ++i) {\n    j = (j + this.S[i] + key[i % key.length]) & 255;\n    t = this.S[i];\n    this.S[i] = this.S[j];\n    this.S[j] = t;\n  }\n  this.i = 0;\n  this.j = 0;\n}\n\nfunction ARC4next() {\n  var t;\n  this.i = (this.i + 1) & 255;\n  this.j = (this.j + this.S[this.i]) & 255;\n  t = this.S[this.i];\n  this.S[this.i] = this.S[this.j];\n  this.S[this.j] = t;\n  return this.S[(t + this.S[this.i]) & 255];\n}\n\nArcfour.prototype.init = ARC4init;\nArcfour.prototype.next = ARC4next;\n\n// Plug in your RNG constructor here\nfunction prng_newstate() {\n  return new Arcfour();\n}\n\n// Pool size must be a multiple of 4 and greater than 32.\n// An array of bytes the size of the pool will be passed to init()\nvar rng_psize = 256;\n"
  },
  {
    "path": "JavaScript/demo/js/rng.js",
    "content": "/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\n// Random number generator - requires a PRNG backend, e.g. prng4.js\n\n// For best results, put code like\n// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>\n// in your main HTML document.\n\nvar rng_state;\nvar rng_pool;\nvar rng_pptr;\n\n// Mix in a 32-bit integer into the pool\nfunction rng_seed_int(x) {\n  rng_pool[rng_pptr++] ^= x & 255;\n  rng_pool[rng_pptr++] ^= (x >> 8) & 255;\n  rng_pool[rng_pptr++] ^= (x >> 16) & 255;\n  rng_pool[rng_pptr++] ^= (x >> 24) & 255;\n  if(rng_pptr >= rng_psize) rng_pptr -= rng_psize;\n}\n\n// Mix in the current time (w/milliseconds) into the pool\nfunction rng_seed_time() {\n  rng_seed_int(new Date().getTime());\n}\n\n// Initialize the pool with junk if needed.\nif(rng_pool == null) {\n  rng_pool = new Array();\n  rng_pptr = 0;\n  var t;\n  if(navigator.appName == \"Netscape\" && navigator.appVersion < \"5\" && window.crypto) {\n    // Extract entropy (256 bits) from NS4 RNG if available\n    var z = window.crypto.random(32);\n    for(t = 0; t < z.length; ++t)\n      rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;\n  }  \n  while(rng_pptr < rng_psize) {  // extract some randomness from Math.random()\n    t = Math.floor(65536 * Math.random());\n    rng_pool[rng_pptr++] = t >>> 8;\n    rng_pool[rng_pptr++] = t & 255;\n  }\n  rng_pptr = 0;\n  rng_seed_time();\n  //rng_seed_int(window.screenX);\n  //rng_seed_int(window.screenY);\n}\n\nfunction rng_get_byte() {\n  if(rng_state == null) {\n    rng_seed_time();\n    rng_state = prng_newstate();\n    rng_state.init(rng_pool);\n    for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)\n      rng_pool[rng_pptr] = 0;\n    rng_pptr = 0;\n    //rng_pool = null;\n  }\n  // TODO: allow reseeding after first request\n  return rng_state.next();\n}\n\nfunction rng_get_bytes(ba) {\n  var i;\n  for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();\n}\n\nfunction SecureRandom() {}\n\nSecureRandom.prototype.nextBytes = rng_get_bytes;\n"
  },
  {
    "path": "JavaScript/demo/js/rsa.js",
    "content": "/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\n// Depends on jsbn.js and rng.js\n\n// Version 1.1: support utf-8 encoding in pkcs1pad2\n\n// convert a (hex) string to a bignum object\nfunction parseBigInt(str,r) {\n  return new BigInteger(str,r);\n}\n\nfunction linebrk(s,n) {\n  var ret = \"\";\n  var i = 0;\n  while(i + n < s.length) {\n    ret += s.substring(i,i+n) + \"\\n\";\n    i += n;\n  }\n  return ret + s.substring(i,s.length);\n}\n\nfunction byte2Hex(b) {\n  if(b < 0x10)\n    return \"0\" + b.toString(16);\n  else\n    return b.toString(16);\n}\n\n// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint\nfunction pkcs1pad2(s,n) {\n  if(n < s.length + 11) { // TODO: fix for utf-8\n    alert(\"Message too long for RSA\");\n    return null;\n  }\n  var ba = new Array();\n  var i = s.length - 1;\n  while(i >= 0 && n > 0) {\n    var c = s.charCodeAt(i--);\n    if(c < 128) { // encode using utf-8\n      ba[--n] = c;\n    }\n    else if((c > 127) && (c < 2048)) {\n      ba[--n] = (c & 63) | 128;\n      ba[--n] = (c >> 6) | 192;\n    }\n    else {\n      ba[--n] = (c & 63) | 128;\n      ba[--n] = ((c >> 6) & 63) | 128;\n      ba[--n] = (c >> 12) | 224;\n    }\n  }\n  ba[--n] = 0;\n  var rng = new SecureRandom();\n  var x = new Array();\n  while(n > 2) { // random non-zero pad\n    x[0] = 0;\n    while(x[0] == 0) rng.nextBytes(x);\n    ba[--n] = x[0];\n  }\n  ba[--n] = 2;\n  ba[--n] = 0;\n  return new BigInteger(ba);\n}\n\n// PKCS#1 (OAEP) mask generation function\nfunction oaep_mgf1_arr(seed, len, hash)\n{\n    var mask = '', i = 0;\n\n    while (mask.length < len)\n    {\n        mask += hash(String.fromCharCode.apply(String, seed.concat([\n                (i & 0xff000000) >> 24,\n                (i & 0x00ff0000) >> 16,\n                (i & 0x0000ff00) >> 8,\n                i & 0x000000ff])));\n        i += 1;\n    }\n\n    return mask;\n}\n\nvar SHA1_SIZE = 20;\n\n// PKCS#1 (OAEP) pad input string s to n bytes, and return a bigint\nfunction oaep_pad(s, n, hash)\n{\n    if (s.length + 2 * SHA1_SIZE + 2 > n)\n    {\n        throw \"Message too long for RSA\";\n    }\n\n    var PS = '', i;\n\n    for (i = 0; i < n - s.length - 2 * SHA1_SIZE - 2; i += 1)\n    {\n        PS += '\\x00';\n    }\n\n    var DB = rstr_sha1('') + PS + '\\x01' + s;\n    var seed = new Array(SHA1_SIZE);\n    new SecureRandom().nextBytes(seed);\n    \n    var dbMask = oaep_mgf1_arr(seed, DB.length, hash || rstr_sha1);\n    var maskedDB = [];\n\n    for (i = 0; i < DB.length; i += 1)\n    {\n        maskedDB[i] = DB.charCodeAt(i) ^ dbMask.charCodeAt(i);\n    }\n\n    var seedMask = oaep_mgf1_arr(maskedDB, seed.length, rstr_sha1);\n    var maskedSeed = [0];\n\n    for (i = 0; i < seed.length; i += 1)\n    {\n        maskedSeed[i + 1] = seed[i] ^ seedMask.charCodeAt(i);\n    }\n\n    return new BigInteger(maskedSeed.concat(maskedDB));\n}\n\n// \"empty\" RSA key constructor\nfunction RSAKey() {\n  this.n = null;\n  this.e = 0;\n  this.d = null;\n  this.p = null;\n  this.q = null;\n  this.dmp1 = null;\n  this.dmq1 = null;\n  this.coeff = null;\n}\n\n// Set the public key fields N and e from hex strings\nfunction RSASetPublic(N,E) {\n  this.isPublic = true;\n  if (typeof N !== \"string\") \n  {\n    this.n = N;\n    this.e = E;\n  }\n  else if(N != null && E != null && N.length > 0 && E.length > 0) {\n    this.n = parseBigInt(N,16);\n    this.e = parseInt(E,16);\n  }\n  else\n    alert(\"Invalid RSA public key\");\n}\n\n// Perform raw public operation on \"x\": return x^e (mod n)\nfunction RSADoPublic(x) {\n  return x.modPowInt(this.e, this.n);\n}\n\n// Return the PKCS#1 RSA encryption of \"text\" as an even-length hex string\nfunction RSAEncrypt(text) {\n  var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);\n  if(m == null) return null;\n  var c = this.doPublic(m);\n  if(c == null) return null;\n  var h = c.toString(16);\n  if((h.length & 1) == 0) return h; else return \"0\" + h;\n}\n\n// Return the PKCS#1 OAEP RSA encryption of \"text\" as an even-length hex string\nfunction RSAEncryptOAEP(text, hash) {\n  var m = oaep_pad(text, (this.n.bitLength()+7)>>3, hash);\n  if(m == null) return null;\n  var c = this.doPublic(m);\n  if(c == null) return null;\n  var h = c.toString(16);\n  if((h.length & 1) == 0) return h; else return \"0\" + h;\n}\n\n// Return the PKCS#1 RSA encryption of \"text\" as a Base64-encoded string\n//function RSAEncryptB64(text) {\n//  var h = this.encrypt(text);\n//  if(h) return hex2b64(h); else return null;\n//}\n\n// protected\nRSAKey.prototype.doPublic = RSADoPublic;\n\n// public\nRSAKey.prototype.setPublic = RSASetPublic;\nRSAKey.prototype.encrypt = RSAEncrypt;\nRSAKey.prototype.encryptOAEP = RSAEncryptOAEP;\n//RSAKey.prototype.encrypt_b64 = RSAEncryptB64;\n\nRSAKey.prototype.type = \"RSA\";\n"
  },
  {
    "path": "JavaScript/demo/js/rsa2.js",
    "content": "/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\n// Depends on rsa.js and jsbn2.js\n\n// Version 1.1: support utf-8 decoding in pkcs1unpad2\n\n// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext\nfunction pkcs1unpad2(d,n) {\n  var b = d.toByteArray();\n  var i = 0;\n  while(i < b.length && b[i] == 0) ++i;\n  if(b.length-i != n-1 || b[i] != 2)\n    return null;\n  ++i;\n  while(b[i] != 0)\n    if(++i >= b.length) return null;\n  var ret = \"\";\n  while(++i < b.length) {\n    var c = b[i] & 255;\n    if(c < 128) { // utf-8 decode\n      ret += String.fromCharCode(c);\n    }\n    else if((c > 191) && (c < 224)) {\n      ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63));\n      ++i;\n    }\n    else {\n      ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63));\n      i += 2;\n    }\n  }\n  return ret;\n}\n\n// PKCS#1 (OAEP) mask generation function\nfunction oaep_mgf1_str(seed, len, hash)\n{\n    var mask = '', i = 0;\n\n    while (mask.length < len)\n    {\n        mask += hash(seed + String.fromCharCode.apply(String, [\n                (i & 0xff000000) >> 24,\n                (i & 0x00ff0000) >> 16,\n                (i & 0x0000ff00) >> 8,\n                i & 0x000000ff]));\n        i += 1;\n    }\n\n    return mask;\n}\n\nvar SHA1_SIZE = 20;\n\n// Undo PKCS#1 (OAEP) padding and, if valid, return the plaintext\nfunction oaep_unpad(d, n, hash)\n{\n    d = d.toByteArray();\n\n    var i;\n\n    for (i = 0; i < d.length; i += 1)\n    {\n        d[i] &= 0xff;\n    }\n\n    while (d.length < n)\n    {\n        d.unshift(0);\n    }\n\n    d = String.fromCharCode.apply(String, d);\n\n    if (d.length < 2 * SHA1_SIZE + 2)\n    {\n        throw \"Cipher too short\";\n    }\n\n    var maskedSeed = d.substr(1, SHA1_SIZE)\n    var maskedDB = d.substr(SHA1_SIZE + 1);\n\n    var seedMask = oaep_mgf1_str(maskedDB, SHA1_SIZE, hash || rstr_sha1);\n    var seed = [], i;\n\n    for (i = 0; i < maskedSeed.length; i += 1)\n    {\n        seed[i] = maskedSeed.charCodeAt(i) ^ seedMask.charCodeAt(i);\n    }\n\n    var dbMask = oaep_mgf1_str(String.fromCharCode.apply(String, seed),\n                           d.length - SHA1_SIZE, rstr_sha1);\n\n    var DB = [];\n\n    for (i = 0; i < maskedDB.length; i += 1)\n    {\n        DB[i] = maskedDB.charCodeAt(i) ^ dbMask.charCodeAt(i);\n    }\n\n    DB = String.fromCharCode.apply(String, DB);\n\n    if (DB.substr(0, SHA1_SIZE) !== rstr_sha1(''))\n    {\n        throw \"Hash mismatch\";\n    }\n\n    DB = DB.substr(SHA1_SIZE);\n\n    var first_one = DB.indexOf('\\x01');\n    var last_zero = (first_one != -1) ? DB.substr(0, first_one).lastIndexOf('\\x00') : -1;\n\n    if (last_zero + 1 != first_one)\n    {\n        throw \"Malformed data\";\n    }\n\n    return DB.substr(first_one + 1);\n}\n\n// Set the private key fields N, e, and d from hex strings\nfunction RSASetPrivate(N,E,D) {\n  this.isPrivate = true;\n  if (typeof N !== \"string\")\n  {\n    this.n = N;\n    this.e = E;\n    this.d = D;\n  }\n  else if(N != null && E != null && N.length > 0 && E.length > 0) {\n    this.n = parseBigInt(N,16);\n    this.e = parseInt(E,16);\n    this.d = parseBigInt(D,16);\n  }\n  else\n    alert(\"Invalid RSA private key\");\n}\n\n// Set the private key fields N, e, d and CRT params from hex strings\nfunction RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) {\n  this.isPrivate = true;\n  if (N == null) throw \"RSASetPrivateEx N == null\";\n  if (E == null) throw \"RSASetPrivateEx E == null\";\n  if (N.length == 0) throw \"RSASetPrivateEx N.length == 0\";\n  if (E.length == 0) throw \"RSASetPrivateEx E.length == 0\";\n\n  if (N != null && E != null && N.length > 0 && E.length > 0) {\n    this.n = parseBigInt(N,16);\n    this.e = parseInt(E,16);\n    this.d = parseBigInt(D,16);\n    this.p = parseBigInt(P,16);\n    this.q = parseBigInt(Q,16);\n    this.dmp1 = parseBigInt(DP,16);\n    this.dmq1 = parseBigInt(DQ,16);\n    this.coeff = parseBigInt(C,16);\n  } else {\n    alert(\"Invalid RSA private key in RSASetPrivateEx\");\n  }\n}\n\n// Generate a new random private key B bits long, using public expt E\nfunction RSAGenerate(B,E) {\n  var rng = new SecureRandom();\n  var qs = B>>1;\n  this.e = parseInt(E,16);\n  var ee = new BigInteger(E,16);\n  for(;;) {\n    for(;;) {\n      this.p = new BigInteger(B-qs,1,rng);\n      if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break;\n    }\n    for(;;) {\n      this.q = new BigInteger(qs,1,rng);\n      if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break;\n    }\n    if(this.p.compareTo(this.q) <= 0) {\n      var t = this.p;\n      this.p = this.q;\n      this.q = t;\n    }\n    var p1 = this.p.subtract(BigInteger.ONE);\t// p1 = p - 1\n    var q1 = this.q.subtract(BigInteger.ONE);\t// q1 = q - 1\n    var phi = p1.multiply(q1);\n    if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {\n      this.n = this.p.multiply(this.q);\t// this.n = p * q\n      this.d = ee.modInverse(phi);\t// this.d = \n      this.dmp1 = this.d.mod(p1);\t// this.dmp1 = d mod (p - 1)\n      this.dmq1 = this.d.mod(q1);\t// this.dmq1 = d mod (q - 1)\n      this.coeff = this.q.modInverse(this.p);\t// this.coeff = (q ^ -1) mod p\n      break;\n    }\n  }\n}\n\n// Perform raw private operation on \"x\": return x^d (mod n)\nfunction RSADoPrivate(x) {\n  if(this.p == null || this.q == null)\n    return x.modPow(this.d, this.n);\n\n  // TODO: re-calculate any missing CRT params\n  var xp = x.mod(this.p).modPow(this.dmp1, this.p); // xp=cp?\n  var xq = x.mod(this.q).modPow(this.dmq1, this.q); // xq=cq?\n\n  while(xp.compareTo(xq) < 0)\n    xp = xp.add(this.p);\n  // NOTE:\n  // xp.subtract(xq) => cp -cq\n  // xp.subtract(xq).multiply(this.coeff).mod(this.p) => (cp - cq) * u mod p = h\n  // xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq) => cq + (h * q) = M\n  return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);\n}\n\n// Return the PKCS#1 RSA decryption of \"ctext\".\n// \"ctext\" is an even-length hex string and the output is a plain string.\nfunction RSADecrypt(ctext) {\n  var c = parseBigInt(ctext, 16);\n  var m = this.doPrivate(c);\n  if(m == null) return null;\n  return pkcs1unpad2(m, (this.n.bitLength()+7)>>3);\n}\n\n// Return the PKCS#1 OAEP RSA decryption of \"ctext\".\n// \"ctext\" is an even-length hex string and the output is a plain string.\nfunction RSADecryptOAEP(ctext, hash) {\n  var c = parseBigInt(ctext, 16);\n  var m = this.doPrivate(c);\n  if(m == null) return null;\n  return oaep_unpad(m, (this.n.bitLength()+7)>>3, hash);\n}\n\n// Return the PKCS#1 RSA decryption of \"ctext\".\n// \"ctext\" is a Base64-encoded string and the output is a plain string.\n//function RSAB64Decrypt(ctext) {\n//  var h = b64tohex(ctext);\n//  if(h) return this.decrypt(h); else return null;\n//}\n\n// protected\nRSAKey.prototype.doPrivate = RSADoPrivate;\n\n// public\nRSAKey.prototype.setPrivate = RSASetPrivate;\nRSAKey.prototype.setPrivateEx = RSASetPrivateEx;\nRSAKey.prototype.generate = RSAGenerate;\nRSAKey.prototype.decrypt = RSADecrypt;\nRSAKey.prototype.decryptOAEP = RSADecryptOAEP;\n//RSAKey.prototype.b64_decrypt = RSAB64Decrypt;\n"
  },
  {
    "path": "JavaScript/demo/js/rsapem-1.1.js",
    "content": "/*! rsapem-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n//\n// rsa-pem.js - adding function for reading/writing PKCS#1 PEM private key\n//              to RSAKey class.\n//\n// version: 1.1.1 (2013-Apr-12)\n//\n// Copyright (c) 2010-2013 Kenji Urushima (kenji.urushima@gmail.com)\n//\n// This software is licensed under the terms of the MIT License.\n// http://kjur.github.com/jsrsasign/license/\n//\n// The above copyright and license notice shall be \n// included in all copies or substantial portions of the Software.\n// \n//\n// Depends on:\n//\n//\n//\n// _RSApem_pemToBase64(sPEM)\n//\n//   removing PEM header, PEM footer and space characters including\n//   new lines from PEM formatted RSA private key string.\n//\n\n/**\n * @fileOverview\n * @name rsapem-1.1.js\n * @author Kenji Urushima kenji.urushima@gmail.com\n * @version 1.1\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\n */\nfunction _rsapem_pemToBase64(sPEMPrivateKey) {\n  var s = sPEMPrivateKey;\n  s = s.replace(\"-----BEGIN RSA PRIVATE KEY-----\", \"\");\n  s = s.replace(\"-----END RSA PRIVATE KEY-----\", \"\");\n  s = s.replace(/[ \\n]+/g, \"\");\n  return s;\n}\n\nfunction _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey) {\n  var a = new Array();\n  var v1 = ASN1HEX.getStartPosOfV_AtObj(hPrivateKey, 0);\n  var n1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, v1);\n  var e1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, n1);\n  var d1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, e1);\n  var p1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, d1);\n  var q1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, p1);\n  var dp1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, q1);\n  var dq1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, dp1);\n  var co1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, dq1);\n  a.push(v1, n1, e1, d1, p1, q1, dp1, dq1, co1);\n  return a;\n}\n\nfunction _rsapem_getHexValueArrayOfChildrenFromHex(hPrivateKey) {\n  var posArray = _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey);\n  var v =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[0]);\n  var n =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[1]);\n  var e =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[2]);\n  var d =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[3]);\n  var p =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[4]);\n  var q =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[5]);\n  var dp = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[6]);\n  var dq = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[7]);\n  var co = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[8]);\n  var a = new Array();\n  a.push(v, n, e, d, p, q, dp, dq, co);\n  return a;\n}\n\n/**\n * read RSA private key from a ASN.1 hexadecimal string\n * @name readPrivateKeyFromASN1HexString\n * @memberOf RSAKey#\n * @function\n * @param {String} keyHex ASN.1 hexadecimal string of PKCS#1 private key.\n * @since 1.1.1\n */\nfunction _rsapem_readPrivateKeyFromASN1HexString(keyHex) {\n  var a = _rsapem_getHexValueArrayOfChildrenFromHex(keyHex);\n  this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]);\n}\n\n/**\n * read PKCS#1 private key from a string\n * @name readPrivateKeyFromPEMString\n * @memberOf RSAKey#\n * @function\n * @param {String} keyPEM string of PKCS#1 private key.\n */\nfunction _rsapem_readPrivateKeyFromPEMString(keyPEM) {\n  var keyB64 = _rsapem_pemToBase64(keyPEM);\n  var keyHex = b64tohex(keyB64) // depends base64.js\n  var a = _rsapem_getHexValueArrayOfChildrenFromHex(keyHex);\n  this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]);\n}\n\nRSAKey.prototype.readPrivateKeyFromPEMString = _rsapem_readPrivateKeyFromPEMString;\nRSAKey.prototype.readPrivateKeyFromASN1HexString = _rsapem_readPrivateKeyFromASN1HexString;\n"
  },
  {
    "path": "JavaScript/demo/js/rsasign-1.2.js",
    "content": "/*! rsasign-1.2.7.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n/*\n * rsa-sign.js - adding signing functions to RSAKey class.\n *\n * version: 1.2.7 (2013 Aug 25)\n *\n * Copyright (c) 2010-2013 Kenji Urushima (kenji.urushima@gmail.com)\n *\n * This software is licensed under the terms of the MIT License.\n * http://kjur.github.com/jsrsasign/license/\n *\n * The above copyright and license notice shall be \n * included in all copies or substantial portions of the Software.\n */\n\n/**\n * @fileOverview\n * @name rsasign-1.2.js\n * @author Kenji Urushima kenji.urushima@gmail.com\n * @version rsasign 1.2.7\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\n */\n\nvar _RE_HEXDECONLY = new RegExp(\"\");\n_RE_HEXDECONLY.compile(\"[^0-9a-f]\", \"gi\");\n\n// ========================================================================\n// Signature Generation\n// ========================================================================\n\nfunction _rsasign_getHexPaddedDigestInfoForString(s, keySize, hashAlg) {\n    var hashFunc = function(s) { return KJUR.crypto.Util.hashString(s, hashAlg); };\n    var sHashHex = hashFunc(s);\n\n    return KJUR.crypto.Util.getPaddedDigestInfoHex(sHashHex, hashAlg, keySize);\n}\n\nfunction _zeroPaddingOfSignature(hex, bitLength) {\n    var s = \"\";\n    var nZero = bitLength / 4 - hex.length;\n    for (var i = 0; i < nZero; i++) {\n\ts = s + \"0\";\n    }\n    return s + hex;\n}\n\n/**\n * sign for a message string with RSA private key.<br/>\n * @name signString\n * @memberOf RSAKey\n * @function\n * @param {String} s message string to be signed.\n * @param {String} hashAlg hash algorithm name for signing.<br/>\n * @return returns hexadecimal string of signature value.\n */\nfunction _rsasign_signString(s, hashAlg) {\n    var hashFunc = function(s) { return KJUR.crypto.Util.hashString(s, hashAlg); };\n    var sHashHex = hashFunc(s);\n\n    return this.signWithMessageHash(sHashHex, hashAlg);\n}\n\n/**\n * sign hash value of message to be signed with RSA private key.<br/>\n * @name signWithMessageHash\n * @memberOf RSAKey\n * @function\n * @param {String} sHashHex hexadecimal string of hash value of message to be signed.\n * @param {String} hashAlg hash algorithm name for signing.<br/>\n * @return returns hexadecimal string of signature value.\n * @since rsasign 1.2.6\n */\nfunction _rsasign_signWithMessageHash(sHashHex, hashAlg) {\n    var hPM = KJUR.crypto.Util.getPaddedDigestInfoHex(sHashHex, hashAlg, this.n.bitLength());\n    var biPaddedMessage = parseBigInt(hPM, 16);\n    var biSign = this.doPrivate(biPaddedMessage);\n    var hexSign = biSign.toString(16);\n    return _zeroPaddingOfSignature(hexSign, this.n.bitLength());\n}\n\nfunction _rsasign_signStringWithSHA1(s) {\n    return _rsasign_signString.call(this, s, 'sha1');\n}\n\nfunction _rsasign_signStringWithSHA256(s) {\n    return _rsasign_signString.call(this, s, 'sha256');\n}\n\n// PKCS#1 (PSS) mask generation function\nfunction pss_mgf1_str(seed, len, hash) {\n    var mask = '', i = 0;\n\n    while (mask.length < len) {\n        mask += hextorstr(hash(rstrtohex(seed + String.fromCharCode.apply(String, [\n                (i & 0xff000000) >> 24,\n                (i & 0x00ff0000) >> 16,\n                (i & 0x0000ff00) >> 8,\n                i & 0x000000ff]))));\n        i += 1;\n    }\n\n    return mask;\n}\n\n/**\n * sign for a message string with RSA private key by PKCS#1 PSS signing.<br/>\n * @name signStringPSS\n * @memberOf RSAKey\n * @function\n * @param {String} s message string to be signed.\n * @param {String} hashAlg hash algorithm name for signing.\n * @param {Integer} sLen salt byte length from 0 to (keybytelen - hashbytelen - 2).\n *        There are two special values:\n *        <ul>\n *        <li>-1: sets the salt length to the digest length</li>\n *        <li>-2: sets the salt length to maximum permissible value\n *           (i.e. keybytelen - hashbytelen - 2)</li>\n *        </ul>\n *        DEFAULT is -1. (NOTE: OpenSSL's default is -2.)\n * @return returns hexadecimal string of signature value.\n */\nfunction _rsasign_signStringPSS(s, hashAlg, sLen) {\n    var hashFunc = function(sHex) { return KJUR.crypto.Util.hashHex(sHex, hashAlg); } \n    var hHash = hashFunc(rstrtohex(s));\n\n    if (sLen === undefined) sLen = -1;\n    return this.signWithMessageHashPSS(hHash, hashAlg, sLen);\n}\n\n/**\n * sign hash value of message with RSA private key by PKCS#1 PSS signing.<br/>\n * @name signWithMessageHashPSS\n * @memberOf RSAKey\n * @function\n * @param {String} hHash hexadecimal hash value of message to be signed.\n * @param {String} hashAlg hash algorithm name for signing.\n * @param {Integer} sLen salt byte length from 0 to (keybytelen - hashbytelen - 2).\n *        There are two special values:\n *        <ul>\n *        <li>-1: sets the salt length to the digest length</li>\n *        <li>-2: sets the salt length to maximum permissible value\n *           (i.e. keybytelen - hashbytelen - 2)</li>\n *        </ul>\n *        DEFAULT is -1. (NOTE: OpenSSL's default is -2.)\n * @return returns hexadecimal string of signature value.\n * @since rsasign 1.2.6\n */\nfunction _rsasign_signWithMessageHashPSS(hHash, hashAlg, sLen) {\n    var mHash = hextorstr(hHash);\n    var hLen = mHash.length;\n    var emBits = this.n.bitLength() - 1;\n    var emLen = Math.ceil(emBits / 8);\n    var i;\n    var hashFunc = function(sHex) { return KJUR.crypto.Util.hashHex(sHex, hashAlg); } \n\n    if (sLen === -1 || sLen === undefined) {\n        sLen = hLen; // same as hash length\n    } else if (sLen === -2) {\n        sLen = emLen - hLen - 2; // maximum\n    } else if (sLen < -2) {\n        throw \"invalid salt length\";\n    }\n\n    if (emLen < (hLen + sLen + 2)) {\n        throw \"data too long\";\n    }\n\n    var salt = '';\n\n    if (sLen > 0) {\n        salt = new Array(sLen);\n        new SecureRandom().nextBytes(salt);\n        salt = String.fromCharCode.apply(String, salt);\n    }\n\n    var H = hextorstr(hashFunc(rstrtohex('\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00' + mHash + salt)));\n    var PS = [];\n\n    for (i = 0; i < emLen - sLen - hLen - 2; i += 1) {\n        PS[i] = 0x00;\n    }\n\n    var DB = String.fromCharCode.apply(String, PS) + '\\x01' + salt;\n    var dbMask = pss_mgf1_str(H, DB.length, hashFunc);\n    var maskedDB = [];\n\n    for (i = 0; i < DB.length; i += 1) {\n        maskedDB[i] = DB.charCodeAt(i) ^ dbMask.charCodeAt(i);\n    }\n\n    var mask = (0xff00 >> (8 * emLen - emBits)) & 0xff;\n    maskedDB[0] &= ~mask;\n\n    for (i = 0; i < hLen; i++) {\n        maskedDB.push(H.charCodeAt(i));\n    }\n\n    maskedDB.push(0xbc);\n\n    return _zeroPaddingOfSignature(this.doPrivate(new BigInteger(maskedDB)).toString(16),\n\t\t\t\t   this.n.bitLength());\n}\n\n// ========================================================================\n// Signature Verification\n// ========================================================================\n\nfunction _rsasign_getDecryptSignatureBI(biSig, hN, hE) {\n    var rsa = new RSAKey();\n    rsa.setPublic(hN, hE);\n    var biDecryptedSig = rsa.doPublic(biSig);\n    return biDecryptedSig;\n}\n\nfunction _rsasign_getHexDigestInfoFromSig(biSig, hN, hE) {\n    var biDecryptedSig = _rsasign_getDecryptSignatureBI(biSig, hN, hE);\n    var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');\n    return hDigestInfo;\n}\n\nfunction _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo) {\n    for (var algName in KJUR.crypto.Util.DIGESTINFOHEAD) {\n\tvar head = KJUR.crypto.Util.DIGESTINFOHEAD[algName];\n\tvar len = head.length;\n\tif (hDigestInfo.substring(0, len) == head) {\n\t    var a = [algName, hDigestInfo.substring(len)];\n\t    return a;\n\t}\n    }\n    return [];\n}\n\nfunction _rsasign_verifySignatureWithArgs(sMsg, biSig, hN, hE) {\n    var hDigestInfo = _rsasign_getHexDigestInfoFromSig(biSig, hN, hE);\n    var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);\n    if (digestInfoAry.length == 0) return false;\n    var algName = digestInfoAry[0];\n    var diHashValue = digestInfoAry[1];\n    var ff = function(s) { return KJUR.crypto.Util.hashString(s, algName); };\n    var msgHashValue = ff(sMsg);\n    return (diHashValue == msgHashValue);\n}\n\nfunction _rsasign_verifyHexSignatureForMessage(hSig, sMsg) {\n    var biSig = parseBigInt(hSig, 16);\n    var result = _rsasign_verifySignatureWithArgs(sMsg, biSig,\n\t\t\t\t\t\t  this.n.toString(16),\n\t\t\t\t\t\t  this.e.toString(16));\n    return result;\n}\n\n/**\n * verifies a sigature for a message string with RSA public key.<br/>\n * @name verifyString\n * @memberOf RSAKey#\n * @function\n * @param {String} sMsg message string to be verified.\n * @param {String} hSig hexadecimal string of siganture.<br/>\n *                 non-hexadecimal charactors including new lines will be ignored.\n * @return returns 1 if valid, otherwise 0\n */\nfunction _rsasign_verifyString(sMsg, hSig) {\n    hSig = hSig.replace(_RE_HEXDECONLY, '');\n    hSig = hSig.replace(/[ \\n]+/g, \"\");\n    var biSig = parseBigInt(hSig, 16);\n    if (biSig.bitLength() > this.n.bitLength()) return 0;\n    var biDecryptedSig = this.doPublic(biSig);\n    var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');\n    var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);\n  \n    if (digestInfoAry.length == 0) return false;\n    var algName = digestInfoAry[0];\n    var diHashValue = digestInfoAry[1];\n    var ff = function(s) { return KJUR.crypto.Util.hashString(s, algName); };\n    var msgHashValue = ff(sMsg);\n    return (diHashValue == msgHashValue);\n}\n\n/**\n * verifies a sigature for a message string with RSA public key.<br/>\n * @name verifyWithMessageHash\n * @memberOf RSAKey\n * @function\n * @param {String} sHashHex hexadecimal hash value of message to be verified.\n * @param {String} hSig hexadecimal string of siganture.<br/>\n *                 non-hexadecimal charactors including new lines will be ignored.\n * @return returns 1 if valid, otherwise 0\n * @since rsasign 1.2.6\n */\nfunction _rsasign_verifyWithMessageHash(sHashHex, hSig) {\n    hSig = hSig.replace(_RE_HEXDECONLY, '');\n    hSig = hSig.replace(/[ \\n]+/g, \"\");\n    var biSig = parseBigInt(hSig, 16);\n    if (biSig.bitLength() > this.n.bitLength()) return 0;\n    var biDecryptedSig = this.doPublic(biSig);\n    var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');\n    var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);\n  \n    if (digestInfoAry.length == 0) return false;\n    var algName = digestInfoAry[0];\n    var diHashValue = digestInfoAry[1];\n    return (diHashValue == sHashHex);\n}\n\n/**\n * verifies a sigature for a message string with RSA public key by PKCS#1 PSS sign.<br/>\n * @name verifyStringPSS\n * @memberOf RSAKey\n * @function\n * @param {String} sMsg message string to be verified.\n * @param {String} hSig hexadecimal string of signature value\n * @param {String} hashAlg hash algorithm name\n * @param {Integer} sLen salt byte length from 0 to (keybytelen - hashbytelen - 2).\n *        There are two special values:\n *        <ul>\n *        <li>-1: sets the salt length to the digest length</li>\n *        <li>-2: sets the salt length to maximum permissible value\n *           (i.e. keybytelen - hashbytelen - 2)</li>\n *        </ul>\n *        DEFAULT is -1. (NOTE: OpenSSL's default is -2.)\n * @return returns true if valid, otherwise false\n */\nfunction _rsasign_verifyStringPSS(sMsg, hSig, hashAlg, sLen) {\n    var hashFunc = function(sHex) { return KJUR.crypto.Util.hashHex(sHex, hashAlg); };\n    var hHash = hashFunc(rstrtohex(sMsg));\n\n    if (sLen === undefined) sLen = -1;\n    return this.verifyWithMessageHashPSS(hHash, hSig, hashAlg, sLen);\n}\n\n/**\n * verifies a sigature for a hash value of message string with RSA public key by PKCS#1 PSS sign.<br/>\n * @name verifyWithMessageHashPSS\n * @memberOf RSAKey\n * @function\n * @param {String} hHash hexadecimal hash value of message string to be verified.\n * @param {String} hSig hexadecimal string of signature value\n * @param {String} hashAlg hash algorithm name\n * @param {Integer} sLen salt byte length from 0 to (keybytelen - hashbytelen - 2).\n *        There are two special values:\n *        <ul>\n *        <li>-1: sets the salt length to the digest length</li>\n *        <li>-2: sets the salt length to maximum permissible value\n *           (i.e. keybytelen - hashbytelen - 2)</li>\n *        </ul>\n *        DEFAULT is -1 (NOTE: OpenSSL's default is -2.)\n * @return returns true if valid, otherwise false\n * @since rsasign 1.2.6\n */\nfunction _rsasign_verifyWithMessageHashPSS(hHash, hSig, hashAlg, sLen) {\n    var biSig = new BigInteger(hSig, 16);\n\n    if (biSig.bitLength() > this.n.bitLength()) {\n        return false;\n    }\n\n    var hashFunc = function(sHex) { return KJUR.crypto.Util.hashHex(sHex, hashAlg); };\n    var mHash = hextorstr(hHash);\n    var hLen = mHash.length;\n    var emBits = this.n.bitLength() - 1;\n    var emLen = Math.ceil(emBits / 8);\n    var i;\n\n    if (sLen === -1 || sLen === undefined) {\n        sLen = hLen; // same as hash length\n    } else if (sLen === -2) {\n        sLen = emLen - hLen - 2; // recover\n    } else if (sLen < -2) {\n        throw \"invalid salt length\";\n    }\n\n    if (emLen < (hLen + sLen + 2)) {\n        throw \"data too long\";\n    }\n\n    var em = this.doPublic(biSig).toByteArray();\n\n    for (i = 0; i < em.length; i += 1) {\n        em[i] &= 0xff;\n    }\n\n    while (em.length < emLen) {\n        em.unshift(0);\n    }\n\n    if (em[emLen -1] !== 0xbc) {\n        throw \"encoded message does not end in 0xbc\";\n    }\n\n    em = String.fromCharCode.apply(String, em);\n\n    var maskedDB = em.substr(0, emLen - hLen - 1);\n    var H = em.substr(maskedDB.length, hLen);\n\n    var mask = (0xff00 >> (8 * emLen - emBits)) & 0xff;\n\n    if ((maskedDB.charCodeAt(0) & mask) !== 0) {\n        throw \"bits beyond keysize not zero\";\n    }\n\n    var dbMask = pss_mgf1_str(H, maskedDB.length, hashFunc);\n    var DB = [];\n\n    for (i = 0; i < maskedDB.length; i += 1) {\n        DB[i] = maskedDB.charCodeAt(i) ^ dbMask.charCodeAt(i);\n    }\n\n    DB[0] &= ~mask;\n\n    var checkLen = emLen - hLen - sLen - 2;\n\n    for (i = 0; i < checkLen; i += 1) {\n        if (DB[i] !== 0x00) {\n            throw \"leftmost octets not zero\";\n        }\n    }\n\n    if (DB[checkLen] !== 0x01) {\n        throw \"0x01 marker not found\";\n    }\n\n    return H === hextorstr(hashFunc(rstrtohex('\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00' + mHash +\n\t\t\t\t     String.fromCharCode.apply(String, DB.slice(-sLen)))));\n}\n\nRSAKey.prototype.signWithMessageHash = _rsasign_signWithMessageHash;\nRSAKey.prototype.signString = _rsasign_signString;\nRSAKey.prototype.signStringWithSHA1 = _rsasign_signStringWithSHA1;\nRSAKey.prototype.signStringWithSHA256 = _rsasign_signStringWithSHA256;\nRSAKey.prototype.sign = _rsasign_signString;\nRSAKey.prototype.signWithSHA1 = _rsasign_signStringWithSHA1;\nRSAKey.prototype.signWithSHA256 = _rsasign_signStringWithSHA256;\n\nRSAKey.prototype.signWithMessageHashPSS = _rsasign_signWithMessageHashPSS;\nRSAKey.prototype.signStringPSS = _rsasign_signStringPSS;\nRSAKey.prototype.signPSS = _rsasign_signStringPSS;\nRSAKey.SALT_LEN_HLEN = -1;\nRSAKey.SALT_LEN_MAX = -2;\n\nRSAKey.prototype.verifyWithMessageHash = _rsasign_verifyWithMessageHash;\nRSAKey.prototype.verifyString = _rsasign_verifyString;\nRSAKey.prototype.verifyHexSignatureForMessage = _rsasign_verifyHexSignatureForMessage;\nRSAKey.prototype.verify = _rsasign_verifyString;\nRSAKey.prototype.verifyHexSignatureForByteArrayMessage = _rsasign_verifyHexSignatureForMessage;\n\nRSAKey.prototype.verifyWithMessageHashPSS = _rsasign_verifyWithMessageHashPSS;\nRSAKey.prototype.verifyStringPSS = _rsasign_verifyStringPSS;\nRSAKey.prototype.verifyPSS = _rsasign_verifyStringPSS;\nRSAKey.SALT_LEN_RECOVER = -2;\n\n/**\n * @name RSAKey\n * @class key of RSA public key algorithm\n * @description Tom Wu's RSA Key class and extension\n */\n"
  },
  {
    "path": "JavaScript/demo/js/sha1.js",
    "content": "/*\nCryptoJS v3.1.2\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function () {\r\n    // Shortcuts\r\n    var C = CryptoJS;\r\n    var C_lib = C.lib;\r\n    var WordArray = C_lib.WordArray;\r\n    var Hasher = C_lib.Hasher;\r\n    var C_algo = C.algo;\r\n\r\n    // Reusable object\r\n    var W = [];\r\n\r\n    /**\r\n     * SHA-1 hash algorithm.\r\n     */\r\n    var SHA1 = C_algo.SHA1 = Hasher.extend({\r\n        _doReset: function () {\r\n            this._hash = new WordArray.init([\r\n                0x67452301, 0xefcdab89,\r\n                0x98badcfe, 0x10325476,\r\n                0xc3d2e1f0\r\n            ]);\r\n        },\r\n\r\n        _doProcessBlock: function (M, offset) {\r\n            // Shortcut\r\n            var H = this._hash.words;\r\n\r\n            // Working variables\r\n            var a = H[0];\r\n            var b = H[1];\r\n            var c = H[2];\r\n            var d = H[3];\r\n            var e = H[4];\r\n\r\n            // Computation\r\n            for (var i = 0; i < 80; i++) {\r\n                if (i < 16) {\r\n                    W[i] = M[offset + i] | 0;\r\n                } else {\r\n                    var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];\r\n                    W[i] = (n << 1) | (n >>> 31);\r\n                }\r\n\r\n                var t = ((a << 5) | (a >>> 27)) + e + W[i];\r\n                if (i < 20) {\r\n                    t += ((b & c) | (~b & d)) + 0x5a827999;\r\n                } else if (i < 40) {\r\n                    t += (b ^ c ^ d) + 0x6ed9eba1;\r\n                } else if (i < 60) {\r\n                    t += ((b & c) | (b & d) | (c & d)) - 0x70e44324;\r\n                } else /* if (i < 80) */ {\r\n                    t += (b ^ c ^ d) - 0x359d3e2a;\r\n                }\r\n\r\n                e = d;\r\n                d = c;\r\n                c = (b << 30) | (b >>> 2);\r\n                b = a;\r\n                a = t;\r\n            }\r\n\r\n            // Intermediate hash value\r\n            H[0] = (H[0] + a) | 0;\r\n            H[1] = (H[1] + b) | 0;\r\n            H[2] = (H[2] + c) | 0;\r\n            H[3] = (H[3] + d) | 0;\r\n            H[4] = (H[4] + e) | 0;\r\n        },\r\n\r\n        _doFinalize: function () {\r\n            // Shortcuts\r\n            var data = this._data;\r\n            var dataWords = data.words;\r\n\r\n            var nBitsTotal = this._nDataBytes * 8;\r\n            var nBitsLeft = data.sigBytes * 8;\r\n\r\n            // Add padding\r\n            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);\r\n            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);\r\n            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;\r\n            data.sigBytes = dataWords.length * 4;\r\n\r\n            // Hash final blocks\r\n            this._process();\r\n\r\n            // Return final computed hash\r\n            return this._hash;\r\n        },\r\n\r\n        clone: function () {\r\n            var clone = Hasher.clone.call(this);\r\n            clone._hash = this._hash.clone();\r\n\r\n            return clone;\r\n        }\r\n    });\r\n\r\n    /**\r\n     * Shortcut function to the hasher's object interface.\r\n     *\r\n     * @param {WordArray|string} message The message to hash.\r\n     *\r\n     * @return {WordArray} The hash.\r\n     *\r\n     * @static\r\n     *\r\n     * @example\r\n     *\r\n     *     var hash = CryptoJS.SHA1('message');\r\n     *     var hash = CryptoJS.SHA1(wordArray);\r\n     */\r\n    C.SHA1 = Hasher._createHelper(SHA1);\r\n\r\n    /**\r\n     * Shortcut function to the HMAC's object interface.\r\n     *\r\n     * @param {WordArray|string} message The message to hash.\r\n     * @param {WordArray|string} key The secret key.\r\n     *\r\n     * @return {WordArray} The HMAC.\r\n     *\r\n     * @static\r\n     *\r\n     * @example\r\n     *\r\n     *     var hmac = CryptoJS.HmacSHA1(message, key);\r\n     */\r\n    C.HmacSHA1 = Hasher._createHmacHelper(SHA1);\r\n}());\r\n"
  },
  {
    "path": "JavaScript/demo/js/sha256.js",
    "content": "/*\nCryptoJS v3.1.2\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function (Math) {\r\n    // Shortcuts\r\n    var C = CryptoJS;\r\n    var C_lib = C.lib;\r\n    var WordArray = C_lib.WordArray;\r\n    var Hasher = C_lib.Hasher;\r\n    var C_algo = C.algo;\r\n\r\n    // Initialization and round constants tables\r\n    var H = [];\r\n    var K = [];\r\n\r\n    // Compute constants\r\n    (function () {\r\n        function isPrime(n) {\r\n            var sqrtN = Math.sqrt(n);\r\n            for (var factor = 2; factor <= sqrtN; factor++) {\r\n                if (!(n % factor)) {\r\n                    return false;\r\n                }\r\n            }\r\n\r\n            return true;\r\n        }\r\n\r\n        function getFractionalBits(n) {\r\n            return ((n - (n | 0)) * 0x100000000) | 0;\r\n        }\r\n\r\n        var n = 2;\r\n        var nPrime = 0;\r\n        while (nPrime < 64) {\r\n            if (isPrime(n)) {\r\n                if (nPrime < 8) {\r\n                    H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2));\r\n                }\r\n                K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3));\r\n\r\n                nPrime++;\r\n            }\r\n\r\n            n++;\r\n        }\r\n    }());\r\n\r\n    // Reusable object\r\n    var W = [];\r\n\r\n    /**\r\n     * SHA-256 hash algorithm.\r\n     */\r\n    var SHA256 = C_algo.SHA256 = Hasher.extend({\r\n        _doReset: function () {\r\n            this._hash = new WordArray.init(H.slice(0));\r\n        },\r\n\r\n        _doProcessBlock: function (M, offset) {\r\n            // Shortcut\r\n            var H = this._hash.words;\r\n\r\n            // Working variables\r\n            var a = H[0];\r\n            var b = H[1];\r\n            var c = H[2];\r\n            var d = H[3];\r\n            var e = H[4];\r\n            var f = H[5];\r\n            var g = H[6];\r\n            var h = H[7];\r\n\r\n            // Computation\r\n            for (var i = 0; i < 64; i++) {\r\n                if (i < 16) {\r\n                    W[i] = M[offset + i] | 0;\r\n                } else {\r\n                    var gamma0x = W[i - 15];\r\n                    var gamma0  = ((gamma0x << 25) | (gamma0x >>> 7))  ^\r\n                                  ((gamma0x << 14) | (gamma0x >>> 18)) ^\r\n                                   (gamma0x >>> 3);\r\n\r\n                    var gamma1x = W[i - 2];\r\n                    var gamma1  = ((gamma1x << 15) | (gamma1x >>> 17)) ^\r\n                                  ((gamma1x << 13) | (gamma1x >>> 19)) ^\r\n                                   (gamma1x >>> 10);\r\n\r\n                    W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16];\r\n                }\r\n\r\n                var ch  = (e & f) ^ (~e & g);\r\n                var maj = (a & b) ^ (a & c) ^ (b & c);\r\n\r\n                var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22));\r\n                var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7)  | (e >>> 25));\r\n\r\n                var t1 = h + sigma1 + ch + K[i] + W[i];\r\n                var t2 = sigma0 + maj;\r\n\r\n                h = g;\r\n                g = f;\r\n                f = e;\r\n                e = (d + t1) | 0;\r\n                d = c;\r\n                c = b;\r\n                b = a;\r\n                a = (t1 + t2) | 0;\r\n            }\r\n\r\n            // Intermediate hash value\r\n            H[0] = (H[0] + a) | 0;\r\n            H[1] = (H[1] + b) | 0;\r\n            H[2] = (H[2] + c) | 0;\r\n            H[3] = (H[3] + d) | 0;\r\n            H[4] = (H[4] + e) | 0;\r\n            H[5] = (H[5] + f) | 0;\r\n            H[6] = (H[6] + g) | 0;\r\n            H[7] = (H[7] + h) | 0;\r\n        },\r\n\r\n        _doFinalize: function () {\r\n            // Shortcuts\r\n            var data = this._data;\r\n            var dataWords = data.words;\r\n\r\n            var nBitsTotal = this._nDataBytes * 8;\r\n            var nBitsLeft = data.sigBytes * 8;\r\n\r\n            // Add padding\r\n            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);\r\n            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);\r\n            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;\r\n            data.sigBytes = dataWords.length * 4;\r\n\r\n            // Hash final blocks\r\n            this._process();\r\n\r\n            // Return final computed hash\r\n            return this._hash;\r\n        },\r\n\r\n        clone: function () {\r\n            var clone = Hasher.clone.call(this);\r\n            clone._hash = this._hash.clone();\r\n\r\n            return clone;\r\n        }\r\n    });\r\n\r\n    /**\r\n     * Shortcut function to the hasher's object interface.\r\n     *\r\n     * @param {WordArray|string} message The message to hash.\r\n     *\r\n     * @return {WordArray} The hash.\r\n     *\r\n     * @static\r\n     *\r\n     * @example\r\n     *\r\n     *     var hash = CryptoJS.SHA256('message');\r\n     *     var hash = CryptoJS.SHA256(wordArray);\r\n     */\r\n    C.SHA256 = Hasher._createHelper(SHA256);\r\n\r\n    /**\r\n     * Shortcut function to the HMAC's object interface.\r\n     *\r\n     * @param {WordArray|string} message The message to hash.\r\n     * @param {WordArray|string} key The secret key.\r\n     *\r\n     * @return {WordArray} The HMAC.\r\n     *\r\n     * @static\r\n     *\r\n     * @example\r\n     *\r\n     *     var hmac = CryptoJS.HmacSHA256(message, key);\r\n     */\r\n    C.HmacSHA256 = Hasher._createHmacHelper(SHA256);\r\n}(Math));\r\n"
  },
  {
    "path": "JavaScript/demo/js/sm2-guomi.js",
    "content": "function SM2Cipher(cipherMode) {\r\n    this.ct = 1;\r\n    this.p2 = null;\r\n    this.sm3keybase = null;\r\n    this.sm3c3 = null;\r\n    this.key = new Array(32);\r\n    this.keyOff = 0;\r\n    if (typeof(cipherMode) != 'undefined') {\r\n        this.cipherMode = cipherMode\r\n    } else {\r\n        this.cipherMode = SM2CipherMode.C1C3C2\r\n    }\r\n}\r\nSM2Cipher.prototype = {\r\n    Reset: function() {\r\n        this.sm3keybase = new SM3Digest();\r\n        this.sm3c3 = new SM3Digest();\r\n        var xWords = this.GetWords(this.p2.getX().toBigInteger().toRadix(16));\r\n        var yWords = this.GetWords(this.p2.getY().toBigInteger().toRadix(16));\r\n        this.sm3keybase.BlockUpdate(xWords, 0, xWords.length);\r\n        this.sm3c3.BlockUpdate(xWords, 0, xWords.length);\r\n        this.sm3keybase.BlockUpdate(yWords, 0, yWords.length);\r\n        this.ct = 1;\r\n        this.NextKey()\r\n    },\r\n    NextKey: function() {\r\n        var sm3keycur = new SM3Digest(this.sm3keybase);\r\n        sm3keycur.Update((this.ct >> 24 & 0x00ff));\r\n        sm3keycur.Update((this.ct >> 16 & 0x00ff));\r\n        sm3keycur.Update((this.ct >> 8 & 0x00ff));\r\n        sm3keycur.Update((this.ct & 0x00ff));\r\n        sm3keycur.DoFinal(this.key, 0);\r\n        this.keyOff = 0;\r\n        this.ct++\r\n    },\r\n    InitEncipher: function(userKey) {\r\n        var k = null;\r\n        var c1 = null;\r\n        var ec = new KJUR.crypto.ECDSA({\r\n            \"curve\": \"sm2\"\r\n        });\r\n        var keypair = ec.generateKeyPairHex();\r\n        k = new BigInteger(keypair.ecprvhex, 16);\r\n        var pubkeyHex = keypair.ecpubhex;\r\n        c1 = ECPointFp.decodeFromHex(ec.ecparams['curve'], pubkeyHex);\r\n        this.p2 = userKey.multiply(k);\r\n        this.Reset();\r\n        return c1\r\n    },\r\n    EncryptBlock: function(data) {\r\n        this.sm3c3.BlockUpdate(data, 0, data.length);\r\n        for (var i = 0; i < data.length; i++) {\r\n            if (this.keyOff == this.key.length) {\r\n                this.NextKey()\r\n            }\r\n            data[i] ^= this.key[this.keyOff++]\r\n        }\r\n    },\r\n    InitDecipher: function(userD, c1) {\r\n        this.p2 = c1.multiply(userD);\r\n        this.Reset()\r\n    },\r\n    DecryptBlock: function(data) {\r\n        for (var i = 0; i < data.length; i++) {\r\n            if (this.keyOff == this.key.length) {\r\n                this.NextKey()\r\n            }\r\n            data[i] ^= this.key[this.keyOff++]\r\n        }\r\n        this.sm3c3.BlockUpdate(data, 0, data.length)\r\n    },\r\n    Dofinal: function(c3) {\r\n        var yWords = this.GetWords(this.p2.getY().toBigInteger().toRadix(16));\r\n        this.sm3c3.BlockUpdate(yWords, 0, yWords.length);\r\n        this.sm3c3.DoFinal(c3, 0);\r\n        this.Reset()\r\n    },\r\n    Encrypt: function(pubKey, plaintext) {\r\n        var data = new Array(plaintext.length);\r\n        Array.Copy(plaintext, 0, data, 0, plaintext.length);\r\n        var c1 = this.InitEncipher(pubKey);\r\n        this.EncryptBlock(data);\r\n        var c3 = new Array(32);\r\n        this.Dofinal(c3);\r\n        var hexString = c1.getX().toBigInteger().toRadix(16) + c1.getY().toBigInteger().toRadix(16) + this.GetHex(data).toString() + this.GetHex(c3).toString();\r\n        if (this.cipherMode == SM2CipherMode.C1C3C2) {\r\n            hexString = c1.getX().toBigInteger().toRadix(16) + c1.getY().toBigInteger().toRadix(16) + this.GetHex(c3).toString() + this.GetHex(data).toString()\r\n        }\r\n        return hexString\r\n    },\r\n    GetWords: function(hexStr) {\r\n        var words = [];\r\n        var hexStrLength = hexStr.length;\r\n        for (var i = 0; i < hexStrLength; i += 2) {\r\n            words[words.length] = parseInt(hexStr.substr(i, 2), 16)\r\n        }\r\n        return words\r\n    },\r\n    GetHex: function(arr) {\r\n        var words = [];\r\n        var j = 0;\r\n        for (var i = 0; i < arr.length * 2; i += 2) {\r\n            words[i >>> 3] |= parseInt(arr[j]) << (24 - (i % 8) * 4);\r\n            j++\r\n        }\r\n        var wordArray = new CryptoJS.lib.WordArray.init(words, arr.length);\r\n        return wordArray\r\n    },\r\n    Decrypt: function(privateKey, ciphertext) {\r\n        var hexString = ciphertext;\r\n        var c1X = hexString.substr(0, 64);\r\n        var c1Y = hexString.substr(0 + c1X.length, 64);\r\n        var encrypData = hexString.substr(c1X.length + c1Y.length, hexString.length - c1X.length - c1Y.length - 64);\r\n        var c3 = hexString.substr(hexString.length - 64);\r\n        if (this.cipherMode == SM2CipherMode.C1C3C2) {\r\n            c3 = hexString.substr(c1X.length + c1Y.length, 64);\r\n            encrypData = hexString.substr(c1X.length + c1Y.length + 64)\r\n        }\r\n        var data = this.GetWords(encrypData);\r\n        var c1 = this.CreatePoint(c1X, c1Y);\r\n        this.InitDecipher(privateKey, c1);\r\n        this.DecryptBlock(data);\r\n        var c3_ = new Array(32);\r\n        this.Dofinal(c3_);\r\n        var isDecrypt = this.GetHex(c3_).toString() == c3;\r\n        if (isDecrypt) {\r\n            var wordArray = this.GetHex(data);\r\n            var decryptData = CryptoJS.enc.Utf8.stringify(wordArray);\r\n            return decryptData\r\n        } else {\r\n            return ''\r\n        }\r\n    },\r\n    CreatePoint: function(x, y) {\r\n        var ec = new KJUR.crypto.ECDSA({\r\n            \"curve\": \"sm2\"\r\n        });\r\n        var ecc_curve = ec.ecparams['curve'];\r\n        var pubkeyHex = '04' + x + y;\r\n        var point = ECPointFp.decodeFromHex(ec.ecparams['curve'], pubkeyHex);\r\n        return point\r\n    }\r\n};\r\nwindow.SM2CipherMode = {\r\n    C1C2C3: '0',\r\n    C1C3C2: '1'\r\n};"
  },
  {
    "path": "JavaScript/demo/js/sm2.js",
    "content": "function SM2Cipher(cipherMode){this.ct=1;this.p2=null;this.sm3keybase=null;this.sm3c3=null;this.key=new Array(32);this.keyOff=0;if(typeof(cipherMode)!='undefined'){this.cipherMode=cipherMode}else{this.cipherMode=SM2CipherMode.C1C3C2}}SM2Cipher.prototype={Reset:function(){this.sm3keybase=new SM3Digest();this.sm3c3=new SM3Digest();var xWords=this.GetWords(this.p2.getX().toBigInteger().toRadix(16));var yWords=this.GetWords(this.p2.getY().toBigInteger().toRadix(16));this.sm3keybase.BlockUpdate(xWords,0,xWords.length);this.sm3c3.BlockUpdate(xWords,0,xWords.length);this.sm3keybase.BlockUpdate(yWords,0,yWords.length);this.ct=1;this.NextKey()},NextKey:function(){var sm3keycur=new SM3Digest(this.sm3keybase);sm3keycur.Update((this.ct>>24&0x00ff));sm3keycur.Update((this.ct>>16&0x00ff));sm3keycur.Update((this.ct>>8&0x00ff));sm3keycur.Update((this.ct&0x00ff));sm3keycur.DoFinal(this.key,0);this.keyOff=0;this.ct++},InitEncipher:function(userKey){var k=null;var c1=null;var ec=new KJUR.crypto.ECDSA({\"curve\":\"sm2\"});var keypair=ec.generateKeyPairHex();k=new BigInteger(keypair.ecprvhex,16);var pubkeyHex=keypair.ecpubhex;c1=ECPointFp.decodeFromHex(ec.ecparams['curve'],pubkeyHex);this.p2=userKey.multiply(k);this.Reset();return c1},EncryptBlock:function(data){this.sm3c3.BlockUpdate(data,0,data.length);for(var i=0;i<data.length;i++){if(this.keyOff==this.key.length){this.NextKey()}data[i]^=this.key[this.keyOff++]}},InitDecipher:function(userD,c1){this.p2=c1.multiply(userD);this.Reset()},DecryptBlock:function(data){for(var i=0;i<data.length;i++){if(this.keyOff==this.key.length){this.NextKey()}data[i]^=this.key[this.keyOff++]}this.sm3c3.BlockUpdate(data,0,data.length)},Dofinal:function(c3){var yWords=this.GetWords(this.p2.getY().toBigInteger().toRadix(16));this.sm3c3.BlockUpdate(yWords,0,yWords.length);this.sm3c3.DoFinal(c3,0);this.Reset()},Encrypt:function(pubKey,plaintext){var data=new Array(plaintext.length);Array.Copy(plaintext,0,data,0,plaintext.length);var c1=this.InitEncipher(pubKey);this.EncryptBlock(data);var c3=new Array(32);this.Dofinal(c3);var hexString=c1.getX().toBigInteger().toRadix(16)+c1.getY().toBigInteger().toRadix(16)+this.GetHex(data).toString()+this.GetHex(c3).toString();if(this.cipherMode==SM2CipherMode.C1C3C2){hexString=c1.getX().toBigInteger().toRadix(16)+c1.getY().toBigInteger().toRadix(16)+this.GetHex(c3).toString()+this.GetHex(data).toString()}return hexString},GetWords:function(hexStr){var words=[];var hexStrLength=hexStr.length;for(var i=0;i<hexStrLength;i+=2){words[words.length]=parseInt(hexStr.substr(i,2),16)}return words},GetHex:function(arr){var words=[];var j=0;for(var i=0;i<arr.length*2;i+=2){words[i>>>3]|=parseInt(arr[j])<<(24-(i%8)*4);j++}var wordArray=new CryptoJS.lib.WordArray.init(words,arr.length);return wordArray},Decrypt:function(privateKey,ciphertext){var hexString=ciphertext;var c1X=hexString.substr(0,64);var c1Y=hexString.substr(0+c1X.length,64);var encrypData=hexString.substr(c1X.length+c1Y.length,hexString.length-c1X.length-c1Y.length-64);var c3=hexString.substr(hexString.length-64);if(this.cipherMode==SM2CipherMode.C1C3C2){c3=hexString.substr(c1X.length+c1Y.length,64);encrypData=hexString.substr(c1X.length+c1Y.length+64)}var data=this.GetWords(encrypData);var c1=this.CreatePoint(c1X,c1Y);this.InitDecipher(privateKey,c1);this.DecryptBlock(data);var c3_=new Array(32);this.Dofinal(c3_);var isDecrypt=this.GetHex(c3_).toString()==c3;if(isDecrypt){var wordArray=this.GetHex(data);var decryptData=CryptoJS.enc.Utf8.stringify(wordArray);return decryptData}else{return''}},CreatePoint:function(x,y){var ec=new KJUR.crypto.ECDSA({\"curve\":\"sm2\"});var ecc_curve=ec.ecparams['curve'];var pubkeyHex='04'+x+y;var point=ECPointFp.decodeFromHex(ec.ecparams['curve'],pubkeyHex);return point}};window.SM2CipherMode={C1C2C3:'0',C1C3C2:'1'};"
  },
  {
    "path": "JavaScript/demo/js/sm3-guomi.js",
    "content": "(function() {\r\n    var C = CryptoJS;\r\n    var C_lib = C.lib;\r\n    var WordArray = C_lib.WordArray;\r\n    var Hasher = C_lib.Hasher;\r\n    var C_algo = C.algo;\r\n    var W = [];\r\n    var SM3 = C_algo.SM3 = Hasher.extend({\r\n        _doReset: function() {\r\n            this._hash = new WordArray.init([0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e])\r\n        },\r\n        _doProcessBlock: function(M, offset) {\r\n            var H = this._hash.words;\r\n            var a = H[0];\r\n            var b = H[1];\r\n            var c = H[2];\r\n            var d = H[3];\r\n            var e = H[4];\r\n            for (var i = 0; i < 80; i++) {\r\n                if (i < 16) {\r\n                    W[i] = M[offset + i] | 0\r\n                } else {\r\n                    var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];\r\n                    W[i] = (n << 1) | (n >>> 31)\r\n                }\r\n                var t = ((a << 5) | (a >>> 27)) + e + W[i];\r\n                if (i < 20) {\r\n                    t += ((b & c) | (~b & d)) + 0x5a827999\r\n                } else if (i < 40) {\r\n                    t += (b ^ c ^ d) + 0x6ed9eba1\r\n                } else if (i < 60) {\r\n                    t += ((b & c) | (b & d) | (c & d)) - 0x70e44324\r\n                } else {\r\n                    t += (b ^ c ^ d) - 0x359d3e2a\r\n                }\r\n                e = d;\r\n                d = c;\r\n                c = (b << 30) | (b >>> 2);\r\n                b = a;\r\n                a = t\r\n            }\r\n            H[0] = (H[0] + a) | 0;\r\n            H[1] = (H[1] + b) | 0;\r\n            H[2] = (H[2] + c) | 0;\r\n            H[3] = (H[3] + d) | 0;\r\n            H[4] = (H[4] + e) | 0\r\n        },\r\n        _doFinalize: function() {\r\n            var data = this._data;\r\n            var dataWords = data.words;\r\n            var nBitsTotal = this._nDataBytes * 8;\r\n            var nBitsLeft = data.sigBytes * 8;\r\n            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);\r\n            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);\r\n            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;\r\n            data.sigBytes = dataWords.length * 4;\r\n            this._process();\r\n            return this._hash\r\n        },\r\n        clone: function() {\r\n            var clone = Hasher.clone.call(this);\r\n            clone._hash = this._hash.clone();\r\n            return clone\r\n        }\r\n    });\r\n    C.SM3 = Hasher._createHelper(SM3);\r\n    C.HmacSM3 = Hasher._createHmacHelper(SM3)\r\n}());\r\n\r\nfunction SM3Digest() {\r\n    this.BYTE_LENGTH = 64;\r\n    this.xBuf = new Array();\r\n    this.xBufOff = 0;\r\n    this.byteCount = 0;\r\n    this.DIGEST_LENGTH = 32;\r\n    this.v0 = [0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e];\r\n    this.v0 = [0x7380166f, 0x4914b2b9, 0x172442d7, -628488704, -1452330820, 0x163138aa, -477237683, -1325724082];\r\n    this.v = new Array(8);\r\n    this.v_ = new Array(8);\r\n    this.X0 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\r\n    this.X = new Array(68);\r\n    this.xOff = 0;\r\n    this.T_00_15 = 0x79cc4519;\r\n    this.T_16_63 = 0x7a879d8a;\r\n    if (arguments.length > 0) {\r\n        this.InitDigest(arguments[0])\r\n    } else {\r\n        this.Init()\r\n    }\r\n}\r\nSM3Digest.prototype = {\r\n    Init: function() {\r\n        this.xBuf = new Array(4);\r\n        this.Reset()\r\n    },\r\n    InitDigest: function(t) {\r\n        this.xBuf = new Array(t.xBuf.length);\r\n        Array.Copy(t.xBuf, 0, this.xBuf, 0, t.xBuf.length);\r\n        this.xBufOff = t.xBufOff;\r\n        this.byteCount = t.byteCount;\r\n        Array.Copy(t.X, 0, this.X, 0, t.X.length);\r\n        this.xOff = t.xOff;\r\n        Array.Copy(t.v, 0, this.v, 0, t.v.length)\r\n    },\r\n    GetDigestSize: function() {\r\n        return this.DIGEST_LENGTH\r\n    },\r\n    Reset: function() {\r\n        this.byteCount = 0;\r\n        this.xBufOff = 0;\r\n        Array.Clear(this.xBuf, 0, this.xBuf.length);\r\n        Array.Copy(this.v0, 0, this.v, 0, this.v0.length);\r\n        this.xOff = 0;\r\n        Array.Copy(this.X0, 0, this.X, 0, this.X0.length)\r\n    },\r\n    GetByteLength: function() {\r\n        return this.BYTE_LENGTH\r\n    },\r\n    ProcessBlock: function() {\r\n        var i;\r\n        var ww = this.X;\r\n        var ww_ = new Array(64);\r\n        for (i = 16; i < 68; i++) {\r\n            ww[i] = this.P1(ww[i - 16] ^ ww[i - 9] ^ (this.ROTATE(ww[i - 3], 15))) ^ (this.ROTATE(ww[i - 13], 7)) ^ ww[i - 6]\r\n        }\r\n        for (i = 0; i < 64; i++) {\r\n            ww_[i] = ww[i] ^ ww[i + 4]\r\n        }\r\n        var vv = this.v;\r\n        var vv_ = this.v_;\r\n        Array.Copy(vv, 0, vv_, 0, this.v0.length);\r\n        var SS1, SS2, TT1, TT2, aaa;\r\n        for (i = 0; i < 16; i++) {\r\n            aaa = this.ROTATE(vv_[0], 12);\r\n            SS1 = Int32.parse(Int32.parse(aaa + vv_[4]) + this.ROTATE(this.T_00_15, i));\r\n            SS1 = this.ROTATE(SS1, 7);\r\n            SS2 = SS1 ^ aaa;\r\n            TT1 = Int32.parse(Int32.parse(this.FF_00_15(vv_[0], vv_[1], vv_[2]) + vv_[3]) + SS2) + ww_[i];\r\n            TT2 = Int32.parse(Int32.parse(this.GG_00_15(vv_[4], vv_[5], vv_[6]) + vv_[7]) + SS1) + ww[i];\r\n            vv_[3] = vv_[2];\r\n            vv_[2] = this.ROTATE(vv_[1], 9);\r\n            vv_[1] = vv_[0];\r\n            vv_[0] = TT1;\r\n            vv_[7] = vv_[6];\r\n            vv_[6] = this.ROTATE(vv_[5], 19);\r\n            vv_[5] = vv_[4];\r\n            vv_[4] = this.P0(TT2)\r\n        }\r\n        for (i = 16; i < 64; i++) {\r\n            aaa = this.ROTATE(vv_[0], 12);\r\n            SS1 = Int32.parse(Int32.parse(aaa + vv_[4]) + this.ROTATE(this.T_16_63, i));\r\n            SS1 = this.ROTATE(SS1, 7);\r\n            SS2 = SS1 ^ aaa;\r\n            TT1 = Int32.parse(Int32.parse(this.FF_16_63(vv_[0], vv_[1], vv_[2]) + vv_[3]) + SS2) + ww_[i];\r\n            TT2 = Int32.parse(Int32.parse(this.GG_16_63(vv_[4], vv_[5], vv_[6]) + vv_[7]) + SS1) + ww[i];\r\n            vv_[3] = vv_[2];\r\n            vv_[2] = this.ROTATE(vv_[1], 9);\r\n            vv_[1] = vv_[0];\r\n            vv_[0] = TT1;\r\n            vv_[7] = vv_[6];\r\n            vv_[6] = this.ROTATE(vv_[5], 19);\r\n            vv_[5] = vv_[4];\r\n            vv_[4] = this.P0(TT2)\r\n        }\r\n        for (i = 0; i < 8; i++) {\r\n            vv[i] ^= Int32.parse(vv_[i])\r\n        }\r\n        this.xOff = 0;\r\n        Array.Copy(this.X0, 0, this.X, 0, this.X0.length)\r\n    },\r\n    ProcessWord: function(in_Renamed, inOff) {\r\n        var n = in_Renamed[inOff] << 24;\r\n        n |= (in_Renamed[++inOff] & 0xff) << 16;\r\n        n |= (in_Renamed[++inOff] & 0xff) << 8;\r\n        n |= (in_Renamed[++inOff] & 0xff);\r\n        this.X[this.xOff] = n;\r\n        if (++this.xOff == 16) {\r\n            this.ProcessBlock()\r\n        }\r\n    },\r\n    ProcessLength: function(bitLength) {\r\n        if (this.xOff > 14) {\r\n            this.ProcessBlock()\r\n        }\r\n        this.X[14] = (this.URShiftLong(bitLength, 32));\r\n        this.X[15] = (bitLength & (0xffffffff))\r\n    },\r\n    IntToBigEndian: function(n, bs, off) {\r\n        bs[off] = Int32.parseByte(this.URShift(n, 24));\r\n        bs[++off] = Int32.parseByte(this.URShift(n, 16));\r\n        bs[++off] = Int32.parseByte(this.URShift(n, 8));\r\n        bs[++off] = Int32.parseByte(n)\r\n    },\r\n    DoFinal: function(out_Renamed, outOff) {\r\n        this.Finish();\r\n        for (var i = 0; i < 8; i++) {\r\n            this.IntToBigEndian(this.v[i], out_Renamed, outOff + i * 4)\r\n        }\r\n        this.Reset();\r\n        return this.DIGEST_LENGTH\r\n    },\r\n    Update: function(input) {\r\n        this.xBuf[this.xBufOff++] = input;\r\n        if (this.xBufOff == this.xBuf.length) {\r\n            this.ProcessWord(this.xBuf, 0);\r\n            this.xBufOff = 0\r\n        }\r\n        this.byteCount++\r\n    },\r\n    BlockUpdate: function(input, inOff, length) {\r\n        while ((this.xBufOff != 0) && (length > 0)) {\r\n            this.Update(input[inOff]);\r\n            inOff++;\r\n            length--\r\n        }\r\n        while (length > this.xBuf.length) {\r\n            this.ProcessWord(input, inOff);\r\n            inOff += this.xBuf.length;\r\n            length -= this.xBuf.length;\r\n            this.byteCount += this.xBuf.length\r\n        }\r\n        while (length > 0) {\r\n            this.Update(input[inOff]);\r\n            inOff++;\r\n            length--\r\n        }\r\n    },\r\n    Finish: function() {\r\n        var bitLength = (this.byteCount << 3);\r\n        this.Update((128));\r\n        while (this.xBufOff != 0) this.Update((0));\r\n        this.ProcessLength(bitLength);\r\n        this.ProcessBlock()\r\n    },\r\n    ROTATE: function(x, n) {\r\n        return (x << n) | (this.URShift(x, (32 - n)))\r\n    },\r\n    P0: function(X) {\r\n        return ((X) ^ this.ROTATE((X), 9) ^ this.ROTATE((X), 17))\r\n    },\r\n    P1: function(X) {\r\n        return ((X) ^ this.ROTATE((X), 15) ^ this.ROTATE((X), 23))\r\n    },\r\n    FF_00_15: function(X, Y, Z) {\r\n        return (X ^ Y ^ Z)\r\n    },\r\n    FF_16_63: function(X, Y, Z) {\r\n        return ((X & Y) | (X & Z) | (Y & Z))\r\n    },\r\n    GG_00_15: function(X, Y, Z) {\r\n        return (X ^ Y ^ Z)\r\n    },\r\n    GG_16_63: function(X, Y, Z) {\r\n        return ((X & Y) | (~X & Z))\r\n    },\r\n    URShift: function(number, bits) {\r\n        if (number > Int32.maxValue || number < Int32.minValue) {\r\n            number = Int32.parse(number)\r\n        }\r\n        if (number >= 0) {\r\n            return number >> bits\r\n        } else {\r\n            return (number >> bits) + (2 << ~bits)\r\n        }\r\n    },\r\n    URShiftLong: function(number, bits) {\r\n        var returnV;\r\n        var big = new BigInteger();\r\n        big.fromInt(number);\r\n        if (big.signum() >= 0) {\r\n            returnV = big.shiftRight(bits).intValue()\r\n        } else {\r\n            var bigAdd = new BigInteger();\r\n            bigAdd.fromInt(2);\r\n            var shiftLeftBits = ~bits;\r\n            var shiftLeftNumber = '';\r\n            if (shiftLeftBits < 0) {\r\n                var shiftRightBits = 64 + shiftLeftBits;\r\n                for (var i = 0; i < shiftRightBits; i++) {\r\n                    shiftLeftNumber += '0'\r\n                }\r\n                var shiftLeftNumberBigAdd = new BigInteger();\r\n                shiftLeftNumberBigAdd.fromInt(number >> bits);\r\n                var shiftLeftNumberBig = new BigInteger(\"10\" + shiftLeftNumber, 2);\r\n                shiftLeftNumber = shiftLeftNumberBig.toRadix(10);\r\n                var r = shiftLeftNumberBig.add(shiftLeftNumberBigAdd);\r\n                returnV = r.toRadix(10)\r\n            } else {\r\n                shiftLeftNumber = bigAdd.shiftLeft((~bits)).intValue();\r\n                returnV = (number >> bits) + shiftLeftNumber\r\n            }\r\n        }\r\n        return returnV\r\n    },\r\n    GetZ: function(g, pubKeyHex) {\r\n        var userId = CryptoJS.enc.Utf8.parse(\"1234567812345678\");\r\n        var len = userId.words.length * 4 * 8;\r\n        this.Update((len >> 8 & 0x00ff));\r\n        this.Update((len & 0x00ff));\r\n        var userIdWords = this.GetWords(userId.toString());\r\n        this.BlockUpdate(userIdWords, 0, userIdWords.length);\r\n        var aWords = this.GetWords(g.curve.a.toBigInteger().toRadix(16));\r\n        var bWords = this.GetWords(g.curve.b.toBigInteger().toRadix(16));\r\n        var gxWords = this.GetWords(g.getX().toBigInteger().toRadix(16));\r\n        var gyWords = this.GetWords(g.getY().toBigInteger().toRadix(16));\r\n        var pxWords = this.GetWords(pubKeyHex.substr(0, 64));\r\n        var pyWords = this.GetWords(pubKeyHex.substr(64, 64));\r\n        this.BlockUpdate(aWords, 0, aWords.length);\r\n        this.BlockUpdate(bWords, 0, bWords.length);\r\n        this.BlockUpdate(gxWords, 0, gxWords.length);\r\n        this.BlockUpdate(gyWords, 0, gyWords.length);\r\n        this.BlockUpdate(pxWords, 0, pxWords.length);\r\n        this.BlockUpdate(pyWords, 0, pyWords.length);\r\n        var md = new Array(this.GetDigestSize());\r\n        this.DoFinal(md, 0);\r\n        return md\r\n    },\r\n    GetWords: function(hexStr) {\r\n        var words = [];\r\n        var hexStrLength = hexStr.length;\r\n        for (var i = 0; i < hexStrLength; i += 2) {\r\n            words[words.length] = parseInt(hexStr.substr(i, 2), 16)\r\n        }\r\n        return words\r\n    },\r\n    GetHex: function(arr) {\r\n        var words = [];\r\n        var j = 0;\r\n        for (var i = 0; i < arr.length * 2; i += 2) {\r\n            words[i >>> 3] |= parseInt(arr[j]) << (24 - (i % 8) * 4);\r\n            j++\r\n        }\r\n        var wordArray = new CryptoJS.lib.WordArray.init(words, arr.length);\r\n        return wordArray\r\n    }\r\n};\r\nArray.Clear = function(destinationArray, destinationIndex, length) {\r\n    for (elm in destinationArray) {\r\n        destinationArray[elm] = null\r\n    }\r\n};\r\nArray.Copy = function(sourceArray, sourceIndex, destinationArray, destinationIndex, length) {\r\n    var cloneArray = sourceArray.slice(sourceIndex, sourceIndex + length);\r\n    for (var i = 0; i < cloneArray.length; i++) {\r\n        destinationArray[destinationIndex] = cloneArray[i];\r\n        destinationIndex++\r\n    }\r\n};\r\nwindow.Int32 = {\r\n    minValue: -parseInt('10000000000000000000000000000000', 2),\r\n    maxValue: parseInt('1111111111111111111111111111111', 2),\r\n    parse: function(n) {\r\n        if (n < this.minValue) {\r\n            var bigInteger = new Number(-n);\r\n            var bigIntegerRadix = bigInteger.toString(2);\r\n            var subBigIntegerRadix = bigIntegerRadix.substr(bigIntegerRadix.length - 31, 31);\r\n            var reBigIntegerRadix = '';\r\n            for (var i = 0; i < subBigIntegerRadix.length; i++) {\r\n                var subBigIntegerRadixItem = subBigIntegerRadix.substr(i, 1);\r\n                reBigIntegerRadix += subBigIntegerRadixItem == '0' ? '1' : '0'\r\n            }\r\n            var result = parseInt(reBigIntegerRadix, 2);\r\n            return (result + 1)\r\n        } else if (n > this.maxValue) {\r\n            var bigInteger = Number(n);\r\n            var bigIntegerRadix = bigInteger.toString(2);\r\n            var subBigIntegerRadix = bigIntegerRadix.substr(bigIntegerRadix.length - 31, 31);\r\n            var reBigIntegerRadix = '';\r\n            for (var i = 0; i < subBigIntegerRadix.length; i++) {\r\n                var subBigIntegerRadixItem = subBigIntegerRadix.substr(i, 1);\r\n                reBigIntegerRadix += subBigIntegerRadixItem == '0' ? '1' : '0'\r\n            }\r\n            var result = parseInt(reBigIntegerRadix, 2);\r\n            return -(result + 1)\r\n        } else {\r\n            return n\r\n        }\r\n    },\r\n    parseByte: function(n) {\r\n        if (n < 0) {\r\n            var bigInteger = new Number(-n);\r\n            var bigIntegerRadix = bigInteger.toString(2);\r\n            var subBigIntegerRadix = bigIntegerRadix.substr(bigIntegerRadix.length - 8, 8);\r\n            var reBigIntegerRadix = '';\r\n            for (var i = 0; i < subBigIntegerRadix.length; i++) {\r\n                var subBigIntegerRadixItem = subBigIntegerRadix.substr(i, 1);\r\n                reBigIntegerRadix += subBigIntegerRadixItem == '0' ? '1' : '0'\r\n            }\r\n            var result = parseInt(reBigIntegerRadix, 2);\r\n            return (result + 1)\r\n        } else if (n > 255) {\r\n            var bigInteger = Number(n);\r\n            var bigIntegerRadix = bigInteger.toString(2);\r\n            return parseInt(bigIntegerRadix.substr(bigIntegerRadix.length - 8, 8), 2)\r\n        } else {\r\n            return n\r\n        }\r\n    }\r\n};"
  },
  {
    "path": "JavaScript/demo/js/sm3-sm2-1.0.js",
    "content": "/*! sm3-sm2-1.0.js (c) Jonllen Peng | http://www.jonllen.com/\r\n */\r\n/*\r\n * sm3-sm2-1.0.js\r\n * \r\n * Copyright (c) 2014 Jonllen Peng (www.jonllen.com)\r\n */\r\n/**\r\n * @fileOverview\r\n * @name sm3-sm2-1.0.js\r\n * @author Jonllen (www.jonllen.com)\r\n * @version 1.0.0 (2014-06-18)\r\n */\r\n\r\nif (typeof KJUR == \"undefined\" || !KJUR) KJUR = {};\r\nif (typeof KJUR.crypto == \"undefined\" || !KJUR.crypto) KJUR.crypto = {};\r\n\r\n/**\r\n * class for SM2 key generation,  sm3WithSM2 signing and verifcation\r\n * @name KJUR.crypto.SM3withSM2\r\n * @class class for SM2 key generation,  SM2 signing and verifcation\r\n * @description\r\n * <p>\r\n * CAUTION: Most of the case, you don't need to use this class except\r\n * for generating an SM2 key pair. Please use {@link KJUR.crypto.Signature} class instead.\r\n * </p>\r\n * <p>\r\n * This class was originally developped by Stefan Thomas for Bitcoin JavaScript library.\r\n * Currently this class supports following named curves and their aliases.\r\n * <ul>\r\n * <li>secp256r1, NIST P-256, P-256, prime256v1 (*)</li>\r\n * <li>secp256k1 (*)</li>\r\n * <li>secp384r1, NIST P-384, P-384 (*)</li>\r\n  * <li>sm2</li>\r\n * </ul>\r\n * </p>\r\n */\r\nKJUR.crypto.SM3withSM2 = function(params) {\r\n    var curveName = \"sm2\";\t// curve name default\r\n    var ecparams = null;\r\n    var prvKeyHex = null;\r\n    var pubKeyHex = null;\r\n\r\n    var rng = new SecureRandom();\r\n\r\n    var P_OVER_FOUR = null;\r\n\r\n    this.type = \"SM2\";\r\n\r\n    function implShamirsTrick(P, k, Q, l) {\r\n\tvar m = Math.max(k.bitLength(), l.bitLength());\r\n\tvar Z = P.add2D(Q);\r\n\tvar R = P.curve.getInfinity();\r\n\r\n\tfor (var i = m - 1; i >= 0; --i) {\r\n\t    R = R.twice2D();\r\n\r\n\t    R.z = BigInteger.ONE;\r\n\r\n\t    if (k.testBit(i)) {\r\n\t\tif (l.testBit(i)) {\r\n\t\t    R = R.add2D(Z);\r\n\t\t} else {\r\n\t\t    R = R.add2D(P);\r\n\t\t}\r\n\t    } else {\r\n\t\tif (l.testBit(i)) {\r\n\t\t    R = R.add2D(Q);\r\n\t\t}\r\n\t    }\r\n\t}\r\n\t\r\n\treturn R;\r\n    };\r\n\r\n    //===========================\r\n    // PUBLIC METHODS\r\n    //===========================\r\n    this.getBigRandom = function (limit) {\r\n\treturn new BigInteger(limit.bitLength(), rng)\r\n\t.mod(limit.subtract(BigInteger.ONE))\r\n\t.add(BigInteger.ONE)\r\n\t;\r\n    };\r\n\r\n    this.setNamedCurve = function(curveName) {\r\n\tthis.ecparams = KJUR.crypto.ECParameterDB.getByName(curveName);\r\n\tthis.prvKeyHex = null;\r\n\tthis.pubKeyHex = null;\r\n\tthis.curveName = curveName;\r\n    }\r\n\r\n    this.setPrivateKeyHex = function(prvKeyHex) {\r\n        this.isPrivate = true;\r\n\tthis.prvKeyHex = prvKeyHex;\r\n    }\r\n\r\n    this.setPublicKeyHex = function(pubKeyHex) {\r\n        this.isPublic = true;\r\n\tthis.pubKeyHex = pubKeyHex;\r\n    }\r\n\r\n    /**\r\n     * generate a EC key pair\r\n     * @name generateKeyPairHex\r\n     * @memberOf KJUR.crypto.ECDSA\r\n     * @function\r\n     * @return {Array} associative array of hexadecimal string of private and public key\r\n     * @since ecdsa-modified 1.0.1\r\n     * @example\r\n     * var ec = KJUR.crypto.ECDSA({'curve': 'sm2'});\r\n     * var keypair = ec.generateKeyPairHex();\r\n     * var pubhex = keypair.ecpubhex; // hexadecimal string of EC private key (=d)\r\n     * var prvhex = keypair.ecprvhex; // hexadecimal string of EC public key\r\n     */\r\n    this.generateKeyPairHex = function() {\r\n\tvar biN = this.ecparams['n'];\r\n\tvar biPrv = this.getBigRandom(biN);\r\n\tvar epPub = this.ecparams['G'].multiply(biPrv);\r\n\tvar biX = epPub.getX().toBigInteger();\r\n\tvar biY = epPub.getY().toBigInteger();\r\n\r\n\tvar charlen = this.ecparams['keylen'] / 4;\r\n\tvar hPrv = (\"0000000000\" + biPrv.toString(16)).slice(- charlen);\r\n\tvar hX   = (\"0000000000\" + biX.toString(16)).slice(- charlen);\r\n\tvar hY   = (\"0000000000\" + biY.toString(16)).slice(- charlen);\r\n\tvar hPub = \"04\" + hX + hY;\r\n\r\n\tthis.setPrivateKeyHex(hPrv);\r\n\tthis.setPublicKeyHex(hPub);\r\n\treturn {'ecprvhex': hPrv, 'ecpubhex': hPub};\r\n    };\r\n\r\n    this.signWithMessageHash = function(hashHex) {\r\n\treturn this.signHex(hashHex, this.prvKeyHex);\r\n    };\r\n\r\n    /**\r\n     * signing to message hash\r\n     * @name signHex\r\n     * @memberOf KJUR.crypto.SM3withSM2\r\n     * @function\r\n     * @param {String} hashHex hexadecimal string of hash value of signing message\r\n     * @param {String} privHex hexadecimal string of EC private key\r\n     * @return {String} hexadecimal string of ECDSA signature\r\n     * @since ecdsa-modified 1.0.1\r\n     * @example\r\n     * var ec = KJUR.crypto.SM3withSM2({'curve': 'sm2'});\r\n     * var sigValue = ec.signHex(hash, prvKey);\r\n     */\r\n    this.signHex = function (hashHex, privHex) {\r\n\tvar d = new BigInteger(privHex, 16);\r\n\tvar n = this.ecparams['n'];\r\n\tvar e = new BigInteger(hashHex, 16);\r\n\t\r\n\t// k BigInteger\r\n    var k = null;\r\n    var kp = null;\r\n    var r = null;\r\n    var s = null;\r\n    var userD = d;\r\n    \r\n    do\r\n    {\r\n        do\r\n        {\r\n\t\t\t\r\n\t\t\tvar keypair = this.generateKeyPairHex();\r\n\t\t\t\r\n\t\t\tk = new BigInteger(keypair.ecprvhex, 16);\r\n\t\t\tvar pubkeyHex = keypair.ecpubhex;\r\n\t\t\t\r\n  \t\t\tkp = ECPointFp.decodeFromHex(this.ecparams['curve'], pubkeyHex);\r\n\r\n            // r\r\n            r = e.add(kp.getX().toBigInteger());\r\n            r = r.mod(n);\r\n        }\r\n        while (r.equals(BigInteger.ZERO) || r.add(k).equals(n));\r\n\r\n        // (1 + dA)~-1\r\n        var da_1 = userD.add(BigInteger.ONE);\r\n        da_1 = da_1.modInverse(n);\r\n        // s\r\n        s = r.multiply(userD);\r\n        s = k.subtract(s).mod(n);\r\n        s = da_1.multiply(s).mod(n);\r\n    }\r\n    while (s.equals(BigInteger.ZERO));\r\n    \r\n\r\n\treturn KJUR.crypto.ECDSA.biRSSigToASN1Sig(r, s);\r\n    };\r\n\r\n    this.sign = function (hash, priv) {\r\n\tvar d = priv;\r\n\tvar n = this.ecparams['n'];\r\n\tvar e = BigInteger.fromByteArrayUnsigned(hash);\r\n\r\n\tdo {\r\n\t    var k = this.getBigRandom(n);\r\n\t    var G = this.ecparams['G'];\r\n\t    var Q = G.multiply(k);\r\n\t    var r = Q.getX().toBigInteger().mod(n);\r\n\t} while (r.compareTo(BigInteger.ZERO) <= 0);\r\n\r\n\tvar s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);\r\n\treturn this.serializeSig(r, s);\r\n    };\r\n\r\n    this.verifyWithMessageHash = function(hashHex, sigHex) {\r\n\treturn this.verifyHex(hashHex, sigHex, this.pubKeyHex);\r\n    };\r\n\r\n    /**\r\n     * verifying signature with message hash and public key\r\n     * @name verifyHex\r\n     * @memberOf KJUR.crypto.SM3withSM2\r\n     * @function\r\n     * @param {String} hashHex hexadecimal string of hash value of signing message\r\n     * @param {String} sigHex hexadecimal string of signature value\r\n     * @param {String} pubkeyHex hexadecimal string of public key\r\n     * @return {Boolean} true if the signature is valid, otherwise false\r\n     * @since ecdsa-modified 1.0.1\r\n     * @example\r\n     * var ec = KJUR.crypto.SM3withSM2({'curve': 'sm2'});\r\n     * var result = ec.verifyHex(msgHashHex, sigHex, pubkeyHex);\r\n     */\r\n    this.verifyHex = function(hashHex, sigHex, pubkeyHex) {\r\n\tvar r,s;\r\n\r\n\tvar obj = KJUR.crypto.ECDSA.parseSigHex(sigHex);\r\n\tr = obj.r;\r\n\ts = obj.s;\r\n\r\n\tvar Q;\r\n\tQ = ECPointFp.decodeFromHex(this.ecparams['curve'], pubkeyHex);\r\n\tvar e = new BigInteger(hashHex, 16);\r\n\r\n\treturn this.verifyRaw(e, r, s, Q);\r\n    };\r\n\r\n    this.verify = function (hash, sig, pubkey) {\r\n\tvar r,s;\r\n\tif (Bitcoin.Util.isArray(sig)) {\r\n\t    var obj = this.parseSig(sig);\r\n\t    r = obj.r;\r\n\t    s = obj.s;\r\n\t} else if (\"object\" === typeof sig && sig.r && sig.s) {\r\n\t    r = sig.r;\r\n\t    s = sig.s;\r\n\t} else {\r\n\t    throw \"Invalid value for signature\";\r\n\t}\r\n\r\n\tvar Q;\r\n\tif (pubkey instanceof ECPointFp) {\r\n\t    Q = pubkey;\r\n\t} else if (Bitcoin.Util.isArray(pubkey)) {\r\n\t    Q = ECPointFp.decodeFrom(this.ecparams['curve'], pubkey);\r\n\t} else {\r\n\t    throw \"Invalid format for pubkey value, must be byte array or ECPointFp\";\r\n\t}\r\n\tvar e = BigInteger.fromByteArrayUnsigned(hash);\r\n\r\n\treturn this.verifyRaw(e, r, s, Q);\r\n    };\r\n\r\n    this.verifyRaw = function (e, r, s, Q) {\r\n\tvar n = this.ecparams['n'];\r\n\tvar G = this.ecparams['G'];\r\n\t\r\n\tvar t = r.add(s).mod(n);\r\n    if (t.equals(BigInteger.ZERO))\r\n        return false;\r\n        \r\n    var x1y1 = G.multiply(s);\r\n    x1y1 = x1y1.add(Q.multiply(t));\r\n\r\n    var R = e.add(x1y1.getX().toBigInteger()).mod(n);\r\n    return r.equals(R);\r\n    };\r\n\r\n    /**\r\n     * Serialize a signature into DER format.\r\n     *\r\n     * Takes two BigIntegers representing r and s and returns a byte array.\r\n     */\r\n    this.serializeSig = function (r, s) {\r\n\tvar rBa = r.toByteArraySigned();\r\n\tvar sBa = s.toByteArraySigned();\r\n\r\n\tvar sequence = [];\r\n\tsequence.push(0x02); // INTEGER\r\n\tsequence.push(rBa.length);\r\n\tsequence = sequence.concat(rBa);\r\n\r\n\tsequence.push(0x02); // INTEGER\r\n\tsequence.push(sBa.length);\r\n\tsequence = sequence.concat(sBa);\r\n\r\n\tsequence.unshift(sequence.length);\r\n\tsequence.unshift(0x30); // SEQUENCE\r\n\treturn sequence;\r\n    };\r\n\r\n    /**\r\n     * Parses a byte array containing a DER-encoded signature.\r\n     *\r\n     * This function will return an object of the form:\r\n     *\r\n     * {\r\n     *   r: BigInteger,\r\n     *   s: BigInteger\r\n     * }\r\n     */\r\n    this.parseSig = function (sig) {\r\n\tvar cursor;\r\n\tif (sig[0] != 0x30)\r\n\t    throw new Error(\"Signature not a valid DERSequence\");\r\n\r\n\tcursor = 2;\r\n\tif (sig[cursor] != 0x02)\r\n\t    throw new Error(\"First element in signature must be a DERInteger\");;\r\n\tvar rBa = sig.slice(cursor+2, cursor+2+sig[cursor+1]);\r\n\r\n\tcursor += 2+sig[cursor+1];\r\n\tif (sig[cursor] != 0x02)\r\n\t    throw new Error(\"Second element in signature must be a DERInteger\");\r\n\tvar sBa = sig.slice(cursor+2, cursor+2+sig[cursor+1]);\r\n\r\n\tcursor += 2+sig[cursor+1];\r\n\r\n\t//if (cursor != sig.length)\r\n\t//  throw new Error(\"Extra bytes in signature\");\r\n\r\n\tvar r = BigInteger.fromByteArrayUnsigned(rBa);\r\n\tvar s = BigInteger.fromByteArrayUnsigned(sBa);\r\n\r\n\treturn {r: r, s: s};\r\n    };\r\n\r\n    this.parseSigCompact = function (sig) {\r\n\tif (sig.length !== 65) {\r\n\t    throw \"Signature has the wrong length\";\r\n\t}\r\n\r\n\t// Signature is prefixed with a type byte storing three bits of\r\n\t// information.\r\n\tvar i = sig[0] - 27;\r\n\tif (i < 0 || i > 7) {\r\n\t    throw \"Invalid signature type\";\r\n\t}\r\n\r\n\tvar n = this.ecparams['n'];\r\n\tvar r = BigInteger.fromByteArrayUnsigned(sig.slice(1, 33)).mod(n);\r\n\tvar s = BigInteger.fromByteArrayUnsigned(sig.slice(33, 65)).mod(n);\r\n\r\n\treturn {r: r, s: s, i: i};\r\n    };\r\n\r\n    if (params !== undefined) {\r\n\tif (params['curve'] !== undefined) {\r\n\t    this.curveName = params['curve'];\r\n\t}\r\n    }\r\n    if (this.curveName === undefined) this.curveName = curveName;\r\n    this.setNamedCurve(this.curveName);\r\n    if (params !== undefined) {\r\n\tif (params['prv'] !== undefined) this.setPrivateKeyHex(params['prv']);\r\n\tif (params['pub'] !== undefined) this.setPublicKeyHex(params['pub']);\r\n    }\r\n};\r\n"
  },
  {
    "path": "JavaScript/demo/js/sm3.js",
    "content": "(function(){var C=CryptoJS;var C_lib=C.lib;var WordArray=C_lib.WordArray;var Hasher=C_lib.Hasher;var C_algo=C.algo;var W=[];var SM3=C_algo.SM3=Hasher.extend({_doReset:function(){this._hash=new WordArray.init([0x7380166f,0x4914b2b9,0x172442d7,0xda8a0600,0xa96f30bc,0x163138aa,0xe38dee4d,0xb0fb0e4e])},_doProcessBlock:function(M,offset){var H=this._hash.words;var a=H[0];var b=H[1];var c=H[2];var d=H[3];var e=H[4];for(var i=0;i<80;i++){if(i<16){W[i]=M[offset+i]|0}else{var n=W[i-3]^W[i-8]^W[i-14]^W[i-16];W[i]=(n<<1)|(n>>>31)}var t=((a<<5)|(a>>>27))+e+W[i];if(i<20){t+=((b&c)|(~b&d))+0x5a827999}else if(i<40){t+=(b^c^d)+0x6ed9eba1}else if(i<60){t+=((b&c)|(b&d)|(c&d))-0x70e44324}else{t+=(b^c^d)-0x359d3e2a}e=d;d=c;c=(b<<30)|(b>>>2);b=a;a=t}H[0]=(H[0]+a)|0;H[1]=(H[1]+b)|0;H[2]=(H[2]+c)|0;H[3]=(H[3]+d)|0;H[4]=(H[4]+e)|0},_doFinalize:function(){var data=this._data;var dataWords=data.words;var nBitsTotal=this._nDataBytes*8;var nBitsLeft=data.sigBytes*8;dataWords[nBitsLeft>>>5]|=0x80<<(24-nBitsLeft%32);dataWords[(((nBitsLeft+64)>>>9)<<4)+14]=Math.floor(nBitsTotal/0x100000000);dataWords[(((nBitsLeft+64)>>>9)<<4)+15]=nBitsTotal;data.sigBytes=dataWords.length*4;this._process();return this._hash},clone:function(){var clone=Hasher.clone.call(this);clone._hash=this._hash.clone();return clone}});C.SM3=Hasher._createHelper(SM3);C.HmacSM3=Hasher._createHmacHelper(SM3)}());function SM3Digest(){this.BYTE_LENGTH=64;this.xBuf=new Array();this.xBufOff=0;this.byteCount=0;this.DIGEST_LENGTH=32;this.v0=[0x7380166f,0x4914b2b9,0x172442d7,0xda8a0600,0xa96f30bc,0x163138aa,0xe38dee4d,0xb0fb0e4e];this.v0=[0x7380166f,0x4914b2b9,0x172442d7,-628488704,-1452330820,0x163138aa,-477237683,-1325724082];this.v=new Array(8);this.v_=new Array(8);this.X0=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];this.X=new Array(68);this.xOff=0;this.T_00_15=0x79cc4519;this.T_16_63=0x7a879d8a;if(arguments.length>0){this.InitDigest(arguments[0])}else{this.Init()}}SM3Digest.prototype={Init:function(){this.xBuf=new Array(4);this.Reset()},InitDigest:function(t){this.xBuf=new Array(t.xBuf.length);Array.Copy(t.xBuf,0,this.xBuf,0,t.xBuf.length);this.xBufOff=t.xBufOff;this.byteCount=t.byteCount;Array.Copy(t.X,0,this.X,0,t.X.length);this.xOff=t.xOff;Array.Copy(t.v,0,this.v,0,t.v.length)},GetDigestSize:function(){return this.DIGEST_LENGTH},Reset:function(){this.byteCount=0;this.xBufOff=0;Array.Clear(this.xBuf,0,this.xBuf.length);Array.Copy(this.v0,0,this.v,0,this.v0.length);this.xOff=0;Array.Copy(this.X0,0,this.X,0,this.X0.length)},GetByteLength:function(){return this.BYTE_LENGTH},ProcessBlock:function(){var i;var ww=this.X;var ww_=new Array(64);for(i=16;i<68;i++){ww[i]=this.P1(ww[i-16]^ww[i-9]^(this.ROTATE(ww[i-3],15)))^(this.ROTATE(ww[i-13],7))^ww[i-6]}for(i=0;i<64;i++){ww_[i]=ww[i]^ww[i+4]}var vv=this.v;var vv_=this.v_;Array.Copy(vv,0,vv_,0,this.v0.length);var SS1,SS2,TT1,TT2,aaa;for(i=0;i<16;i++){aaa=this.ROTATE(vv_[0],12);SS1=Int32.parse(Int32.parse(aaa+vv_[4])+this.ROTATE(this.T_00_15,i));SS1=this.ROTATE(SS1,7);SS2=SS1^aaa;TT1=Int32.parse(Int32.parse(this.FF_00_15(vv_[0],vv_[1],vv_[2])+vv_[3])+SS2)+ww_[i];TT2=Int32.parse(Int32.parse(this.GG_00_15(vv_[4],vv_[5],vv_[6])+vv_[7])+SS1)+ww[i];vv_[3]=vv_[2];vv_[2]=this.ROTATE(vv_[1],9);vv_[1]=vv_[0];vv_[0]=TT1;vv_[7]=vv_[6];vv_[6]=this.ROTATE(vv_[5],19);vv_[5]=vv_[4];vv_[4]=this.P0(TT2)}for(i=16;i<64;i++){aaa=this.ROTATE(vv_[0],12);SS1=Int32.parse(Int32.parse(aaa+vv_[4])+this.ROTATE(this.T_16_63,i));SS1=this.ROTATE(SS1,7);SS2=SS1^aaa;TT1=Int32.parse(Int32.parse(this.FF_16_63(vv_[0],vv_[1],vv_[2])+vv_[3])+SS2)+ww_[i];TT2=Int32.parse(Int32.parse(this.GG_16_63(vv_[4],vv_[5],vv_[6])+vv_[7])+SS1)+ww[i];vv_[3]=vv_[2];vv_[2]=this.ROTATE(vv_[1],9);vv_[1]=vv_[0];vv_[0]=TT1;vv_[7]=vv_[6];vv_[6]=this.ROTATE(vv_[5],19);vv_[5]=vv_[4];vv_[4]=this.P0(TT2)}for(i=0;i<8;i++){vv[i]^=Int32.parse(vv_[i])}this.xOff=0;Array.Copy(this.X0,0,this.X,0,this.X0.length)},ProcessWord:function(in_Renamed,inOff){var n=in_Renamed[inOff]<<24;n|=(in_Renamed[++inOff]&0xff)<<16;n|=(in_Renamed[++inOff]&0xff)<<8;n|=(in_Renamed[++inOff]&0xff);this.X[this.xOff]=n;if(++this.xOff==16){this.ProcessBlock()}},ProcessLength:function(bitLength){if(this.xOff>14){this.ProcessBlock()}this.X[14]=(this.URShiftLong(bitLength,32));this.X[15]=(bitLength&(0xffffffff))},IntToBigEndian:function(n,bs,off){bs[off]=Int32.parseByte(this.URShift(n,24));bs[++off]=Int32.parseByte(this.URShift(n,16));bs[++off]=Int32.parseByte(this.URShift(n,8));bs[++off]=Int32.parseByte(n)},DoFinal:function(out_Renamed,outOff){this.Finish();for(var i=0;i<8;i++){this.IntToBigEndian(this.v[i],out_Renamed,outOff+i*4)}this.Reset();return this.DIGEST_LENGTH},Update:function(input){this.xBuf[this.xBufOff++]=input;if(this.xBufOff==this.xBuf.length){this.ProcessWord(this.xBuf,0);this.xBufOff=0}this.byteCount++},BlockUpdate:function(input,inOff,length){while((this.xBufOff!=0)&&(length>0)){this.Update(input[inOff]);inOff++;length--}while(length>this.xBuf.length){this.ProcessWord(input,inOff);inOff+=this.xBuf.length;length-=this.xBuf.length;this.byteCount+=this.xBuf.length}while(length>0){this.Update(input[inOff]);inOff++;length--}},Finish:function(){var bitLength=(this.byteCount<<3);this.Update((128));while(this.xBufOff!=0)this.Update((0));this.ProcessLength(bitLength);this.ProcessBlock()},ROTATE:function(x,n){return(x<<n)|(this.URShift(x,(32-n)))},P0:function(X){return((X)^this.ROTATE((X),9)^this.ROTATE((X),17))},P1:function(X){return((X)^this.ROTATE((X),15)^this.ROTATE((X),23))},FF_00_15:function(X,Y,Z){return(X^Y^Z)},FF_16_63:function(X,Y,Z){return((X&Y)|(X&Z)|(Y&Z))},GG_00_15:function(X,Y,Z){return(X^Y^Z)},GG_16_63:function(X,Y,Z){return((X&Y)|(~X&Z))},URShift:function(number,bits){if(number>Int32.maxValue||number<Int32.minValue){number=Int32.parse(number)}if(number>=0){return number>>bits}else{return(number>>bits)+(2<<~bits)}},URShiftLong:function(number,bits){var returnV;var big=new BigInteger();big.fromInt(number);if(big.signum()>=0){returnV=big.shiftRight(bits).intValue()}else{var bigAdd=new BigInteger();bigAdd.fromInt(2);var shiftLeftBits=~bits;var shiftLeftNumber='';if(shiftLeftBits<0){var shiftRightBits=64+shiftLeftBits;for(var i=0;i<shiftRightBits;i++){shiftLeftNumber+='0'}var shiftLeftNumberBigAdd=new BigInteger();shiftLeftNumberBigAdd.fromInt(number>>bits);var shiftLeftNumberBig=new BigInteger(\"10\"+shiftLeftNumber,2);shiftLeftNumber=shiftLeftNumberBig.toRadix(10);var r=shiftLeftNumberBig.add(shiftLeftNumberBigAdd);returnV=r.toRadix(10)}else{shiftLeftNumber=bigAdd.shiftLeft((~bits)).intValue();returnV=(number>>bits)+shiftLeftNumber}}return returnV},GetZ:function(g,pubKeyHex){var userId=CryptoJS.enc.Utf8.parse(\"1234567812345678\");var len=userId.words.length*4*8;this.Update((len>>8&0x00ff));this.Update((len&0x00ff));var userIdWords=this.GetWords(userId.toString());this.BlockUpdate(userIdWords,0,userIdWords.length);var aWords=this.GetWords(g.curve.a.toBigInteger().toRadix(16));var bWords=this.GetWords(g.curve.b.toBigInteger().toRadix(16));var gxWords=this.GetWords(g.getX().toBigInteger().toRadix(16));var gyWords=this.GetWords(g.getY().toBigInteger().toRadix(16));var pxWords=this.GetWords(pubKeyHex.substr(0,64));var pyWords=this.GetWords(pubKeyHex.substr(64,64));this.BlockUpdate(aWords,0,aWords.length);this.BlockUpdate(bWords,0,bWords.length);this.BlockUpdate(gxWords,0,gxWords.length);this.BlockUpdate(gyWords,0,gyWords.length);this.BlockUpdate(pxWords,0,pxWords.length);this.BlockUpdate(pyWords,0,pyWords.length);var md=new Array(this.GetDigestSize());this.DoFinal(md,0);return md},GetWords:function(hexStr){var words=[];var hexStrLength=hexStr.length;for(var i=0;i<hexStrLength;i+=2){words[words.length]=parseInt(hexStr.substr(i,2),16)}return words},GetHex:function(arr){var words=[];var j=0;for(var i=0;i<arr.length*2;i+=2){words[i>>>3]|=parseInt(arr[j])<<(24-(i%8)*4);j++}var wordArray=new CryptoJS.lib.WordArray.init(words,arr.length);return wordArray}};Array.Clear=function(destinationArray,destinationIndex,length){for(elm in destinationArray){destinationArray[elm]=null}};Array.Copy=function(sourceArray,sourceIndex,destinationArray,destinationIndex,length){var cloneArray=sourceArray.slice(sourceIndex,sourceIndex+length);for(var i=0;i<cloneArray.length;i++){destinationArray[destinationIndex]=cloneArray[i];destinationIndex++}};window.Int32={minValue:-parseInt('10000000000000000000000000000000',2),maxValue:parseInt('1111111111111111111111111111111',2),parse:function(n){if(n<this.minValue){var bigInteger=new Number(-n);var bigIntegerRadix=bigInteger.toString(2);var subBigIntegerRadix=bigIntegerRadix.substr(bigIntegerRadix.length-31,31);var reBigIntegerRadix='';for(var i=0;i<subBigIntegerRadix.length;i++){var subBigIntegerRadixItem=subBigIntegerRadix.substr(i,1);reBigIntegerRadix+=subBigIntegerRadixItem=='0'?'1':'0'}var result=parseInt(reBigIntegerRadix,2);return(result+1)}else if(n>this.maxValue){var bigInteger=Number(n);var bigIntegerRadix=bigInteger.toString(2);var subBigIntegerRadix=bigIntegerRadix.substr(bigIntegerRadix.length-31,31);var reBigIntegerRadix='';for(var i=0;i<subBigIntegerRadix.length;i++){var subBigIntegerRadixItem=subBigIntegerRadix.substr(i,1);reBigIntegerRadix+=subBigIntegerRadixItem=='0'?'1':'0'}var result=parseInt(reBigIntegerRadix,2);return-(result+1)}else{return n}},parseByte:function(n){if(n<0){var bigInteger=new Number(-n);var bigIntegerRadix=bigInteger.toString(2);var subBigIntegerRadix=bigIntegerRadix.substr(bigIntegerRadix.length-8,8);var reBigIntegerRadix='';for(var i=0;i<subBigIntegerRadix.length;i++){var subBigIntegerRadixItem=subBigIntegerRadix.substr(i,1);reBigIntegerRadix+=subBigIntegerRadixItem=='0'?'1':'0'}var result=parseInt(reBigIntegerRadix,2);return(result+1)}else if(n>255){var bigInteger=Number(n);var bigIntegerRadix=bigInteger.toString(2);return parseInt(bigIntegerRadix.substr(bigIntegerRadix.length-8,8),2)}else{return n}}};"
  },
  {
    "path": "JavaScript/demo/js/sm4.js",
    "content": "/*! sm4-1.0.js (c) Windard Yang | https://www.windard.com/\r\n */\r\n/*\r\n * sm4-1.0.js\r\n * \r\n * Copyright (c) 2014 Windard Yang (www.windard.com)\r\n */\r\n/**\r\n * @fileOverview\r\n * @name sm4-1.0.js\r\n * @author Windard (www.windard.com)\r\n * @version 1.0.0 (2016-11-17)\r\n */\r\n\r\n/* this is sm4 in javascript by windard , today is 2016 11-17 , \r\n *I'm afraid that can I finished this project , but after all \r\n *in December, everything will be done , that's prefect\r\n */\r\n\r\n/*\r\n * garbage , rubbish programe language, should havn't big decimal number\r\n * can't circular bitwise left shift, can do xor well\r\n */\r\n\r\n/*\r\n * fuck it at all , finally finished it , and there has many other works need to do\r\n *\r\n */\r\n\r\n\r\nvar SboxTable = new Array();\r\nSboxTable[ 0] = new Array(0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05);\r\nSboxTable[ 1] = new Array(0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99);\r\nSboxTable[ 2] = new Array(0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62);\r\nSboxTable[ 3] = new Array(0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6);\r\nSboxTable[ 4] = new Array(0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8);\r\nSboxTable[ 5] = new Array(0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35);\r\nSboxTable[ 6] = new Array(0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87);\r\nSboxTable[ 7] = new Array(0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e);\r\nSboxTable[ 8] = new Array(0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1);\r\nSboxTable[ 9] = new Array(0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3);\r\nSboxTable[10] = new Array(0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f);\r\nSboxTable[11] = new Array(0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51);\r\nSboxTable[12] = new Array(0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8);\r\nSboxTable[13] = new Array(0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0);\r\nSboxTable[14] = new Array(0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84);\r\nSboxTable[15] = new Array(0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48);\r\n\r\nvar CK = new Array(\r\n0x00070e15,0x1c232a31,0x383f464d,0x545b6269,\r\n0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9,\r\n0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249,\r\n0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9,\r\n0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229,\r\n0x30373e45,0x4c535a61,0x686f767d,0x848b9299,\r\n0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209,\r\n0x10171e25,0x2c333a41,0x484f565d,0x646b7279\r\n);\r\n\r\nvar FK = new Array(0xa3b1bac6,0x56aa3350,0x677d9197,0xb27022dc);\r\n\r\n// function bigxor(a, b) {\r\n// \tif (a.toString(2).length < 33 && b.toString(2).length < 33){\t\t\r\n// \t\treturn a ^ b\r\n// \t}\r\n// \tvar abin = a.toString(2);\r\n// \tvar bbin = b.toString(2);\r\n// \tvar loggest = abin.length >= bbin.length ? abin.length : bbin.length;\r\n// \tabin = abin.length == loggest ? abin :\"0\".repeat(loggest - abin.length) + abin;\r\n// \tbbin = bbin.length == loggest ? bbin :\"0\".repeat(loggest - bbin.length) + bbin;\r\n// \tvar result = \"\";\r\n// \tfor (var i = loggest - 1; i >= 0; i--) {\r\n// \t\tresult = abin[i] == bbin[i] ? '0'+result : '1'+result; \r\n// \t};\r\n// \treturn parseInt(result, 2);\r\n// }\r\n\r\nfunction bigxor(a, b){\r\n\treturn a ^ b\r\n}\r\n\r\n// function leftshift(a, n, size=32) {\r\n// \tvar result = new Array(size);\r\n// \tresult.fill(0);\r\n// \tvar bin = a.toString(2);\r\n// \tbin = bin.length == size ? bin :\"0\".repeat(size - bin.length) + bin;\r\n// \tfor (var i = bin.length - 1; i >= 0; i--) {\r\n// \t\tresult[(i - n + size)%size] = bin[i];\r\n// \t};\r\n// \tresult = result.join(\"\");\r\n// \treturn parseInt(result, 2);\r\n// }\r\n\r\nfunction leftshift(a, n, size=32) {\r\n\tn = n % size\r\n\treturn (a << n) | (a >>> (size - n))\r\n}\r\n\r\nfunction prefixInteger(str, length) {\r\n  return Array(length+1).join(\"0\").split(\"\").concat(String(str).split(\"\"))\r\n           .slice(-length).join(\"\");\r\n}\r\n\r\n// function sm4Sbox(a) {\r\n// \tvar a1 = prefixInteger(a.toString(16),8).slice(0,2);\r\n// \tvar a2 = prefixInteger(a.toString(16),8).slice(2,4);\r\n// \tvar a3 = prefixInteger(a.toString(16),8).slice(4,6);\r\n// \tvar a4 = prefixInteger(a.toString(16),8).slice(6,8);\r\n// \tvar b1 = SboxTable[parseInt(a1[0], 16)][parseInt(a1[1], 16)];\r\n// \tvar b2 = SboxTable[parseInt(a2[0], 16)][parseInt(a2[1], 16)];\r\n// \tvar b3 = SboxTable[parseInt(a3[0], 16)][parseInt(a3[1], 16)];\r\n// \tvar b4 = SboxTable[parseInt(a4[0], 16)][parseInt(a4[1], 16)];\r\n// \treturn parseInt(prefixInteger(b1.toString(16), 2) + prefixInteger(b2.toString(16), 2) + prefixInteger(b3.toString(16), 2) + prefixInteger(b4.toString(16), 2) , 16)\r\n// }\r\n\r\nfunction sm4Sbox(a) {\r\n\tvar b1 = SboxTable[(a & 0xf0000000) >>> 28][(a & 0x0f000000) >>> 24]\r\n\tvar b2 = SboxTable[(a & 0x00f00000) >>> 20][(a & 0x000f0000) >>> 16]\r\n\tvar b3 = SboxTable[(a & 0x0000f000) >>> 12][(a & 0x00000f00) >>>  8]\r\n\tvar b4 = SboxTable[(a & 0x000000f0) >>>  4][(a & 0x0000000f) >>>  0]\r\n\treturn (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4 << 0)\r\n}\r\n\r\nfunction GET_ULONG_BE (a) {\r\n\ta = sm4Sbox(a)\r\n\treturn bigxor(bigxor(bigxor(a, leftshift(a, 2)), bigxor(leftshift(a, 10), leftshift(a, 18))), leftshift(a, 24))\r\n}\r\n\r\nfunction PUT_ULONG_BE(b) {\r\n\tb = sm4Sbox(b)\r\n\treturn bigxor(b, bigxor(leftshift(b, 13), leftshift(b, 23)));\r\n}\r\n\r\nfunction sm4_getkey (MK) {\r\n\tvar  K = new Array();\r\n\tvar rk = new Array();\r\n\tK[0] = bigxor(MK[0], FK[0]);\r\n\tK[1] = bigxor(MK[1], FK[1]);\r\n\tK[2] = bigxor(MK[2], FK[2]);\r\n\tK[3] = bigxor(MK[3], FK[3]);\r\n\r\n\tfor (var i = 0; i < 32; i++) {\r\n\t\tK[i+4] = bigxor(K[i], PUT_ULONG_BE(bigxor(bigxor(K[i+1], K[i+2]), bigxor(K[i+3], CK[i]))));\r\n\t\trk[i] = K[i+4].toString(16);\r\n\t};\r\n\treturn rk;\r\n}\r\n\r\nfunction KJUR_encrypt_sm4 (messsage, key, method) {\r\n\tvar MK = key;\r\n\tvar X = messsage;\r\n\tvar rk = sm4_getkey(MK);\r\n\tfor (var i = 0; i < 32; i++) {\r\n\t\tX[i+4] = bigxor(X[i], GET_ULONG_BE(bigxor(bigxor(X[i+1], X[i+2]), bigxor(X[i+3], parseInt(rk[i], 16)))))\r\n\t};\r\n\tvar Y = new Array(X[35], X[34], X[33], X[32])\r\n\treturn Y;\r\n}\r\n\r\nfunction KJUR_decrypt_sm4 (ciphertext, key, method) {\r\n\tvar MK = key;\r\n\tvar X = ciphertext;\r\n\tvar frk = sm4_getkey(MK);\r\n\tvar rk = new Array()\r\n\tfor (var i = frk.length - 1; i >= 0; i--) {\r\n\t\trk[frk.length - 1 - i] = frk[i]\r\n\t};\r\n\tfor (var i = 0; i < 32; i++) {\r\n\t\tX[i+4] = bigxor(X[i], GET_ULONG_BE(bigxor(bigxor(X[i+1], X[i+2]), bigxor(X[i+3], parseInt(rk[i], 16)))))\r\n\t};\r\n\tvar Y = new Array(X[35], X[34], X[33], X[32])\r\n\treturn Y;\r\n}\r\n\r\n\r\n"
  },
  {
    "path": "JavaScript/demo/js/tripledes.js",
    "content": "/*\nCryptoJS v3.1.2\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function () {\r\n    // Shortcuts\r\n    var C = CryptoJS;\r\n    var C_lib = C.lib;\r\n    var WordArray = C_lib.WordArray;\r\n    var BlockCipher = C_lib.BlockCipher;\r\n    var C_algo = C.algo;\r\n\r\n    // Permuted Choice 1 constants\r\n    var PC1 = [\r\n        57, 49, 41, 33, 25, 17, 9,  1,\r\n        58, 50, 42, 34, 26, 18, 10, 2,\r\n        59, 51, 43, 35, 27, 19, 11, 3,\r\n        60, 52, 44, 36, 63, 55, 47, 39,\r\n        31, 23, 15, 7,  62, 54, 46, 38,\r\n        30, 22, 14, 6,  61, 53, 45, 37,\r\n        29, 21, 13, 5,  28, 20, 12, 4\r\n    ];\r\n\r\n    // Permuted Choice 2 constants\r\n    var PC2 = [\r\n        14, 17, 11, 24, 1,  5,\r\n        3,  28, 15, 6,  21, 10,\r\n        23, 19, 12, 4,  26, 8,\r\n        16, 7,  27, 20, 13, 2,\r\n        41, 52, 31, 37, 47, 55,\r\n        30, 40, 51, 45, 33, 48,\r\n        44, 49, 39, 56, 34, 53,\r\n        46, 42, 50, 36, 29, 32\r\n    ];\r\n\r\n    // Cumulative bit shift constants\r\n    var BIT_SHIFTS = [1,  2,  4,  6,  8,  10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28];\r\n\r\n    // SBOXes and round permutation constants\r\n    var SBOX_P = [\r\n        {\r\n            0x0: 0x808200,\r\n            0x10000000: 0x8000,\r\n            0x20000000: 0x808002,\r\n            0x30000000: 0x2,\r\n            0x40000000: 0x200,\r\n            0x50000000: 0x808202,\r\n            0x60000000: 0x800202,\r\n            0x70000000: 0x800000,\r\n            0x80000000: 0x202,\r\n            0x90000000: 0x800200,\r\n            0xa0000000: 0x8200,\r\n            0xb0000000: 0x808000,\r\n            0xc0000000: 0x8002,\r\n            0xd0000000: 0x800002,\r\n            0xe0000000: 0x0,\r\n            0xf0000000: 0x8202,\r\n            0x8000000: 0x0,\r\n            0x18000000: 0x808202,\r\n            0x28000000: 0x8202,\r\n            0x38000000: 0x8000,\r\n            0x48000000: 0x808200,\r\n            0x58000000: 0x200,\r\n            0x68000000: 0x808002,\r\n            0x78000000: 0x2,\r\n            0x88000000: 0x800200,\r\n            0x98000000: 0x8200,\r\n            0xa8000000: 0x808000,\r\n            0xb8000000: 0x800202,\r\n            0xc8000000: 0x800002,\r\n            0xd8000000: 0x8002,\r\n            0xe8000000: 0x202,\r\n            0xf8000000: 0x800000,\r\n            0x1: 0x8000,\r\n            0x10000001: 0x2,\r\n            0x20000001: 0x808200,\r\n            0x30000001: 0x800000,\r\n            0x40000001: 0x808002,\r\n            0x50000001: 0x8200,\r\n            0x60000001: 0x200,\r\n            0x70000001: 0x800202,\r\n            0x80000001: 0x808202,\r\n            0x90000001: 0x808000,\r\n            0xa0000001: 0x800002,\r\n            0xb0000001: 0x8202,\r\n            0xc0000001: 0x202,\r\n            0xd0000001: 0x800200,\r\n            0xe0000001: 0x8002,\r\n            0xf0000001: 0x0,\r\n            0x8000001: 0x808202,\r\n            0x18000001: 0x808000,\r\n            0x28000001: 0x800000,\r\n            0x38000001: 0x200,\r\n            0x48000001: 0x8000,\r\n            0x58000001: 0x800002,\r\n            0x68000001: 0x2,\r\n            0x78000001: 0x8202,\r\n            0x88000001: 0x8002,\r\n            0x98000001: 0x800202,\r\n            0xa8000001: 0x202,\r\n            0xb8000001: 0x808200,\r\n            0xc8000001: 0x800200,\r\n            0xd8000001: 0x0,\r\n            0xe8000001: 0x8200,\r\n            0xf8000001: 0x808002\r\n        },\r\n        {\r\n            0x0: 0x40084010,\r\n            0x1000000: 0x4000,\r\n            0x2000000: 0x80000,\r\n            0x3000000: 0x40080010,\r\n            0x4000000: 0x40000010,\r\n            0x5000000: 0x40084000,\r\n            0x6000000: 0x40004000,\r\n            0x7000000: 0x10,\r\n            0x8000000: 0x84000,\r\n            0x9000000: 0x40004010,\r\n            0xa000000: 0x40000000,\r\n            0xb000000: 0x84010,\r\n            0xc000000: 0x80010,\r\n            0xd000000: 0x0,\r\n            0xe000000: 0x4010,\r\n            0xf000000: 0x40080000,\r\n            0x800000: 0x40004000,\r\n            0x1800000: 0x84010,\r\n            0x2800000: 0x10,\r\n            0x3800000: 0x40004010,\r\n            0x4800000: 0x40084010,\r\n            0x5800000: 0x40000000,\r\n            0x6800000: 0x80000,\r\n            0x7800000: 0x40080010,\r\n            0x8800000: 0x80010,\r\n            0x9800000: 0x0,\r\n            0xa800000: 0x4000,\r\n            0xb800000: 0x40080000,\r\n            0xc800000: 0x40000010,\r\n            0xd800000: 0x84000,\r\n            0xe800000: 0x40084000,\r\n            0xf800000: 0x4010,\r\n            0x10000000: 0x0,\r\n            0x11000000: 0x40080010,\r\n            0x12000000: 0x40004010,\r\n            0x13000000: 0x40084000,\r\n            0x14000000: 0x40080000,\r\n            0x15000000: 0x10,\r\n            0x16000000: 0x84010,\r\n            0x17000000: 0x4000,\r\n            0x18000000: 0x4010,\r\n            0x19000000: 0x80000,\r\n            0x1a000000: 0x80010,\r\n            0x1b000000: 0x40000010,\r\n            0x1c000000: 0x84000,\r\n            0x1d000000: 0x40004000,\r\n            0x1e000000: 0x40000000,\r\n            0x1f000000: 0x40084010,\r\n            0x10800000: 0x84010,\r\n            0x11800000: 0x80000,\r\n            0x12800000: 0x40080000,\r\n            0x13800000: 0x4000,\r\n            0x14800000: 0x40004000,\r\n            0x15800000: 0x40084010,\r\n            0x16800000: 0x10,\r\n            0x17800000: 0x40000000,\r\n            0x18800000: 0x40084000,\r\n            0x19800000: 0x40000010,\r\n            0x1a800000: 0x40004010,\r\n            0x1b800000: 0x80010,\r\n            0x1c800000: 0x0,\r\n            0x1d800000: 0x4010,\r\n            0x1e800000: 0x40080010,\r\n            0x1f800000: 0x84000\r\n        },\r\n        {\r\n            0x0: 0x104,\r\n            0x100000: 0x0,\r\n            0x200000: 0x4000100,\r\n            0x300000: 0x10104,\r\n            0x400000: 0x10004,\r\n            0x500000: 0x4000004,\r\n            0x600000: 0x4010104,\r\n            0x700000: 0x4010000,\r\n            0x800000: 0x4000000,\r\n            0x900000: 0x4010100,\r\n            0xa00000: 0x10100,\r\n            0xb00000: 0x4010004,\r\n            0xc00000: 0x4000104,\r\n            0xd00000: 0x10000,\r\n            0xe00000: 0x4,\r\n            0xf00000: 0x100,\r\n            0x80000: 0x4010100,\r\n            0x180000: 0x4010004,\r\n            0x280000: 0x0,\r\n            0x380000: 0x4000100,\r\n            0x480000: 0x4000004,\r\n            0x580000: 0x10000,\r\n            0x680000: 0x10004,\r\n            0x780000: 0x104,\r\n            0x880000: 0x4,\r\n            0x980000: 0x100,\r\n            0xa80000: 0x4010000,\r\n            0xb80000: 0x10104,\r\n            0xc80000: 0x10100,\r\n            0xd80000: 0x4000104,\r\n            0xe80000: 0x4010104,\r\n            0xf80000: 0x4000000,\r\n            0x1000000: 0x4010100,\r\n            0x1100000: 0x10004,\r\n            0x1200000: 0x10000,\r\n            0x1300000: 0x4000100,\r\n            0x1400000: 0x100,\r\n            0x1500000: 0x4010104,\r\n            0x1600000: 0x4000004,\r\n            0x1700000: 0x0,\r\n            0x1800000: 0x4000104,\r\n            0x1900000: 0x4000000,\r\n            0x1a00000: 0x4,\r\n            0x1b00000: 0x10100,\r\n            0x1c00000: 0x4010000,\r\n            0x1d00000: 0x104,\r\n            0x1e00000: 0x10104,\r\n            0x1f00000: 0x4010004,\r\n            0x1080000: 0x4000000,\r\n            0x1180000: 0x104,\r\n            0x1280000: 0x4010100,\r\n            0x1380000: 0x0,\r\n            0x1480000: 0x10004,\r\n            0x1580000: 0x4000100,\r\n            0x1680000: 0x100,\r\n            0x1780000: 0x4010004,\r\n            0x1880000: 0x10000,\r\n            0x1980000: 0x4010104,\r\n            0x1a80000: 0x10104,\r\n            0x1b80000: 0x4000004,\r\n            0x1c80000: 0x4000104,\r\n            0x1d80000: 0x4010000,\r\n            0x1e80000: 0x4,\r\n            0x1f80000: 0x10100\r\n        },\r\n        {\r\n            0x0: 0x80401000,\r\n            0x10000: 0x80001040,\r\n            0x20000: 0x401040,\r\n            0x30000: 0x80400000,\r\n            0x40000: 0x0,\r\n            0x50000: 0x401000,\r\n            0x60000: 0x80000040,\r\n            0x70000: 0x400040,\r\n            0x80000: 0x80000000,\r\n            0x90000: 0x400000,\r\n            0xa0000: 0x40,\r\n            0xb0000: 0x80001000,\r\n            0xc0000: 0x80400040,\r\n            0xd0000: 0x1040,\r\n            0xe0000: 0x1000,\r\n            0xf0000: 0x80401040,\r\n            0x8000: 0x80001040,\r\n            0x18000: 0x40,\r\n            0x28000: 0x80400040,\r\n            0x38000: 0x80001000,\r\n            0x48000: 0x401000,\r\n            0x58000: 0x80401040,\r\n            0x68000: 0x0,\r\n            0x78000: 0x80400000,\r\n            0x88000: 0x1000,\r\n            0x98000: 0x80401000,\r\n            0xa8000: 0x400000,\r\n            0xb8000: 0x1040,\r\n            0xc8000: 0x80000000,\r\n            0xd8000: 0x400040,\r\n            0xe8000: 0x401040,\r\n            0xf8000: 0x80000040,\r\n            0x100000: 0x400040,\r\n            0x110000: 0x401000,\r\n            0x120000: 0x80000040,\r\n            0x130000: 0x0,\r\n            0x140000: 0x1040,\r\n            0x150000: 0x80400040,\r\n            0x160000: 0x80401000,\r\n            0x170000: 0x80001040,\r\n            0x180000: 0x80401040,\r\n            0x190000: 0x80000000,\r\n            0x1a0000: 0x80400000,\r\n            0x1b0000: 0x401040,\r\n            0x1c0000: 0x80001000,\r\n            0x1d0000: 0x400000,\r\n            0x1e0000: 0x40,\r\n            0x1f0000: 0x1000,\r\n            0x108000: 0x80400000,\r\n            0x118000: 0x80401040,\r\n            0x128000: 0x0,\r\n            0x138000: 0x401000,\r\n            0x148000: 0x400040,\r\n            0x158000: 0x80000000,\r\n            0x168000: 0x80001040,\r\n            0x178000: 0x40,\r\n            0x188000: 0x80000040,\r\n            0x198000: 0x1000,\r\n            0x1a8000: 0x80001000,\r\n            0x1b8000: 0x80400040,\r\n            0x1c8000: 0x1040,\r\n            0x1d8000: 0x80401000,\r\n            0x1e8000: 0x400000,\r\n            0x1f8000: 0x401040\r\n        },\r\n        {\r\n            0x0: 0x80,\r\n            0x1000: 0x1040000,\r\n            0x2000: 0x40000,\r\n            0x3000: 0x20000000,\r\n            0x4000: 0x20040080,\r\n            0x5000: 0x1000080,\r\n            0x6000: 0x21000080,\r\n            0x7000: 0x40080,\r\n            0x8000: 0x1000000,\r\n            0x9000: 0x20040000,\r\n            0xa000: 0x20000080,\r\n            0xb000: 0x21040080,\r\n            0xc000: 0x21040000,\r\n            0xd000: 0x0,\r\n            0xe000: 0x1040080,\r\n            0xf000: 0x21000000,\r\n            0x800: 0x1040080,\r\n            0x1800: 0x21000080,\r\n            0x2800: 0x80,\r\n            0x3800: 0x1040000,\r\n            0x4800: 0x40000,\r\n            0x5800: 0x20040080,\r\n            0x6800: 0x21040000,\r\n            0x7800: 0x20000000,\r\n            0x8800: 0x20040000,\r\n            0x9800: 0x0,\r\n            0xa800: 0x21040080,\r\n            0xb800: 0x1000080,\r\n            0xc800: 0x20000080,\r\n            0xd800: 0x21000000,\r\n            0xe800: 0x1000000,\r\n            0xf800: 0x40080,\r\n            0x10000: 0x40000,\r\n            0x11000: 0x80,\r\n            0x12000: 0x20000000,\r\n            0x13000: 0x21000080,\r\n            0x14000: 0x1000080,\r\n            0x15000: 0x21040000,\r\n            0x16000: 0x20040080,\r\n            0x17000: 0x1000000,\r\n            0x18000: 0x21040080,\r\n            0x19000: 0x21000000,\r\n            0x1a000: 0x1040000,\r\n            0x1b000: 0x20040000,\r\n            0x1c000: 0x40080,\r\n            0x1d000: 0x20000080,\r\n            0x1e000: 0x0,\r\n            0x1f000: 0x1040080,\r\n            0x10800: 0x21000080,\r\n            0x11800: 0x1000000,\r\n            0x12800: 0x1040000,\r\n            0x13800: 0x20040080,\r\n            0x14800: 0x20000000,\r\n            0x15800: 0x1040080,\r\n            0x16800: 0x80,\r\n            0x17800: 0x21040000,\r\n            0x18800: 0x40080,\r\n            0x19800: 0x21040080,\r\n            0x1a800: 0x0,\r\n            0x1b800: 0x21000000,\r\n            0x1c800: 0x1000080,\r\n            0x1d800: 0x40000,\r\n            0x1e800: 0x20040000,\r\n            0x1f800: 0x20000080\r\n        },\r\n        {\r\n            0x0: 0x10000008,\r\n            0x100: 0x2000,\r\n            0x200: 0x10200000,\r\n            0x300: 0x10202008,\r\n            0x400: 0x10002000,\r\n            0x500: 0x200000,\r\n            0x600: 0x200008,\r\n            0x700: 0x10000000,\r\n            0x800: 0x0,\r\n            0x900: 0x10002008,\r\n            0xa00: 0x202000,\r\n            0xb00: 0x8,\r\n            0xc00: 0x10200008,\r\n            0xd00: 0x202008,\r\n            0xe00: 0x2008,\r\n            0xf00: 0x10202000,\r\n            0x80: 0x10200000,\r\n            0x180: 0x10202008,\r\n            0x280: 0x8,\r\n            0x380: 0x200000,\r\n            0x480: 0x202008,\r\n            0x580: 0x10000008,\r\n            0x680: 0x10002000,\r\n            0x780: 0x2008,\r\n            0x880: 0x200008,\r\n            0x980: 0x2000,\r\n            0xa80: 0x10002008,\r\n            0xb80: 0x10200008,\r\n            0xc80: 0x0,\r\n            0xd80: 0x10202000,\r\n            0xe80: 0x202000,\r\n            0xf80: 0x10000000,\r\n            0x1000: 0x10002000,\r\n            0x1100: 0x10200008,\r\n            0x1200: 0x10202008,\r\n            0x1300: 0x2008,\r\n            0x1400: 0x200000,\r\n            0x1500: 0x10000000,\r\n            0x1600: 0x10000008,\r\n            0x1700: 0x202000,\r\n            0x1800: 0x202008,\r\n            0x1900: 0x0,\r\n            0x1a00: 0x8,\r\n            0x1b00: 0x10200000,\r\n            0x1c00: 0x2000,\r\n            0x1d00: 0x10002008,\r\n            0x1e00: 0x10202000,\r\n            0x1f00: 0x200008,\r\n            0x1080: 0x8,\r\n            0x1180: 0x202000,\r\n            0x1280: 0x200000,\r\n            0x1380: 0x10000008,\r\n            0x1480: 0x10002000,\r\n            0x1580: 0x2008,\r\n            0x1680: 0x10202008,\r\n            0x1780: 0x10200000,\r\n            0x1880: 0x10202000,\r\n            0x1980: 0x10200008,\r\n            0x1a80: 0x2000,\r\n            0x1b80: 0x202008,\r\n            0x1c80: 0x200008,\r\n            0x1d80: 0x0,\r\n            0x1e80: 0x10000000,\r\n            0x1f80: 0x10002008\r\n        },\r\n        {\r\n            0x0: 0x100000,\r\n            0x10: 0x2000401,\r\n            0x20: 0x400,\r\n            0x30: 0x100401,\r\n            0x40: 0x2100401,\r\n            0x50: 0x0,\r\n            0x60: 0x1,\r\n            0x70: 0x2100001,\r\n            0x80: 0x2000400,\r\n            0x90: 0x100001,\r\n            0xa0: 0x2000001,\r\n            0xb0: 0x2100400,\r\n            0xc0: 0x2100000,\r\n            0xd0: 0x401,\r\n            0xe0: 0x100400,\r\n            0xf0: 0x2000000,\r\n            0x8: 0x2100001,\r\n            0x18: 0x0,\r\n            0x28: 0x2000401,\r\n            0x38: 0x2100400,\r\n            0x48: 0x100000,\r\n            0x58: 0x2000001,\r\n            0x68: 0x2000000,\r\n            0x78: 0x401,\r\n            0x88: 0x100401,\r\n            0x98: 0x2000400,\r\n            0xa8: 0x2100000,\r\n            0xb8: 0x100001,\r\n            0xc8: 0x400,\r\n            0xd8: 0x2100401,\r\n            0xe8: 0x1,\r\n            0xf8: 0x100400,\r\n            0x100: 0x2000000,\r\n            0x110: 0x100000,\r\n            0x120: 0x2000401,\r\n            0x130: 0x2100001,\r\n            0x140: 0x100001,\r\n            0x150: 0x2000400,\r\n            0x160: 0x2100400,\r\n            0x170: 0x100401,\r\n            0x180: 0x401,\r\n            0x190: 0x2100401,\r\n            0x1a0: 0x100400,\r\n            0x1b0: 0x1,\r\n            0x1c0: 0x0,\r\n            0x1d0: 0x2100000,\r\n            0x1e0: 0x2000001,\r\n            0x1f0: 0x400,\r\n            0x108: 0x100400,\r\n            0x118: 0x2000401,\r\n            0x128: 0x2100001,\r\n            0x138: 0x1,\r\n            0x148: 0x2000000,\r\n            0x158: 0x100000,\r\n            0x168: 0x401,\r\n            0x178: 0x2100400,\r\n            0x188: 0x2000001,\r\n            0x198: 0x2100000,\r\n            0x1a8: 0x0,\r\n            0x1b8: 0x2100401,\r\n            0x1c8: 0x100401,\r\n            0x1d8: 0x400,\r\n            0x1e8: 0x2000400,\r\n            0x1f8: 0x100001\r\n        },\r\n        {\r\n            0x0: 0x8000820,\r\n            0x1: 0x20000,\r\n            0x2: 0x8000000,\r\n            0x3: 0x20,\r\n            0x4: 0x20020,\r\n            0x5: 0x8020820,\r\n            0x6: 0x8020800,\r\n            0x7: 0x800,\r\n            0x8: 0x8020000,\r\n            0x9: 0x8000800,\r\n            0xa: 0x20800,\r\n            0xb: 0x8020020,\r\n            0xc: 0x820,\r\n            0xd: 0x0,\r\n            0xe: 0x8000020,\r\n            0xf: 0x20820,\r\n            0x80000000: 0x800,\r\n            0x80000001: 0x8020820,\r\n            0x80000002: 0x8000820,\r\n            0x80000003: 0x8000000,\r\n            0x80000004: 0x8020000,\r\n            0x80000005: 0x20800,\r\n            0x80000006: 0x20820,\r\n            0x80000007: 0x20,\r\n            0x80000008: 0x8000020,\r\n            0x80000009: 0x820,\r\n            0x8000000a: 0x20020,\r\n            0x8000000b: 0x8020800,\r\n            0x8000000c: 0x0,\r\n            0x8000000d: 0x8020020,\r\n            0x8000000e: 0x8000800,\r\n            0x8000000f: 0x20000,\r\n            0x10: 0x20820,\r\n            0x11: 0x8020800,\r\n            0x12: 0x20,\r\n            0x13: 0x800,\r\n            0x14: 0x8000800,\r\n            0x15: 0x8000020,\r\n            0x16: 0x8020020,\r\n            0x17: 0x20000,\r\n            0x18: 0x0,\r\n            0x19: 0x20020,\r\n            0x1a: 0x8020000,\r\n            0x1b: 0x8000820,\r\n            0x1c: 0x8020820,\r\n            0x1d: 0x20800,\r\n            0x1e: 0x820,\r\n            0x1f: 0x8000000,\r\n            0x80000010: 0x20000,\r\n            0x80000011: 0x800,\r\n            0x80000012: 0x8020020,\r\n            0x80000013: 0x20820,\r\n            0x80000014: 0x20,\r\n            0x80000015: 0x8020000,\r\n            0x80000016: 0x8000000,\r\n            0x80000017: 0x8000820,\r\n            0x80000018: 0x8020820,\r\n            0x80000019: 0x8000020,\r\n            0x8000001a: 0x8000800,\r\n            0x8000001b: 0x0,\r\n            0x8000001c: 0x20800,\r\n            0x8000001d: 0x820,\r\n            0x8000001e: 0x20020,\r\n            0x8000001f: 0x8020800\r\n        }\r\n    ];\r\n\r\n    // Masks that select the SBOX input\r\n    var SBOX_MASK = [\r\n        0xf8000001, 0x1f800000, 0x01f80000, 0x001f8000,\r\n        0x0001f800, 0x00001f80, 0x000001f8, 0x8000001f\r\n    ];\r\n\r\n    /**\r\n     * DES block cipher algorithm.\r\n     */\r\n    var DES = C_algo.DES = BlockCipher.extend({\r\n        _doReset: function () {\r\n            // Shortcuts\r\n            var key = this._key;\r\n            var keyWords = key.words;\r\n\r\n            // Select 56 bits according to PC1\r\n            var keyBits = [];\r\n            for (var i = 0; i < 56; i++) {\r\n                var keyBitPos = PC1[i] - 1;\r\n                keyBits[i] = (keyWords[keyBitPos >>> 5] >>> (31 - keyBitPos % 32)) & 1;\r\n            }\r\n\r\n            // Assemble 16 subkeys\r\n            var subKeys = this._subKeys = [];\r\n            for (var nSubKey = 0; nSubKey < 16; nSubKey++) {\r\n                // Create subkey\r\n                var subKey = subKeys[nSubKey] = [];\r\n\r\n                // Shortcut\r\n                var bitShift = BIT_SHIFTS[nSubKey];\r\n\r\n                // Select 48 bits according to PC2\r\n                for (var i = 0; i < 24; i++) {\r\n                    // Select from the left 28 key bits\r\n                    subKey[(i / 6) | 0] |= keyBits[((PC2[i] - 1) + bitShift) % 28] << (31 - i % 6);\r\n\r\n                    // Select from the right 28 key bits\r\n                    subKey[4 + ((i / 6) | 0)] |= keyBits[28 + (((PC2[i + 24] - 1) + bitShift) % 28)] << (31 - i % 6);\r\n                }\r\n\r\n                // Since each subkey is applied to an expanded 32-bit input,\r\n                // the subkey can be broken into 8 values scaled to 32-bits,\r\n                // which allows the key to be used without expansion\r\n                subKey[0] = (subKey[0] << 1) | (subKey[0] >>> 31);\r\n                for (var i = 1; i < 7; i++) {\r\n                    subKey[i] = subKey[i] >>> ((i - 1) * 4 + 3);\r\n                }\r\n                subKey[7] = (subKey[7] << 5) | (subKey[7] >>> 27);\r\n            }\r\n\r\n            // Compute inverse subkeys\r\n            var invSubKeys = this._invSubKeys = [];\r\n            for (var i = 0; i < 16; i++) {\r\n                invSubKeys[i] = subKeys[15 - i];\r\n            }\r\n        },\r\n\r\n        encryptBlock: function (M, offset) {\r\n            this._doCryptBlock(M, offset, this._subKeys);\r\n        },\r\n\r\n        decryptBlock: function (M, offset) {\r\n            this._doCryptBlock(M, offset, this._invSubKeys);\r\n        },\r\n\r\n        _doCryptBlock: function (M, offset, subKeys) {\r\n            // Get input\r\n            this._lBlock = M[offset];\r\n            this._rBlock = M[offset + 1];\r\n\r\n            // Initial permutation\r\n            exchangeLR.call(this, 4,  0x0f0f0f0f);\r\n            exchangeLR.call(this, 16, 0x0000ffff);\r\n            exchangeRL.call(this, 2,  0x33333333);\r\n            exchangeRL.call(this, 8,  0x00ff00ff);\r\n            exchangeLR.call(this, 1,  0x55555555);\r\n\r\n            // Rounds\r\n            for (var round = 0; round < 16; round++) {\r\n                // Shortcuts\r\n                var subKey = subKeys[round];\r\n                var lBlock = this._lBlock;\r\n                var rBlock = this._rBlock;\r\n\r\n                // Feistel function\r\n                var f = 0;\r\n                for (var i = 0; i < 8; i++) {\r\n                    f |= SBOX_P[i][((rBlock ^ subKey[i]) & SBOX_MASK[i]) >>> 0];\r\n                }\r\n                this._lBlock = rBlock;\r\n                this._rBlock = lBlock ^ f;\r\n            }\r\n\r\n            // Undo swap from last round\r\n            var t = this._lBlock;\r\n            this._lBlock = this._rBlock;\r\n            this._rBlock = t;\r\n\r\n            // Final permutation\r\n            exchangeLR.call(this, 1,  0x55555555);\r\n            exchangeRL.call(this, 8,  0x00ff00ff);\r\n            exchangeRL.call(this, 2,  0x33333333);\r\n            exchangeLR.call(this, 16, 0x0000ffff);\r\n            exchangeLR.call(this, 4,  0x0f0f0f0f);\r\n\r\n            // Set output\r\n            M[offset] = this._lBlock;\r\n            M[offset + 1] = this._rBlock;\r\n        },\r\n\r\n        keySize: 64/32,\r\n\r\n        ivSize: 64/32,\r\n\r\n        blockSize: 64/32\r\n    });\r\n\r\n    // Swap bits across the left and right words\r\n    function exchangeLR(offset, mask) {\r\n        var t = ((this._lBlock >>> offset) ^ this._rBlock) & mask;\r\n        this._rBlock ^= t;\r\n        this._lBlock ^= t << offset;\r\n    }\r\n\r\n    function exchangeRL(offset, mask) {\r\n        var t = ((this._rBlock >>> offset) ^ this._lBlock) & mask;\r\n        this._lBlock ^= t;\r\n        this._rBlock ^= t << offset;\r\n    }\r\n\r\n    /**\r\n     * Shortcut functions to the cipher's object interface.\r\n     *\r\n     * @example\r\n     *\r\n     *     var ciphertext = CryptoJS.DES.encrypt(message, key, cfg);\r\n     *     var plaintext  = CryptoJS.DES.decrypt(ciphertext, key, cfg);\r\n     */\r\n    C.DES = BlockCipher._createHelper(DES);\r\n\r\n    /**\r\n     * Triple-DES block cipher algorithm.\r\n     */\r\n    var TripleDES = C_algo.TripleDES = BlockCipher.extend({\r\n        _doReset: function () {\r\n            // Shortcuts\r\n            var key = this._key;\r\n            var keyWords = key.words;\r\n\r\n            // Create DES instances\r\n            this._des1 = DES.createEncryptor(WordArray.create(keyWords.slice(0, 2)));\r\n            this._des2 = DES.createEncryptor(WordArray.create(keyWords.slice(2, 4)));\r\n            this._des3 = DES.createEncryptor(WordArray.create(keyWords.slice(4, 6)));\r\n        },\r\n\r\n        encryptBlock: function (M, offset) {\r\n            this._des1.encryptBlock(M, offset);\r\n            this._des2.decryptBlock(M, offset);\r\n            this._des3.encryptBlock(M, offset);\r\n        },\r\n\r\n        decryptBlock: function (M, offset) {\r\n            this._des3.decryptBlock(M, offset);\r\n            this._des2.encryptBlock(M, offset);\r\n            this._des1.decryptBlock(M, offset);\r\n        },\r\n\r\n        keySize: 192/32,\r\n\r\n        ivSize: 64/32,\r\n\r\n        blockSize: 64/32\r\n    });\r\n\r\n    /**\r\n     * Shortcut functions to the cipher's object interface.\r\n     *\r\n     * @example\r\n     *\r\n     *     var ciphertext = CryptoJS.TripleDES.encrypt(message, key, cfg);\r\n     *     var plaintext  = CryptoJS.TripleDES.decrypt(ciphertext, key, cfg);\r\n     */\r\n    C.TripleDES = BlockCipher._createHelper(TripleDES);\r\n}());\r\n"
  },
  {
    "path": "JavaScript/demo/js/utils.js",
    "content": "/*! utils-1.0.js (c) Windard Yang | https://www.windard.com/\n */\n/*\n * utils-1.0.js\n * \n * Copyright (c) 2014 Windard Yang (www.windard.com)\n */\n/**\n * @fileOverview\n * @name utils-1.0.js\n * @author Windard (www.windard.com)\n * @version 1.0.0 (2017-11-15)\n */\n\nfunction encode(s) {\n    return s.replace(/[\\d\\D]/g, function($) {\n        return (\"000\" + $.charCodeAt(0).toString(16)).slice(-4);\n    });\n}\n\nfunction decode(s) {\n    return s.replace(/.{4}/g, function($) {\n        return String.fromCharCode(parseInt($, 16));\n    });\n}\n\nfunction PKCS7_padding_encode(data){\n    var result = new Array();\n    for (var i = 0; i < data.length; i++) {\n        result.push(data.charCodeAt(i))\n    };\n    var size = 4-result.length%4\n    for (i = 0; i < size; i++) {\n        result.push(size)\n    };\n    return result;\n}\n\nfunction PKCS7_padding_decode(data){\n    var result=\"\";\n    var size = data[data.length-1];\n    for (var i = 0; i < size ; i++) {\n        data.pop();\n    };\n    for(i = 0;i < data.length; i++) {\n        result += String.fromCharCode(data[i]);\n    };\n    return result;\n}\n\nfunction randomkey(key) {\n    var result = \"\";\n    for(var i = 0;i < key.length/2 ;i+=8 ) {\n        tempnum = bigxor(parseInt(key.slice(i,i+8), 16), Math.round(Math.random()*1000000000)).toString(16)\n        console.log(tempnum,tempnum.length)\n        result += tempnum.length == 8 ? tempnum : \"0\".repeat(8 - tempnum.length) + tempnum \n    }\n    return result;\n}\n\nfunction xorkey(key) {\n    var result = new Array();\n    for(var i = 0;i < key.length ;i+=8 ) {\n        result.push(parseInt(key.slice(i,i+8), 16))\n    }\n    return result;\n}\n\nfunction sm4_encode_cbc(data, key) {\n    var iv = new Array(0x01234567,0x89abcdef,0xfedcba98,0x76543210);\n    var message = new Array();\n    var result = new Array();\n    key = xorkey(key);\n    data = PKCS7_padding_encode(data);\n    for (var x = 0 ; x < data.length/4 ; x++) {\n        for (var i = 0 ; i < iv.length ; i++) {\n            message.push(bigxor(iv[i], data[i+x*4]));\n        };\n        ciphertext = KJUR_encrypt_sm4(message, key, \"cbc\")\n        iv = ciphertext\n        result = result.concat(ciphertext);\n        message = new Array();\n    }\n    return result;\n}\n\nfunction bigxor(a, b) {\n    var abin = a.toString(2);\n    var bbin = b.toString(2);\n    var loggest = abin.length >= bbin.length ? abin.length : bbin.length;\n    abin = abin.length == loggest ? abin :\"0\".repeat(loggest - abin.length) + abin;\n    bbin = bbin.length == loggest ? bbin :\"0\".repeat(loggest - bbin.length) + bbin;\n    var result = \"\";\n    for (var i = loggest - 1; i >= 0; i--) {\n        result = abin[i] == bbin[i] ? '0'+result : '1'+result; \n    };\n    return parseInt(result, 2);\n}\n\nfunction sm4_decode_cbc(data, key) {\n    var iv = new Array(0x01234567,0x89abcdef,0xfedcba98,0x76543210);\n    var message = new Array();\n    var result = new Array();\n    key = xorkey(key);\n    for(var x=data.length/4-1;x>=0;x--){\n        if(x==0){\n            iv = new Array(0x01234567,0x89abcdef,0xfedcba98,0x76543210);\n        }else{\n            iv = data.slice((x-1)*4,x*4)\n        }\n        message = KJUR_decrypt_sm4(data.slice(x*4,(x+1)*4), key);\n        for(var j=message.length-1;j>=0;j--){\n            result.push(bigxor(message[j], iv[j]))\n        }\n    }\n    result.reverse();\n    result = PKCS7_padding_decode(result);\n    return result;\n}\n"
  },
  {
    "path": "JavaScript/demo/js/x509-1.1.js",
    "content": "/*! x509-1.1.2.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n/* \n * x509.js - X509 class to read subject public key from certificate.\n *\n * Copyright (c) 2010-2013 Kenji Urushima (kenji.urushima@gmail.com)\n *\n * This software is licensed under the terms of the MIT License.\n * http://kjur.github.com/jsrsasign/license\n *\n * The above copyright and license notice shall be \n * included in all copies or substantial portions of the Software.\n */\n\n/**\n * @fileOverview\n * @name x509-1.1.js\n * @author Kenji Urushima kenji.urushima@gmail.com\n * @version x509 1.1.2 (2013-Oct-06)\n * @since jsrsasign 1.x.x\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\n */\n\n/*\n * Depends:\n *   base64.js\n *   rsa.js\n *   asn1hex.js\n */\n\n/**\n * X.509 certificate class.<br/>\n * @class X.509 certificate class\n * @property {RSAKey} subjectPublicKeyRSA Tom Wu's RSAKey object\n * @property {String} subjectPublicKeyRSA_hN hexadecimal string for modulus of RSA public key\n * @property {String} subjectPublicKeyRSA_hE hexadecimal string for public exponent of RSA public key\n * @property {String} hex hexacedimal string for X.509 certificate.\n * @author Kenji Urushima\n * @version 1.0.1 (08 May 2012)\n * @see <a href=\"http://kjur.github.com/jsrsasigns/\">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a>\n */\nfunction X509() {\n    this.subjectPublicKeyRSA = null;\n    this.subjectPublicKeyRSA_hN = null;\n    this.subjectPublicKeyRSA_hE = null;\n    this.hex = null;\n\n    // ===== get basic fields from hex =====================================\n\n    /**\n     * get hexadecimal string of serialNumber field of certificate.<br/>\n     * @name getSerialNumberHex\n     * @memberOf X509#\n     * @function\n     */\n    this.getSerialNumberHex = function() {\n\treturn ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 1]);\n    };\n\n    /**\n     * get hexadecimal string of issuer field of certificate.<br/>\n     * @name getIssuerHex\n     * @memberOf X509#\n     * @function\n     */\n    this.getIssuerHex = function() {\n\treturn ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]);\n    };\n\n    /**\n     * get string of issuer field of certificate.<br/>\n     * @name getIssuerString\n     * @memberOf X509#\n     * @function\n     */\n    this.getIssuerString = function() {\n\treturn X509.hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]));\n    };\n\n    /**\n     * get hexadecimal string of subject field of certificate.<br/>\n     * @name getSubjectHex\n     * @memberOf X509#\n     * @function\n     */\n    this.getSubjectHex = function() {\n\treturn ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]);\n    };\n\n    /**\n     * get string of subject field of certificate.<br/>\n     * @name getSubjectString\n     * @memberOf X509#\n     * @function\n     */\n    this.getSubjectString = function() {\n\treturn X509.hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]));\n    };\n\n    /**\n     * get notBefore field string of certificate.<br/>\n     * @name getNotBefore\n     * @memberOf X509#\n     * @function\n     */\n    this.getNotBefore = function() {\n\tvar s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 0]);\n\ts = s.replace(/(..)/g, \"%$1\");\n\ts = decodeURIComponent(s);\n\treturn s;\n    };\n\n    /**\n     * get notAfter field string of certificate.<br/>\n     * @name getNotAfter\n     * @memberOf X509#\n     * @function\n     */\n    this.getNotAfter = function() {\n\tvar s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 1]);\n\ts = s.replace(/(..)/g, \"%$1\");\n\ts = decodeURIComponent(s);\n\treturn s;\n    };\n\n    // ===== read certificate public key ==========================\n\n    // ===== read certificate =====================================\n    /**\n     * read PEM formatted X.509 certificate from string.<br/>\n     * @name readCertPEM\n     * @memberOf X509#\n     * @function\n     * @param {String} sCertPEM string for PEM formatted X.509 certificate\n     */\n    this.readCertPEM = function(sCertPEM) {\n\tvar hCert = X509.pemToHex(sCertPEM);\n\tvar a = X509.getPublicKeyHexArrayFromCertHex(hCert);\n\tvar rsa = new RSAKey();\n\trsa.setPublic(a[0], a[1]);\n\tthis.subjectPublicKeyRSA = rsa;\n\tthis.subjectPublicKeyRSA_hN = a[0];\n\tthis.subjectPublicKeyRSA_hE = a[1];\n\tthis.hex = hCert;\n    };\n\n    this.readCertPEMWithoutRSAInit = function(sCertPEM) {\n\tvar hCert = X509.pemToHex(sCertPEM);\n\tvar a = X509.getPublicKeyHexArrayFromCertHex(hCert);\n\tthis.subjectPublicKeyRSA.setPublic(a[0], a[1]);\n\tthis.subjectPublicKeyRSA_hN = a[0];\n\tthis.subjectPublicKeyRSA_hE = a[1];\n\tthis.hex = hCert;\n    };\n};\n\nX509.pemToBase64 = function(sCertPEM) {\n    var s = sCertPEM;\n    s = s.replace(\"-----BEGIN CERTIFICATE-----\", \"\");\n    s = s.replace(\"-----END CERTIFICATE-----\", \"\");\n    s = s.replace(/[ \\n]+/g, \"\");\n    return s;\n};\n\nX509.pemToHex = function(sCertPEM) {\n    var b64Cert = X509.pemToBase64(sCertPEM);\n    var hCert = b64tohex(b64Cert);\n    return hCert;\n};\n\n// NOTE: Without BITSTRING encapsulation.\nX509.getSubjectPublicKeyPosFromCertHex = function(hCert) {\n    var pInfo = X509.getSubjectPublicKeyInfoPosFromCertHex(hCert);\n    if (pInfo == -1) return -1;    \n    var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pInfo); \n    if (a.length != 2) return -1;\n    var pBitString = a[1];\n    if (hCert.substring(pBitString, pBitString + 2) != '03') return -1;\n    var pBitStringV = ASN1HEX.getStartPosOfV_AtObj(hCert, pBitString);\n    \n    if (hCert.substring(pBitStringV, pBitStringV + 2) != '00') return -1;\n    return pBitStringV + 2;\n};\n\n// NOTE: privateKeyUsagePeriod field of X509v2 not supported.\n// NOTE: v1 and v3 supported\nX509.getSubjectPublicKeyInfoPosFromCertHex = function(hCert) {\n    var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);\n    var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pTbsCert); \n    if (a.length < 1) return -1;\n    if (hCert.substring(a[0], a[0] + 10) == \"a003020102\") { // v3\n\tif (a.length < 6) return -1;\n\treturn a[6];\n    } else {\n\tif (a.length < 5) return -1;\n\treturn a[5];\n    }\n};\n\nX509.getPublicKeyHexArrayFromCertHex = function(hCert) {\n    var p = X509.getSubjectPublicKeyPosFromCertHex(hCert);\n    var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, p); \n    if (a.length != 2) return [];\n    var hN = ASN1HEX.getHexOfV_AtObj(hCert, a[0]);\n    var hE = ASN1HEX.getHexOfV_AtObj(hCert, a[1]);\n    if (hN != null && hE != null) {\n\treturn [hN, hE];\n    } else {\n\treturn [];\n    }\n};\n\nX509.getHexTbsCertificateFromCert = function(hCert) {\n    var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);\n    return pTbsCert;\n};\n\nX509.getPublicKeyHexArrayFromCertPEM = function(sCertPEM) {\n    var hCert = X509.pemToHex(sCertPEM);\n    var a = X509.getPublicKeyHexArrayFromCertHex(hCert);\n    return a;\n};\n\nX509.hex2dn = function(hDN) {\n    var s = \"\";\n    var a = ASN1HEX.getPosArrayOfChildren_AtObj(hDN, 0);\n    for (var i = 0; i < a.length; i++) {\n\tvar hRDN = ASN1HEX.getHexOfTLV_AtObj(hDN, a[i]);\n\ts = s + \"/\" + X509.hex2rdn(hRDN);\n    }\n    return s;\n};\n\nX509.hex2rdn = function(hRDN) {\n    var hType = ASN1HEX.getDecendantHexTLVByNthList(hRDN, 0, [0, 0]);\n    var hValue = ASN1HEX.getDecendantHexVByNthList(hRDN, 0, [0, 1]);\n    var type = \"\";\n    try { type = X509.DN_ATTRHEX[hType]; } catch (ex) { type = hType; }\n    hValue = hValue.replace(/(..)/g, \"%$1\");\n    var value = decodeURIComponent(hValue);\n    return type + \"=\" + value;\n};\n\nX509.DN_ATTRHEX = {\n    \"0603550406\": \"C\",\n    \"060355040a\": \"O\",\n    \"060355040b\": \"OU\",\n    \"0603550403\": \"CN\",\n    \"0603550405\": \"SN\",\n    \"0603550408\": \"ST\",\n    \"0603550407\": \"L\",\n};\n\n/**\n * get RSAKey/ECDSA public key object from PEM certificate string\n * @name getPublicKeyFromCertPEM\n * @memberOf X509\n * @function\n * @param {String} sCertPEM PEM formatted RSA/ECDSA/DSA X.509 certificate\n * @return returns RSAKey/KJUR.crypto.{ECDSA,DSA} object of public key\n * @since x509 1.1.1\n * @description\n * NOTE: DSA is also supported since x509 1.1.2.\n */\nX509.getPublicKeyFromCertPEM = function(sCertPEM) {\n    var info = X509.getPublicKeyInfoPropOfCertPEM(sCertPEM);\n\n    if (info.algoid == \"2a864886f70d010101\") { // RSA\n\tvar aRSA = KEYUTIL.parsePublicRawRSAKeyHex(info.keyhex);\n\tvar key = new RSAKey();\n\tkey.setPublic(aRSA.n, aRSA.e);\n\treturn key;\n    } else if (info.algoid == \"2a8648ce3d0201\") { // ECC\n\tvar curveName = KJUR.crypto.OID.oidhex2name[info.algparam];\n\tvar key = new KJUR.crypto.ECDSA({'curve': curveName, 'info': info.keyhex});\n        key.setPublicKeyHex(info.keyhex);\n\treturn key;\n    } else if (info.algoid == \"2a8648ce380401\") { // DSA 1.2.840.10040.4.1\n\tvar p = ASN1HEX.getVbyList(info.algparam, 0, [0], \"02\");\n\tvar q = ASN1HEX.getVbyList(info.algparam, 0, [1], \"02\");\n\tvar g = ASN1HEX.getVbyList(info.algparam, 0, [2], \"02\");\n\tvar y = ASN1HEX.getHexOfV_AtObj(info.keyhex, 0);\n\ty = y.substr(2);\n\tvar key = new KJUR.crypto.DSA();\n\tkey.setPublic(new BigInteger(p, 16),\n\t\t      new BigInteger(q, 16),\n\t\t      new BigInteger(g, 16),\n\t\t      new BigInteger(y, 16));\n\treturn key;\n    } else {\n\tthrow \"unsupported key\";\n    }\n};\n\n/**\n * get public key information from PEM certificate\n * @name getPublicKeyInfoPropOfCertPEM\n * @memberOf X509\n * @function\n * @param {String} sCertPEM string of PEM formatted certificate\n * @return {Hash} hash of information for public key\n * @since x509 1.1.1\n * @description\n * Resulted associative array has following properties:\n * <ul>\n * <li>algoid - hexadecimal string of OID of asymmetric key algorithm</li>\n * <li>algparam - hexadecimal string of OID of ECC curve name or null</li>\n * <li>keyhex - hexadecimal string of key in the certificate</li>\n * </ul>\n * @since x509 1.1.1\n */\nX509.getPublicKeyInfoPropOfCertPEM = function(sCertPEM) {\n    var result = {};\n    result.algparam = null;\n    var hCert = X509.pemToHex(sCertPEM);\n\n    // 1. Certificate ASN.1\n    var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, 0); \n    if (a1.length != 3)\n\tthrow \"malformed X.509 certificate PEM (code:001)\"; // not 3 item of seq Cert\n\n    // 2. tbsCertificate\n    if (hCert.substr(a1[0], 2) != \"30\")\n\tthrow \"malformed X.509 certificate PEM (code:002)\"; // tbsCert not seq \n\n    var a2 = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, a1[0]); \n\n    // 3. subjectPublicKeyInfo\n    if (a2.length < 7)\n\tthrow \"malformed X.509 certificate PEM (code:003)\"; // no subjPubKeyInfo\n\n    var a3 = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, a2[6]); \n\n    if (a3.length != 2)\n\tthrow \"malformed X.509 certificate PEM (code:004)\"; // not AlgId and PubKey\n\n    // 4. AlgId\n    var a4 = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, a3[0]); \n\n    if (a4.length != 2)\n\tthrow \"malformed X.509 certificate PEM (code:005)\"; // not 2 item in AlgId\n\n    result.algoid = ASN1HEX.getHexOfV_AtObj(hCert, a4[0]);\n\n    if (hCert.substr(a4[1], 2) == \"06\") { // EC\n\tresult.algparam = ASN1HEX.getHexOfV_AtObj(hCert, a4[1]);\n    } else if (hCert.substr(a4[1], 2) == \"30\") { // DSA\n\tresult.algparam = ASN1HEX.getHexOfTLV_AtObj(hCert, a4[1]);\n    }\n\n    // 5. Public Key Hex\n    if (hCert.substr(a3[1], 02) != \"03\")\n\tthrow \"malformed X.509 certificate PEM (code:006)\"; // not bitstring\n\n    var unusedBitAndKeyHex = ASN1HEX.getHexOfV_AtObj(hCert, a3[1]);\n    result.keyhex = unusedBitAndKeyHex.substr(2);\n\n    return result;\n};\n\n/*\nX509.prototype.readCertPEM = _x509_readCertPEM;\nX509.prototype.readCertPEMWithoutRSAInit = _x509_readCertPEMWithoutRSAInit;\nX509.prototype.getSerialNumberHex = _x509_getSerialNumberHex;\nX509.prototype.getIssuerHex = _x509_getIssuerHex;\nX509.prototype.getSubjectHex = _x509_getSubjectHex;\nX509.prototype.getIssuerString = _x509_getIssuerString;\nX509.prototype.getSubjectString = _x509_getSubjectString;\nX509.prototype.getNotBefore = _x509_getNotBefore;\nX509.prototype.getNotAfter = _x509_getNotAfter;\n*/\n"
  },
  {
    "path": "JavaScript/demo/js/yahoo-min.js",
    "content": "/*\nCopyright (c) 2011, Yahoo! Inc. All rights reserved.\nCode licensed under the BSD License:\nhttp://developer.yahoo.com/yui/license.html\nversion: 2.9.0\n*/\nif(typeof YAHOO==\"undefined\"||!YAHOO){var YAHOO={};}YAHOO.namespace=function(){var b=arguments,g=null,e,c,f;for(e=0;e<b.length;e=e+1){f=(\"\"+b[e]).split(\".\");g=YAHOO;for(c=(f[0]==\"YAHOO\")?1:0;c<f.length;c=c+1){g[f[c]]=g[f[c]]||{};g=g[f[c]];}}return g;};YAHOO.log=function(d,a,c){var b=YAHOO.widget.Logger;if(b&&b.log){return b.log(d,a,c);}else{return false;}};YAHOO.register=function(a,f,e){var k=YAHOO.env.modules,c,j,h,g,d;if(!k[a]){k[a]={versions:[],builds:[]};}c=k[a];j=e.version;h=e.build;g=YAHOO.env.listeners;c.name=a;c.version=j;c.build=h;c.versions.push(j);c.builds.push(h);c.mainClass=f;for(d=0;d<g.length;d=d+1){g[d](c);}if(f){f.VERSION=j;f.BUILD=h;}else{YAHOO.log(\"mainClass is undefined for module \"+a,\"warn\");}};YAHOO.env=YAHOO.env||{modules:[],listeners:[]};YAHOO.env.getVersion=function(a){return YAHOO.env.modules[a]||null;};YAHOO.env.parseUA=function(d){var e=function(i){var j=0;return parseFloat(i.replace(/\\./g,function(){return(j++==1)?\"\":\".\";}));},h=navigator,g={ie:0,opera:0,gecko:0,webkit:0,chrome:0,mobile:null,air:0,ipad:0,iphone:0,ipod:0,ios:null,android:0,webos:0,caja:h&&h.cajaVersion,secure:false,os:null},c=d||(navigator&&navigator.userAgent),f=window&&window.location,b=f&&f.href,a;g.secure=b&&(b.toLowerCase().indexOf(\"https\")===0);if(c){if((/windows|win32/i).test(c)){g.os=\"windows\";}else{if((/macintosh/i).test(c)){g.os=\"macintosh\";}else{if((/rhino/i).test(c)){g.os=\"rhino\";}}}if((/KHTML/).test(c)){g.webkit=1;}a=c.match(/AppleWebKit\\/([^\\s]*)/);if(a&&a[1]){g.webkit=e(a[1]);if(/ Mobile\\//.test(c)){g.mobile=\"Apple\";a=c.match(/OS ([^\\s]*)/);if(a&&a[1]){a=e(a[1].replace(\"_\",\".\"));}g.ios=a;g.ipad=g.ipod=g.iphone=0;a=c.match(/iPad|iPod|iPhone/);if(a&&a[0]){g[a[0].toLowerCase()]=g.ios;}}else{a=c.match(/NokiaN[^\\/]*|Android \\d\\.\\d|webOS\\/\\d\\.\\d/);if(a){g.mobile=a[0];}if(/webOS/.test(c)){g.mobile=\"WebOS\";a=c.match(/webOS\\/([^\\s]*);/);if(a&&a[1]){g.webos=e(a[1]);}}if(/ Android/.test(c)){g.mobile=\"Android\";a=c.match(/Android ([^\\s]*);/);if(a&&a[1]){g.android=e(a[1]);}}}a=c.match(/Chrome\\/([^\\s]*)/);if(a&&a[1]){g.chrome=e(a[1]);}else{a=c.match(/AdobeAIR\\/([^\\s]*)/);if(a){g.air=a[0];}}}if(!g.webkit){a=c.match(/Opera[\\s\\/]([^\\s]*)/);if(a&&a[1]){g.opera=e(a[1]);a=c.match(/Version\\/([^\\s]*)/);if(a&&a[1]){g.opera=e(a[1]);}a=c.match(/Opera Mini[^;]*/);if(a){g.mobile=a[0];}}else{a=c.match(/MSIE\\s([^;]*)/);if(a&&a[1]){g.ie=e(a[1]);}else{a=c.match(/Gecko\\/([^\\s]*)/);if(a){g.gecko=1;a=c.match(/rv:([^\\s\\)]*)/);if(a&&a[1]){g.gecko=e(a[1]);}}}}}}return g;};YAHOO.env.ua=YAHOO.env.parseUA();(function(){YAHOO.namespace(\"util\",\"widget\",\"example\");if(\"undefined\"!==typeof YAHOO_config){var b=YAHOO_config.listener,a=YAHOO.env.listeners,d=true,c;if(b){for(c=0;c<a.length;c++){if(a[c]==b){d=false;break;}}if(d){a.push(b);}}}})();YAHOO.lang=YAHOO.lang||{};(function(){var f=YAHOO.lang,a=Object.prototype,c=\"[object Array]\",h=\"[object Function]\",i=\"[object Object]\",b=[],g={\"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#x27;\",\"/\":\"&#x2F;\",\"`\":\"&#x60;\"},d=[\"toString\",\"valueOf\"],e={isArray:function(j){return a.toString.apply(j)===c;},isBoolean:function(j){return typeof j===\"boolean\";},isFunction:function(j){return(typeof j===\"function\")||a.toString.apply(j)===h;},isNull:function(j){return j===null;},isNumber:function(j){return typeof j===\"number\"&&isFinite(j);},isObject:function(j){return(j&&(typeof j===\"object\"||f.isFunction(j)))||false;},isString:function(j){return typeof j===\"string\";},isUndefined:function(j){return typeof j===\"undefined\";},_IEEnumFix:(YAHOO.env.ua.ie)?function(l,k){var j,n,m;for(j=0;j<d.length;j=j+1){n=d[j];m=k[n];if(f.isFunction(m)&&m!=a[n]){l[n]=m;}}}:function(){},escapeHTML:function(j){return j.replace(/[&<>\"'\\/`]/g,function(k){return g[k];});},extend:function(m,n,l){if(!n||!m){throw new Error(\"extend failed, please check that \"+\"all dependencies are included.\");}var k=function(){},j;k.prototype=n.prototype;m.prototype=new k();m.prototype.constructor=m;m.superclass=n.prototype;if(n.prototype.constructor==a.constructor){n.prototype.constructor=n;}if(l){for(j in l){if(f.hasOwnProperty(l,j)){m.prototype[j]=l[j];}}f._IEEnumFix(m.prototype,l);}},augmentObject:function(n,m){if(!m||!n){throw new Error(\"Absorb failed, verify dependencies.\");}var j=arguments,l,o,k=j[2];if(k&&k!==true){for(l=2;l<j.length;l=l+1){n[j[l]]=m[j[l]];}}else{for(o in m){if(k||!(o in n)){n[o]=m[o];}}f._IEEnumFix(n,m);}return n;},augmentProto:function(m,l){if(!l||!m){throw new Error(\"Augment failed, verify dependencies.\");}var j=[m.prototype,l.prototype],k;for(k=2;k<arguments.length;k=k+1){j.push(arguments[k]);}f.augmentObject.apply(this,j);return m;},dump:function(j,p){var l,n,r=[],t=\"{...}\",k=\"f(){...}\",q=\", \",m=\" => \";if(!f.isObject(j)){return j+\"\";}else{if(j instanceof Date||(\"nodeType\" in j&&\"tagName\" in j)){return j;}else{if(f.isFunction(j)){return k;}}}p=(f.isNumber(p))?p:3;if(f.isArray(j)){r.push(\"[\");for(l=0,n=j.length;l<n;l=l+1){if(f.isObject(j[l])){r.push((p>0)?f.dump(j[l],p-1):t);}else{r.push(j[l]);}r.push(q);}if(r.length>1){r.pop();}r.push(\"]\");}else{r.push(\"{\");for(l in j){if(f.hasOwnProperty(j,l)){r.push(l+m);if(f.isObject(j[l])){r.push((p>0)?f.dump(j[l],p-1):t);}else{r.push(j[l]);}r.push(q);}}if(r.length>1){r.pop();}r.push(\"}\");}return r.join(\"\");},substitute:function(x,y,E,l){var D,C,B,G,t,u,F=[],p,z=x.length,A=\"dump\",r=\" \",q=\"{\",m=\"}\",n,w;for(;;){D=x.lastIndexOf(q,z);if(D<0){break;}C=x.indexOf(m,D);if(D+1>C){break;}p=x.substring(D+1,C);G=p;u=null;B=G.indexOf(r);if(B>-1){u=G.substring(B+1);G=G.substring(0,B);}t=y[G];if(E){t=E(G,t,u);}if(f.isObject(t)){if(f.isArray(t)){t=f.dump(t,parseInt(u,10));}else{u=u||\"\";n=u.indexOf(A);if(n>-1){u=u.substring(4);}w=t.toString();if(w===i||n>-1){t=f.dump(t,parseInt(u,10));}else{t=w;}}}else{if(!f.isString(t)&&!f.isNumber(t)){t=\"~-\"+F.length+\"-~\";F[F.length]=p;}}x=x.substring(0,D)+t+x.substring(C+1);if(l===false){z=D-1;}}for(D=F.length-1;D>=0;D=D-1){x=x.replace(new RegExp(\"~-\"+D+\"-~\"),\"{\"+F[D]+\"}\",\"g\");}return x;},trim:function(j){try{return j.replace(/^\\s+|\\s+$/g,\"\");}catch(k){return j;\n}},merge:function(){var n={},k=arguments,j=k.length,m;for(m=0;m<j;m=m+1){f.augmentObject(n,k[m],true);}return n;},later:function(t,k,u,n,p){t=t||0;k=k||{};var l=u,s=n,q,j;if(f.isString(u)){l=k[u];}if(!l){throw new TypeError(\"method undefined\");}if(!f.isUndefined(n)&&!f.isArray(s)){s=[n];}q=function(){l.apply(k,s||b);};j=(p)?setInterval(q,t):setTimeout(q,t);return{interval:p,cancel:function(){if(this.interval){clearInterval(j);}else{clearTimeout(j);}}};},isValue:function(j){return(f.isObject(j)||f.isString(j)||f.isNumber(j)||f.isBoolean(j));}};f.hasOwnProperty=(a.hasOwnProperty)?function(j,k){return j&&j.hasOwnProperty&&j.hasOwnProperty(k);}:function(j,k){return !f.isUndefined(j[k])&&j.constructor.prototype[k]!==j[k];};e.augmentObject(f,e,true);YAHOO.util.Lang=f;f.augment=f.augmentProto;YAHOO.augment=f.augmentProto;YAHOO.extend=f.extend;})();YAHOO.register(\"yahoo\",YAHOO,{version:\"2.9.0\",build:\"2800\"});"
  },
  {
    "path": "JavaScript/demo/performance.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>国密算法实现</title>\n    <!-- for pkcs5pkey -->\n    <script src=\"js/core.js\"></script>\n    <script src=\"js/cipher-core.js\"></script>\n    <script src=\"js/md5.js\"></script>\n    <script src=\"js/tripledes.js\"></script>\n    <script src=\"js/enc-base64.js\"></script>\n    <!-- for crypto -->\n    <script src=\"js/sha1.js\"></script>\n    <script src=\"js/sha256.js\"></script>\n    <!-- for crypto, asn1, asn1x509 -->\n    <script src=\"js/yahoo-min.js\"></script>\n    <!-- for asn1x509(stohex)\n    <script src=\"http://kjur.github.io/jsjws/base64x-1.1.min.js\"></script> -->\n\n    <script src=\"js/jsbn.js\"></script>\n    <script src=\"js/jsbn2.js\"></script>\n    <script src=\"js/prng4.js\"></script>\n    <script src=\"js/rng.js\"></script>\n    <script src=\"js/rsa.js\"></script>\n    <script src=\"js/rsa2.js\"></script>\n    <script src=\"js/base64.js\"></script>\n    <script src=\"js/asn1hex-1.1.js\"></script>\n    <script src=\"js/rsapem-1.1.js\"></script>\n    <script src=\"js/rsasign-1.2.js\"></script>\n    <script src=\"js/x509-1.1.js\"></script>\n    <script src=\"js/pkcs5pkey-1.0.js\"></script>\n    <script src=\"js/asn1-1.0.js\"></script>\n    <script src=\"js/asn1x509-1.0.js\"></script>\n    <script src=\"js/crypto-1.1.js\"></script>\n\n    <script src=\"js/ec.js\"></script>\n    <script src=\"js/ec-patch.js\"></script>\n    <script src=\"js/ecdsa-modified-1.0.js\"></script>\n    <script src=\"js/sm3.js\"></script>\n    <script src=\"js/sm3-sm2-1.0.js\"></script>\n    <script src=\"js/ecparam-1.0.js\"></script>\n    <script src=\"js/sm2-guomi.js\"></script>\n    \n    <!-- sm4 -->\n    <script src=\"js/sm4.js\"></script>\n    <script src=\"js/utils.js\"></script>\n    <!-- fingerprint -->\n    <script src=\"js/fingerprint2.js\"></script>\n    <!-- sm3 -->\n    <script src=\"js/sm3-guomi.js\"></script>\n\n</head>\n<body>\n    <div id=\"sm2\"></div>\n    <div id=\"sm3\"></div>\n    <div id=\"sm4\"></div>\n</body>\n<script>\n\n    // --------------------------- SM2 ---------------------------------------\n    var sm2 = \"\";\n    var method = \"SM2\"\n\n    var ec = new KJUR.crypto.ECDSA({\"curve\": method});\n    var keypair = ec.generateKeyPairHex();\n\n    var privkey = keypair.ecprvhex;\n    var publkey = keypair.ecpubhex\n    sm2 += \"<h3>SM2 算法性能测试</h3>\";\n    sm2 += \"message: This is message\";\n    sm2 += \"<br>\"+\"private key:\" + privkey;\n    sm2 += \"<br>\"+\"public key :\" + publkey;\n\n    var start = new Date().getTime();\n    var msgData = CryptoJS.enc.Utf8.parse(\"This is message\");\n\n    if (publkey.length > 64 * 2) {\n        publkey = publkey.substr(publkey.length - 64 * 2);\n    }\n\n    var xHex = publkey.substr(0, 64);\n    var yHex = publkey.substr(64);\n\n    var cipherMode = \"0\";\n\n    var cipher = new SM2Cipher(cipherMode);\n    var userKey = cipher.CreatePoint(xHex, yHex);\n\n    msgData = cipher.GetWords(msgData.toString());\n\n    var encryptData = cipher.Encrypt(userKey, msgData);\n    var second = new Date().getTime();\n    sm2 += \"<br>Ciphertext: \"+encryptData;\n    sm2 += \"<br>加密耗时: \"+(second-start)+\" ms\";\n    var privateKey = new BigInteger(privkey, 16);\n\n    var second = new Date().getTime();\n    var cipher = new SM2Cipher(cipherMode);\n    var data = cipher.Decrypt(privateKey, encryptData);\n    sm2 += \"<br>Plaintext: \"+data;\n    var end = new Date().getTime();\n    sm2 += \"<br />解密耗时: \"+(end-second)+\" ms\";\n    document.getElementById('sm2').innerHTML = sm2;\n    // --------------------------- SM3 ---------------------------------------\n    var sm3 = \"\";\n    new Fingerprint2().get(function(result, components){\n        sm3 += \"<h3>SM3 算法性能测试</h3>\"\n        sm3 += \"message: \"+result;\n        // var smDigest = new SM3Digest();\n        // smDigest.GetWords(result);\n        // var smHash = new Array(smDigest.GetDigestSize());\n        // smDigest.DoFinal(smHash, 0);\n        var start = new Date().getTime();\n        ciphertext = CryptoJS.SM3(result).toString(CryptoJS.enc.Hex)\n        var second = new Date().getTime();\n        sm3 += \"<br>Ciphertext: \"+ciphertext;\n        sm3 += \"<br>加密耗时: \"+(second-start)+\" ms\";\n        document.getElementById('sm3').innerHTML = sm3;\n    });\n    // --------------------------- SM4 ---------------------------------------\n    var sm4 = \"\";\n    sm4 += \"<h3>SM4 算法性能测试</h3>\";\n    sm4 += \"message: 12.3,14.5,23-54,12,57,3\"\n    key = randomkey(\"1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b\");\n    sm4 += \"<br>key: \"+key;\n    var start = new Date().getTime();\n    ciphertext = sm4_encode_cbc(\"12.3,14.5,23-54,12,57,3\",key);\n    var second = new Date().getTime();\n    var result = \"\";\n    for(var i=0;i<ciphertext.length;i++){\n        hextext = ciphertext[i].toString(16);\n        result += hextext.length == 16 ? hextext :\"0\".repeat(8-hextext.length)+hextext;\n    }\n    sm4 += \"<br>Ciphertext: \"+result;\n    sm4 += \"<br>加密耗时: \"+(second-start)+\" ms\";\n    var text = new Array();\n    for(var i=0;i<result.length;i+=8){\n        text.push(parseInt(result.slice(i,i+8),16))\n    }\n    var second = new Date().getTime();\n    plaintext = sm4_decode_cbc(text,key);\n    var end = new Date().getTime();\n    sm4 += \"<br>Plaintext: \"+plaintext;\n    sm4 += \"<br>解密耗时: \"+(end-second)+\" ms\";\n    document.getElementById('sm4').innerHTML = sm4;\n</script>\n\n</html>"
  },
  {
    "path": "JavaScript/des/JavaScript DES Example.html",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n<!-- saved from url=(0048)http://people.eku.edu/styere/Encrypt/JS-DES.html -->\n<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=windows-1252\">\n  <title>JavaScript DES Example</title>\n  <script language=\"JavaScript\">\n// accumulate values to put into text area\nvar accumulated_output_info;\n\n// add a labeled value to the text area\nfunction accumulate_output( str )\n{\n   accumulated_output_info = accumulated_output_info + str + \"\\n\";\n}\n\n// add a bit string to the output, inserting spaces as designated\nfunction accumulate_bitstring( label, ary, spacing )\n{\n   var i;\n\n   accumulated_output_info += label;\n\n   // add bits\n   for( i=1; i<ary.length; i++ )\n   {\n      if ( (i%spacing) == 1 )\n         accumulated_output_info += \" \";\t// time to add a space\n      accumulated_output_info += ary[i];\t// and the bit\n   }\n\n   // insert trailing end-of-line\n   accumulated_output_info += \"\\n\";\n}\n\n// special value stored in x[0] to indicate a problem\nvar ERROR_VAL = -9876;\n\n// initial permutation (split into left/right halves )\n// since DES numbers bits starting at 1, we will ignore x[0]\nvar IP_perm = new Array( -1,\n\t58, 50, 42, 34, 26, 18, 10, 2,\n\t60, 52, 44, 36, 28, 20, 12, 4,\n\t62, 54, 46, 38, 30, 22, 14, 6,\n\t64, 56, 48, 40, 32, 24, 16, 8,\n\t57, 49, 41, 33, 25, 17, 9, 1,\n\t59, 51, 43, 35, 27, 19, 11, 3,\n\t61, 53, 45, 37, 29, 21, 13, 5,\n\t63, 55, 47, 39, 31, 23, 15, 7 );\n\n// final permutation (inverse initial permutation)\nvar FP_perm = new Array( -1,\n\t40, 8, 48, 16, 56, 24, 64, 32,\n\t39, 7, 47, 15, 55, 23, 63, 31,\n\t38, 6, 46, 14, 54, 22, 62, 30,\n\t37, 5, 45, 13, 53, 21, 61, 29,\n\t36, 4, 44, 12, 52, 20, 60, 28,\n\t35, 3, 43, 11, 51, 19, 59, 27,\n\t34, 2, 42, 10, 50, 18, 58, 26,\n\t33, 1, 41, 9, 49, 17, 57, 25 );\n\n// per-round expansion\nvar E_perm = new Array( -1,\n\t32, 1, 2, 3, 4, 5,\n\t4, 5, 6, 7, 8, 9,\n\t8, 9, 10, 11, 12, 13,\n\t12, 13, 14, 15, 16, 17,\n\t16, 17, 18, 19, 20, 21,\n\t20, 21, 22, 23, 24, 25,\n\t24, 25, 26, 27, 28, 29,\n\t28, 29, 30, 31, 32, 1 );\n\n// per-round permutation\nvar P_perm = new Array( -1,\n\t16, 7, 20, 21, 29, 12, 28, 17,\n\t1, 15, 23, 26, 5, 18, 31, 10,\n\t2, 8, 24, 14, 32, 27, 3, 9,\n\t19, 13, 30, 6, 22, 11, 4, 25 );\n\n// note we do use element 0 in the S-Boxes\nvar S1 = new Array(\n\t14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,\n\t0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,\n\t4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,\n\t15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 );\nvar S2 = new Array(\n\t15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,\n\t3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,\n\t0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,\n\t13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 );\nvar S3 = new Array(\n\t10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,\n\t13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,\n\t13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,\n\t1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 );\nvar S4 = new Array(\n\t7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,\n\t13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,\n\t10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,\n\t3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 );\nvar S5 = new Array(\n\t2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,\n\t14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,\n\t4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,\n\t11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 );\nvar S6 = new Array(\n\t12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,\n\t10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,\n\t9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,\n\t4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 );\nvar S7 = new Array(\n\t4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,\n\t13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,\n\t1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,\n\t6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 );\nvar S8 = new Array(\n\t13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,\n\t1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,\n\t7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,\n\t2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 );\n\n//, first, key, permutation\nvar PC_1_perm = new Array( -1, \n\t// C subkey bits\n\t57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,\n\t10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,\n\t// D subkey bits\n\t63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,\n\t14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 );\n\n//, per-round, key, selection, permutation\nvar PC_2_perm = new Array( -1, \n\t14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,\n\t23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,\n\t41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,\n\t44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 );\n\n// save output in case we want to reformat it later\nvar DES_output = new Array( 65 );\n\n// remove spaces from input\nfunction remove_spaces( instr )\n{\n   var i;\n   var outstr=\"\";\n\n   for( i=0; i<instr.length; i++ )\n      if ( instr.charAt(i) != \" \" )\n         // not a space, include it\n         outstr += instr.charAt(i);\n\n   return outstr;\n}\n\n// split an integer into bits\n// ary   = array to store bits in\n// start = starting subscript\n// bitc  = number of bits to convert\n// val   = number to convert\nfunction split_int( ary, start, bitc, val )\n{\n   var i = start;\n   var j;\n   for( j=bitc-1; j>=0; j-- )\n   {\n      // isolate low-order bit\n      ary[i+j] = val & 1;\n      // remove that bit\n      val >>= 1;\n   }\n}\n\n// get the message to encrypt/decrypt\nfunction get_value( bitarray, str, isASCII )\n{\n   var i;\n   var val;\t// one hex digit\n\n   // insert note we probably are ok\n   bitarray[0] = -1;\n\n   if ( isASCII )\n   {\n      // check length of data\n      if ( str.length != 8 )\n      {\n         window.alert(\"Message and key must be 64 bits (8 ASCII characters)\");\n         bitarray[0] = ERROR_VAL;\n         return\n      }\n\n      // have ASCII data\n      for( i=0; i<8; i++ )\n      {\n         split_int( bitarray, i*8+1, 8, str.charCodeAt(i) );\n      }\n   }\n   else\n   {\n      // have hex data - remove any spaces they used, then convert\n      str = remove_spaces(str);\n\n      // check length of data\n      if ( str.length != 16 )\n      {\n         window.alert(\"Message and key must be 64 bits (16 hex digits)\");\n         bitarray[0] = ERROR_VAL;\n         return;\n      }\n\n      for( i=0; i<16; i++ )\n      {\n         // get the next hex digit\n         val = str.charCodeAt(i);\n\n         // do some error checking\n         if ( val >= 48 && val <= 57 )\n            // have a valid digit 0-9\n            val -= 48;\n         else if ( val >= 65 && val <= 70 )\n            // have a valid digit A-F\n            val -= 55;\n         else if ( val >= 97 && val <= 102 )\n            // have a valid digit A-F\n            val -= 87;\n         else\n         {\n            // not 0-9 or A-F, complain\n            window.alert( str.charAt(i)+\" is not a valid hex digit\" );\n            bitarray[0] = ERROR_VAL;\n            return;\n         }\n\n         // add this digit to the array\n         split_int( bitarray, i*4+1, 4, val-48 );\n      }\n   }\n}\n\n// format the output in the desired form\n// if -1, use existing value\n// -- uses the global array DES_output\nfunction format_DES_output( )\n{\n   var i;\n   var bits;\n   var str=\"\";\n\n   // what type of data do we have to work with?\n   if ( document.stuff.outtype[0].checked )\n   {\n      // convert each set of bits back to ASCII\n      for( i=1; i<=64; i+= 8 )\n      {\n            str += String.fromCharCode(\n                        DES_output[i  ]*128 + DES_output[i+1]*64  +\n                        DES_output[i+2]*32  + DES_output[i+3]*16  +\n                        DES_output[i+4]*8   + DES_output[i+5]*4   +\n                        DES_output[i+6]*2   + DES_output[i+7] );\n      }\n   }\n   else \n   {\n      // output hexdecimal data\n      for( i=1; i<=64; i+= 4 )\n      {\n            bits = DES_output[i  ]*8   + DES_output[i+1]*4   +\n                   DES_output[i+2]*2   + DES_output[i+3];\n\n            // 0-9 or A-F?\n            if ( bits <= 9 )\n               str += String.fromCharCode( bits+48 );\n            else\n               str += String.fromCharCode( bits+87 );\n      }\n   }\n\n   // copy to textbox\n   document.stuff.outdata.value = str;\n}\n\n// copy bits in a permutation\n//   dest = where to copy the bits to\n//   src  = Where to copy the bits from\n//   perm = The order to copy/permute the bits\n// note: since DES ingores x[0], we do also\nfunction permute( dest, src, perm )\n{\n  var i;\n  var fromloc;\n\n  for( i=1; i<perm.length; i++ )\n  {\n    fromloc = perm[i];\n    dest[i] = src[fromloc];\n  }\n}\n\n// do an array XOR\n// assume all array entries are 0 or 1\nfunction xor( a1, a2 )\n{\n   var i;\n\n   for( i=1; i<a1.length; i++ )\n      a1[i] = a1[i] ^ a2[i];\n}\n\n// process one S-Box, return integer from S-Box\nfunction do_S( SBox, index, inbits )\n{\n   // collect the 6 bits into a single integer\n   var S_index = inbits[index  ]*32 + inbits[index+5]*16 +\n                 inbits[index+1]*8  + inbits[index+2]*4 +\n                 inbits[index+3]*2  + inbits[index+4];\n\n   // do lookup\n   return SBox[S_index];\n}\n\n// do one round of DES encryption\nfunction des_round( L, R, KeyR )\n{\n   var E_result = new Array( 49 );\n   var S_out = new Array( 33 );\n\n   // copy the existing L bits, then set new L = old R\n   var temp_L = new Array( 33 );\n   for( i=0; i<33; i++ )\n   {\n      // copy exising L bits\n      temp_L[i] = L[i];\n\n      // set L = R\n      L[i] = R[i];\n   }\n\n   // expand R using E permutation\n   permute( E_result, R, E_perm );\n   accumulate_bitstring( \"E   : \", E_result, 6 );\n   accumulate_bitstring( \"KS  : \", KeyR, 6 );\n\n   // exclusive-or with current key\n   xor( E_result, KeyR );\n   accumulate_bitstring( \"E xor KS: \", E_result, 6 );\n\n   // put through the S-Boxes\n   split_int( S_out,  1, 4, do_S( S1,  1, E_result ) );\n   split_int( S_out,  5, 4, do_S( S2,  7, E_result ) );\n   split_int( S_out,  9, 4, do_S( S3, 13, E_result ) );\n   split_int( S_out, 13, 4, do_S( S4, 19, E_result ) );\n   split_int( S_out, 17, 4, do_S( S5, 25, E_result ) );\n   split_int( S_out, 21, 4, do_S( S6, 31, E_result ) );\n   split_int( S_out, 25, 4, do_S( S7, 37, E_result ) );\n   split_int( S_out, 29, 4, do_S( S8, 43, E_result ) );\n   accumulate_bitstring( \"Sbox: \", S_out, 4 );\n\n   // do the P permutation\n   permute( R, S_out, P_perm );\n   accumulate_bitstring( \"P   :\", R, 8 );\n\n   // xor this with old L to get the new R\n   xor( R, temp_L );\n   accumulate_bitstring( \"L[i]:\", L, 8 );\n   accumulate_bitstring( \"R[i]:\", R, 8 );\n}\n\n// shift the CD values left 1 bit\nfunction shift_CD_1( CD )\n{\n   var i;\n\n   // note we use [0] to hold the bit shifted around the end\n   for( i=0; i<=55; i++ )\n      CD[i] = CD[i+1];\n\n   // shift D bit around end\n   CD[56] = CD[28];\n   // shift C bit around end\n   CD[28] = CD[0];\n}\n\n// shift the CD values left 2 bits\nfunction shift_CD_2( CD )\n{\n   var i;\n   var C1 = CD[1];\n\n   // note we use [0] to hold the bit shifted around the end\n   for( i=0; i<=54; i++ )\n      CD[i] = CD[i+2];\n\n   // shift D bits around end\n   CD[55] = CD[27];\n   CD[56] = CD[28];\n   // shift C bits around end\n   CD[27] = C1;\n   CD[28] = CD[0];\n}\n\n\n// do the actual DES encryption/decryption\nfunction des_encrypt( inData, Key, do_encrypt )\n{\n   var tempData = new Array( 65 );\t// output bits\n   var CD = new Array( 57 );\t\t// halves of current key\n   var KS = new Array( 16 );\t\t// per-round key schedules\n   var L = new Array( 33 );\t\t// left half of current data\n   var R = new Array( 33 );\t\t// right half of current data\n   var result = new Array( 65 );\t// DES output\n   var i;\n\n   // do the initial key permutation\n   permute( CD, Key, PC_1_perm );\n   accumulate_bitstring( \"CD[0]: \", CD, 7 );\n\n   // create the subkeys\n   for( i=1; i<=16; i++ )\n   {\n      // create a new array for each round\n      KS[i] = new Array( 49 );\n\n      // how much should we shift C and D?\n      if ( i==1 || i==2 || i==9 || i == 16 )\n         shift_CD_1( CD );\n      else\n         shift_CD_2( CD );\n      accumulate_bitstring( \"CD[\"+i+\"]: \", CD, 7 );\n\n      // create the actual subkey\n      permute( KS[i], CD, PC_2_perm );\n      accumulate_bitstring( \"KS[\"+i+\"]: \", KS[i], 6 );\n   }\n\n   // handle the initial permutation\n   permute( tempData, inData, IP_perm );\n\n   // split data into L/R parts\n   for( i=1; i<=32; i++ )\n   {\n      L[i] = tempData[i];\n      R[i] = tempData[i+32];\n   }\n   accumulate_bitstring( \"L[0]: \", L, 8 );\n   accumulate_bitstring( \"R[0]: \", R, 8 );\n\n   // encrypting or decrypting?\n   if ( do_encrypt )\n   {\n      // encrypting\n      for( i=1; i<=16; i++ )\n      {\n         accumulate_output( \"Round \" + i );\n         des_round( L, R, KS[i] );\n      }\n   }\n   else\n   {\n      // decrypting\n      for( i=16; i>=1; i-- )\n      {\n         accumulate_output( \"Round \" + (17-i) );\n         des_round( L, R, KS[i] );\n      }\n   }\n\n   // create the 64-bit preoutput block = R16/L16\n   for( i=1; i<=32; i++ )\n   {\n      // copy R bits into left half of block, L bits into right half\n      tempData[i] = R[i];\n      tempData[i+32] = L[i];\n   }\n   accumulate_bitstring (\"LR[16] \", tempData, 8 );\n\n   // do final permutation and return result\n   permute( result, tempData, FP_perm );\n   return result;\n}\n// do encrytion/decryption\n// do_encrypt is TRUE for encrypt, FALSE for decrypt\nfunction do_des( do_encrypt )\n{\n   var inData = new Array( 65 );\t// input message bits\n   var Key = new Array( 65 );\n\n   accumulated_output_info = \"\";\n\n   // get the message from the user\n   // also check if it is ASCII or hex\n   get_value( inData, document.stuff.indata.value,\n\t\tdocument.stuff.intype[0].checked );\n\n   // problems??\n   if ( inData[0] == ERROR_VAL )\n   {\n      document.stuff.details.value = accumulated_output_info;\n      return;\n   }\n   accumulate_bitstring( \"Input bits:\", inData, 8 );\n\n   // get the key from the user\n   get_value( Key, document.stuff.key.value, false );\n   // problems??\n   if ( Key[0] == ERROR_VAL )\n   {\n      document.stuff.details.value = accumulated_output_info;\n      return;\n   }\n   accumulate_bitstring( \"Key bits:\", Key, 8 );\n\n   // do the encryption/decryption, put output in DES_output for display\n   DES_output = des_encrypt( inData, Key, do_encrypt )\n\n   accumulate_bitstring (\"Output \", DES_output, 8 );\n\n   // process output\n   format_DES_output( );\n   document.stuff.details.value = accumulated_output_info;\n}\n\n// do Triple-DES encrytion/decryption\n// do_encrypt is TRUE for encrypt, FALSE for decrypt\nfunction do_tdes( do_encrypt )\n{\n   var inData = new Array( 65 );\t// input message bits\n   var tempdata = new Array( 65 );\t// interm result bits\n   var KeyA = new Array( 65 );\n   var KeyB = new Array( 65 );\n\n   accumulated_output_info = \"\";\n\n   // get the message from the user\n   // also check if it is ASCII or hex\n   get_value( inData, document.stuff.indata.value,\n\t\tdocument.stuff.intype[0].checked );\n\n   // problems??\n   if ( inData[0] == ERROR_VAL )\n   {\n      document.stuff.details.value = accumulated_output_info;\n      return;\n   }\n   accumulate_bitstring( \"Input bits:\", inData, 8 );\n\n   // get the key part A from the user\n   get_value( KeyA, document.stuff.key.value, false );\n   // problems??\n   if ( KeyA[0] == ERROR_VAL )\n   {\n      document.stuff.details.value = accumulated_output_info;\n      return;\n   }\n   accumulate_bitstring( \"Key A bits:\", KeyA, 8 );\n\n\n   // get the key part B from the user\n   get_value( KeyB, document.stuff.keyb.value, false );\n   // problems??\n   if ( KeyB[0] == ERROR_VAL )\n   {\n      document.stuff.details.value = accumulated_output_info;\n      return;\n   }\n   accumulate_bitstring( \"Key B bits:\", KeyB, 8 );\n\n   if ( do_encrypt )\n   {\n      // TDES encrypt = DES encrypt/decrypt/encrypt\n      accumulate_output(\"---- Starting first encryption ----\");\n      tempdata = des_encrypt( inData, KeyA, true );\n      accumulate_output(\"---- Starting second decryption ----\");\n      tempdata = des_encrypt( tempdata, KeyB, false );\n      accumulate_output(\"---- Starting third encryption ----\");\n      DES_output = des_encrypt( tempdata, KeyA, true );\n   }\n   else\n   {\n      // TDES decrypt = DES decrypt/encrypt/decrypt\n      accumulate_output(\"---- Starting first decryption ----\");\n      tempdata = des_encrypt( inData, KeyA, false );\n      accumulate_output(\"---- Starting second encryption ----\");\n      tempdata = des_encrypt( tempdata, KeyB, true );\n      accumulate_output(\"---- Starting third decryption ----\");\n      DES_output = des_encrypt( tempdata, KeyA, false );\n   }\n\n   accumulate_bitstring (\"Output \", DES_output, 8 );\n\n   // process output\n   format_DES_output( );\n   document.stuff.details.value = accumulated_output_info;\n}\n  </script>\n</head>\n<body>\nThe Data Encryption Standard (DES) was introduced in 19xx and\nis formally defined in\n<a href=\"http://csrc.nist.gov/publications/fips/\">FIPS 46-3</a>\nUsing a 56-bit key (usually entered as a 64-bit value with odd parity bits),\nworking on a 64-bit data block.\nThere are several <a href=\"http://people.eku.edu/styere/Encrypt/xxx\">modes</a> for using DES to encrypt blocks of data\nthat may be more (or less) than 8 bytes in size. Click <a href=\"http://people.eku.edu/styere/Encrypt/JS-DES.html#how\">here</a>\nfor more details on how DES works.\n\n<p>\nThe 56-bit key used by DES is no longer sufficient for good security, but\nmany applications use triple-DES\n(encrypt using key part A, decrypt using key part B, encrypt using key part A)\nto acheive a 112-bit key while maintaining compatibility with\nplain DES (using key part A = key part B).\n</p>\n<hr>\n<form name=\"stuff\">\n  <table>\n    <tbody>\n      <tr>\n        <td valign=\"top\">Message</td>\n        <td><input type=\"text\" name=\"indata\" size=\"25\"><br>\n        <input type=\"radio\" name=\"intype\">ASCII\n        <input type=\"radio\" name=\"intype\" checked=\"checked\">Hexadecimal </td>\n      </tr>\n      <tr>\n        <td>DES Key/Triple DES Key Part A</td>\n        <td><input type=\"text\" name=\"key\" value=\"3b3898371520f75e\" readonly=\"\" size=\"25\"></td>\n      </tr>\n      <tr>\n        <td>Triple DES Key Part B</td>\n        <td><input type=\"text\" name=\"keyb\" value=\"922fb510c71f436e\" readonly=\"\" size=\"25\"></td>\n      </tr>\n      <tr>\n        <td colspan=\"2\" align=\"center\">\n            <input type=\"button\" value=\"DES Encrypt\" onclick=\"do_des(true);\">\n            <input type=\"button\" value=\"DES Decrypt\" onclick=\"do_des(false);\"><br>\n            <input type=\"button\" value=\"Triple DES Encrypt\" onclick=\"do_tdes(true);\">\n            <input type=\"button\" value=\"Triple DES Decrypt\" onclick=\"do_tdes(false);\"> </td>\n      </tr>\n      <tr>\n        <td valign=\"top\">Output message</td>\n        <td><input type=\"text\" name=\"outdata\" size=\"20\"><br>\n        <input type=\"radio\" name=\"outtype\" onclick=\"format_DES_output();\">ASCII\n        <input type=\"radio\" name=\"outtype\" checked=\"checked\" onclick=\"format_DES_output();\">\n\t\tHexadecimal\n        </td>\n      </tr>\n    </tbody>\n  </table>\n<i>10/27/06: I have decided to not allow the key to changed to reduce the chance of\nthis page being used to solve homework problems</i>\n  <hr>\nDetails:<br>\n  <textarea name=\"details\" id=\"details\" rows=\"25\" cols=\"90\"></textarea>\n</form>\n<hr>\n<a name=\"#how\">\n<h2>How DES works</h2>\nEncryption starts with an initial permutation of the 64 input bits.  These bits are then\ndivided into two 32-bit halves called L and R.\nThe encryption then proceeds through 16 rounds, each using the existing L and R parts, \nand a </a><a href=\"http://people.eku.edu/styere/Encrypt/JS-DES.html#subkey\">subkey</a>.\nThe R and subkeys are processed in a function <a href=\"http://people.eku.edu/styere/Encrypt/JS-DES.html#ffunc\"><i>f</i></a>, and the\noutput of the <i>f</i> function are exclusive-or'ed with the existing L part to create\nthe new R part.  The new L part is simply a copy of the incoming R part.\nIn the final round, the L and R parts are swapped once more before the final permutation\nproducing the output block.\n<p>\nDecryption is identical to encryption, except that the subkeys are used in the\nopposite order.  That is, subkey 16 is used in round 1, subkey 15 is used in round 2, etc.,\nending with subkey 1 being used in round 16.\n</p><p>\nHere is a diagram of the DES algorithm:<br>\n<img src=\"./JavaScript DES Example_files/DES-gen.GIF\" alt=\"Diagram of DES encryption\" width=\"663\" height=\"783\">\n</p><p>\n<a name=\"ffunc\">\n</a></p><h2><a name=\"ffunc\">The <i>f</i> function</a></h2><a name=\"ffunc\">\nThe <i>f</i> function mixes the bits of the R portion using the\n</a><a href=\"http://people.eku.edu/styere/Encrypt/JS-DES.html#subkey\">subkey</a> for the current round.\nFirst the 32-bit R value is expanded to 48 bits using a permutation E.\nThat value is then exclusive-or'ed with the subkey.  The 48 bits are then divided into\neight 6-bit chunks, each of which is fed into a S-Box that mixes the bits and produces\na 4-bit output.  Those 4-bit outputs are combined into a 32-bit value, and permuted\nonce again to produce the <i>f</i>-function output.\n<p>\n<img src=\"./JavaScript DES Example_files/DES-f.GIF\" alt=\"DES F function\" style=\"width: 538px; height: 366px;\"><br>\n\n<a name=\"subkey\">\n</a></p><h2><a name=\"subkey\">Subkey Generation</a></h2><a name=\"subkey\">\nTo generate the subkeys, start with the 56-bit key (64 bits if you include the parity\nbits).  These are permuted and divided into two halves called C and D.\nFor each round, C and D are each shifted left circularly one or two bits (the number\nof bits depending on the round).  The 48-bit subkey is then selected from the current\nC and D bits.<br>\n<img src=\"./JavaScript DES Example_files/DES-keygen.GIF\" alt=\"DES Key Generation Diagram\" width=\"738\" height=\"623\">\n<p>\n</p><hr>\nReturn to my </a><a href=\"http://people.eku.edu/styere/index.html\">home page</a><br>\nGo to the <a href=\"http://www.computerscience.eku.edu/\">EKU CS Department</a> page\n\n\n<audio controls=\"controls\" style=\"display: none;\"></audio></body><style type=\"text/css\">#yddContainer{display:block;font-family:Microsoft YaHei;position:relative;width:100%;height:100%;top:-4px;left:-4px;font-size:12px;border:1px solid}#yddTop{display:block;height:22px}#yddTopBorderlr{display:block;position:static;height:17px;padding:2px 28px;line-height:17px;font-size:12px;color:#5079bb;font-weight:bold;border-style:none solid;border-width:1px}#yddTopBorderlr .ydd-sp{position:absolute;top:2px;height:0;overflow:hidden}.ydd-icon{left:5px;width:17px;padding:0px 0px 0px 0px;padding-top:17px;background-position:-16px -44px}.ydd-close{right:5px;width:16px;padding-top:16px;background-position:left -44px}#yddKeyTitle{float:left;text-decoration:none}#yddMiddle{display:block;margin-bottom:10px}.ydd-tabs{display:block;margin:5px 0;padding:0 5px;height:18px;border-bottom:1px solid}.ydd-tab{display:block;float:left;height:18px;margin:0 5px -1px 0;padding:0 4px;line-height:18px;border:1px solid;border-bottom:none}.ydd-trans-container{display:block;line-height:160%}.ydd-trans-container a{text-decoration:none;}#yddBottom{position:absolute;bottom:0;left:0;width:100%;height:22px;line-height:22px;overflow:hidden;background-position:left -22px}.ydd-padding010{padding:0 10px}#yddWrapper{color:#252525;z-index:10001;background:url(chrome-extension://eopjamdnofihpioajgfdikhhbobonhbb/ab20.png);}#yddContainer{background:#fff;border-color:#4b7598}#yddTopBorderlr{border-color:#f0f8fc}#yddWrapper .ydd-sp{background-image:url(chrome-extension://eopjamdnofihpioajgfdikhhbobonhbb/ydd-sprite.png)}#yddWrapper a,#yddWrapper a:hover,#yddWrapper a:visited{color:#50799b}#yddWrapper .ydd-tabs{color:#959595}.ydd-tabs,.ydd-tab{background:#fff;border-color:#d5e7f3}#yddBottom{color:#363636}#yddWrapper{min-width:250px;max-width:400px;}</style></html>"
  },
  {
    "path": "JavaScript/js/sm4.js",
    "content": "/*! sm4-1.0.js (c) Windard Yang | https://www.windard.com/\n */\n/*\n * sm4-1.0.js\n * \n * Copyright (c) 2014 Windard Yang (www.windard.com)\n */\n/**\n * @fileOverview\n * @name sm4-1.0.js\n * @author Windard (www.windard.com)\n * @version 1.0.0 (2016-11-17)\n */\n\n/* this is sm4 in javascript by windard , today is 2016 11-17 , \n *I'm afraid that can I finished this project , but after all \n *in December, everything will be done , that's prefect\n */\n\n/*\n * garbage , rubbish programe language, should havn't big decimal number\n * can't circular bitwise left shift, can do xor well\n */\n\n/*\n * fuck it at all , finally finished it , and there has many other works need to do\n *\n */\n\n\nvar SboxTable = new Array();\nSboxTable[ 0] = new Array(0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05);\nSboxTable[ 1] = new Array(0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99);\nSboxTable[ 2] = new Array(0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62);\nSboxTable[ 3] = new Array(0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6);\nSboxTable[ 4] = new Array(0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8);\nSboxTable[ 5] = new Array(0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35);\nSboxTable[ 6] = new Array(0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87);\nSboxTable[ 7] = new Array(0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e);\nSboxTable[ 8] = new Array(0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1);\nSboxTable[ 9] = new Array(0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3);\nSboxTable[10] = new Array(0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f);\nSboxTable[11] = new Array(0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51);\nSboxTable[12] = new Array(0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8);\nSboxTable[13] = new Array(0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0);\nSboxTable[14] = new Array(0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84);\nSboxTable[15] = new Array(0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48);\n\nvar CK = new Array(\n0x00070e15,0x1c232a31,0x383f464d,0x545b6269,\n0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9,\n0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249,\n0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9,\n0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229,\n0x30373e45,0x4c535a61,0x686f767d,0x848b9299,\n0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209,\n0x10171e25,0x2c333a41,0x484f565d,0x646b7279\n);\n\nvar FK = new Array(0xa3b1bac6,0x56aa3350,0x677d9197,0xb27022dc);\n\n// function bigxor(a, b) {\n// \tif (a.toString(2).length < 33 && b.toString(2).length < 33){\t\t\n// \t\treturn a ^ b\n// \t}\n// \tvar abin = a.toString(2);\n// \tvar bbin = b.toString(2);\n// \tvar loggest = abin.length >= bbin.length ? abin.length : bbin.length;\n// \tabin = abin.length == loggest ? abin :\"0\".repeat(loggest - abin.length) + abin;\n// \tbbin = bbin.length == loggest ? bbin :\"0\".repeat(loggest - bbin.length) + bbin;\n// \tvar result = \"\";\n// \tfor (var i = loggest - 1; i >= 0; i--) {\n// \t\tresult = abin[i] == bbin[i] ? '0'+result : '1'+result; \n// \t};\n// \treturn parseInt(result, 2);\n// }\n\nfunction bigxor(a, b){\n\treturn a ^ b\n}\n\n// function leftshift(a, n, size=32) {\n// \tvar result = new Array(size);\n// \tresult.fill(0);\n// \tvar bin = a.toString(2);\n// \tbin = bin.length == size ? bin :\"0\".repeat(size - bin.length) + bin;\n// \tfor (var i = bin.length - 1; i >= 0; i--) {\n// \t\tresult[(i - n + size)%size] = bin[i];\n// \t};\n// \tresult = result.join(\"\");\n// \treturn parseInt(result, 2);\n// }\n\nfunction leftshift(a, n, size=32) {\n\tn = n % size\n\treturn (a << n) | (a >>> (size - n))\n}\n\nfunction prefixInteger(str, length) {\n  return Array(length+1).join(\"0\").split(\"\").concat(String(str).split(\"\"))\n           .slice(-length).join(\"\");\n}\n\n// function sm4Sbox(a) {\n// \tvar a1 = prefixInteger(a.toString(16),8).slice(0,2);\n// \tvar a2 = prefixInteger(a.toString(16),8).slice(2,4);\n// \tvar a3 = prefixInteger(a.toString(16),8).slice(4,6);\n// \tvar a4 = prefixInteger(a.toString(16),8).slice(6,8);\n// \tvar b1 = SboxTable[parseInt(a1[0], 16)][parseInt(a1[1], 16)];\n// \tvar b2 = SboxTable[parseInt(a2[0], 16)][parseInt(a2[1], 16)];\n// \tvar b3 = SboxTable[parseInt(a3[0], 16)][parseInt(a3[1], 16)];\n// \tvar b4 = SboxTable[parseInt(a4[0], 16)][parseInt(a4[1], 16)];\n// \treturn parseInt(prefixInteger(b1.toString(16), 2) + prefixInteger(b2.toString(16), 2) + prefixInteger(b3.toString(16), 2) + prefixInteger(b4.toString(16), 2) , 16)\n// }\n\nfunction sm4Sbox(a) {\n\tvar b1 = SboxTable[(a & 0xf0000000) >>> 28][(a & 0x0f000000) >>> 24]\n\tvar b2 = SboxTable[(a & 0x00f00000) >>> 20][(a & 0x000f0000) >>> 16]\n\tvar b3 = SboxTable[(a & 0x0000f000) >>> 12][(a & 0x00000f00) >>>  8]\n\tvar b4 = SboxTable[(a & 0x000000f0) >>>  4][(a & 0x0000000f) >>>  0]\n\treturn (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4 << 0)\n}\n\nfunction GET_ULONG_BE (a) {\n\ta = sm4Sbox(a)\n\treturn bigxor(bigxor(bigxor(a, leftshift(a, 2)), bigxor(leftshift(a, 10), leftshift(a, 18))), leftshift(a, 24))\n}\n\nfunction PUT_ULONG_BE(b) {\n\tb = sm4Sbox(b)\n\treturn bigxor(b, bigxor(leftshift(b, 13), leftshift(b, 23)));\n}\n\nfunction sm4_getkey (MK) {\n\tvar  K = new Array();\n\tvar rk = new Array();\n\tK[0] = bigxor(MK[0], FK[0]);\n\tK[1] = bigxor(MK[1], FK[1]);\n\tK[2] = bigxor(MK[2], FK[2]);\n\tK[3] = bigxor(MK[3], FK[3]);\n\n\tfor (var i = 0; i < 32; i++) {\n\t\tK[i+4] = bigxor(K[i], PUT_ULONG_BE(bigxor(bigxor(K[i+1], K[i+2]), bigxor(K[i+3], CK[i]))));\n\t\trk[i] = K[i+4].toString(16);\n\t};\n\treturn rk;\n}\n\nfunction KJUR_encrypt_sm4 (messsage, key, method=\"cbc\") {\n\tvar MK = key;\n\tvar X = messsage;\n\tvar rk = sm4_getkey(MK);\n\tfor (var i = 0; i < 32; i++) {\n\t\tX[i+4] = bigxor(X[i], GET_ULONG_BE(bigxor(bigxor(X[i+1], X[i+2]), bigxor(X[i+3], parseInt(rk[i], 16)))))\n\t};\n\tvar Y = new Array(X[35].toString(16), X[34].toString(16), X[33].toString(16), X[32].toString(16))\n\treturn Y;\n}\n\nfunction KJUR_decrypt_sm4 (ciphertext, key, method=\"cbc\") {\n\tvar MK = key;\n\tvar X = ciphertext;\n\tvar frk = sm4_getkey(MK);\n\tvar rk = new Array()\n\tfor (var i = frk.length - 1; i >= 0; i--) {\n\t\trk[frk.length - 1 - i] = frk[i]\n\t};\n\tfor (var i = 0; i < 32; i++) {\n\t\tX[i+4] = bigxor(X[i], GET_ULONG_BE(bigxor(bigxor(X[i+1], X[i+2]), bigxor(X[i+3], parseInt(rk[i], 16)))))\n\t};\n\tvar Y = new Array(X[35].toString(16), X[34].toString(16), X[33].toString(16), X[32].toString(16))\n\treturn Y;\n}\n\n\n"
  },
  {
    "path": "JavaScript/sm2/js/asn1-1.0.js",
    "content": "/*! asn1-1.0.4.js (c) 2013 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n/*\n * asn1.js - ASN.1 DER encoder classes\n *\n * Copyright (c) 2013 Kenji Urushima (kenji.urushima@gmail.com)\n *\n * This software is licensed under the terms of the MIT License.\n * http://kjur.github.com/jsrsasign/license\n *\n * The above copyright and license notice shall be \n * included in all copies or substantial portions of the Software.\n */\n\n/**\n * @fileOverview\n * @name asn1-1.0.js\n * @author Kenji Urushima kenji.urushima@gmail.com\n * @version asn1 1.0.4 (2013-Oct-02)\n * @since jsrsasign 2.1\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\n */\n\n/** \n * kjur's class library name space\n * <p>\n * This name space provides following name spaces:\n * <ul>\n * <li>{@link KJUR.asn1} - ASN.1 primitive hexadecimal encoder</li>\n * <li>{@link KJUR.asn1.x509} - ASN.1 structure for X.509 certificate and CRL</li>\n * <li>{@link KJUR.crypto} - Java Cryptographic Extension(JCE) style MessageDigest/Signature \n * class and utilities</li>\n * </ul>\n * </p> \n * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.\n  * @name KJUR\n * @namespace kjur's class library name space\n */\nif (typeof KJUR == \"undefined\" || !KJUR) KJUR = {};\n\n/**\n * kjur's ASN.1 class library name space\n * <p>\n * This is ITU-T X.690 ASN.1 DER encoder class library and\n * class structure and methods is very similar to \n * org.bouncycastle.asn1 package of \n * well known BouncyCaslte Cryptography Library.\n *\n * <h4>PROVIDING ASN.1 PRIMITIVES</h4>\n * Here are ASN.1 DER primitive classes.\n * <ul>\n * <li>0x01 {@link KJUR.asn1.DERBoolean}</li>\n * <li>0x02 {@link KJUR.asn1.DERInteger}</li>\n * <li>0x03 {@link KJUR.asn1.DERBitString}</li>\n * <li>0x04 {@link KJUR.asn1.DEROctetString}</li>\n * <li>0x05 {@link KJUR.asn1.DERNull}</li>\n * <li>0x06 {@link KJUR.asn1.DERObjectIdentifier}</li>\n * <li>0x0c {@link KJUR.asn1.DERUTF8String}</li>\n * <li>0x12 {@link KJUR.asn1.DERNumericString}</li>\n * <li>0x13 {@link KJUR.asn1.DERPrintableString}</li>\n * <li>0x14 {@link KJUR.asn1.DERTeletexString}</li>\n * <li>0x16 {@link KJUR.asn1.DERIA5String}</li>\n * <li>0x17 {@link KJUR.asn1.DERUTCTime}</li>\n * <li>0x18 {@link KJUR.asn1.DERGeneralizedTime}</li>\n * <li>0x30 {@link KJUR.asn1.DERSequence}</li>\n * <li>0x31 {@link KJUR.asn1.DERSet}</li>\n * </ul>\n *\n * <h4>OTHER ASN.1 CLASSES</h4>\n * <ul>\n * <li>{@link KJUR.asn1.ASN1Object}</li>\n * <li>{@link KJUR.asn1.DERAbstractString}</li>\n * <li>{@link KJUR.asn1.DERAbstractTime}</li>\n * <li>{@link KJUR.asn1.DERAbstractStructured}</li>\n * <li>{@link KJUR.asn1.DERTaggedObject}</li>\n * </ul>\n * </p>\n * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.\n * @name KJUR.asn1\n * @namespace\n */\nif (typeof KJUR.asn1 == \"undefined\" || !KJUR.asn1) KJUR.asn1 = {};\n\n/**\n * ASN1 utilities class\n * @name KJUR.asn1.ASN1Util\n * @class ASN1 utilities class\n * @since asn1 1.0.2\n */\nKJUR.asn1.ASN1Util = new function() {\n    this.integerToByteHex = function(i) {\n\tvar h = i.toString(16);\n\tif ((h.length % 2) == 1) h = '0' + h;\n\treturn h;\n    };\n    this.bigIntToMinTwosComplementsHex = function(bigIntegerValue) {\n\tvar h = bigIntegerValue.toString(16);\n\tif (h.substr(0, 1) != '-') {\n\t    if (h.length % 2 == 1) {\n\t\th = '0' + h;\n\t    } else {\n\t\tif (! h.match(/^[0-7]/)) {\n\t\t    h = '00' + h;\n\t\t}\n\t    }\n\t} else {\n\t    var hPos = h.substr(1);\n\t    var xorLen = hPos.length;\n\t    if (xorLen % 2 == 1) {\n\t\txorLen += 1;\n\t    } else {\n\t\tif (! h.match(/^[0-7]/)) {\n\t\t    xorLen += 2;\n\t\t}\n\t    }\n\t    var hMask = '';\n\t    for (var i = 0; i < xorLen; i++) {\n\t\thMask += 'f';\n\t    }\n\t    var biMask = new BigInteger(hMask, 16);\n\t    var biNeg = biMask.xor(bigIntegerValue).add(BigInteger.ONE);\n\t    h = biNeg.toString(16).replace(/^-/, '');\n\t}\n\treturn h;\n    };\n    /**\n     * get PEM string from hexadecimal data and header string\n     * @name getPEMStringFromHex\n     * @memberOf KJUR.asn1.ASN1Util\n     * @function\n     * @param {String} dataHex hexadecimal string of PEM body\n     * @param {String} pemHeader PEM header string (ex. 'RSA PRIVATE KEY')\n     * @return {String} PEM formatted string of input data\n     * @description\n     * @example\n     * var pem  = KJUR.asn1.ASN1Util.getPEMStringFromHex('616161', 'RSA PRIVATE KEY');\n     * // value of pem will be:\n     * -----BEGIN PRIVATE KEY-----\n     * YWFh\n     * -----END PRIVATE KEY-----\n     */\n    this.getPEMStringFromHex = function(dataHex, pemHeader) {\n\tvar ns1 = KJUR.asn1;\n\tvar dataWA = CryptoJS.enc.Hex.parse(dataHex);\n\tvar dataB64 = CryptoJS.enc.Base64.stringify(dataWA);\n\tvar pemBody = dataB64.replace(/(.{64})/g, \"$1\\r\\n\");\n        pemBody = pemBody.replace(/\\r\\n$/, '');\n\treturn \"-----BEGIN \" + pemHeader + \"-----\\r\\n\" + \n               pemBody + \n               \"\\r\\n-----END \" + pemHeader + \"-----\\r\\n\";\n    };\n\n    /**\n     * generate ASN1Object specifed by JSON parameters\n     * @name newObject\n     * @memberOf KJUR.asn1.ASN1Util\n     * @function\n     * @param {Array} param JSON parameter to generate ASN1Object\n     * @return {KJUR.asn1.ASN1Object} generated object\n     * @since asn1 1.0.3\n     * @description\n     * generate any ASN1Object specified by JSON param\n     * including ASN.1 primitive or structured.\n     * Generally 'param' can be described as follows:\n     * <blockquote>\n     * {TYPE-OF-ASNOBJ: ASN1OBJ-PARAMETER}\n     * </blockquote>\n     * 'TYPE-OF-ASN1OBJ' can be one of following symbols:\n     * <ul>\n     * <li>'bool' - DERBoolean</li>\n     * <li>'int' - DERInteger</li>\n     * <li>'bitstr' - DERBitString</li>\n     * <li>'octstr' - DEROctetString</li>\n     * <li>'null' - DERNull</li>\n     * <li>'oid' - DERObjectIdentifier</li>\n     * <li>'utf8str' - DERUTF8String</li>\n     * <li>'numstr' - DERNumericString</li>\n     * <li>'prnstr' - DERPrintableString</li>\n     * <li>'telstr' - DERTeletexString</li>\n     * <li>'ia5str' - DERIA5String</li>\n     * <li>'utctime' - DERUTCTime</li>\n     * <li>'gentime' - DERGeneralizedTime</li>\n     * <li>'seq' - DERSequence</li>\n     * <li>'set' - DERSet</li>\n     * <li>'tag' - DERTaggedObject</li>\n     * </ul>\n     * @example\n     * newObject({'prnstr': 'aaa'});\n     * newObject({'seq': [{'int': 3}, {'prnstr': 'aaa'}]})\n     * // ASN.1 Tagged Object\n     * newObject({'tag': {'tag': 'a1', \n     *                    'explicit': true,\n     *                    'obj': {'seq': [{'int': 3}, {'prnstr': 'aaa'}]}}});\n     * // more simple representation of ASN.1 Tagged Object\n     * newObject({'tag': ['a1',\n     *                    true,\n     *                    {'seq': [\n     *                      {'int': 3}, \n     *                      {'prnstr': 'aaa'}]}\n     *                   ]});\n     */\n    this.newObject = function(param) {\n\tvar ns1 = KJUR.asn1;\n\tvar keys = Object.keys(param);\n\tif (keys.length != 1)\n\t    throw \"key of param shall be only one.\";\n\tvar key = keys[0];\n\n\tif (\":bool:int:bitstr:octstr:null:oid:utf8str:numstr:prnstr:telstr:ia5str:utctime:gentime:seq:set:tag:\".indexOf(\":\" + key + \":\") == -1)\n\t    throw \"undefined key: \" + key;\n\n\tif (key == \"bool\")    return new ns1.DERBoolean(param[key]);\n\tif (key == \"int\")     return new ns1.DERInteger(param[key]);\n\tif (key == \"bitstr\")  return new ns1.DERBitString(param[key]);\n\tif (key == \"octstr\")  return new ns1.DEROctetString(param[key]);\n\tif (key == \"null\")    return new ns1.DERNull(param[key]);\n\tif (key == \"oid\")     return new ns1.DERObjectIdentifier(param[key]);\n\tif (key == \"utf8str\") return new ns1.DERUTF8String(param[key]);\n\tif (key == \"numstr\")  return new ns1.DERNumericString(param[key]);\n\tif (key == \"prnstr\")  return new ns1.DERPrintableString(param[key]);\n\tif (key == \"telstr\")  return new ns1.DERTeletexString(param[key]);\n\tif (key == \"ia5str\")  return new ns1.DERIA5String(param[key]);\n\tif (key == \"utctime\") return new ns1.DERUTCTime(param[key]);\n\tif (key == \"gentime\") return new ns1.DERGeneralizedTime(param[key]);\n\n\tif (key == \"seq\") {\n\t    var paramList = param[key];\n\t    var a = [];\n\t    for (var i = 0; i < paramList.length; i++) {\n\t\tvar asn1Obj = ns1.ASN1Util.newObject(paramList[i]);\n\t\ta.push(asn1Obj);\n\t    }\n\t    return new ns1.DERSequence({'array': a});\n\t}\n\n\tif (key == \"set\") {\n\t    var paramList = param[key];\n\t    var a = [];\n\t    for (var i = 0; i < paramList.length; i++) {\n\t\tvar asn1Obj = ns1.ASN1Util.newObject(paramList[i]);\n\t\ta.push(asn1Obj);\n\t    }\n\t    return new ns1.DERSet({'array': a});\n\t}\n\n\tif (key == \"tag\") {\n\t    var tagParam = param[key];\n\t    if (Object.prototype.toString.call(tagParam) === '[object Array]' &&\n\t\ttagParam.length == 3) {\n\t\tvar obj = ns1.ASN1Util.newObject(tagParam[2]);\n\t\treturn new ns1.DERTaggedObject({tag: tagParam[0], explicit: tagParam[1], obj: obj});\n\t    } else {\n\t\tvar newParam = {};\n\t\tif (tagParam.explicit !== undefined)\n\t\t    newParam.explicit = tagParam.explicit;\n\t\tif (tagParam.tag !== undefined)\n\t\t    newParam.tag = tagParam.tag;\n\t\tif (tagParam.obj === undefined)\n\t\t    throw \"obj shall be specified for 'tag'.\";\n\t\tnewParam.obj = ns1.ASN1Util.newObject(tagParam.obj);\n\t\treturn new ns1.DERTaggedObject(newParam);\n\t    }\n\t}\n    };\n\n    /**\n     * get encoded hexadecimal string of ASN1Object specifed by JSON parameters\n     * @name jsonToASN1HEX\n     * @memberOf KJUR.asn1.ASN1Util\n     * @function\n     * @param {Array} param JSON parameter to generate ASN1Object\n     * @return hexadecimal string of ASN1Object\n     * @since asn1 1.0.4\n     * @description\n     * As for ASN.1 object representation of JSON object,\n     * please see {@link newObject}.\n     * @example\n     * jsonToASN1HEX({'prnstr': 'aaa'}); \n     */\n    this.jsonToASN1HEX = function(param) {\n\tvar asn1Obj = this.newObject(param);\n\treturn asn1Obj.getEncodedHex();\n    };\n};\n\n// ********************************************************************\n//  Abstract ASN.1 Classes\n// ********************************************************************\n\n// ********************************************************************\n\n/**\n * base class for ASN.1 DER encoder object\n * @name KJUR.asn1.ASN1Object\n * @class base class for ASN.1 DER encoder object\n * @property {Boolean} isModified flag whether internal data was changed\n * @property {String} hTLV hexadecimal string of ASN.1 TLV\n * @property {String} hT hexadecimal string of ASN.1 TLV tag(T)\n * @property {String} hL hexadecimal string of ASN.1 TLV length(L)\n * @property {String} hV hexadecimal string of ASN.1 TLV value(V)\n * @description\n */\nKJUR.asn1.ASN1Object = function() {\n    var isModified = true;\n    var hTLV = null;\n    var hT = '00';\n    var hL = '00';\n    var hV = '';\n\n    /**\n     * get hexadecimal ASN.1 TLV length(L) bytes from TLV value(V)\n     * @name getLengthHexFromValue\n     * @memberOf KJUR.asn1.ASN1Object\n     * @function\n     * @return {String} hexadecimal string of ASN.1 TLV length(L)\n     */\n    this.getLengthHexFromValue = function() {\n\tif (typeof this.hV == \"undefined\" || this.hV == null) {\n\t    throw \"this.hV is null or undefined.\";\n\t}\n\tif (this.hV.length % 2 == 1) {\n\t    throw \"value hex must be even length: n=\" + hV.length + \",v=\" + this.hV;\n\t}\n\tvar n = this.hV.length / 2;\n\tvar hN = n.toString(16);\n\tif (hN.length % 2 == 1) {\n\t    hN = \"0\" + hN;\n\t}\n\tif (n < 128) {\n\t    return hN;\n\t} else {\n\t    var hNlen = hN.length / 2;\n\t    if (hNlen > 15) {\n\t\tthrow \"ASN.1 length too long to represent by 8x: n = \" + n.toString(16);\n\t    }\n\t    var head = 128 + hNlen;\n\t    return head.toString(16) + hN;\n\t}\n    };\n\n    /**\n     * get hexadecimal string of ASN.1 TLV bytes\n     * @name getEncodedHex\n     * @memberOf KJUR.asn1.ASN1Object\n     * @function\n     * @return {String} hexadecimal string of ASN.1 TLV\n     */\n    this.getEncodedHex = function() {\n\tif (this.hTLV == null || this.isModified) {\n\t    this.hV = this.getFreshValueHex();\n\t    this.hL = this.getLengthHexFromValue();\n\t    this.hTLV = this.hT + this.hL + this.hV;\n\t    this.isModified = false;\n\t    //alert(\"first time: \" + this.hTLV);\n\t}\n\treturn this.hTLV;\n    };\n\n    /**\n     * get hexadecimal string of ASN.1 TLV value(V) bytes\n     * @name getValueHex\n     * @memberOf KJUR.asn1.ASN1Object\n     * @function\n     * @return {String} hexadecimal string of ASN.1 TLV value(V) bytes\n     */\n    this.getValueHex = function() {\n\tthis.getEncodedHex();\n\treturn this.hV;\n    }\n\n    this.getFreshValueHex = function() {\n\treturn '';\n    };\n};\n\n// == BEGIN DERAbstractString ================================================\n/**\n * base class for ASN.1 DER string classes\n * @name KJUR.asn1.DERAbstractString\n * @class base class for ASN.1 DER string classes\n * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})\n * @property {String} s internal string of value\n * @extends KJUR.asn1.ASN1Object\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>str - specify initial ASN.1 value(V) by a string</li>\n * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n */\nKJUR.asn1.DERAbstractString = function(params) {\n    KJUR.asn1.DERAbstractString.superclass.constructor.call(this);\n    var s = null;\n    var hV = null;\n\n    /**\n     * get string value of this string object\n     * @name getString\n     * @memberOf KJUR.asn1.DERAbstractString\n     * @function\n     * @return {String} string value of this string object\n     */\n    this.getString = function() {\n\treturn this.s;\n    };\n\n    /**\n     * set value by a string\n     * @name setString\n     * @memberOf KJUR.asn1.DERAbstractString\n     * @function\n     * @param {String} newS value by a string to set\n     */\n    this.setString = function(newS) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.s = newS;\n\tthis.hV = stohex(this.s);\n    };\n\n    /**\n     * set value by a hexadecimal string\n     * @name setStringHex\n     * @memberOf KJUR.asn1.DERAbstractString\n     * @function\n     * @param {String} newHexString value by a hexadecimal string to set\n     */\n    this.setStringHex = function(newHexString) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.s = null;\n\tthis.hV = newHexString;\n    };\n\n    this.getFreshValueHex = function() {\n\treturn this.hV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params == \"string\") {\n\t    this.setString(params);\n\t} else if (typeof params['str'] != \"undefined\") {\n\t    this.setString(params['str']);\n\t} else if (typeof params['hex'] != \"undefined\") {\n\t    this.setStringHex(params['hex']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.DERAbstractString, KJUR.asn1.ASN1Object);\n// == END   DERAbstractString ================================================\n\n// == BEGIN DERAbstractTime ==================================================\n/**\n * base class for ASN.1 DER Generalized/UTCTime class\n * @name KJUR.asn1.DERAbstractTime\n * @class base class for ASN.1 DER Generalized/UTCTime class\n * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @see KJUR.asn1.ASN1Object - superclass\n */\nKJUR.asn1.DERAbstractTime = function(params) {\n    KJUR.asn1.DERAbstractTime.superclass.constructor.call(this);\n    var s = null;\n    var date = null;\n\n    // --- PRIVATE METHODS --------------------\n    this.localDateToUTC = function(d) {\n\tutc = d.getTime() + (d.getTimezoneOffset() * 60000);\n\tvar utcDate = new Date(utc);\n\treturn utcDate;\n    };\n\n    this.formatDate = function(dateObject, type) {\n\tvar pad = this.zeroPadding;\n\tvar d = this.localDateToUTC(dateObject);\n\tvar year = String(d.getFullYear());\n\tif (type == 'utc') year = year.substr(2, 2);\n\tvar month = pad(String(d.getMonth() + 1), 2);\n\tvar day = pad(String(d.getDate()), 2);\n\tvar hour = pad(String(d.getHours()), 2);\n\tvar min = pad(String(d.getMinutes()), 2);\n\tvar sec = pad(String(d.getSeconds()), 2);\n\treturn year + month + day + hour + min + sec + 'Z';\n    };\n\n    this.zeroPadding = function(s, len) {\n\tif (s.length >= len) return s;\n\treturn new Array(len - s.length + 1).join('0') + s;\n    };\n\n    // --- PUBLIC METHODS --------------------\n    /**\n     * get string value of this string object\n     * @name getString\n     * @memberOf KJUR.asn1.DERAbstractTime\n     * @function\n     * @return {String} string value of this time object\n     */\n    this.getString = function() {\n\treturn this.s;\n    };\n\n    /**\n     * set value by a string\n     * @name setString\n     * @memberOf KJUR.asn1.DERAbstractTime\n     * @function\n     * @param {String} newS value by a string to set such like \"130430235959Z\"\n     */\n    this.setString = function(newS) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.s = newS;\n\tthis.hV = stohex(newS);\n    };\n\n    /**\n     * set value by a Date object\n     * @name setByDateValue\n     * @memberOf KJUR.asn1.DERAbstractTime\n     * @function\n     * @param {Integer} year year of date (ex. 2013)\n     * @param {Integer} month month of date between 1 and 12 (ex. 12)\n     * @param {Integer} day day of month\n     * @param {Integer} hour hours of date\n     * @param {Integer} min minutes of date\n     * @param {Integer} sec seconds of date\n     */\n    this.setByDateValue = function(year, month, day, hour, min, sec) {\n\tvar dateObject = new Date(Date.UTC(year, month - 1, day, hour, min, sec, 0));\n\tthis.setByDate(dateObject);\n    };\n\n    this.getFreshValueHex = function() {\n\treturn this.hV;\n    };\n};\nYAHOO.lang.extend(KJUR.asn1.DERAbstractTime, KJUR.asn1.ASN1Object);\n// == END   DERAbstractTime ==================================================\n\n// == BEGIN DERAbstractStructured ============================================\n/**\n * base class for ASN.1 DER structured class\n * @name KJUR.asn1.DERAbstractStructured\n * @class base class for ASN.1 DER structured class\n * @property {Array} asn1Array internal array of ASN1Object\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @see KJUR.asn1.ASN1Object - superclass\n */\nKJUR.asn1.DERAbstractStructured = function(params) {\n    KJUR.asn1.DERAbstractString.superclass.constructor.call(this);\n    var asn1Array = null;\n\n    /**\n     * set value by array of ASN1Object\n     * @name setByASN1ObjectArray\n     * @memberOf KJUR.asn1.DERAbstractStructured\n     * @function\n     * @param {array} asn1ObjectArray array of ASN1Object to set\n     */\n    this.setByASN1ObjectArray = function(asn1ObjectArray) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.asn1Array = asn1ObjectArray;\n    };\n\n    /**\n     * append an ASN1Object to internal array\n     * @name appendASN1Object\n     * @memberOf KJUR.asn1.DERAbstractStructured\n     * @function\n     * @param {ASN1Object} asn1Object to add\n     */\n    this.appendASN1Object = function(asn1Object) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.asn1Array.push(asn1Object);\n    };\n\n    this.asn1Array = new Array();\n    if (typeof params != \"undefined\") {\n\tif (typeof params['array'] != \"undefined\") {\n\t    this.asn1Array = params['array'];\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.DERAbstractStructured, KJUR.asn1.ASN1Object);\n\n\n// ********************************************************************\n//  ASN.1 Object Classes\n// ********************************************************************\n\n// ********************************************************************\n/**\n * class for ASN.1 DER Boolean\n * @name KJUR.asn1.DERBoolean\n * @class class for ASN.1 DER Boolean\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @see KJUR.asn1.ASN1Object - superclass\n */\nKJUR.asn1.DERBoolean = function() {\n    KJUR.asn1.DERBoolean.superclass.constructor.call(this);\n    this.hT = \"01\";\n    this.hTLV = \"0101ff\";\n};\nYAHOO.lang.extend(KJUR.asn1.DERBoolean, KJUR.asn1.ASN1Object);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER Integer\n * @name KJUR.asn1.DERInteger\n * @class class for ASN.1 DER Integer\n * @extends KJUR.asn1.ASN1Object\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>int - specify initial ASN.1 value(V) by integer value</li>\n * <li>bigint - specify initial ASN.1 value(V) by BigInteger object</li>\n * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n */\nKJUR.asn1.DERInteger = function(params) {\n    KJUR.asn1.DERInteger.superclass.constructor.call(this);\n    this.hT = \"02\";\n\n    /**\n     * set value by Tom Wu's BigInteger object\n     * @name setByBigInteger\n     * @memberOf KJUR.asn1.DERInteger\n     * @function\n     * @param {BigInteger} bigIntegerValue to set\n     */\n    this.setByBigInteger = function(bigIntegerValue) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue);\n    };\n\n    /**\n     * set value by integer value\n     * @name setByInteger\n     * @memberOf KJUR.asn1.DERInteger\n     * @function\n     * @param {Integer} integer value to set\n     */\n    this.setByInteger = function(intValue) {\n\tvar bi = new BigInteger(String(intValue), 10);\n\tthis.setByBigInteger(bi);\n    };\n\n    /**\n     * set value by integer value\n     * @name setValueHex\n     * @memberOf KJUR.asn1.DERInteger\n     * @function\n     * @param {String} hexadecimal string of integer value\n     * @description\n     * <br/>\n     * NOTE: Value shall be represented by minimum octet length of\n     * two's complement representation.\n     * @example\n     * new KJUR.asn1.DERInteger(123);\n     * new KJUR.asn1.DERInteger({'int': 123});\n     * new KJUR.asn1.DERInteger({'hex': '1fad'});\n     */\n    this.setValueHex = function(newHexString) {\n\tthis.hV = newHexString;\n    };\n\n    this.getFreshValueHex = function() {\n\treturn this.hV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['bigint'] != \"undefined\") {\n\t    this.setByBigInteger(params['bigint']);\n\t} else if (typeof params['int'] != \"undefined\") {\n\t    this.setByInteger(params['int']);\n\t} else if (typeof params == \"number\") {\n\t    this.setByInteger(params);\n\t} else if (typeof params['hex'] != \"undefined\") {\n\t    this.setValueHex(params['hex']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.DERInteger, KJUR.asn1.ASN1Object);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER encoded BitString primitive\n * @name KJUR.asn1.DERBitString\n * @class class for ASN.1 DER encoded BitString primitive\n * @extends KJUR.asn1.ASN1Object\n * @description \n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>bin - specify binary string (ex. '10111')</li>\n * <li>array - specify array of boolean (ex. [true,false,true,true])</li>\n * <li>hex - specify hexadecimal string of ASN.1 value(V) including unused bits</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n */\nKJUR.asn1.DERBitString = function(params) {\n    KJUR.asn1.DERBitString.superclass.constructor.call(this);\n    this.hT = \"03\";\n\n    /**\n     * set ASN.1 value(V) by a hexadecimal string including unused bits\n     * @name setHexValueIncludingUnusedBits\n     * @memberOf KJUR.asn1.DERBitString\n     * @function\n     * @param {String} newHexStringIncludingUnusedBits\n     */\n    this.setHexValueIncludingUnusedBits = function(newHexStringIncludingUnusedBits) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.hV = newHexStringIncludingUnusedBits;\n    };\n\n    /**\n     * set ASN.1 value(V) by unused bit and hexadecimal string of value\n     * @name setUnusedBitsAndHexValue\n     * @memberOf KJUR.asn1.DERBitString\n     * @function\n     * @param {Integer} unusedBits\n     * @param {String} hValue\n     */\n    this.setUnusedBitsAndHexValue = function(unusedBits, hValue) {\n\tif (unusedBits < 0 || 7 < unusedBits) {\n\t    throw \"unused bits shall be from 0 to 7: u = \" + unusedBits;\n\t}\n\tvar hUnusedBits = \"0\" + unusedBits;\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.hV = hUnusedBits + hValue;\n    };\n\n    /**\n     * set ASN.1 DER BitString by binary string\n     * @name setByBinaryString\n     * @memberOf KJUR.asn1.DERBitString\n     * @function\n     * @param {String} binaryString binary value string (i.e. '10111')\n     * @description\n     * Its unused bits will be calculated automatically by length of \n     * 'binaryValue'. <br/>\n     * NOTE: Trailing zeros '0' will be ignored.\n     */\n    this.setByBinaryString = function(binaryString) {\n\tbinaryString = binaryString.replace(/0+$/, '');\n\tvar unusedBits = 8 - binaryString.length % 8;\n\tif (unusedBits == 8) unusedBits = 0;\n\tfor (var i = 0; i <= unusedBits; i++) {\n\t    binaryString += '0';\n\t}\n\tvar h = '';\n\tfor (var i = 0; i < binaryString.length - 1; i += 8) {\n\t    var b = binaryString.substr(i, 8);\n\t    var x = parseInt(b, 2).toString(16);\n\t    if (x.length == 1) x = '0' + x;\n\t    h += x;  \n\t}\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.hV = '0' + unusedBits + h;\n    };\n\n    /**\n     * set ASN.1 TLV value(V) by an array of boolean\n     * @name setByBooleanArray\n     * @memberOf KJUR.asn1.DERBitString\n     * @function\n     * @param {array} booleanArray array of boolean (ex. [true, false, true])\n     * @description\n     * NOTE: Trailing falses will be ignored.\n     */\n    this.setByBooleanArray = function(booleanArray) {\n\tvar s = '';\n\tfor (var i = 0; i < booleanArray.length; i++) {\n\t    if (booleanArray[i] == true) {\n\t\ts += '1';\n\t    } else {\n\t\ts += '0';\n\t    }\n\t}\n\tthis.setByBinaryString(s);\n    };\n\n    /**\n     * generate an array of false with specified length\n     * @name newFalseArray\n     * @memberOf KJUR.asn1.DERBitString\n     * @function\n     * @param {Integer} nLength length of array to generate\n     * @return {array} array of boolean faluse\n     * @description\n     * This static method may be useful to initialize boolean array.\n     */\n    this.newFalseArray = function(nLength) {\n\tvar a = new Array(nLength);\n\tfor (var i = 0; i < nLength; i++) {\n\t    a[i] = false;\n\t}\n\treturn a;\n    };\n\n    this.getFreshValueHex = function() {\n\treturn this.hV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params == \"string\" && params.toLowerCase().match(/^[0-9a-f]+$/)) {\n\t    this.setHexValueIncludingUnusedBits(params);\n        } else if (typeof params['hex'] != \"undefined\") {\n\t    this.setHexValueIncludingUnusedBits(params['hex']);\n\t} else if (typeof params['bin'] != \"undefined\") {\n\t    this.setByBinaryString(params['bin']);\n\t} else if (typeof params['array'] != \"undefined\") {\n\t    this.setByBooleanArray(params['array']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.DERBitString, KJUR.asn1.ASN1Object);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER OctetString\n * @name KJUR.asn1.DEROctetString\n * @class class for ASN.1 DER OctetString\n * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})\n * @extends KJUR.asn1.DERAbstractString\n * @description\n * @see KJUR.asn1.DERAbstractString - superclass\n */\nKJUR.asn1.DEROctetString = function(params) {\n    KJUR.asn1.DEROctetString.superclass.constructor.call(this, params);\n    this.hT = \"04\";\n};\nYAHOO.lang.extend(KJUR.asn1.DEROctetString, KJUR.asn1.DERAbstractString);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER Null\n * @name KJUR.asn1.DERNull\n * @class class for ASN.1 DER Null\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @see KJUR.asn1.ASN1Object - superclass\n */\nKJUR.asn1.DERNull = function() {\n    KJUR.asn1.DERNull.superclass.constructor.call(this);\n    this.hT = \"05\";\n    this.hTLV = \"0500\";\n};\nYAHOO.lang.extend(KJUR.asn1.DERNull, KJUR.asn1.ASN1Object);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER ObjectIdentifier\n * @name KJUR.asn1.DERObjectIdentifier\n * @class class for ASN.1 DER ObjectIdentifier\n * @param {Array} params associative array of parameters (ex. {'oid': '2.5.4.5'})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>oid - specify initial ASN.1 value(V) by a oid string (ex. 2.5.4.13)</li>\n * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n */\nKJUR.asn1.DERObjectIdentifier = function(params) {\n    var itox = function(i) {\n\tvar h = i.toString(16);\n\tif (h.length == 1) h = '0' + h;\n\treturn h;\n    };\n    var roidtox = function(roid) {\n\tvar h = '';\n\tvar bi = new BigInteger(roid, 10);\n\tvar b = bi.toString(2);\n\tvar padLen = 7 - b.length % 7;\n\tif (padLen == 7) padLen = 0;\n\tvar bPad = '';\n\tfor (var i = 0; i < padLen; i++) bPad += '0';\n\tb = bPad + b;\n\tfor (var i = 0; i < b.length - 1; i += 7) {\n\t    var b8 = b.substr(i, 7);\n\t    if (i != b.length - 7) b8 = '1' + b8;\n\t    h += itox(parseInt(b8, 2));\n\t}\n\treturn h;\n    }\n\n    KJUR.asn1.DERObjectIdentifier.superclass.constructor.call(this);\n    this.hT = \"06\";\n\n    /**\n     * set value by a hexadecimal string\n     * @name setValueHex\n     * @memberOf KJUR.asn1.DERObjectIdentifier\n     * @function\n     * @param {String} newHexString hexadecimal value of OID bytes\n     */\n    this.setValueHex = function(newHexString) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.s = null;\n\tthis.hV = newHexString;\n    };\n\n    /**\n     * set value by a OID string\n     * @name setValueOidString\n     * @memberOf KJUR.asn1.DERObjectIdentifier\n     * @function\n     * @param {String} oidString OID string (ex. 2.5.4.13)\n     */\n    this.setValueOidString = function(oidString) {\n\tif (! oidString.match(/^[0-9.]+$/)) {\n\t    throw \"malformed oid string: \" + oidString;\n\t}\n\tvar h = '';\n\tvar a = oidString.split('.');\n\tvar i0 = parseInt(a[0]) * 40 + parseInt(a[1]);\n\th += itox(i0);\n\ta.splice(0, 2);\n\tfor (var i = 0; i < a.length; i++) {\n\t    h += roidtox(a[i]);\n\t}\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.s = null;\n\tthis.hV = h;\n    };\n\n    /**\n     * set value by a OID name\n     * @name setValueName\n     * @memberOf KJUR.asn1.DERObjectIdentifier\n     * @function\n     * @param {String} oidName OID name (ex. 'serverAuth')\n     * @since 1.0.1\n     * @description\n     * OID name shall be defined in 'KJUR.asn1.x509.OID.name2oidList'.\n     * Otherwise raise error.\n     */\n    this.setValueName = function(oidName) {\n\tif (typeof KJUR.asn1.x509.OID.name2oidList[oidName] != \"undefined\") {\n\t    var oid = KJUR.asn1.x509.OID.name2oidList[oidName];\n\t    this.setValueOidString(oid);\n\t} else {\n\t    throw \"DERObjectIdentifier oidName undefined: \" + oidName;\n\t}\n    };\n\n    this.getFreshValueHex = function() {\n\treturn this.hV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params == \"string\" && params.match(/^[0-2].[0-9.]+$/)) {\n\t    this.setValueOidString(params);\n\t} else if (KJUR.asn1.x509.OID.name2oidList[params] !== undefined) {\n\t    this.setValueOidString(KJUR.asn1.x509.OID.name2oidList[params]);\n\t} else if (typeof params['oid'] != \"undefined\") {\n\t    this.setValueOidString(params['oid']);\n\t} else if (typeof params['hex'] != \"undefined\") {\n\t    this.setValueHex(params['hex']);\n\t} else if (typeof params['name'] != \"undefined\") {\n\t    this.setValueName(params['name']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.DERObjectIdentifier, KJUR.asn1.ASN1Object);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER UTF8String\n * @name KJUR.asn1.DERUTF8String\n * @class class for ASN.1 DER UTF8String\n * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})\n * @extends KJUR.asn1.DERAbstractString\n * @description\n * @see KJUR.asn1.DERAbstractString - superclass\n */\nKJUR.asn1.DERUTF8String = function(params) {\n    KJUR.asn1.DERUTF8String.superclass.constructor.call(this, params);\n    this.hT = \"0c\";\n};\nYAHOO.lang.extend(KJUR.asn1.DERUTF8String, KJUR.asn1.DERAbstractString);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER NumericString\n * @name KJUR.asn1.DERNumericString\n * @class class for ASN.1 DER NumericString\n * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})\n * @extends KJUR.asn1.DERAbstractString\n * @description\n * @see KJUR.asn1.DERAbstractString - superclass\n */\nKJUR.asn1.DERNumericString = function(params) {\n    KJUR.asn1.DERNumericString.superclass.constructor.call(this, params);\n    this.hT = \"12\";\n};\nYAHOO.lang.extend(KJUR.asn1.DERNumericString, KJUR.asn1.DERAbstractString);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER PrintableString\n * @name KJUR.asn1.DERPrintableString\n * @class class for ASN.1 DER PrintableString\n * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})\n * @extends KJUR.asn1.DERAbstractString\n * @description\n * @see KJUR.asn1.DERAbstractString - superclass\n */\nKJUR.asn1.DERPrintableString = function(params) {\n    KJUR.asn1.DERPrintableString.superclass.constructor.call(this, params);\n    this.hT = \"13\";\n};\nYAHOO.lang.extend(KJUR.asn1.DERPrintableString, KJUR.asn1.DERAbstractString);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER TeletexString\n * @name KJUR.asn1.DERTeletexString\n * @class class for ASN.1 DER TeletexString\n * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})\n * @extends KJUR.asn1.DERAbstractString\n * @description\n * @see KJUR.asn1.DERAbstractString - superclass\n */\nKJUR.asn1.DERTeletexString = function(params) {\n    KJUR.asn1.DERTeletexString.superclass.constructor.call(this, params);\n    this.hT = \"14\";\n};\nYAHOO.lang.extend(KJUR.asn1.DERTeletexString, KJUR.asn1.DERAbstractString);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER IA5String\n * @name KJUR.asn1.DERIA5String\n * @class class for ASN.1 DER IA5String\n * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})\n * @extends KJUR.asn1.DERAbstractString\n * @description\n * @see KJUR.asn1.DERAbstractString - superclass\n */\nKJUR.asn1.DERIA5String = function(params) {\n    KJUR.asn1.DERIA5String.superclass.constructor.call(this, params);\n    this.hT = \"16\";\n};\nYAHOO.lang.extend(KJUR.asn1.DERIA5String, KJUR.asn1.DERAbstractString);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER UTCTime\n * @name KJUR.asn1.DERUTCTime\n * @class class for ASN.1 DER UTCTime\n * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'})\n * @extends KJUR.asn1.DERAbstractTime\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>str - specify initial ASN.1 value(V) by a string (ex.'130430235959Z')</li>\n * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>\n * <li>date - specify Date object.</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n * <h4>EXAMPLES</h4>\n * @example\n * var d1 = new KJUR.asn1.DERUTCTime();\n * d1.setString('130430125959Z');\n *\n * var d2 = new KJUR.asn1.DERUTCTime({'str': '130430125959Z'});\n * var d3 = new KJUR.asn1.DERUTCTime({'date': new Date(Date.UTC(2015, 0, 31, 0, 0, 0, 0))});\n * var d4 = new KJUR.asn1.DERUTCTime('130430125959Z');\n */\nKJUR.asn1.DERUTCTime = function(params) {\n    KJUR.asn1.DERUTCTime.superclass.constructor.call(this, params);\n    this.hT = \"17\";\n\n    /**\n     * set value by a Date object\n     * @name setByDate\n     * @memberOf KJUR.asn1.DERUTCTime\n     * @function\n     * @param {Date} dateObject Date object to set ASN.1 value(V)\n     */\n    this.setByDate = function(dateObject) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.date = dateObject;\n\tthis.s = this.formatDate(this.date, 'utc');\n\tthis.hV = stohex(this.s);\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['str'] != \"undefined\") {\n\t    this.setString(params['str']);\n\t} else if (typeof params == \"string\" && params.match(/^[0-9]{12}Z$/)) {\n\t    this.setString(params);\n\t} else if (typeof params['hex'] != \"undefined\") {\n\t    this.setStringHex(params['hex']);\n\t} else if (typeof params['date'] != \"undefined\") {\n\t    this.setByDate(params['date']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.DERUTCTime, KJUR.asn1.DERAbstractTime);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER GeneralizedTime\n * @name KJUR.asn1.DERGeneralizedTime\n * @class class for ASN.1 DER GeneralizedTime\n * @param {Array} params associative array of parameters (ex. {'str': '20130430235959Z'})\n * @extends KJUR.asn1.DERAbstractTime\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>str - specify initial ASN.1 value(V) by a string (ex.'20130430235959Z')</li>\n * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>\n * <li>date - specify Date object.</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n */\nKJUR.asn1.DERGeneralizedTime = function(params) {\n    KJUR.asn1.DERGeneralizedTime.superclass.constructor.call(this, params);\n    this.hT = \"18\";\n\n    /**\n     * set value by a Date object\n     * @name setByDate\n     * @memberOf KJUR.asn1.DERGeneralizedTime\n     * @function\n     * @param {Date} dateObject Date object to set ASN.1 value(V)\n     * @example\n     * When you specify UTC time, use 'Date.UTC' method like this:<br/>\n     * var o = new DERUTCTime();\n     * var date = new Date(Date.UTC(2015, 0, 31, 23, 59, 59, 0)); #2015JAN31 23:59:59\n     * o.setByDate(date);\n     */\n    this.setByDate = function(dateObject) {\n\tthis.hTLV = null;\n\tthis.isModified = true;\n\tthis.date = dateObject;\n\tthis.s = this.formatDate(this.date, 'gen');\n\tthis.hV = stohex(this.s);\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['str'] != \"undefined\") {\n\t    this.setString(params['str']);\n\t} else if (typeof params == \"string\" && params.match(/^[0-9]{14}Z$/)) {\n\t    this.setString(params);\n\t} else if (typeof params['hex'] != \"undefined\") {\n\t    this.setStringHex(params['hex']);\n\t} else if (typeof params['date'] != \"undefined\") {\n\t    this.setByDate(params['date']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.DERGeneralizedTime, KJUR.asn1.DERAbstractTime);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER Sequence\n * @name KJUR.asn1.DERSequence\n * @class class for ASN.1 DER Sequence\n * @extends KJUR.asn1.DERAbstractStructured\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>array - specify array of ASN1Object to set elements of content</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n */\nKJUR.asn1.DERSequence = function(params) {\n    KJUR.asn1.DERSequence.superclass.constructor.call(this, params);\n    this.hT = \"30\";\n    this.getFreshValueHex = function() {\n\tvar h = '';\n\tfor (var i = 0; i < this.asn1Array.length; i++) {\n\t    var asn1Obj = this.asn1Array[i];\n\t    h += asn1Obj.getEncodedHex();\n\t}\n\tthis.hV = h;\n\treturn this.hV;\n    };\n};\nYAHOO.lang.extend(KJUR.asn1.DERSequence, KJUR.asn1.DERAbstractStructured);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER Set\n * @name KJUR.asn1.DERSet\n * @class class for ASN.1 DER Set\n * @extends KJUR.asn1.DERAbstractStructured\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>array - specify array of ASN1Object to set elements of content</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n */\nKJUR.asn1.DERSet = function(params) {\n    KJUR.asn1.DERSet.superclass.constructor.call(this, params);\n    this.hT = \"31\";\n    this.getFreshValueHex = function() {\n\tvar a = new Array();\n\tfor (var i = 0; i < this.asn1Array.length; i++) {\n\t    var asn1Obj = this.asn1Array[i];\n\t    a.push(asn1Obj.getEncodedHex());\n\t}\n\ta.sort();\n\tthis.hV = a.join('');\n\treturn this.hV;\n    };\n};\nYAHOO.lang.extend(KJUR.asn1.DERSet, KJUR.asn1.DERAbstractStructured);\n\n// ********************************************************************\n/**\n * class for ASN.1 DER TaggedObject\n * @name KJUR.asn1.DERTaggedObject\n * @class class for ASN.1 DER TaggedObject\n * @extends KJUR.asn1.ASN1Object\n * @description\n * <br/>\n * Parameter 'tagNoNex' is ASN.1 tag(T) value for this object.\n * For example, if you find '[1]' tag in a ASN.1 dump, \n * 'tagNoHex' will be 'a1'.\n * <br/>\n * As for optional argument 'params' for constructor, you can specify *ANY* of\n * following properties:\n * <ul>\n * <li>explicit - specify true if this is explicit tag otherwise false \n *     (default is 'true').</li>\n * <li>tag - specify tag (default is 'a0' which means [0])</li>\n * <li>obj - specify ASN1Object which is tagged</li>\n * </ul>\n * @example\n * d1 = new KJUR.asn1.DERUTF8String({'str':'a'});\n * d2 = new KJUR.asn1.DERTaggedObject({'obj': d1});\n * hex = d2.getEncodedHex();\n */\nKJUR.asn1.DERTaggedObject = function(params) {\n    KJUR.asn1.DERTaggedObject.superclass.constructor.call(this);\n    this.hT = \"a0\";\n    this.hV = '';\n    this.isExplicit = true;\n    this.asn1Object = null;\n\n    /**\n     * set value by an ASN1Object\n     * @name setString\n     * @memberOf KJUR.asn1.DERTaggedObject\n     * @function\n     * @param {Boolean} isExplicitFlag flag for explicit/implicit tag\n     * @param {Integer} tagNoHex hexadecimal string of ASN.1 tag\n     * @param {ASN1Object} asn1Object ASN.1 to encapsulate\n     */\n    this.setASN1Object = function(isExplicitFlag, tagNoHex, asn1Object) {\n\tthis.hT = tagNoHex;\n\tthis.isExplicit = isExplicitFlag;\n\tthis.asn1Object = asn1Object;\n\tif (this.isExplicit) {\n\t    this.hV = this.asn1Object.getEncodedHex();\n\t    this.hTLV = null;\n\t    this.isModified = true;\n\t} else {\n\t    this.hV = null;\n\t    this.hTLV = asn1Object.getEncodedHex();\n\t    this.hTLV = this.hTLV.replace(/^../, tagNoHex);\n\t    this.isModified = false;\n\t}\n    };\n\n    this.getFreshValueHex = function() {\n\treturn this.hV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['tag'] != \"undefined\") {\n\t    this.hT = params['tag'];\n\t}\n\tif (typeof params['explicit'] != \"undefined\") {\n\t    this.isExplicit = params['explicit'];\n\t}\n\tif (typeof params['obj'] != \"undefined\") {\n\t    this.asn1Object = params['obj'];\n\t    this.setASN1Object(this.isExplicit, this.hT, this.asn1Object);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.DERTaggedObject, KJUR.asn1.ASN1Object);\n"
  },
  {
    "path": "JavaScript/sm2/js/asn1hex-1.1.js",
    "content": "/*! asn1hex-1.1.4.js (c) 2012-2013 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n/*\n * asn1hex.js - Hexadecimal represented ASN.1 string library\n *\n * Copyright (c) 2010-2013 Kenji Urushima (kenji.urushima@gmail.com)\n *\n * This software is licensed under the terms of the MIT License.\n * http://kjur.github.com/jsrsasign/license/\n *\n * The above copyright and license notice shall be \n * included in all copies or substantial portions of the Software.\n */\n\n/**\n * @fileOverview\n * @name asn1hex-1.1.js\n * @author Kenji Urushima kenji.urushima@gmail.com\n * @version asn1hex 1.1.4 (2013-Oct-02)\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\n */\n\n/*\n * MEMO:\n *   f('3082025b02...', 2) ... 82025b ... 3bytes\n *   f('020100', 2) ... 01 ... 1byte\n *   f('0203001...', 2) ... 03 ... 1byte\n *   f('02818003...', 2) ... 8180 ... 2bytes\n *   f('3080....0000', 2) ... 80 ... -1\n *\n *   Requirements:\n *   - ASN.1 type octet length MUST be 1. \n *     (i.e. ASN.1 primitives like SET, SEQUENCE, INTEGER, OCTETSTRING ...)\n */\n\n/**\n * ASN.1 DER encoded hexadecimal string utility class\n * @name ASN1HEX\n * @class ASN.1 DER encoded hexadecimal string utility class\n * @since jsrsasign 1.1\n */\nvar ASN1HEX = new function() {\n    /**\n     * get byte length for ASN.1 L(length) bytes\n     * @name getByteLengthOfL_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} s hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} pos string index\n     * @return byte length for ASN.1 L(length) bytes\n     */\n    this.getByteLengthOfL_AtObj = function(s, pos) {\n\tif (s.substring(pos + 2, pos + 3) != '8') return 1;\n\tvar i = parseInt(s.substring(pos + 3, pos + 4));\n\tif (i == 0) return -1; \t\t// length octet '80' indefinite length\n\tif (0 < i && i < 10) return i + 1;\t// including '8?' octet;\n\treturn -2;\t\t\t\t// malformed format\n    };\n\n    /**\n     * get hexadecimal string for ASN.1 L(length) bytes\n     * @name getHexOfL_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} s hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} pos string index\n     * @return {String} hexadecimal string for ASN.1 L(length) bytes\n     */\n    this.getHexOfL_AtObj = function(s, pos) {\n\tvar len = this.getByteLengthOfL_AtObj(s, pos);\n\tif (len < 1) return '';\n\treturn s.substring(pos + 2, pos + 2 + len * 2);\n    };\n\n    //   getting ASN.1 length value at the position 'idx' of\n    //   hexa decimal string 's'.\n    //\n    //   f('3082025b02...', 0) ... 82025b ... ???\n    //   f('020100', 0) ... 01 ... 1\n    //   f('0203001...', 0) ... 03 ... 3\n    //   f('02818003...', 0) ... 8180 ... 128\n    /**\n     * get integer value of ASN.1 length for ASN.1 data\n     * @name getIntOfL_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} s hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} pos string index\n     * @return ASN.1 L(length) integer value\n     */\n    this.getIntOfL_AtObj = function(s, pos) {\n\tvar hLength = this.getHexOfL_AtObj(s, pos);\n\tif (hLength == '') return -1;\n\tvar bi;\n\tif (parseInt(hLength.substring(0, 1)) < 8) {\n\t    bi = new BigInteger(hLength, 16);\n\t} else {\n\t    bi = new BigInteger(hLength.substring(2), 16);\n\t}\n\treturn bi.intValue();\n    };\n\n    /**\n     * get ASN.1 value starting string position for ASN.1 object refered by index 'idx'.\n     * @name getStartPosOfV_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} s hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} pos string index\n     */\n    this.getStartPosOfV_AtObj = function(s, pos) {\n\tvar l_len = this.getByteLengthOfL_AtObj(s, pos);\n\tif (l_len < 0) return l_len;\n\treturn pos + (l_len + 1) * 2;\n    };\n\n    /**\n     * get hexadecimal string of ASN.1 V(value)\n     * @name getHexOfV_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} s hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} pos string index\n     * @return {String} hexadecimal string of ASN.1 value.\n     */\n    this.getHexOfV_AtObj = function(s, pos) {\n\tvar pos1 = this.getStartPosOfV_AtObj(s, pos);\n\tvar len = this.getIntOfL_AtObj(s, pos);\n\treturn s.substring(pos1, pos1 + len * 2);\n    };\n\n    /**\n     * get hexadecimal string of ASN.1 TLV at\n     * @name getHexOfTLV_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} s hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} pos string index\n     * @return {String} hexadecimal string of ASN.1 TLV.\n     * @since 1.1\n     */\n    this.getHexOfTLV_AtObj = function(s, pos) {\n\tvar hT = s.substr(pos, 2);\n\tvar hL = this.getHexOfL_AtObj(s, pos);\n\tvar hV = this.getHexOfV_AtObj(s, pos);\n\treturn hT + hL + hV;\n    };\n\n    /**\n     * get next sibling starting index for ASN.1 object string\n     * @name getPosOfNextSibling_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} s hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} pos string index\n     * @return next sibling starting index for ASN.1 object string\n     */\n    this.getPosOfNextSibling_AtObj = function(s, pos) {\n\tvar pos1 = this.getStartPosOfV_AtObj(s, pos);\n\tvar len = this.getIntOfL_AtObj(s, pos);\n\treturn pos1 + len * 2;\n    };\n\n    /**\n     * get array of indexes of child ASN.1 objects\n     * @name getPosArrayOfChildren_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} s hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} start string index of ASN.1 object\n     * @return {Array of Number} array of indexes for childen of ASN.1 objects\n     */\n    this.getPosArrayOfChildren_AtObj = function(h, pos) {\n\tvar a = new Array();\n\tvar p0 = this.getStartPosOfV_AtObj(h, pos);\n\ta.push(p0);\n\n\tvar len = this.getIntOfL_AtObj(h, pos);\n\tvar p = p0;\n\tvar k = 0;\n\twhile (1) {\n\t    var pNext = this.getPosOfNextSibling_AtObj(h, p);\n\t    if (pNext == null || (pNext - p0  >= (len * 2))) break;\n\t    if (k >= 200) break;\n\t    \n\t    a.push(pNext);\n\t    p = pNext;\n\t    \n\t    k++;\n\t}\n\t\n\treturn a;\n    };\n\n    /**\n     * get string index of nth child object of ASN.1 object refered by h, idx\n     * @name getNthChildIndex_AtObj\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} h hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} idx start string index of ASN.1 object\n     * @param {Number} nth for child\n     * @return {Number} string index of nth child.\n     * @since 1.1\n     */\n    this.getNthChildIndex_AtObj = function(h, idx, nth) {\n\tvar a = this.getPosArrayOfChildren_AtObj(h, idx);\n\treturn a[nth];\n    };\n\n    // ========== decendant methods ==============================\n    /**\n     * get string index of nth child object of ASN.1 object refered by h, idx\n     * @name getDecendantIndexByNthList\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} h hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} currentIndex start string index of ASN.1 object\n     * @param {Array of Number} nthList array list of nth\n     * @return {Number} string index refered by nthList\n     * @since 1.1\n     * @example\n     * The \"nthList\" is a index list of structured ASN.1 object\n     * reference. Here is a sample structure and \"nthList\"s which\n     * refers each objects.\n     *\n     * SQUENCE               - [0]\n     *   SEQUENCE            - [0, 0]\n     *     IA5STRING 000     - [0, 0, 0]\n     *     UTF8STRING 001    - [0, 0, 1]\n     *   SET                 - [0, 1]\n     *     IA5STRING 010     - [0, 1, 0]\n     *     UTF8STRING 011    - [0, 1, 1]\n     */\n    this.getDecendantIndexByNthList = function(h, currentIndex, nthList) {\n\tif (nthList.length == 0) {\n\t    return currentIndex;\n\t}\n\tvar firstNth = nthList.shift();\n\tvar a = this.getPosArrayOfChildren_AtObj(h, currentIndex);\n\treturn this.getDecendantIndexByNthList(h, a[firstNth], nthList);\n    };\n\n    /**\n     * get hexadecimal string of ASN.1 TLV refered by current index and nth index list.\n     * @name getDecendantHexTLVByNthList\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} h hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} currentIndex start string index of ASN.1 object\n     * @param {Array of Number} nthList array list of nth\n     * @return {Number} hexadecimal string of ASN.1 TLV refered by nthList\n     * @since 1.1\n     */\n    this.getDecendantHexTLVByNthList = function(h, currentIndex, nthList) {\n\tvar idx = this.getDecendantIndexByNthList(h, currentIndex, nthList);\n\treturn this.getHexOfTLV_AtObj(h, idx);\n    };\n\n    /**\n     * get hexadecimal string of ASN.1 V refered by current index and nth index list.\n     * @name getDecendantHexVByNthList\n     * @memberOf ASN1HEX\n     * @function\n     * @param {String} h hexadecimal string of ASN.1 DER encoded data\n     * @param {Number} currentIndex start string index of ASN.1 object\n     * @param {Array of Number} nthList array list of nth\n     * @return {Number} hexadecimal string of ASN.1 V refered by nthList\n     * @since 1.1\n     */\n    this.getDecendantHexVByNthList = function(h, currentIndex, nthList) {\n\tvar idx = this.getDecendantIndexByNthList(h, currentIndex, nthList);\n\treturn this.getHexOfV_AtObj(h, idx);\n    };\n};\n\n/*\n * @since asn1hex 1.1.4\n */\nASN1HEX.getVbyList = function(h, currentIndex, nthList, checkingTag) {\n    var idx = this.getDecendantIndexByNthList(h, currentIndex, nthList);\n    if (idx === undefined) {\n\tthrow \"can't find nthList object\";\n    }\n    if (checkingTag !== undefined) {\n\tif (h.substr(idx, 2) != checkingTag) {\n\t    throw \"checking tag doesn't match: \" + h.substr(idx,2) + \"!=\" + checkingTag;\n\t}\n    }\n    return this.getHexOfV_AtObj(h, idx);\n};\n\n"
  },
  {
    "path": "JavaScript/sm2/js/asn1x509-1.0.js",
    "content": "/*! asn1x509-1.0.7.js (c) 2013 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n/*\n * asn1x509.js - ASN.1 DER encoder classes for X.509 certificate\n *\n * Copyright (c) 2013 Kenji Urushima (kenji.urushima@gmail.com)\n *\n * This software is licensed under the terms of the MIT License.\n * http://kjur.github.com/jsrsasign/license\n *\n * The above copyright and license notice shall be \n * included in all copies or substantial portions of the Software.\n */\n\n/**\n * @fileOverview\n * @name asn1x509-1.0.js\n * @author Kenji Urushima kenji.urushima@gmail.com\n * @version 1.0.7 (2013-Oct-11)\n * @since jsrsasign 2.1\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\n */\n\n/** \n * kjur's class library name space\n * // already documented in asn1-1.0.js\n * @name KJUR\n * @namespace kjur's class library name space\n */\nif (typeof KJUR == \"undefined\" || !KJUR) KJUR = {};\n\n/**\n * kjur's ASN.1 class library name space\n * // already documented in asn1-1.0.js\n * @name KJUR.asn1\n * @namespace\n */\nif (typeof KJUR.asn1 == \"undefined\" || !KJUR.asn1) KJUR.asn1 = {};\n\n/**\n * kjur's ASN.1 class for X.509 certificate library name space\n * <p>\n * <h4>FEATURES</h4>\n * <ul>\n * <li>easily issue any kind of certificate</li>\n * <li>APIs are very similar to BouncyCastle library ASN.1 classes. So easy to learn.</li>\n * </ul>\n * </p>\n * <h4>PROVIDED CLASSES</h4>\n * <ul>\n * <li>{@link KJUR.asn1.x509.Certificate}</li>\n * <li>{@link KJUR.asn1.x509.TBSCertificate}</li>\n * <li>{@link KJUR.asn1.x509.Extension}</li>\n * <li>{@link KJUR.asn1.x509.X500Name}</li>\n * <li>{@link KJUR.asn1.x509.RDN}</li>\n * <li>{@link KJUR.asn1.x509.AttributeTypeAndValue}</li>\n * <li>{@link KJUR.asn1.x509.SubjectPublicKeyInfo}</li>\n * <li>{@link KJUR.asn1.x509.AlgorithmIdentifier}</li>\n * <li>{@link KJUR.asn1.x509.GeneralName}</li>\n * <li>{@link KJUR.asn1.x509.GeneralNames}</li>\n * <li>{@link KJUR.asn1.x509.DistributionPointName}</li>\n * <li>{@link KJUR.asn1.x509.DistributionPoint}</li>\n * <li>{@link KJUR.asn1.x509.CRL}</li>\n * <li>{@link KJUR.asn1.x509.TBSCertList}</li>\n * <li>{@link KJUR.asn1.x509.CRLEntry}</li>\n * <li>{@link KJUR.asn1.x509.OID}</li>\n * </ul>\n * <h4>SUPPORTED EXTENSIONS</h4>\n * <ul>\n * <li>{@link KJUR.asn1.x509.BasicConstraints}</li>\n * <li>{@link KJUR.asn1.x509.KeyUsage}</li>\n * <li>{@link KJUR.asn1.x509.CRLDistributionPoints}</li>\n * <li>{@link KJUR.asn1.x509.ExtKeyUsage}</li>\n * </ul>\n * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.\n * @name KJUR.asn1.x509\n * @namespace\n */\nif (typeof KJUR.asn1.x509 == \"undefined\" || !KJUR.asn1.x509) KJUR.asn1.x509 = {};\n\n// === BEGIN Certificate ===================================================\n\n/**\n * X.509 Certificate class to sign and generate hex encoded certificate\n * @name KJUR.asn1.x509.Certificate\n * @class X.509 Certificate class to sign and generate hex encoded certificate\n * @param {Array} params associative array of parameters (ex. {'tbscertobj': obj, 'prvkeyobj': key})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>tbscertobj - specify {@link KJUR.asn1.x509.TBSCertificate} object</li>\n * <li>prvkeyobj - specify {@link RSAKey}, {@link KJUR.crypto.ECDSA} or {@link KJUR.crypto.DSA} object for CA private key to sign the certificate</li>\n * <li>(DEPRECATED)rsaprvkey - specify {@link RSAKey} object CA private key</li>\n * <li>(DEPRECATED)rsaprvpem - specify PEM string of RSA CA private key</li>\n * </ul>\n * NOTE1: 'params' can be omitted.<br/>\n * NOTE2: DSA/ECDSA is also supported for CA signging key from asn1x509 1.0.6.\n * @example\n * var caKey = KEYUTIL.getKey(caKeyPEM); // CA's private key\n * var cert = new KJUR.asn1x509.Certificate({'tbscertobj': tbs, 'prvkeyobj': caKey});\n * cert.sign(); // issue certificate by CA's private key\n * var certPEM = cert.getPEMString();\n *\n * // Certificate  ::=  SEQUENCE  {\n * //     tbsCertificate       TBSCertificate,\n * //     signatureAlgorithm   AlgorithmIdentifier,\n * //     signature            BIT STRING  }\t    \n */\nKJUR.asn1.x509.Certificate = function(params) {\n    KJUR.asn1.x509.Certificate.superclass.constructor.call(this);\n    var asn1TBSCert = null;\n    var asn1SignatureAlg = null;\n    var asn1Sig = null;\n    var hexSig = null;\n    var prvKey = null;\n    var rsaPrvKey = null; // DEPRECATED\n\n    \n    /**\n     * set PKCS#5 encrypted RSA PEM private key as CA key\n     * @name setRsaPrvKeyByPEMandPass\n     * @memberOf KJUR.asn1.x509.Certificate\n     * @function\n     * @param {String} rsaPEM string of PKCS#5 encrypted RSA PEM private key\n     * @param {String} passPEM passcode string to decrypt private key\n     * @since 1.0.1\n     * @description\n     * <br/>\n     * <h4>EXAMPLES</h4>\n     * @example\n     * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs});\n     * cert.setRsaPrvKeyByPEMandPass(\"-----BEGIN RSA PRIVATE..(snip)\", \"password\");\n     */\n    this.setRsaPrvKeyByPEMandPass = function(rsaPEM, passPEM) {\n\tvar caKeyHex = PKCS5PKEY.getDecryptedKeyHex(rsaPEM, passPEM);\n\tvar caKey = new RSAKey();\n\tcaKey.readPrivateKeyFromASN1HexString(caKeyHex);  \n\tthis.prvKey = caKey;\n    };\n\n    /**\n     * sign TBSCertificate and set signature value internally\n     * @name sign\n     * @memberOf KJUR.asn1.x509.Certificate\n     * @function\n     * @description\n     * @example\n     * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs, 'rsaprvkey': prvKey});\n     * cert.sign();\n     */\n    this.sign = function() {\n\tthis.asn1SignatureAlg = this.asn1TBSCert.asn1SignatureAlg;\n\n\tsig = new KJUR.crypto.Signature({'alg': 'SHA1withRSA'});\n\tsig.init(this.prvKey);\n\tsig.updateHex(this.asn1TBSCert.getEncodedHex());\n\tthis.hexSig = sig.sign();\n\n\tthis.asn1Sig = new KJUR.asn1.DERBitString({'hex': '00' + this.hexSig});\n\t\n\tvar seq = new KJUR.asn1.DERSequence({'array': [this.asn1TBSCert,\n\t\t\t\t\t\t       this.asn1SignatureAlg,\n\t\t\t\t\t\t       this.asn1Sig]});\n\tthis.hTLV = seq.getEncodedHex();\n\tthis.isModified = false;\n    };\n\n    this.getEncodedHex = function() {\n\tif (this.isModified == false && this.hTLV != null) return this.hTLV;\n\tthrow \"not signed yet\";\n    };\n\n    /**\n     * get PEM formatted certificate string after signed\n     * @name getPEMString\n     * @memberOf KJUR.asn1.x509.Certificate\n     * @function\n     * @return PEM formatted string of certificate\n     * @description\n     * @example\n     * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs, 'rsaprvkey': prvKey});\n     * cert.sign();\n     * var sPEM =  cert.getPEMString();\n     */\n    this.getPEMString = function() {\n\tvar hCert = this.getEncodedHex();\n\tvar wCert = CryptoJS.enc.Hex.parse(hCert);\n\tvar b64Cert = CryptoJS.enc.Base64.stringify(wCert);\n\tvar pemBody = b64Cert.replace(/(.{64})/g, \"$1\\r\\n\");\n\treturn \"-----BEGIN CERTIFICATE-----\\r\\n\" + pemBody + \"\\r\\n-----END CERTIFICATE-----\\r\\n\";\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['tbscertobj'] != \"undefined\") {\n\t    this.asn1TBSCert = params['tbscertobj'];\n\t}\n\tif (typeof params['prvkeyobj'] != \"undefined\") {\n\t    this.prvKey = params['prvkeyobj'];\n\t} else if (typeof params['rsaprvkey'] != \"undefined\") {\n\t    this.prvKey = params['rsaprvkey'];\n        } else if ((typeof params['rsaprvpem'] != \"undefined\") &&\n\t    (typeof params['rsaprvpas'] != \"undefined\")) {\n\t    this.setRsaPrvKeyByPEMandPass(params['rsaprvpem'], params['rsaprvpas']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.Certificate, KJUR.asn1.ASN1Object);\n\n/**\n * ASN.1 TBSCertificate structure class\n * @name KJUR.asn1.x509.TBSCertificate\n * @class ASN.1 TBSCertificate structure class\n * @param {Array} params associative array of parameters (ex. {})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * <br/>\n * <h4>EXAMPLE</h4>\n * @example\n *  var o = new KJUR.asn1.x509.TBSCertificate();\n *  o.setSerialNumberByParam({'int': 4});\n *  o.setSignatureAlgByParam({'name': 'SHA1withRSA'});\n *  o.setIssuerByParam({'str': '/C=US/O=a'});\n *  o.setNotBeforeByParam({'str': '130504235959Z'});\n *  o.setNotAfterByParam({'str': '140504235959Z'});\n *  o.setSubjectByParam({'str': '/C=US/CN=b'});\n *  o.setSubjectPublicKeyByParam({'rsakey': rsaKey});\n *  o.appendExtension(new KJUR.asn1.x509.BasicConstraints({'cA':true}));\n *  o.appendExtension(new KJUR.asn1.x509.KeyUsage({'bin':'11'}));\n */\nKJUR.asn1.x509.TBSCertificate = function(params) {\n    KJUR.asn1.x509.TBSCertificate.superclass.constructor.call(this);\n\n    this._initialize = function() {\n\tthis.asn1Array = new Array();\n\n\tthis.asn1Version = \n\t    new KJUR.asn1.DERTaggedObject({'obj': new KJUR.asn1.DERInteger({'int': 2})});\n\tthis.asn1SerialNumber = null;\n\tthis.asn1SignatureAlg = null;\n\tthis.asn1Issuer = null;\n\tthis.asn1NotBefore = null;\n\tthis.asn1NotAfter = null;\n\tthis.asn1Subject = null;\n\tthis.asn1SubjPKey = null;\n\tthis.extensionsArray = new Array();\n    };\n\n    /**\n     * set serial number field by parameter\n     * @name setSerialNumberByParam\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Array} intParam DERInteger param\n     * @description\n     * @example\n     * tbsc.setSerialNumberByParam({'int': 3});\n     */\n    this.setSerialNumberByParam = function(intParam) {\n\tthis.asn1SerialNumber = new KJUR.asn1.DERInteger(intParam);\n    };\n\n    /**\n     * set signature algorithm field by parameter\n     * @name setSignatureAlgByParam\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Array} algIdParam AlgorithmIdentifier parameter\n     * @description\n     * @example\n     * tbsc.setSignatureAlgByParam({'name': 'SHA1withRSA'});\n     */\n    this.setSignatureAlgByParam = function(algIdParam) {\n\tthis.asn1SignatureAlg = new KJUR.asn1.x509.AlgorithmIdentifier(algIdParam);\n    };\n\n    /**\n     * set issuer name field by parameter\n     * @name setIssuerByParam\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Array} x500NameParam X500Name parameter\n     * @description\n     * @example\n     * tbsc.setIssuerParam({'str': '/C=US/CN=b'});\n     * @see KJUR.asn1.x509.X500Name\n     */\n    this.setIssuerByParam = function(x500NameParam) {\n\tthis.asn1Issuer = new KJUR.asn1.x509.X500Name(x500NameParam);\n    };\n\n    /**\n     * set notBefore field by parameter\n     * @name setNotBeforeByParam\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Array} timeParam Time parameter\n     * @description\n     * @example\n     * tbsc.setNotBeforeByParam({'str': '130508235959Z'});\n     * @see KJUR.asn1.x509.Time\n     */\n    this.setNotBeforeByParam = function(timeParam) {\n\tthis.asn1NotBefore = new KJUR.asn1.x509.Time(timeParam);\n    };\n    \n    /**\n     * set notAfter field by parameter\n     * @name setNotAfterByParam\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Array} timeParam Time parameter\n     * @description\n     * @example\n     * tbsc.setNotAfterByParam({'str': '130508235959Z'});\n     * @see KJUR.asn1.x509.Time\n     */\n    this.setNotAfterByParam = function(timeParam) {\n\tthis.asn1NotAfter = new KJUR.asn1.x509.Time(timeParam);\n    };\n\n    /**\n     * set subject name field by parameter\n     * @name setSubjectByParam\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Array} x500NameParam X500Name parameter\n     * @description\n     * @example\n     * tbsc.setSubjectParam({'str': '/C=US/CN=b'});\n     * @see KJUR.asn1.x509.X500Name\n     */\n    this.setSubjectByParam = function(x500NameParam) {\n\tthis.asn1Subject = new KJUR.asn1.x509.X500Name(x500NameParam);\n    };\n\n    /**\n     * (DEPRECATED) set subject public key info field by RSA key parameter\n     * @name setSubjectPublicKeyByParam\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Array} subjPKeyParam SubjectPublicKeyInfo parameter of RSA\n     * @deprecated\n     * @description\n     * @example\n     * tbsc.setSubjectPublicKeyByParam({'rsakey': pubKey});\n     * @see KJUR.asn1.x509.SubjectPublicKeyInfo\n     */\n    this.setSubjectPublicKeyByParam = function(subjPKeyParam) {\n\tthis.asn1SubjPKey = new KJUR.asn1.x509.SubjectPublicKeyInfo(subjPKeyParam);\n    };\n\n    /**\n     * set subject public key info by RSA/ECDSA/DSA key parameter\n     * @name setSubjectPublicKeyByGetKey\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Object} keyParam public key parameter which passed to {@link KEYUTIL.getKey} argument\n     * @description\n     * @example\n     * tbsc.setSubjectPublicKeyByGetKeyParam(certPEMString); // or \n     * tbsc.setSubjectPublicKeyByGetKeyParam(pkcs8PublicKeyPEMString); // or \n     * tbsc.setSubjectPublicKeyByGetKeyParam(kjurCryptoECDSAKeyObject); // et.al.\n     * @see KJUR.asn1.x509.SubjectPublicKeyInfo\n     * @see KEYUTIL.getKey\n     * @since asn1x509 1.0.6\n     */\n    this.setSubjectPublicKeyByGetKey = function(keyParam) {\n\tvar keyObj = KEYUTIL.getKey(keyParam);\n\tthis.asn1SubjPKey = new KJUR.asn1.x509.SubjectPublicKeyInfo(keyObj);\n    };\n\n    /**\n     * append X.509v3 extension to this object\n     * @name appendExtension\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {Extension} extObj X.509v3 Extension object\n     * @description\n     * @example\n     * tbsc.appendExtension(new KJUR.asn1.x509.BasicConstraints({'cA':true, 'critical': true}));\n     * tbsc.appendExtension(new KJUR.asn1.x509.KeyUsage({'bin':'11'}));\n     * @see KJUR.asn1.x509.Extension\n     */\n    this.appendExtension = function(extObj) {\n\tthis.extensionsArray.push(extObj);\n    };\n\n    /**\n     * append X.509v3 extension to this object by name and parameters\n     * @name appendExtensionByName\n     * @memberOf KJUR.asn1.x509.TBSCertificate\n     * @function\n     * @param {name} name name of X.509v3 Extension object\n     * @param {Array} extParams parameters as argument of Extension constructor.\n     * @description\n     * @example\n     * tbsc.appendExtensionByName('BasicConstraints', {'cA':true, 'critical': true});\n     * tbsc.appendExtensionByName('KeyUsage', {'bin':'11'});\n     * tbsc.appendExtensionByName('CRLDistributionPoints', {uri: 'http://aaa.com/a.crl'});\n     * tbsc.appendExtensionByName('ExtKeyUsage', {array: [{name: 'clientAuth'}]});\n     * @see KJUR.asn1.x509.Extension\n     */\n    this.appendExtensionByName = function(name, extParams) {\n\tif (name.toLowerCase() == \"basicconstraints\") {\n\t    var extObj = new KJUR.asn1.x509.BasicConstraints(extParams);\n\t    this.appendExtension(extObj);\n\t} else if (name.toLowerCase() == \"keyusage\") {\n\t    var extObj = new KJUR.asn1.x509.KeyUsage(extParams);\n\t    this.appendExtension(extObj);\n\t} else if (name.toLowerCase() == \"crldistributionpoints\") {\n\t    var extObj = new KJUR.asn1.x509.CRLDistributionPoints(extParams);\n\t    this.appendExtension(extObj);\n\t} else if (name.toLowerCase() == \"extkeyusage\") {\n\t    var extObj = new KJUR.asn1.x509.ExtKeyUsage(extParams);\n\t    this.appendExtension(extObj);\n\t} else {\n\t    throw \"unsupported extension name: \" + name;\n\t}\n    };\n\n    this.getEncodedHex = function() {\n\tif (this.asn1NotBefore == null || this.asn1NotAfter == null)\n\t    throw \"notBefore and/or notAfter not set\";\n\tvar asn1Validity = \n\t    new KJUR.asn1.DERSequence({'array':[this.asn1NotBefore, this.asn1NotAfter]});\n\n\tthis.asn1Array = new Array();\n\n\tthis.asn1Array.push(this.asn1Version);\n\tthis.asn1Array.push(this.asn1SerialNumber);\n\tthis.asn1Array.push(this.asn1SignatureAlg);\n\tthis.asn1Array.push(this.asn1Issuer);\n\tthis.asn1Array.push(asn1Validity);\n\tthis.asn1Array.push(this.asn1Subject);\n\tthis.asn1Array.push(this.asn1SubjPKey);\n\n\tif (this.extensionsArray.length > 0) {\n\t    var extSeq = new KJUR.asn1.DERSequence({\"array\": this.extensionsArray});\n\t    var extTagObj = new KJUR.asn1.DERTaggedObject({'explicit': true,\n\t\t\t\t\t\t\t   'tag': 'a3',\n\t\t\t\t\t\t\t   'obj': extSeq});\n\t    this.asn1Array.push(extTagObj);\n\t}\n\n\tvar o = new KJUR.asn1.DERSequence({\"array\": this.asn1Array});\n\tthis.hTLV = o.getEncodedHex();\n\tthis.isModified = false;\n\treturn this.hTLV;\n    };\n\n    this._initialize();\n};\nYAHOO.lang.extend(KJUR.asn1.x509.TBSCertificate, KJUR.asn1.ASN1Object);\n\n// === END   TBSCertificate ===================================================\n\n// === BEGIN X.509v3 Extensions Related =======================================\n\n/**\n * base Extension ASN.1 structure class\n * @name KJUR.asn1.x509.Extension\n * @class base Extension ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'critical': true})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @example\n * // Extension  ::=  SEQUENCE  {\n * //     extnID      OBJECT IDENTIFIER,\n * //     critical    BOOLEAN DEFAULT FALSE,\n * //     extnValue   OCTET STRING  }\n */\nKJUR.asn1.x509.Extension = function(params) {\n    KJUR.asn1.x509.Extension.superclass.constructor.call(this);\n    var asn1ExtnValue = null;\n\n    this.getEncodedHex = function() {\n\tvar asn1Oid = new KJUR.asn1.DERObjectIdentifier({'oid': this.oid});\n\tvar asn1EncapExtnValue = \n\t    new KJUR.asn1.DEROctetString({'hex': this.getExtnValueHex()});\n\n\tvar asn1Array = new Array();\n\tasn1Array.push(asn1Oid);\n\tif (this.critical) asn1Array.push(new KJUR.asn1.DERBoolean());\n\tasn1Array.push(asn1EncapExtnValue);\n\n\tvar asn1Seq = new KJUR.asn1.DERSequence({'array': asn1Array});\n\treturn asn1Seq.getEncodedHex();\n    };\n\n    this.critical = false;\n    if (typeof params != \"undefined\") {\n\tif (typeof params['critical'] != \"undefined\") {\n\t    this.critical = params['critical'];\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.Extension, KJUR.asn1.ASN1Object);\n\n/**\n * KeyUsage ASN.1 structure class\n * @name KJUR.asn1.x509.KeyUsage\n * @class KeyUsage ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'bin': '11', 'critical': true})\n * @extends KJUR.asn1.x509.Extension\n * @description\n * @example\n */\nKJUR.asn1.x509.KeyUsage = function(params) {\n    KJUR.asn1.x509.KeyUsage.superclass.constructor.call(this, params);\n\n    this.getExtnValueHex = function() {\n\treturn this.asn1ExtnValue.getEncodedHex();\n    };\n\n    this.oid = \"2.5.29.15\";\n    if (typeof params != \"undefined\") {\n\tif (typeof params['bin'] != \"undefined\") {\n\t    this.asn1ExtnValue = new KJUR.asn1.DERBitString(params);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.KeyUsage, KJUR.asn1.x509.Extension);\n\n/**\n * BasicConstraints ASN.1 structure class\n * @name KJUR.asn1.x509.BasicConstraints\n * @class BasicConstraints ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'cA': true, 'critical': true})\n * @extends KJUR.asn1.x509.Extension\n * @description\n * @example\n */\nKJUR.asn1.x509.BasicConstraints = function(params) {\n    KJUR.asn1.x509.BasicConstraints.superclass.constructor.call(this, params);\n    var cA = false;\n    var pathLen = -1;\n\n    this.getExtnValueHex = function() {\n\tvar asn1Array = new Array();\n\tif (this.cA) asn1Array.push(new KJUR.asn1.DERBoolean());\n\tif (this.pathLen > -1) \n\t    asn1Array.push(new KJUR.asn1.DERInteger({'int': this.pathLen}));\n\tvar asn1Seq = new KJUR.asn1.DERSequence({'array': asn1Array});\n\tthis.asn1ExtnValue = asn1Seq;\n\treturn this.asn1ExtnValue.getEncodedHex();\n    };\n\n    this.oid = \"2.5.29.19\";\n    this.cA = false;\n    this.pathLen = -1;\n    if (typeof params != \"undefined\") {\n\tif (typeof params['cA'] != \"undefined\") {\n\t    this.cA = params['cA'];\n\t}\n\tif (typeof params['pathLen'] != \"undefined\") {\n\t    this.pathLen = params['pathLen'];\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.BasicConstraints, KJUR.asn1.x509.Extension);\n\n/**\n * CRLDistributionPoints ASN.1 structure class\n * @name KJUR.asn1.x509.CRLDistributionPoints\n * @class CRLDistributionPoints ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'uri': 'http://a.com/', 'critical': true})\n * @extends KJUR.asn1.x509.Extension\n * @description\n * @example\n */\nKJUR.asn1.x509.CRLDistributionPoints = function(params) {\n    KJUR.asn1.x509.CRLDistributionPoints.superclass.constructor.call(this, params);\n\n    this.getExtnValueHex = function() {\n\treturn this.asn1ExtnValue.getEncodedHex();\n    };\n\n    this.setByDPArray = function(dpArray) {\n\tthis.asn1ExtnValue = new KJUR.asn1.DERSequence({'array': dpArray});\n    };\n\n    this.setByOneURI = function(uri) {\n\tvar gn1 = new KJUR.asn1.x509.GeneralNames([{'uri': uri}]);\n\tvar dpn1 = new KJUR.asn1.x509.DistributionPointName(gn1);\n\tvar dp1 = new KJUR.asn1.x509.DistributionPoint({'dpobj': dpn1});\n\tthis.setByDPArray([dp1]);\n    };\n\n    this.oid = \"2.5.29.31\";\n    if (typeof params != \"undefined\") {\n\tif (typeof params['array'] != \"undefined\") {\n\t    this.setByDPArray(params['array']);\n\t} else if (typeof params['uri'] != \"undefined\") {\n\t    this.setByOneURI(params['uri']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.CRLDistributionPoints, KJUR.asn1.x509.Extension);\n\n/**\n * KeyUsage ASN.1 structure class\n * @name KJUR.asn1.x509.ExtKeyUsage\n * @class ExtKeyUsage ASN.1 structure class\n * @param {Array} params associative array of parameters\n * @extends KJUR.asn1.x509.Extension\n * @description\n * @example\n * var e1 = \n *     new KJUR.asn1.x509.ExtKeyUsage({'critical': true,\n *                                     'array':\n *                                     [{'oid': '2.5.29.37.0',  // anyExtendedKeyUsage\n *                                       'name': 'clientAuth'}]});\n *\n * // id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }\n * // ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId\n * // KeyPurposeId ::= OBJECT IDENTIFIER\n */\nKJUR.asn1.x509.ExtKeyUsage = function(params) {\n    KJUR.asn1.x509.ExtKeyUsage.superclass.constructor.call(this, params);\n\n    this.setPurposeArray = function(purposeArray) {\n\tthis.asn1ExtnValue = new KJUR.asn1.DERSequence();\n\tfor (var i = 0; i < purposeArray.length; i++) {\n\t    var o = new KJUR.asn1.DERObjectIdentifier(purposeArray[i]);\n\t    this.asn1ExtnValue.appendASN1Object(o);\n\t}\n    };\n\n    this.getExtnValueHex = function() {\n\treturn this.asn1ExtnValue.getEncodedHex();\n    };\n\n    this.oid = \"2.5.29.37\";\n    if (typeof params != \"undefined\") {\n\tif (typeof params['array'] != \"undefined\") {\n            this.setPurposeArray(params['array']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.ExtKeyUsage, KJUR.asn1.x509.Extension);\n\n\n// === END   X.509v3 Extensions Related =======================================\n\n// === BEGIN CRL Related ===================================================\n/**\n * X.509 CRL class to sign and generate hex encoded CRL\n * @name KJUR.asn1.x509.CRL\n * @class X.509 CRL class to sign and generate hex encoded certificate\n * @param {Array} params associative array of parameters (ex. {'tbsobj': obj, 'rsaprvkey': key})\n * @extends KJUR.asn1.ASN1Object\n * @since 1.0.3\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>tbsobj - specify {@link KJUR.asn1.x509.TBSCertList} object to be signed</li>\n * <li>rsaprvkey - specify {@link RSAKey} object CA private key</li>\n * </ul>\n * NOTE: 'params' can be omitted.\n * <h4>EXAMPLE</h4>\n * @example\n * var prvKey = new RSAKey(); // CA's private key\n * prvKey.readPrivateKeyFromASN1HexString(\"3080...\");\n * var crl = new KJUR.asn1x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey});\n * crl.sign(); // issue CRL by CA's private key\n * var hCRL = crl.getEncodedHex();\n *\n * // CertificateList  ::=  SEQUENCE  {\n * //     tbsCertList          TBSCertList,\n * //     signatureAlgorithm   AlgorithmIdentifier,\n * //     signatureValue       BIT STRING  }\n */\nKJUR.asn1.x509.CRL = function(params) {\n    KJUR.asn1.x509.CRL.superclass.constructor.call(this);\n\n    var asn1TBSCertList = null;\n    var asn1SignatureAlg = null;\n    var asn1Sig = null;\n    var hexSig = null;\n    var rsaPrvKey = null;\n    \n    /**\n     * set PKCS#5 encrypted RSA PEM private key as CA key\n     * @name setRsaPrvKeyByPEMandPass\n     * @memberOf KJUR.asn1.x509.CRL\n     * @function\n     * @param {String} rsaPEM string of PKCS#5 encrypted RSA PEM private key\n     * @param {String} passPEM passcode string to decrypt private key\n     * @description\n     * <br/>\n     * <h4>EXAMPLES</h4>\n     * @example\n     */\n    this.setRsaPrvKeyByPEMandPass = function(rsaPEM, passPEM) {\n\tvar caKeyHex = PKCS5PKEY.getDecryptedKeyHex(rsaPEM, passPEM);\n\tvar caKey = new RSAKey();\n\tcaKey.readPrivateKeyFromASN1HexString(caKeyHex);  \n\tthis.rsaPrvKey = caKey;\n    };\n\n    /**\n     * sign TBSCertList and set signature value internally\n     * @name sign\n     * @memberOf KJUR.asn1.x509.CRL\n     * @function\n     * @description\n     * @example\n     * var cert = new KJUR.asn1.x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey});\n     * cert.sign();\n     */\n    this.sign = function() {\n\tthis.asn1SignatureAlg = this.asn1TBSCertList.asn1SignatureAlg;\n\n\tsig = new KJUR.crypto.Signature({'alg': 'SHA1withRSA', 'prov': 'cryptojs/jsrsa'});\n\tsig.initSign(this.rsaPrvKey);\n\tsig.updateHex(this.asn1TBSCertList.getEncodedHex());\n\tthis.hexSig = sig.sign();\n\n\tthis.asn1Sig = new KJUR.asn1.DERBitString({'hex': '00' + this.hexSig});\n\t\n\tvar seq = new KJUR.asn1.DERSequence({'array': [this.asn1TBSCertList,\n\t\t\t\t\t\t       this.asn1SignatureAlg,\n\t\t\t\t\t\t       this.asn1Sig]});\n\tthis.hTLV = seq.getEncodedHex();\n\tthis.isModified = false;\n    };\n\n    this.getEncodedHex = function() {\n\tif (this.isModified == false && this.hTLV != null) return this.hTLV;\n\tthrow \"not signed yet\";\n    };\n\n    /**\n     * get PEM formatted CRL string after signed\n     * @name getPEMString\n     * @memberOf KJUR.asn1.x509.CRL\n     * @function\n     * @return PEM formatted string of certificate\n     * @description\n     * @example\n     * var cert = new KJUR.asn1.x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey});\n     * cert.sign();\n     * var sPEM =  cert.getPEMString();\n     */\n    this.getPEMString = function() {\n\tvar hCert = this.getEncodedHex();\n\tvar wCert = CryptoJS.enc.Hex.parse(hCert);\n\tvar b64Cert = CryptoJS.enc.Base64.stringify(wCert);\n\tvar pemBody = b64Cert.replace(/(.{64})/g, \"$1\\r\\n\");\n\treturn \"-----BEGIN X509 CRL-----\\r\\n\" + pemBody + \"\\r\\n-----END X509 CRL-----\\r\\n\";\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['tbsobj'] != \"undefined\") {\n\t    this.asn1TBSCertList = params['tbsobj'];\n\t}\n\tif (typeof params['rsaprvkey'] != \"undefined\") {\n\t    this.rsaPrvKey = params['rsaprvkey'];\n\t}\n\tif ((typeof params['rsaprvpem'] != \"undefined\") &&\n\t    (typeof params['rsaprvpas'] != \"undefined\")) {\n\t    this.setRsaPrvKeyByPEMandPass(params['rsaprvpem'], params['rsaprvpas']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.CRL, KJUR.asn1.ASN1Object);\n\n/**\n * ASN.1 TBSCertList structure class for CRL\n * @name KJUR.asn1.x509.TBSCertList\n * @class ASN.1 TBSCertList structure class for CRL\n * @param {Array} params associative array of parameters (ex. {})\n * @extends KJUR.asn1.ASN1Object\n * @since 1.0.3\n * @description\n * <br/>\n * <h4>EXAMPLE</h4>\n * @example\n *  var o = new KJUR.asn1.x509.TBSCertList();\n *  o.setSignatureAlgByParam({'name': 'SHA1withRSA'});\n *  o.setIssuerByParam({'str': '/C=US/O=a'});\n *  o.setNotThisUpdateByParam({'str': '130504235959Z'});\n *  o.setNotNextUpdateByParam({'str': '140504235959Z'});\n *  o.addRevokedCert({'int': 4}, {'str':'130514235959Z'}));\n *  o.addRevokedCert({'hex': '0f34dd'}, {'str':'130514235959Z'}));\n * \n * // TBSCertList  ::=  SEQUENCE  {\n * //        version                 Version OPTIONAL,\n * //                                     -- if present, MUST be v2\n * //        signature               AlgorithmIdentifier,\n * //        issuer                  Name,\n * //        thisUpdate              Time,\n * //        nextUpdate              Time OPTIONAL,\n * //        revokedCertificates     SEQUENCE OF SEQUENCE  {\n * //             userCertificate         CertificateSerialNumber,\n * //             revocationDate          Time,\n * //             crlEntryExtensions      Extensions OPTIONAL\n * //                                      -- if present, version MUST be v2\n * //                                  }  OPTIONAL,\n * //        crlExtensions           [0]  EXPLICIT Extensions OPTIONAL\n */\nKJUR.asn1.x509.TBSCertList = function(params) {\n    KJUR.asn1.x509.TBSCertList.superclass.constructor.call(this);\n    var aRevokedCert = null;\n\n    /**\n     * set signature algorithm field by parameter\n     * @name setSignatureAlgByParam\n     * @memberOf KJUR.asn1.x509.TBSCertList\n     * @function\n     * @param {Array} algIdParam AlgorithmIdentifier parameter\n     * @description\n     * @example\n     * tbsc.setSignatureAlgByParam({'name': 'SHA1withRSA'});\n     */\n    this.setSignatureAlgByParam = function(algIdParam) {\n\tthis.asn1SignatureAlg = new KJUR.asn1.x509.AlgorithmIdentifier(algIdParam);\n    };\n\n    /**\n     * set issuer name field by parameter\n     * @name setIssuerByParam\n     * @memberOf KJUR.asn1.x509.TBSCertList\n     * @function\n     * @param {Array} x500NameParam X500Name parameter\n     * @description\n     * @example\n     * tbsc.setIssuerParam({'str': '/C=US/CN=b'});\n     * @see KJUR.asn1.x509.X500Name\n     */\n    this.setIssuerByParam = function(x500NameParam) {\n\tthis.asn1Issuer = new KJUR.asn1.x509.X500Name(x500NameParam);\n    };\n\n    /**\n     * set thisUpdate field by parameter\n     * @name setThisUpdateByParam\n     * @memberOf KJUR.asn1.x509.TBSCertList\n     * @function\n     * @param {Array} timeParam Time parameter\n     * @description\n     * @example\n     * tbsc.setThisUpdateByParam({'str': '130508235959Z'});\n     * @see KJUR.asn1.x509.Time\n     */\n    this.setThisUpdateByParam = function(timeParam) {\n\tthis.asn1ThisUpdate = new KJUR.asn1.x509.Time(timeParam);\n    };\n\n    /**\n     * set nextUpdate field by parameter\n     * @name setNextUpdateByParam\n     * @memberOf KJUR.asn1.x509.TBSCertList\n     * @function\n     * @param {Array} timeParam Time parameter\n     * @description\n     * @example\n     * tbsc.setNextUpdateByParam({'str': '130508235959Z'});\n     * @see KJUR.asn1.x509.Time\n     */\n    this.setNextUpdateByParam = function(timeParam) {\n\tthis.asn1NextUpdate = new KJUR.asn1.x509.Time(timeParam);\n    };\n\n    /**\n     * add revoked certficate by parameter\n     * @name addRevokedCert\n     * @memberOf KJUR.asn1.x509.TBSCertList\n     * @function\n     * @param {Array} snParam DERInteger parameter for certificate serial number\n     * @param {Array} timeParam Time parameter for revocation date\n     * @description\n     * @example\n     * tbsc.addRevokedCert({'int': 3}, {'str': '130508235959Z'});\n     * @see KJUR.asn1.x509.Time\n     */\n    this.addRevokedCert = function(snParam, timeParam) {\n\tvar param = {};\n\tif (snParam != undefined && snParam != null) param['sn'] = snParam;\n\tif (timeParam != undefined && timeParam != null) param['time'] = timeParam;\n\tvar o = new KJUR.asn1.x509.CRLEntry(param);\n\tthis.aRevokedCert.push(o);\n    };\n\n    this.getEncodedHex = function() {\n\tthis.asn1Array = new Array();\n\n\tif (this.asn1Version != null) this.asn1Array.push(this.asn1Version);\n\tthis.asn1Array.push(this.asn1SignatureAlg);\n\tthis.asn1Array.push(this.asn1Issuer);\n\tthis.asn1Array.push(this.asn1ThisUpdate);\n\tif (this.asn1NextUpdate != null) this.asn1Array.push(this.asn1NextUpdate);\n\n\tif (this.aRevokedCert.length > 0) {\n\t    var seq = new KJUR.asn1.DERSequence({'array': this.aRevokedCert});\n\t    this.asn1Array.push(seq);\n\t}\n\n\tvar o = new KJUR.asn1.DERSequence({\"array\": this.asn1Array});\n\tthis.hTLV = o.getEncodedHex();\n\tthis.isModified = false;\n\treturn this.hTLV;\n    };\n\n    this._initialize = function() {\n\tthis.asn1Version = null;\n\tthis.asn1SignatureAlg = null;\n\tthis.asn1Issuer = null;\n\tthis.asn1ThisUpdate = null;\n\tthis.asn1NextUpdate = null;\n\tthis.aRevokedCert = new Array();\n    };\n\n    this._initialize();\n};\nYAHOO.lang.extend(KJUR.asn1.x509.TBSCertList, KJUR.asn1.ASN1Object);\n\n/**\n * ASN.1 CRLEntry structure class for CRL\n * @name KJUR.asn1.x509.CRLEntry\n * @class ASN.1 CRLEntry structure class for CRL\n * @param {Array} params associative array of parameters (ex. {})\n * @extends KJUR.asn1.ASN1Object\n * @since 1.0.3\n * @description\n * @example\n * var e = new KJUR.asn1.x509.CRLEntry({'time': {'str': '130514235959Z'}, 'sn': {'int': 234}});\n * \n * // revokedCertificates     SEQUENCE OF SEQUENCE  {\n * //     userCertificate         CertificateSerialNumber,\n * //     revocationDate          Time,\n * //     crlEntryExtensions      Extensions OPTIONAL\n * //                             -- if present, version MUST be v2 }\n */\nKJUR.asn1.x509.CRLEntry = function(params) {\n    KJUR.asn1.x509.CRLEntry.superclass.constructor.call(this);\n    var sn = null;\n    var time = null;\n\n    /**\n     * set DERInteger parameter for serial number of revoked certificate \n     * @name setCertSerial\n     * @memberOf KJUR.asn1.x509.CRLEntry\n     * @function\n     * @param {Array} intParam DERInteger parameter for certificate serial number\n     * @description\n     * @example\n     * entry.setCertSerial({'int': 3});\n     */\n    this.setCertSerial = function(intParam) {\n\tthis.sn = new KJUR.asn1.DERInteger(intParam);\n    };\n\n    /**\n     * set Time parameter for revocation date\n     * @name setRevocationDate\n     * @memberOf KJUR.asn1.x509.CRLEntry\n     * @function\n     * @param {Array} timeParam Time parameter for revocation date\n     * @description\n     * @example\n     * entry.setRevocationDate({'str': '130508235959Z'});\n     */\n    this.setRevocationDate = function(timeParam) {\n\tthis.time = new KJUR.asn1.x509.Time(timeParam);\n    };\n\n    this.getEncodedHex = function() {\n\tvar o = new KJUR.asn1.DERSequence({\"array\": [this.sn, this.time]});\n\tthis.TLV = o.getEncodedHex();\n\treturn this.TLV;\n    };\n    \n    if (typeof params != \"undefined\") {\n\tif (typeof params['time'] != \"undefined\") {\n\t    this.setRevocationDate(params['time']);\n\t}\n\tif (typeof params['sn'] != \"undefined\") {\n\t    this.setCertSerial(params['sn']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.CRLEntry, KJUR.asn1.ASN1Object);\n\n// === END   CRL Related ===================================================\n\n// === BEGIN X500Name Related =================================================\n/**\n * X500Name ASN.1 structure class\n * @name KJUR.asn1.x509.X500Name\n * @class X500Name ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'str': '/C=US/O=a'})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @example\n */\nKJUR.asn1.x509.X500Name = function(params) {\n    KJUR.asn1.x509.X500Name.superclass.constructor.call(this);\n    this.asn1Array = new Array();\n\n    this.setByString = function(dnStr) {\n\tvar a = dnStr.split('/');\n\ta.shift();\n\tfor (var i = 0; i < a.length; i++) {\n\t    this.asn1Array.push(new KJUR.asn1.x509.RDN({'str':a[i]}));\n\t}\n    };\n\n    this.getEncodedHex = function() {\n\tvar o = new KJUR.asn1.DERSequence({\"array\": this.asn1Array});\n\tthis.TLV = o.getEncodedHex();\n\treturn this.TLV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['str'] != \"undefined\") {\n\t    this.setByString(params['str']);\n\t}\n    }\n\n};\nYAHOO.lang.extend(KJUR.asn1.x509.X500Name, KJUR.asn1.ASN1Object);\n\n/**\n * RDN (Relative Distinguish Name) ASN.1 structure class\n * @name KJUR.asn1.x509.RDN\n * @class RDN (Relative Distinguish Name) ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'str': 'C=US'})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @example\n */\nKJUR.asn1.x509.RDN = function(params) {\n    KJUR.asn1.x509.RDN.superclass.constructor.call(this);\n    this.asn1Array = new Array();\n\n    this.addByString = function(rdnStr) {\n\tthis.asn1Array.push(new KJUR.asn1.x509.AttributeTypeAndValue({'str':rdnStr}));\n    };\n\n    this.getEncodedHex = function() {\n\tvar o = new KJUR.asn1.DERSet({\"array\": this.asn1Array});\n\tthis.TLV = o.getEncodedHex();\n\treturn this.TLV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['str'] != \"undefined\") {\n\t    this.addByString(params['str']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.RDN, KJUR.asn1.ASN1Object);\n\n/**\n * AttributeTypeAndValue ASN.1 structure class\n * @name KJUR.asn1.x509.AttributeTypeAndValue\n * @class AttributeTypeAndValue ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'str': 'C=US'})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @example\n */\nKJUR.asn1.x509.AttributeTypeAndValue = function(params) {\n    KJUR.asn1.x509.AttributeTypeAndValue.superclass.constructor.call(this);\n    var typeObj = null;\n    var valueObj = null;\n    var defaultDSType = \"utf8\";\n\n    this.setByString = function(attrTypeAndValueStr) {\n\tif (attrTypeAndValueStr.match(/^([^=]+)=(.+)$/)) {\n\t    this.setByAttrTypeAndValueStr(RegExp.$1, RegExp.$2);\n\t} else {\n\t    throw \"malformed attrTypeAndValueStr: \" + attrTypeAndValueStr;\n\t}\n    };\n\n    this.setByAttrTypeAndValueStr = function(shortAttrType, valueStr) {\n\tthis.typeObj = KJUR.asn1.x509.OID.atype2obj(shortAttrType);\n\tvar dsType = defaultDSType;\n\tif (shortAttrType == \"C\") dsType = \"prn\";\n\tthis.valueObj = this.getValueObj(dsType, valueStr);\n    };\n\n    this.getValueObj = function(dsType, valueStr) {\n\tif (dsType == \"utf8\")\treturn new KJUR.asn1.DERUTF8String({\"str\": valueStr});\n\tif (dsType == \"prn\")\treturn new KJUR.asn1.DERPrintableString({\"str\": valueStr});\n\tif (dsType == \"tel\")\treturn new KJUR.asn1.DERTeletexString({\"str\": valueStr});\n\tif (dsType == \"ia5\")\treturn new KJUR.asn1.DERIA5String({\"str\": valueStr});\n\tthrow \"unsupported directory string type: type=\" + dsType + \" value=\" + valueStr;\n    };\n\n    this.getEncodedHex = function() {\n\tvar o = new KJUR.asn1.DERSequence({\"array\": [this.typeObj, this.valueObj]});\n\tthis.TLV = o.getEncodedHex();\n\treturn this.TLV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['str'] != \"undefined\") {\n\t    this.setByString(params['str']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.AttributeTypeAndValue, KJUR.asn1.ASN1Object);\n\n// === END   X500Name Related =================================================\n\n// === BEGIN Other ASN1 structure class  ======================================\n\n/**\n * SubjectPublicKeyInfo ASN.1 structure class\n * @name KJUR.asn1.x509.SubjectPublicKeyInfo\n * @class SubjectPublicKeyInfo ASN.1 structure class\n * @param {Object} params parameter for subject public key\n * @extends KJUR.asn1.ASN1Object\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>{@link RSAKey} object</li>\n * <li>{@link KJUR.crypto.ECDSA} object</li>\n * <li>{@link KJUR.crypto.DSA} object</li>\n * <li>(DEPRECATED)rsakey - specify {@link RSAKey} object of subject public key</li>\n * <li>(DEPRECATED)rsapem - specify a string of PEM public key of RSA key</li>\n * </ul>\n * NOTE1: 'params' can be omitted.<br/>\n * NOTE2: DSA/ECDSA key object is also supported since asn1x509 1.0.6.<br/>\n * <h4>EXAMPLE</h4>\n * @example\n * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(RSAKey_object);\n * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoECDSA_object);\n * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoDSA_object);\n */\nKJUR.asn1.x509.SubjectPublicKeyInfo = function(params) {\n    KJUR.asn1.x509.SubjectPublicKeyInfo.superclass.constructor.call(this);\n    var asn1AlgId = null;\n    var asn1SubjPKey = null;\n    var rsaKey = null;\n\n    /**\n     * (DEPRECATED) set RSAKey object as subject public key\n     * @name setRSAKey\n     * @memberOf KJUR.asn1.x509.SubjectPublicKeyInfo\n     * @function\n     * @param {RSAKey} rsaKey {@link RSAKey} object for RSA public key\n     * @description\n     * @deprecated\n     * @example\n     * spki.setRSAKey(rsaKey);\n     */\n    this.setRSAKey = function(rsaKey) {\n\tif (! RSAKey.prototype.isPrototypeOf(rsaKey))\n\t    throw \"argument is not RSAKey instance\";\n        this.rsaKey = rsaKey;\n\tvar asn1RsaN = new KJUR.asn1.DERInteger({'bigint': rsaKey.n});\n\tvar asn1RsaE = new KJUR.asn1.DERInteger({'int': rsaKey.e});\n\tvar asn1RsaPub = new KJUR.asn1.DERSequence({'array': [asn1RsaN, asn1RsaE]});\n\tvar rsaKeyHex = asn1RsaPub.getEncodedHex();\n\tthis.asn1AlgId = new KJUR.asn1.x509.AlgorithmIdentifier({'name':'rsaEncryption'});\n\tthis.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex':'00'+rsaKeyHex});\n    };\n\n    /**\n     * (DEPRECATED) set a PEM formatted RSA public key string as RSA public key\n     * @name setRSAPEM\n     * @memberOf KJUR.asn1.x509.SubjectPublicKeyInfo\n     * @function\n     * @param {String} rsaPubPEM PEM formatted RSA public key string\n     * @deprecated\n     * @description\n     * @example\n     * spki.setRSAPEM(rsaPubPEM);\n     */\n    this.setRSAPEM = function(rsaPubPEM) {\n\tif (rsaPubPEM.match(/-----BEGIN PUBLIC KEY-----/)) {\n\t    var s = rsaPubPEM;\n\t    s = s.replace(/^-----[^-]+-----/, '');\n\t    s = s.replace(/-----[^-]+-----\\s*$/, '');\n\t    var rsaB64 = s.replace(/\\s+/g, '');\n\t    var rsaWA = CryptoJS.enc.Base64.parse(rsaB64);\n\t    var rsaP8Hex = CryptoJS.enc.Hex.stringify(rsaWA);\n\t    var a = _rsapem_getHexValueArrayOfChildrenFromHex(rsaP8Hex);\n\t    var hBitStrVal = a[1];\n\t    var rsaHex = hBitStrVal.substr(2);\n\t    var a3 = _rsapem_getHexValueArrayOfChildrenFromHex(rsaHex);\n\t    var rsaKey = new RSAKey();\n\t    rsaKey.setPublic(a3[0], a3[1]);\n\t    this.setRSAKey(rsaKey);\n\t} else {\n\t    throw \"key not supported\";\n\t}\n    };\n\n    /*\n     * @since asn1x509 1.0.7\n     */\n    this.getASN1Object = function() {\n\tif (this.asn1AlgId == null || this.asn1SubjPKey == null)\n\t    throw \"algId and/or subjPubKey not set\";\n\tvar o = new KJUR.asn1.DERSequence({'array':\n\t\t\t\t\t   [this.asn1AlgId, this.asn1SubjPKey]});\n\treturn o;\n    };\n\n    this.getEncodedHex = function() {\n\tvar o = this.getASN1Object();\n\tthis.hTLV = o.getEncodedHex();\n\treturn this.hTLV;\n    };\n\n    this._setRSAKey = function(key) {\n\tvar asn1RsaPub = KJUR.asn1.ASN1Util.newObject({\n\t\t'seq': [{'int': {'bigint': key.n}}, {'int': {'int': key.e}}]\n\t    });\n\tvar rsaKeyHex = asn1RsaPub.getEncodedHex();\n\tthis.asn1AlgId = new KJUR.asn1.x509.AlgorithmIdentifier({'name':'rsaEncryption'});\n\tthis.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex':'00'+rsaKeyHex});\n    };\n\n    this._setEC = function(key) {\n\tvar asn1Params = new KJUR.asn1.DERObjectIdentifier({'name': key.curveName});\n\tthis.asn1AlgId = \n\t    new KJUR.asn1.x509.AlgorithmIdentifier({'name': 'ecPublicKey',\n\t\t\t\t\t\t    'asn1params': asn1Params});\n\tthis.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex': '00' + key.pubKeyHex});\n    };\n\n    this._setDSA = function(key) {\n\tvar asn1Params = new KJUR.asn1.ASN1Util.newObject({\n\t\t'seq': [{'int': {'bigint': key.p}},\n\t                {'int': {'bigint': key.q}},\n\t                {'int': {'bigint': key.g}}]\n\t    });\n\tthis.asn1AlgId = \n\t    new KJUR.asn1.x509.AlgorithmIdentifier({'name': 'dsa',\n\t\t\t\t\t\t    'asn1params': asn1Params});\n\tvar pubInt = new KJUR.asn1.DERInteger({'bigint': key.y});\n\tthis.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex': '00' + pubInt.getEncodedHex()});\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof RSAKey != 'undefined' && params instanceof RSAKey) {\n\t    this._setRSAKey(params);\n\t} else if (typeof KJUR.crypto.ECDSA != 'undefined' &&\n\t\t   params instanceof KJUR.crypto.ECDSA) {\n\t    this._setEC(params);\n\t} else if (typeof KJUR.crypto.DSA != 'undefined' &&\n\t\t   params instanceof KJUR.crypto.DSA) {\n\t    this._setDSA(params);\n\t} else if (typeof params['rsakey'] != \"undefined\") {\n\t    this.setRSAKey(params['rsakey']);\n\t} else if (typeof params['rsapem'] != \"undefined\") {\n\t    this.setRSAPEM(params['rsapem']);\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.SubjectPublicKeyInfo, KJUR.asn1.ASN1Object);\n\n/**\n * Time ASN.1 structure class\n * @name KJUR.asn1.x509.Time\n * @class Time ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'str': '130508235959Z'})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * <br/>\n * <h4>EXAMPLES</h4>\n * @example\n * var t1 = new KJUR.asn1.x509.Time{'str': '130508235959Z'} // UTCTime by default\n * var t2 = new KJUR.asn1.x509.Time{'type': 'gen',  'str': '20130508235959Z'} // GeneralizedTime\n */\nKJUR.asn1.x509.Time = function(params) {\n    KJUR.asn1.x509.Time.superclass.constructor.call(this);\n    var type = null;\n    var timeParams = null;\n\n    this.setTimeParams = function(timeParams) {\n\tthis.timeParams = timeParams;\n    }\n\n    this.getEncodedHex = function() {\n\tif (this.timeParams == null) {\n\t    throw \"timeParams shall be specified. ({'str':'130403235959Z'}}\";\n\t}\n\tvar o = null;\n\tif (this.type == \"utc\") {\n\t    o = new KJUR.asn1.DERUTCTime(this.timeParams);\n\t} else {\n\t    o = new KJUR.asn1.DERGeneralizedTime(this.timeParams);\n\t}\n\tthis.TLV = o.getEncodedHex();\n\treturn this.TLV;\n    };\n \n    this.type = \"utc\";\n    if (typeof params != \"undefined\") {\n\tif (typeof params['type'] != \"undefined\") {\n\t    this.type = params['type'];\n\t}\n\tthis.timeParams = params;\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.Time, KJUR.asn1.ASN1Object);\n\n/**\n * AlgorithmIdentifier ASN.1 structure class\n * @name KJUR.asn1.x509.AlgorithmIdentifier\n * @class AlgorithmIdentifier ASN.1 structure class\n * @param {Array} params associative array of parameters (ex. {'name': 'SHA1withRSA'})\n * @extends KJUR.asn1.ASN1Object\n * @description\n * @example\n */\nKJUR.asn1.x509.AlgorithmIdentifier = function(params) {\n    KJUR.asn1.x509.AlgorithmIdentifier.superclass.constructor.call(this);\n    var nameAlg = null;\n    var asn1Alg = null;\n    var asn1Params = null;\n    var paramEmpty = false;\n\n    this.getEncodedHex = function() {\n\tif (this.nameAlg == null && this.asn1Alg == null) {\n\t    throw \"algorithm not specified\";\n\t}\n\tif (this.nameAlg != null && this.asn1Alg == null) {\n\t    this.asn1Alg = KJUR.asn1.x509.OID.name2obj(this.nameAlg);\n\t}\n\tvar a = [this.asn1Alg];\n\tif (! this.paramEmpty) a.push(this.asn1Params);\n\tvar o = new KJUR.asn1.DERSequence({'array': a});\n\tthis.hTLV = o.getEncodedHex();\n\treturn this.hTLV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['name'] != \"undefined\") {\n\t    this.nameAlg = params['name'];\n\t}\n\tif (typeof params['asn1params'] != \"undefined\") {\n\t    this.asn1Params = params['asn1params'];\n\t}\n\tif (typeof params['paramempty'] != \"undefined\") {\n\t    this.paramEmpty = params['paramempty'];\n\t}\n    }\n    if (this.asn1Params == null) {\n\tthis.asn1Params = new KJUR.asn1.DERNull();\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.AlgorithmIdentifier, KJUR.asn1.ASN1Object);\n\n/**\n * GeneralName ASN.1 structure class\n * @name KJUR.asn1.x509.GeneralName\n * @class GeneralName ASN.1 structure class\n * @description\n * <br/>\n * As for argument 'params' for constructor, you can specify one of\n * following properties:\n * <ul>\n * <li>rfc822 - rfc822Name[1] (ex. user1@foo.com)</li>\n * <li>dns - dNSName[2] (ex. foo.com)</li>\n * <li>uri - uniformResourceIdentifier[6] (ex. http://foo.com/)</li>\n * </ul>\n * NOTE: Currently this only supports 'uniformResourceIdentifier'.\n * <h4>EXAMPLE AND ASN.1 SYNTAX</h4>\n * @example\n * var gn = new KJUR.asn1.x509.GeneralName({'uri': 'http://aaa.com/'});\n *\n * GeneralName ::= CHOICE {\n *         otherName                       [0]     OtherName,\n *         rfc822Name                      [1]     IA5String,\n *         dNSName                         [2]     IA5String,\n *         x400Address                     [3]     ORAddress,\n *         directoryName                   [4]     Name,\n *         ediPartyName                    [5]     EDIPartyName,\n *         uniformResourceIdentifier       [6]     IA5String,\n *         iPAddress                       [7]     OCTET STRING,\n *         registeredID                    [8]     OBJECT IDENTIFIER } \n */\nKJUR.asn1.x509.GeneralName = function(params) {\n    KJUR.asn1.x509.GeneralName.superclass.constructor.call(this);\n    var asn1Obj = null;\n    var type = null;\n    var pTag = {'rfc822': '81', 'dns': '82', 'uri': '86'};\n\n    this.setByParam = function(params) {\n\tvar str = null;\n\tvar v = null;\n\n\tif (typeof params['rfc822'] != \"undefined\") {\n\t    this.type = 'rfc822';\n\t    v = new KJUR.asn1.DERIA5String({'str': params[this.type]});\n\t}\n\tif (typeof params['dns'] != \"undefined\") {\n\t    this.type = 'dns';\n\t    v = new KJUR.asn1.DERIA5String({'str': params[this.type]});\n\t}\n\tif (typeof params['uri'] != \"undefined\") {\n\t    this.type = 'uri';\n\t    v = new KJUR.asn1.DERIA5String({'str': params[this.type]});\n\t}\n\n\tif (this.type == null)\n\t    throw \"unsupported type in params=\" + params;\n        this.asn1Obj = new KJUR.asn1.DERTaggedObject({'explicit': false,\n\t\t\t\t\t\t      'tag': pTag[this.type],\n\t\t\t\t\t\t      'obj': v});\n    };\n\n    this.getEncodedHex = function() {\n\treturn this.asn1Obj.getEncodedHex();\n    }\n\n    if (typeof params != \"undefined\") {\n\tthis.setByParam(params);\n    }\n\n};\nYAHOO.lang.extend(KJUR.asn1.x509.GeneralName, KJUR.asn1.ASN1Object);\n\n/**\n * GeneralNames ASN.1 structure class\n * @name KJUR.asn1.x509.GeneralNames\n * @class GeneralNames ASN.1 structure class\n * @description\n * <br/>\n * <h4>EXAMPLE AND ASN.1 SYNTAX</h4>\n * @example\n * var gns = new KJUR.asn1.x509.GeneralNames([{'uri': 'http://aaa.com/'}, {'uri': 'http://bbb.com/'}]); \n *\n * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName\n */\nKJUR.asn1.x509.GeneralNames = function(paramsArray) {\n    KJUR.asn1.x509.GeneralNames.superclass.constructor.call(this);\n    var asn1Array = null;\n\n    /**\n     * set a array of {@link KJUR.asn1.x509.GeneralName} parameters\n     * @name setByParamArray\n     * @memberOf KJUR.asn1.x509.GeneralNames\n     * @function\n     * @param {Array} paramsArray Array of {@link KJUR.asn1.x509.GeneralNames}\n     * @description\n     * <br/>\n     * <h4>EXAMPLES</h4>\n     * @example\n     * var gns = new KJUR.asn1.x509.GeneralNames();\n     * gns.setByParamArray([{'uri': 'http://aaa.com/'}, {'uri': 'http://bbb.com/'}]);\n     */\n    this.setByParamArray = function(paramsArray) {\n\tfor (var i = 0; i < paramsArray.length; i++) {\n\t    var o = new KJUR.asn1.x509.GeneralName(paramsArray[i]);\n\t    this.asn1Array.push(o);\n\t}\n    };\n\n    this.getEncodedHex = function() {\n\tvar o = new KJUR.asn1.DERSequence({'array': this.asn1Array});\n\treturn o.getEncodedHex();\n    };\n\n    this.asn1Array = new Array();\n    if (typeof paramsArray != \"undefined\") {\n\tthis.setByParamArray(paramsArray);\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.GeneralNames, KJUR.asn1.ASN1Object);\n\n/**\n * DistributionPointName ASN.1 structure class\n * @name KJUR.asn1.x509.DistributionPointName\n * @class DistributionPointName ASN.1 structure class\n * @description\n * @example\n */\nKJUR.asn1.x509.DistributionPointName = function(gnOrRdn) {\n    KJUR.asn1.x509.DistributionPointName.superclass.constructor.call(this);\n    var asn1Obj = null;\n    var type = null;\n    var tag = null;\n    var asn1V = null;\n\n    this.getEncodedHex = function() {\n\tif (this.type != \"full\")\n\t    throw \"currently type shall be 'full': \" + this.type;\n\tthis.asn1Obj = new KJUR.asn1.DERTaggedObject({'explicit': false,\n\t\t\t\t\t\t      'tag': this.tag,\n\t\t\t\t\t\t      'obj': this.asn1V});\n\tthis.hTLV = this.asn1Obj.getEncodedHex();\n\treturn this.hTLV;\n    };\n\n    if (typeof gnOrRdn != \"undefined\") {\n\tif (KJUR.asn1.x509.GeneralNames.prototype.isPrototypeOf(gnOrRdn)) {\n\t    this.type = \"full\";\n\t    this.tag = \"a0\";\n\t    this.asn1V = gnOrRdn;\n\t} else {\n\t    throw \"This class supports GeneralNames only as argument\";\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.DistributionPointName, KJUR.asn1.ASN1Object);\n\n/**\n * DistributionPoint ASN.1 structure class\n * @name KJUR.asn1.x509.DistributionPoint\n * @class DistributionPoint ASN.1 structure class\n * @description\n * @example\n */\nKJUR.asn1.x509.DistributionPoint = function(params) {\n    KJUR.asn1.x509.DistributionPoint.superclass.constructor.call(this);\n    var asn1DP = null;\n\n    this.getEncodedHex = function() {\n\tvar seq = new KJUR.asn1.DERSequence();\n\tif (this.asn1DP != null) {\n\t    var o1 = new KJUR.asn1.DERTaggedObject({'explicit': true,\n\t\t\t\t\t\t    'tag': 'a0',\n\t\t\t\t\t\t    'obj': this.asn1DP});\n\t    seq.appendASN1Object(o1);\n\t}\n\tthis.hTLV = seq.getEncodedHex();\n\treturn this.hTLV;\n    };\n\n    if (typeof params != \"undefined\") {\n\tif (typeof params['dpobj'] != \"undefined\") {\n\t    this.asn1DP = params['dpobj'];\n\t}\n    }\n};\nYAHOO.lang.extend(KJUR.asn1.x509.DistributionPoint, KJUR.asn1.ASN1Object);\n\n/**\n * static object for OID\n * @name KJUR.asn1.x509.OID\n * @class static object for OID\n * @property {Assoc Array} atype2oidList for short attribyte type name and oid (i.e. 'C' and '2.5.4.6')\n * @property {Assoc Array} name2oidList for oid name and oid (i.e. 'keyUsage' and '2.5.29.15')\n * @property {Assoc Array} objCache for caching name and DERObjectIdentifier object \n * @description\n * <dl>\n * <dt><b>atype2oidList</b>\n * <dd>currently supports 'C', 'O', 'OU', 'ST', 'L' and 'CN' only.\n * <dt><b>name2oidList</b>\n * <dd>currently supports 'SHA1withRSA', 'rsaEncryption' and some extension OIDs\n * </dl>\n * @example\n */\nKJUR.asn1.x509.OID = new function(params) {\n    this.atype2oidList = {\n\t'C':\t'2.5.4.6',\n\t'O':\t'2.5.4.10',\n\t'OU':\t'2.5.4.11',\n\t'ST':\t'2.5.4.8',\n\t'L':\t'2.5.4.7',\n\t'CN':\t'2.5.4.3',\n    };\n    this.name2oidList = {\n\t'sha384':\t\t\t'2.16.840.1.101.3.4.2.2',\n\t'sha224':\t\t\t'2.16.840.1.101.3.4.2.4',\n\n\t'MD2withRSA':\t\t\t'1.2.840.113549.1.1.2',\n\t'MD4withRSA':\t\t\t'1.2.840.113549.1.1.3',\n\t'MD5withRSA':\t\t\t'1.2.840.113549.1.1.4',\n\t'SHA1withRSA':\t\t\t'1.2.840.113549.1.1.5',\n\t'SHA224withRSA':\t\t'1.2.840.113549.1.1.14',\n\t'SHA256withRSA':\t\t'1.2.840.113549.1.1.11',\n\t'SHA384withRSA':\t\t'1.2.840.113549.1.1.12',\n\t'SHA512withRSA':\t\t'1.2.840.113549.1.1.13',\n\n\t'SHA1withECDSA':\t\t'1.2.840.10045.4.1',\n\t'SHA224withECDSA':\t\t'1.2.840.10045.4.3.1',\n\t'SHA256withECDSA':\t\t'1.2.840.10045.4.3.2',\n\t'SHA384withECDSA':\t\t'1.2.840.10045.4.3.3',\n\t'SHA512withECDSA':\t\t'1.2.840.10045.4.3.4',\n\n\t'dsa':\t\t\t\t'1.2.840.10040.4.1',\n\t'SHA1withDSA':\t\t\t'1.2.840.10040.4.3',\n\t'SHA224withDSA':\t\t'2.16.840.1.101.3.4.3.1',\n\t'SHA256withDSA':\t\t'2.16.840.1.101.3.4.3.2',\n\n        'rsaEncryption':\t\t'1.2.840.113549.1.1.1',\n\t'subjectKeyIdentifier':\t\t'2.5.29.14',\n\n\t'countryName':\t\t\t'2.5.4.6',\n\t'organization':\t\t\t'2.5.4.10',\n\t'organizationalUnit':\t\t'2.5.4.11',\n\t'stateOrProvinceName':\t\t'2.5.4.8',\n\t'locality':\t\t\t'2.5.4.7',\n\t'commonName':\t\t\t'2.5.4.3',\n\n\t'keyUsage':\t\t\t'2.5.29.15',\n\t'basicConstraints':\t\t'2.5.29.19',\n\t'cRLDistributionPoints':\t'2.5.29.31',\n\t'certificatePolicies':\t\t'2.5.29.32',\n\t'authorityKeyIdentifier':\t'2.5.29.35',\n\t'extKeyUsage':\t\t\t'2.5.29.37',\n\n\t'anyExtendedKeyUsage':\t\t'2.5.29.37.0',\n\t'serverAuth':\t\t\t'1.3.6.1.5.5.7.3.1',\n\t'clientAuth':\t\t\t'1.3.6.1.5.5.7.3.2',\n\t'codeSigning':\t\t\t'1.3.6.1.5.5.7.3.3',\n\t'emailProtection':\t\t'1.3.6.1.5.5.7.3.4',\n\t'timeStamping':\t\t\t'1.3.6.1.5.5.7.3.8',\n\t'ocspSigning':\t\t\t'1.3.6.1.5.5.7.3.9',\n\n\t'ecPublicKey':\t\t\t'1.2.840.10045.2.1',\n\t'secp256r1':\t\t\t'1.2.840.10045.3.1.7',\n\t'secp256k1':\t\t\t'1.3.132.0.10',\n\t'secp384r1':\t\t\t'1.3.132.0.34',\n\n\t'pkcs5PBES2':\t\t\t'1.2.840.113549.1.5.13',\n\t'pkcs5PBKDF2':\t\t\t'1.2.840.113549.1.5.12',\n\n\t'des-EDE3-CBC':\t\t\t'1.2.840.113549.3.7',\n    };\n\n    this.objCache = {};\n\n    /**\n     * get DERObjectIdentifier by registered OID name\n     * @name name2obj\n     * @memberOf KJUR.asn1.x509.OID\n     * @function\n     * @param {String} name OID\n     * @description\n     * @example\n     * var asn1ObjOID = OID.name2obj('SHA1withRSA');\n     */\n    this.name2obj = function(name) {\n\tif (typeof this.objCache[name] != \"undefined\")\n\t    return this.objCache[name];\n\tif (typeof this.name2oidList[name] == \"undefined\")\n\t    throw \"Name of ObjectIdentifier not defined: \" + name;\n\tvar oid = this.name2oidList[name];\n\tvar obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid});\n\tthis.objCache[name] = obj;\n\treturn obj;\n    };\n\n    /**\n     * get DERObjectIdentifier by registered attribyte type name such like 'C' or 'CN'\n     * @name atype2obj\n     * @memberOf KJUR.asn1.x509.OID\n     * @function\n     * @param {String} atype short attribute type name such like 'C' or 'CN'\n     * @description\n     * @example\n     * var asn1ObjOID = OID.atype2obj('CN');\n     */\n    this.atype2obj = function(atype) {\n\tif (typeof this.objCache[atype] != \"undefined\")\n\t    return this.objCache[atype];\n\tif (typeof this.atype2oidList[atype] == \"undefined\")\n\t    throw \"AttributeType name undefined: \" + atype;\n\tvar oid = this.atype2oidList[atype];\n\tvar obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid});\n\tthis.objCache[atype] = obj;\n\treturn obj;\n    };\n};\n\n/**\n * X.509 certificate and CRL utilities class\n * @name KJUR.asn1.x509.X509Util\n * @class X.509 certificate and CRL utilities class\n */\nKJUR.asn1.x509.X509Util = new function() {\n    /**\n     * get PKCS#8 PEM public key string from RSAKey object\n     * @name getPKCS8PubKeyPEMfromRSAKey\n     * @memberOf KJUR.asn1.x509.X509Util\n     * @function\n     * @param {RSAKey} rsaKey RSA public key of {@link RSAKey} object\n     * @description\n     * @example\n     * var pem = KJUR.asn1.x509.X509Util.getPKCS8PubKeyPEMfromRSAKey(pubKey);\n     */\n   this.getPKCS8PubKeyPEMfromRSAKey = function(rsaKey) {\n       var pem = null;\n       var hN = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(rsaKey.n);\n       var hE = KJUR.asn1.ASN1Util.integerToByteHex(rsaKey.e);\n       var iN = new KJUR.asn1.DERInteger({hex: hN});\n       var iE = new KJUR.asn1.DERInteger({hex: hE});\n       var asn1PubKey = new KJUR.asn1.DERSequence({array: [iN, iE]});\n       var hPubKey = asn1PubKey.getEncodedHex();\n       var o1 = new KJUR.asn1.x509.AlgorithmIdentifier({name: 'rsaEncryption'});\n       var o2 = new KJUR.asn1.DERBitString({hex: '00' + hPubKey});\n       var seq = new KJUR.asn1.DERSequence({array: [o1, o2]});\n       var hP8 = seq.getEncodedHex();\n       var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(hP8, \"PUBLIC KEY\");\n       return pem;\n   };\n};\n/**\n * issue a certificate in PEM format\n * @name newCertPEM\n * @memberOf KJUR.asn1.x509.X509Util\n * @function\n * @param {Array} param parameter to issue a certificate\n * @since asn1x509 1.0.6\n * @description\n * This method can issue a certificate by a simple\n * JSON object.\n * NOTE: When using DSA or ECDSA CA signing key,\n * use 'paramempty' in 'sigalg' to ommit parameter field\n * of AlgorithmIdentifer. In case of RSA, parameter\n * NULL will be specified by default.\n * @example\n * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM(\n * { serial: {int: 4},\n *   sigalg: {name: 'SHA1withECDSA', paramempty: true},\n *   issuer: {str: '/C=US/O=a'},\n *   notbefore: {'str': '130504235959Z'},\n *   notafter: {'str': '140504235959Z'},\n *   subject: {str: '/C=US/O=b'},\n *   sbjpubkey: pubKeyPEM,\n *   ext: [\n *     {basicConstraints: {cA: true, critical: true}},\n *     {keyUsage: {bin: '11'}},\n *   ],\n *   cakey: [prvkey, pass]}\n * );\n */\nKJUR.asn1.x509.X509Util.newCertPEM = function(param) {\n    var ns1 = KJUR.asn1.x509;\n    var o = new ns1.TBSCertificate();\n\n    if (param.serial !== undefined)\n\to.setSerialNumberByParam(param.serial);\n    else\n\tthrow \"serial number undefined.\";\n\n    if (typeof param.sigalg.name == 'string')\n\to.setSignatureAlgByParam(param.sigalg);\n    else \n\tthrow \"unproper signature algorithm name\";\n\n    if (param.issuer !== undefined)\n\to.setIssuerByParam(param.issuer);\n    else\n\tthrow \"issuer name undefined.\";\n    \n    if (param.notbefore !== undefined)\n\to.setNotBeforeByParam(param.notbefore);\n    else\n\tthrow \"notbefore undefined.\";\n\n    if (param.notafter !== undefined)\n\to.setNotAfterByParam(param.notafter);\n    else\n\tthrow \"notafter undefined.\";\n\n    if (param.subject !== undefined)\n\to.setSubjectByParam(param.subject);\n    else\n\tthrow \"subject name undefined.\";\n\n    if (param.sbjpubkey !== undefined)\n\to.setSubjectPublicKeyByGetKey(param.sbjpubkey);\n    else\n\tthrow \"subject public key undefined.\";\n\n    if (param.ext.length !== undefined) {\n\tfor (var i = 0; i < param.ext.length; i++) {\n\t    for (key in param.ext[i]) {\n\t\to.appendExtensionByName(key, param.ext[i][key]);\n\t    }\n\t}\n    }\n\n    var caKey = null;\n    if (param.cakey)\n\tcaKey = KEYUTIL.getKey.apply(null, param.cakey);\n    else\n\tthrow \"ca key undefined\";\n\n    var cert = new ns1.Certificate({'tbscertobj': o, 'prvkeyobj': caKey});\n    cert.sign();\n    return cert.getPEMString();\n};\n\n/*\norg.bouncycastle.asn1.x500\nAttributeTypeAndValue\nDirectoryString\nRDN\nX500Name\nX500NameBuilder\n\norg.bouncycastleasn1.x509\nTBSCertificate\n */\n"
  },
  {
    "path": "JavaScript/sm2/js/base64.js",
    "content": "/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nvar b64map=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nvar b64pad=\"=\";\n\nfunction hex2b64(h) {\n  var i;\n  var c;\n  var ret = \"\";\n  for(i = 0; i+3 <= h.length; i+=3) {\n    c = parseInt(h.substring(i,i+3),16);\n    ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);\n  }\n  if(i+1 == h.length) {\n    c = parseInt(h.substring(i,i+1),16);\n    ret += b64map.charAt(c << 2);\n  }\n  else if(i+2 == h.length) {\n    c = parseInt(h.substring(i,i+2),16);\n    ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);\n  }\n  if (b64pad) while((ret.length & 3) > 0) ret += b64pad;\n  return ret;\n}\n\n// convert a base64 string to hex\nfunction b64tohex(s) {\n  var ret = \"\"\n  var i;\n  var k = 0; // b64 state, 0-3\n  var slop;\n  var v;\n  for(i = 0; i < s.length; ++i) {\n    if(s.charAt(i) == b64pad) break;\n    v = b64map.indexOf(s.charAt(i));\n    if(v < 0) continue;\n    if(k == 0) {\n      ret += int2char(v >> 2);\n      slop = v & 3;\n      k = 1;\n    }\n    else if(k == 1) {\n      ret += int2char((slop << 2) | (v >> 4));\n      slop = v & 0xf;\n      k = 2;\n    }\n    else if(k == 2) {\n      ret += int2char(slop);\n      ret += int2char(v >> 2);\n      slop = v & 3;\n      k = 3;\n    }\n    else {\n      ret += int2char((slop << 2) | (v >> 4));\n      ret += int2char(v & 0xf);\n      k = 0;\n    }\n  }\n  if(k == 1)\n    ret += int2char(slop << 2);\n  return ret;\n}\n\n// convert a base64 string to a byte/number array\nfunction b64toBA(s) {\n  //piggyback on b64tohex for now, optimize later\n  var h = b64tohex(s);\n  var i;\n  var a = new Array();\n  for(i = 0; 2*i < h.length; ++i) {\n    a[i] = parseInt(h.substring(2*i,2*i+2),16);\n  }\n  return a;\n}\n"
  },
  {
    "path": "JavaScript/sm2/js/cipher-core.js",
    "content": "/*\nCryptoJS v3.1.2\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n/**\n * Cipher core components.\n */\nCryptoJS.lib.Cipher || (function (undefined) {\n    // Shortcuts\n    var C = CryptoJS;\n    var C_lib = C.lib;\n    var Base = C_lib.Base;\n    var WordArray = C_lib.WordArray;\n    var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm;\n    var C_enc = C.enc;\n    var Utf8 = C_enc.Utf8;\n    var Base64 = C_enc.Base64;\n    var C_algo = C.algo;\n    var EvpKDF = C_algo.EvpKDF;\n\n    /**\n     * Abstract base cipher template.\n     *\n     * @property {number} keySize This cipher's key size. Default: 4 (128 bits)\n     * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits)\n     * @property {number} _ENC_XFORM_MODE A constant representing encryption mode.\n     * @property {number} _DEC_XFORM_MODE A constant representing decryption mode.\n     */\n    var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({\n        /**\n         * Configuration options.\n         *\n         * @property {WordArray} iv The IV to use for this operation.\n         */\n        cfg: Base.extend(),\n\n        /**\n         * Creates this cipher in encryption mode.\n         *\n         * @param {WordArray} key The key.\n         * @param {Object} cfg (Optional) The configuration options to use for this operation.\n         *\n         * @return {Cipher} A cipher instance.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });\n         */\n        createEncryptor: function (key, cfg) {\n            return this.create(this._ENC_XFORM_MODE, key, cfg);\n        },\n\n        /**\n         * Creates this cipher in decryption mode.\n         *\n         * @param {WordArray} key The key.\n         * @param {Object} cfg (Optional) The configuration options to use for this operation.\n         *\n         * @return {Cipher} A cipher instance.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });\n         */\n        createDecryptor: function (key, cfg) {\n            return this.create(this._DEC_XFORM_MODE, key, cfg);\n        },\n\n        /**\n         * Initializes a newly created cipher.\n         *\n         * @param {number} xformMode Either the encryption or decryption transormation mode constant.\n         * @param {WordArray} key The key.\n         * @param {Object} cfg (Optional) The configuration options to use for this operation.\n         *\n         * @example\n         *\n         *     var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });\n         */\n        init: function (xformMode, key, cfg) {\n            // Apply config defaults\n            this.cfg = this.cfg.extend(cfg);\n\n            // Store transform mode and key\n            this._xformMode = xformMode;\n            this._key = key;\n\n            // Set initial values\n            this.reset();\n        },\n\n        /**\n         * Resets this cipher to its initial state.\n         *\n         * @example\n         *\n         *     cipher.reset();\n         */\n        reset: function () {\n            // Reset data buffer\n            BufferedBlockAlgorithm.reset.call(this);\n\n            // Perform concrete-cipher logic\n            this._doReset();\n        },\n\n        /**\n         * Adds data to be encrypted or decrypted.\n         *\n         * @param {WordArray|string} dataUpdate The data to encrypt or decrypt.\n         *\n         * @return {WordArray} The data after processing.\n         *\n         * @example\n         *\n         *     var encrypted = cipher.process('data');\n         *     var encrypted = cipher.process(wordArray);\n         */\n        process: function (dataUpdate) {\n            // Append\n            this._append(dataUpdate);\n\n            // Process available blocks\n            return this._process();\n        },\n\n        /**\n         * Finalizes the encryption or decryption process.\n         * Note that the finalize operation is effectively a destructive, read-once operation.\n         *\n         * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt.\n         *\n         * @return {WordArray} The data after final processing.\n         *\n         * @example\n         *\n         *     var encrypted = cipher.finalize();\n         *     var encrypted = cipher.finalize('data');\n         *     var encrypted = cipher.finalize(wordArray);\n         */\n        finalize: function (dataUpdate) {\n            // Final data update\n            if (dataUpdate) {\n                this._append(dataUpdate);\n            }\n\n            // Perform concrete-cipher logic\n            var finalProcessedData = this._doFinalize();\n\n            return finalProcessedData;\n        },\n\n        keySize: 128/32,\n\n        ivSize: 128/32,\n\n        _ENC_XFORM_MODE: 1,\n\n        _DEC_XFORM_MODE: 2,\n\n        /**\n         * Creates shortcut functions to a cipher's object interface.\n         *\n         * @param {Cipher} cipher The cipher to create a helper for.\n         *\n         * @return {Object} An object with encrypt and decrypt shortcut functions.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);\n         */\n        _createHelper: (function () {\n            function selectCipherStrategy(key) {\n                if (typeof key == 'string') {\n                    return PasswordBasedCipher;\n                } else {\n                    return SerializableCipher;\n                }\n            }\n\n            return function (cipher) {\n                return {\n                    encrypt: function (message, key, cfg) {\n                        return selectCipherStrategy(key).encrypt(cipher, message, key, cfg);\n                    },\n\n                    decrypt: function (ciphertext, key, cfg) {\n                        return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg);\n                    }\n                };\n            };\n        }())\n    });\n\n    /**\n     * Abstract base stream cipher template.\n     *\n     * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits)\n     */\n    var StreamCipher = C_lib.StreamCipher = Cipher.extend({\n        _doFinalize: function () {\n            // Process partial blocks\n            var finalProcessedBlocks = this._process(!!'flush');\n\n            return finalProcessedBlocks;\n        },\n\n        blockSize: 1\n    });\n\n    /**\n     * Mode namespace.\n     */\n    var C_mode = C.mode = {};\n\n    /**\n     * Abstract base block cipher mode template.\n     */\n    var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({\n        /**\n         * Creates this mode for encryption.\n         *\n         * @param {Cipher} cipher A block cipher instance.\n         * @param {Array} iv The IV words.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);\n         */\n        createEncryptor: function (cipher, iv) {\n            return this.Encryptor.create(cipher, iv);\n        },\n\n        /**\n         * Creates this mode for decryption.\n         *\n         * @param {Cipher} cipher A block cipher instance.\n         * @param {Array} iv The IV words.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words);\n         */\n        createDecryptor: function (cipher, iv) {\n            return this.Decryptor.create(cipher, iv);\n        },\n\n        /**\n         * Initializes a newly created mode.\n         *\n         * @param {Cipher} cipher A block cipher instance.\n         * @param {Array} iv The IV words.\n         *\n         * @example\n         *\n         *     var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words);\n         */\n        init: function (cipher, iv) {\n            this._cipher = cipher;\n            this._iv = iv;\n        }\n    });\n\n    /**\n     * Cipher Block Chaining mode.\n     */\n    var CBC = C_mode.CBC = (function () {\n        /**\n         * Abstract base CBC mode.\n         */\n        var CBC = BlockCipherMode.extend();\n\n        /**\n         * CBC encryptor.\n         */\n        CBC.Encryptor = CBC.extend({\n            /**\n             * Processes the data block at offset.\n             *\n             * @param {Array} words The data words to operate on.\n             * @param {number} offset The offset where the block starts.\n             *\n             * @example\n             *\n             *     mode.processBlock(data.words, offset);\n             */\n            processBlock: function (words, offset) {\n                // Shortcuts\n                var cipher = this._cipher;\n                var blockSize = cipher.blockSize;\n\n                // XOR and encrypt\n                xorBlock.call(this, words, offset, blockSize);\n                cipher.encryptBlock(words, offset);\n\n                // Remember this block to use with next block\n                this._prevBlock = words.slice(offset, offset + blockSize);\n            }\n        });\n\n        /**\n         * CBC decryptor.\n         */\n        CBC.Decryptor = CBC.extend({\n            /**\n             * Processes the data block at offset.\n             *\n             * @param {Array} words The data words to operate on.\n             * @param {number} offset The offset where the block starts.\n             *\n             * @example\n             *\n             *     mode.processBlock(data.words, offset);\n             */\n            processBlock: function (words, offset) {\n                // Shortcuts\n                var cipher = this._cipher;\n                var blockSize = cipher.blockSize;\n\n                // Remember this block to use with next block\n                var thisBlock = words.slice(offset, offset + blockSize);\n\n                // Decrypt and XOR\n                cipher.decryptBlock(words, offset);\n                xorBlock.call(this, words, offset, blockSize);\n\n                // This block becomes the previous block\n                this._prevBlock = thisBlock;\n            }\n        });\n\n        function xorBlock(words, offset, blockSize) {\n            // Shortcut\n            var iv = this._iv;\n\n            // Choose mixing block\n            if (iv) {\n                var block = iv;\n\n                // Remove IV for subsequent blocks\n                this._iv = undefined;\n            } else {\n                var block = this._prevBlock;\n            }\n\n            // XOR blocks\n            for (var i = 0; i < blockSize; i++) {\n                words[offset + i] ^= block[i];\n            }\n        }\n\n        return CBC;\n    }());\n\n    /**\n     * Padding namespace.\n     */\n    var C_pad = C.pad = {};\n\n    /**\n     * PKCS #5/7 padding strategy.\n     */\n    var Pkcs7 = C_pad.Pkcs7 = {\n        /**\n         * Pads data using the algorithm defined in PKCS #5/7.\n         *\n         * @param {WordArray} data The data to pad.\n         * @param {number} blockSize The multiple that the data should be padded to.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     CryptoJS.pad.Pkcs7.pad(wordArray, 4);\n         */\n        pad: function (data, blockSize) {\n            // Shortcut\n            var blockSizeBytes = blockSize * 4;\n\n            // Count padding bytes\n            var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;\n\n            // Create padding word\n            var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes;\n\n            // Create padding\n            var paddingWords = [];\n            for (var i = 0; i < nPaddingBytes; i += 4) {\n                paddingWords.push(paddingWord);\n            }\n            var padding = WordArray.create(paddingWords, nPaddingBytes);\n\n            // Add padding\n            data.concat(padding);\n        },\n\n        /**\n         * Unpads data that had been padded using the algorithm defined in PKCS #5/7.\n         *\n         * @param {WordArray} data The data to unpad.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     CryptoJS.pad.Pkcs7.unpad(wordArray);\n         */\n        unpad: function (data) {\n            // Get number of padding bytes from last byte\n            var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;\n\n            // Remove padding\n            data.sigBytes -= nPaddingBytes;\n        }\n    };\n\n    /**\n     * Abstract base block cipher template.\n     *\n     * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits)\n     */\n    var BlockCipher = C_lib.BlockCipher = Cipher.extend({\n        /**\n         * Configuration options.\n         *\n         * @property {Mode} mode The block mode to use. Default: CBC\n         * @property {Padding} padding The padding strategy to use. Default: Pkcs7\n         */\n        cfg: Cipher.cfg.extend({\n            mode: CBC,\n            padding: Pkcs7\n        }),\n\n        reset: function () {\n            // Reset cipher\n            Cipher.reset.call(this);\n\n            // Shortcuts\n            var cfg = this.cfg;\n            var iv = cfg.iv;\n            var mode = cfg.mode;\n\n            // Reset block mode\n            if (this._xformMode == this._ENC_XFORM_MODE) {\n                var modeCreator = mode.createEncryptor;\n            } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {\n                var modeCreator = mode.createDecryptor;\n\n                // Keep at least one block in the buffer for unpadding\n                this._minBufferSize = 1;\n            }\n            this._mode = modeCreator.call(mode, this, iv && iv.words);\n        },\n\n        _doProcessBlock: function (words, offset) {\n            this._mode.processBlock(words, offset);\n        },\n\n        _doFinalize: function () {\n            // Shortcut\n            var padding = this.cfg.padding;\n\n            // Finalize\n            if (this._xformMode == this._ENC_XFORM_MODE) {\n                // Pad data\n                padding.pad(this._data, this.blockSize);\n\n                // Process final blocks\n                var finalProcessedBlocks = this._process(!!'flush');\n            } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {\n                // Process final blocks\n                var finalProcessedBlocks = this._process(!!'flush');\n\n                // Unpad data\n                padding.unpad(finalProcessedBlocks);\n            }\n\n            return finalProcessedBlocks;\n        },\n\n        blockSize: 128/32\n    });\n\n    /**\n     * A collection of cipher parameters.\n     *\n     * @property {WordArray} ciphertext The raw ciphertext.\n     * @property {WordArray} key The key to this ciphertext.\n     * @property {WordArray} iv The IV used in the ciphering operation.\n     * @property {WordArray} salt The salt used with a key derivation function.\n     * @property {Cipher} algorithm The cipher algorithm.\n     * @property {Mode} mode The block mode used in the ciphering operation.\n     * @property {Padding} padding The padding scheme used in the ciphering operation.\n     * @property {number} blockSize The block size of the cipher.\n     * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string.\n     */\n    var CipherParams = C_lib.CipherParams = Base.extend({\n        /**\n         * Initializes a newly created cipher params object.\n         *\n         * @param {Object} cipherParams An object with any of the possible cipher parameters.\n         *\n         * @example\n         *\n         *     var cipherParams = CryptoJS.lib.CipherParams.create({\n         *         ciphertext: ciphertextWordArray,\n         *         key: keyWordArray,\n         *         iv: ivWordArray,\n         *         salt: saltWordArray,\n         *         algorithm: CryptoJS.algo.AES,\n         *         mode: CryptoJS.mode.CBC,\n         *         padding: CryptoJS.pad.PKCS7,\n         *         blockSize: 4,\n         *         formatter: CryptoJS.format.OpenSSL\n         *     });\n         */\n        init: function (cipherParams) {\n            this.mixIn(cipherParams);\n        },\n\n        /**\n         * Converts this cipher params object to a string.\n         *\n         * @param {Format} formatter (Optional) The formatting strategy to use.\n         *\n         * @return {string} The stringified cipher params.\n         *\n         * @throws Error If neither the formatter nor the default formatter is set.\n         *\n         * @example\n         *\n         *     var string = cipherParams + '';\n         *     var string = cipherParams.toString();\n         *     var string = cipherParams.toString(CryptoJS.format.OpenSSL);\n         */\n        toString: function (formatter) {\n            return (formatter || this.formatter).stringify(this);\n        }\n    });\n\n    /**\n     * Format namespace.\n     */\n    var C_format = C.format = {};\n\n    /**\n     * OpenSSL formatting strategy.\n     */\n    var OpenSSLFormatter = C_format.OpenSSL = {\n        /**\n         * Converts a cipher params object to an OpenSSL-compatible string.\n         *\n         * @param {CipherParams} cipherParams The cipher params object.\n         *\n         * @return {string} The OpenSSL-compatible string.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams);\n         */\n        stringify: function (cipherParams) {\n            // Shortcuts\n            var ciphertext = cipherParams.ciphertext;\n            var salt = cipherParams.salt;\n\n            // Format\n            if (salt) {\n                var wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);\n            } else {\n                var wordArray = ciphertext;\n            }\n\n            return wordArray.toString(Base64);\n        },\n\n        /**\n         * Converts an OpenSSL-compatible string to a cipher params object.\n         *\n         * @param {string} openSSLStr The OpenSSL-compatible string.\n         *\n         * @return {CipherParams} The cipher params object.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString);\n         */\n        parse: function (openSSLStr) {\n            // Parse base64\n            var ciphertext = Base64.parse(openSSLStr);\n\n            // Shortcut\n            var ciphertextWords = ciphertext.words;\n\n            // Test for salt\n            if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) {\n                // Extract salt\n                var salt = WordArray.create(ciphertextWords.slice(2, 4));\n\n                // Remove salt from ciphertext\n                ciphertextWords.splice(0, 4);\n                ciphertext.sigBytes -= 16;\n            }\n\n            return CipherParams.create({ ciphertext: ciphertext, salt: salt });\n        }\n    };\n\n    /**\n     * A cipher wrapper that returns ciphertext as a serializable cipher params object.\n     */\n    var SerializableCipher = C_lib.SerializableCipher = Base.extend({\n        /**\n         * Configuration options.\n         *\n         * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL\n         */\n        cfg: Base.extend({\n            format: OpenSSLFormatter\n        }),\n\n        /**\n         * Encrypts a message.\n         *\n         * @param {Cipher} cipher The cipher algorithm to use.\n         * @param {WordArray|string} message The message to encrypt.\n         * @param {WordArray} key The key.\n         * @param {Object} cfg (Optional) The configuration options to use for this operation.\n         *\n         * @return {CipherParams} A cipher params object.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key);\n         *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv });\n         *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n         */\n        encrypt: function (cipher, message, key, cfg) {\n            // Apply config defaults\n            cfg = this.cfg.extend(cfg);\n\n            // Encrypt\n            var encryptor = cipher.createEncryptor(key, cfg);\n            var ciphertext = encryptor.finalize(message);\n\n            // Shortcut\n            var cipherCfg = encryptor.cfg;\n\n            // Create and return serializable cipher params\n            return CipherParams.create({\n                ciphertext: ciphertext,\n                key: key,\n                iv: cipherCfg.iv,\n                algorithm: cipher,\n                mode: cipherCfg.mode,\n                padding: cipherCfg.padding,\n                blockSize: cipher.blockSize,\n                formatter: cfg.format\n            });\n        },\n\n        /**\n         * Decrypts serialized ciphertext.\n         *\n         * @param {Cipher} cipher The cipher algorithm to use.\n         * @param {CipherParams|string} ciphertext The ciphertext to decrypt.\n         * @param {WordArray} key The key.\n         * @param {Object} cfg (Optional) The configuration options to use for this operation.\n         *\n         * @return {WordArray} The plaintext.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n         *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL });\n         */\n        decrypt: function (cipher, ciphertext, key, cfg) {\n            // Apply config defaults\n            cfg = this.cfg.extend(cfg);\n\n            // Convert string to CipherParams\n            ciphertext = this._parse(ciphertext, cfg.format);\n\n            // Decrypt\n            var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext);\n\n            return plaintext;\n        },\n\n        /**\n         * Converts serialized ciphertext to CipherParams,\n         * else assumed CipherParams already and returns ciphertext unchanged.\n         *\n         * @param {CipherParams|string} ciphertext The ciphertext.\n         * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext.\n         *\n         * @return {CipherParams} The unserialized ciphertext.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format);\n         */\n        _parse: function (ciphertext, format) {\n            if (typeof ciphertext == 'string') {\n                return format.parse(ciphertext, this);\n            } else {\n                return ciphertext;\n            }\n        }\n    });\n\n    /**\n     * Key derivation function namespace.\n     */\n    var C_kdf = C.kdf = {};\n\n    /**\n     * OpenSSL key derivation function.\n     */\n    var OpenSSLKdf = C_kdf.OpenSSL = {\n        /**\n         * Derives a key and IV from a password.\n         *\n         * @param {string} password The password to derive from.\n         * @param {number} keySize The size in words of the key to generate.\n         * @param {number} ivSize The size in words of the IV to generate.\n         * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly.\n         *\n         * @return {CipherParams} A cipher params object with the key, IV, and salt.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32);\n         *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt');\n         */\n        execute: function (password, keySize, ivSize, salt) {\n            // Generate random salt\n            if (!salt) {\n                salt = WordArray.random(64/8);\n            }\n\n            // Derive key and IV\n            var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);\n\n            // Separate key and IV\n            var iv = WordArray.create(key.words.slice(keySize), ivSize * 4);\n            key.sigBytes = keySize * 4;\n\n            // Return params\n            return CipherParams.create({ key: key, iv: iv, salt: salt });\n        }\n    };\n\n    /**\n     * A serializable cipher wrapper that derives the key from a password,\n     * and returns ciphertext as a serializable cipher params object.\n     */\n    var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({\n        /**\n         * Configuration options.\n         *\n         * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL\n         */\n        cfg: SerializableCipher.cfg.extend({\n            kdf: OpenSSLKdf\n        }),\n\n        /**\n         * Encrypts a message using a password.\n         *\n         * @param {Cipher} cipher The cipher algorithm to use.\n         * @param {WordArray|string} message The message to encrypt.\n         * @param {string} password The password.\n         * @param {Object} cfg (Optional) The configuration options to use for this operation.\n         *\n         * @return {CipherParams} A cipher params object.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password');\n         *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL });\n         */\n        encrypt: function (cipher, message, password, cfg) {\n            // Apply config defaults\n            cfg = this.cfg.extend(cfg);\n\n            // Derive key and other params\n            var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize);\n\n            // Add IV to config\n            cfg.iv = derivedParams.iv;\n\n            // Encrypt\n            var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);\n\n            // Mix in derived params\n            ciphertext.mixIn(derivedParams);\n\n            return ciphertext;\n        },\n\n        /**\n         * Decrypts serialized ciphertext using a password.\n         *\n         * @param {Cipher} cipher The cipher algorithm to use.\n         * @param {CipherParams|string} ciphertext The ciphertext to decrypt.\n         * @param {string} password The password.\n         * @param {Object} cfg (Optional) The configuration options to use for this operation.\n         *\n         * @return {WordArray} The plaintext.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL });\n         *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL });\n         */\n        decrypt: function (cipher, ciphertext, password, cfg) {\n            // Apply config defaults\n            cfg = this.cfg.extend(cfg);\n\n            // Convert string to CipherParams\n            ciphertext = this._parse(ciphertext, cfg.format);\n\n            // Derive key and other params\n            var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt);\n\n            // Add IV to config\n            cfg.iv = derivedParams.iv;\n\n            // Decrypt\n            var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg);\n\n            return plaintext;\n        }\n    });\n}());\n"
  },
  {
    "path": "JavaScript/sm2/js/core.js",
    "content": "/*\nCryptoJS v3.1.2\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n/**\n * CryptoJS core components.\n */\nvar CryptoJS = CryptoJS || (function (Math, undefined) {\n    /**\n     * CryptoJS namespace.\n     */\n    var C = {};\n\n    /**\n     * Library namespace.\n     */\n    var C_lib = C.lib = {};\n\n    /**\n     * Base object for prototypal inheritance.\n     */\n    var Base = C_lib.Base = (function () {\n        function F() {}\n\n        return {\n            /**\n             * Creates a new object that inherits from this object.\n             *\n             * @param {Object} overrides Properties to copy into the new object.\n             *\n             * @return {Object} The new object.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var MyType = CryptoJS.lib.Base.extend({\n             *         field: 'value',\n             *\n             *         method: function () {\n             *         }\n             *     });\n             */\n            extend: function (overrides) {\n                // Spawn\n                F.prototype = this;\n                var subtype = new F();\n\n                // Augment\n                if (overrides) {\n                    subtype.mixIn(overrides);\n                }\n\n                // Create default initializer\n                if (!subtype.hasOwnProperty('init')) {\n                    subtype.init = function () {\n                        subtype.$super.init.apply(this, arguments);\n                    };\n                }\n\n                // Initializer's prototype is the subtype object\n                subtype.init.prototype = subtype;\n\n                // Reference supertype\n                subtype.$super = this;\n\n                return subtype;\n            },\n\n            /**\n             * Extends this object and runs the init method.\n             * Arguments to create() will be passed to init().\n             *\n             * @return {Object} The new object.\n             *\n             * @static\n             *\n             * @example\n             *\n             *     var instance = MyType.create();\n             */\n            create: function () {\n                var instance = this.extend();\n                instance.init.apply(instance, arguments);\n\n                return instance;\n            },\n\n            /**\n             * Initializes a newly created object.\n             * Override this method to add some logic when your objects are created.\n             *\n             * @example\n             *\n             *     var MyType = CryptoJS.lib.Base.extend({\n             *         init: function () {\n             *             // ...\n             *         }\n             *     });\n             */\n            init: function () {\n            },\n\n            /**\n             * Copies properties into this object.\n             *\n             * @param {Object} properties The properties to mix in.\n             *\n             * @example\n             *\n             *     MyType.mixIn({\n             *         field: 'value'\n             *     });\n             */\n            mixIn: function (properties) {\n                for (var propertyName in properties) {\n                    if (properties.hasOwnProperty(propertyName)) {\n                        this[propertyName] = properties[propertyName];\n                    }\n                }\n\n                // IE won't copy toString using the loop above\n                if (properties.hasOwnProperty('toString')) {\n                    this.toString = properties.toString;\n                }\n            },\n\n            /**\n             * Creates a copy of this object.\n             *\n             * @return {Object} The clone.\n             *\n             * @example\n             *\n             *     var clone = instance.clone();\n             */\n            clone: function () {\n                return this.init.prototype.extend(this);\n            }\n        };\n    }());\n\n    /**\n     * An array of 32-bit words.\n     *\n     * @property {Array} words The array of 32-bit words.\n     * @property {number} sigBytes The number of significant bytes in this word array.\n     */\n    var WordArray = C_lib.WordArray = Base.extend({\n        /**\n         * Initializes a newly created word array.\n         *\n         * @param {Array} words (Optional) An array of 32-bit words.\n         * @param {number} sigBytes (Optional) The number of significant bytes in the words.\n         *\n         * @example\n         *\n         *     var wordArray = CryptoJS.lib.WordArray.create();\n         *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);\n         *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);\n         */\n        init: function (words, sigBytes) {\n            words = this.words = words || [];\n\n            if (sigBytes != undefined) {\n                this.sigBytes = sigBytes;\n            } else {\n                this.sigBytes = words.length * 4;\n            }\n        },\n\n        /**\n         * Converts this word array to a string.\n         *\n         * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex\n         *\n         * @return {string} The stringified word array.\n         *\n         * @example\n         *\n         *     var string = wordArray + '';\n         *     var string = wordArray.toString();\n         *     var string = wordArray.toString(CryptoJS.enc.Utf8);\n         */\n        toString: function (encoder) {\n            return (encoder || Hex).stringify(this);\n        },\n\n        /**\n         * Concatenates a word array to this word array.\n         *\n         * @param {WordArray} wordArray The word array to append.\n         *\n         * @return {WordArray} This word array.\n         *\n         * @example\n         *\n         *     wordArray1.concat(wordArray2);\n         */\n        concat: function (wordArray) {\n            // Shortcuts\n            var thisWords = this.words;\n            var thatWords = wordArray.words;\n            var thisSigBytes = this.sigBytes;\n            var thatSigBytes = wordArray.sigBytes;\n\n            // Clamp excess bits\n            this.clamp();\n\n            // Concat\n            if (thisSigBytes % 4) {\n                // Copy one byte at a time\n                for (var i = 0; i < thatSigBytes; i++) {\n                    var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;\n                    thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);\n                }\n            } else if (thatWords.length > 0xffff) {\n                // Copy one word at a time\n                for (var i = 0; i < thatSigBytes; i += 4) {\n                    thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2];\n                }\n            } else {\n                // Copy all words at once\n                thisWords.push.apply(thisWords, thatWords);\n            }\n            this.sigBytes += thatSigBytes;\n\n            // Chainable\n            return this;\n        },\n\n        /**\n         * Removes insignificant bits.\n         *\n         * @example\n         *\n         *     wordArray.clamp();\n         */\n        clamp: function () {\n            // Shortcuts\n            var words = this.words;\n            var sigBytes = this.sigBytes;\n\n            // Clamp\n            words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);\n            words.length = Math.ceil(sigBytes / 4);\n        },\n\n        /**\n         * Creates a copy of this word array.\n         *\n         * @return {WordArray} The clone.\n         *\n         * @example\n         *\n         *     var clone = wordArray.clone();\n         */\n        clone: function () {\n            var clone = Base.clone.call(this);\n            clone.words = this.words.slice(0);\n\n            return clone;\n        },\n\n        /**\n         * Creates a word array filled with random bytes.\n         *\n         * @param {number} nBytes The number of random bytes to generate.\n         *\n         * @return {WordArray} The random word array.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var wordArray = CryptoJS.lib.WordArray.random(16);\n         */\n        random: function (nBytes) {\n            var words = [];\n            for (var i = 0; i < nBytes; i += 4) {\n                words.push((Math.random() * 0x100000000) | 0);\n            }\n\n            return new WordArray.init(words, nBytes);\n        }\n    });\n\n    /**\n     * Encoder namespace.\n     */\n    var C_enc = C.enc = {};\n\n    /**\n     * Hex encoding strategy.\n     */\n    var Hex = C_enc.Hex = {\n        /**\n         * Converts a word array to a hex string.\n         *\n         * @param {WordArray} wordArray The word array.\n         *\n         * @return {string} The hex string.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var hexString = CryptoJS.enc.Hex.stringify(wordArray);\n         */\n        stringify: function (wordArray) {\n            // Shortcuts\n            var words = wordArray.words;\n            var sigBytes = wordArray.sigBytes;\n\n            // Convert\n            var hexChars = [];\n            for (var i = 0; i < sigBytes; i++) {\n                var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;\n                hexChars.push((bite >>> 4).toString(16));\n                hexChars.push((bite & 0x0f).toString(16));\n            }\n\n            return hexChars.join('');\n        },\n\n        /**\n         * Converts a hex string to a word array.\n         *\n         * @param {string} hexStr The hex string.\n         *\n         * @return {WordArray} The word array.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var wordArray = CryptoJS.enc.Hex.parse(hexString);\n         */\n        parse: function (hexStr) {\n            // Shortcut\n            var hexStrLength = hexStr.length;\n\n            // Convert\n            var words = [];\n            for (var i = 0; i < hexStrLength; i += 2) {\n                words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);\n            }\n\n            return new WordArray.init(words, hexStrLength / 2);\n        }\n    };\n\n    /**\n     * Latin1 encoding strategy.\n     */\n    var Latin1 = C_enc.Latin1 = {\n        /**\n         * Converts a word array to a Latin1 string.\n         *\n         * @param {WordArray} wordArray The word array.\n         *\n         * @return {string} The Latin1 string.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);\n         */\n        stringify: function (wordArray) {\n            // Shortcuts\n            var words = wordArray.words;\n            var sigBytes = wordArray.sigBytes;\n\n            // Convert\n            var latin1Chars = [];\n            for (var i = 0; i < sigBytes; i++) {\n                var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;\n                latin1Chars.push(String.fromCharCode(bite));\n            }\n\n            return latin1Chars.join('');\n        },\n\n        /**\n         * Converts a Latin1 string to a word array.\n         *\n         * @param {string} latin1Str The Latin1 string.\n         *\n         * @return {WordArray} The word array.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var wordArray = CryptoJS.enc.Latin1.parse(latin1String);\n         */\n        parse: function (latin1Str) {\n            // Shortcut\n            var latin1StrLength = latin1Str.length;\n\n            // Convert\n            var words = [];\n            for (var i = 0; i < latin1StrLength; i++) {\n                words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);\n            }\n\n            return new WordArray.init(words, latin1StrLength);\n        }\n    };\n\n    /**\n     * UTF-8 encoding strategy.\n     */\n    var Utf8 = C_enc.Utf8 = {\n        /**\n         * Converts a word array to a UTF-8 string.\n         *\n         * @param {WordArray} wordArray The word array.\n         *\n         * @return {string} The UTF-8 string.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);\n         */\n        stringify: function (wordArray) {\n            try {\n                return decodeURIComponent(escape(Latin1.stringify(wordArray)));\n            } catch (e) {\n                throw new Error('Malformed UTF-8 data');\n            }\n        },\n\n        /**\n         * Converts a UTF-8 string to a word array.\n         *\n         * @param {string} utf8Str The UTF-8 string.\n         *\n         * @return {WordArray} The word array.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var wordArray = CryptoJS.enc.Utf8.parse(utf8String);\n         */\n        parse: function (utf8Str) {\n            return Latin1.parse(unescape(encodeURIComponent(utf8Str)));\n        }\n    };\n\n    /**\n     * Abstract buffered block algorithm template.\n     *\n     * The property blockSize must be implemented in a concrete subtype.\n     *\n     * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0\n     */\n    var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({\n        /**\n         * Resets this block algorithm's data buffer to its initial state.\n         *\n         * @example\n         *\n         *     bufferedBlockAlgorithm.reset();\n         */\n        reset: function () {\n            // Initial values\n            this._data = new WordArray.init();\n            this._nDataBytes = 0;\n        },\n\n        /**\n         * Adds new data to this block algorithm's buffer.\n         *\n         * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.\n         *\n         * @example\n         *\n         *     bufferedBlockAlgorithm._append('data');\n         *     bufferedBlockAlgorithm._append(wordArray);\n         */\n        _append: function (data) {\n            // Convert string to WordArray, else assume WordArray already\n            if (typeof data == 'string') {\n                data = Utf8.parse(data);\n            }\n\n            // Append\n            this._data.concat(data);\n            this._nDataBytes += data.sigBytes;\n        },\n\n        /**\n         * Processes available data blocks.\n         *\n         * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.\n         *\n         * @param {boolean} doFlush Whether all blocks and partial blocks should be processed.\n         *\n         * @return {WordArray} The processed data.\n         *\n         * @example\n         *\n         *     var processedData = bufferedBlockAlgorithm._process();\n         *     var processedData = bufferedBlockAlgorithm._process(!!'flush');\n         */\n        _process: function (doFlush) {\n            // Shortcuts\n            var data = this._data;\n            var dataWords = data.words;\n            var dataSigBytes = data.sigBytes;\n            var blockSize = this.blockSize;\n            var blockSizeBytes = blockSize * 4;\n\n            // Count blocks ready\n            var nBlocksReady = dataSigBytes / blockSizeBytes;\n            if (doFlush) {\n                // Round up to include partial blocks\n                nBlocksReady = Math.ceil(nBlocksReady);\n            } else {\n                // Round down to include only full blocks,\n                // less the number of blocks that must remain in the buffer\n                nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);\n            }\n\n            // Count words ready\n            var nWordsReady = nBlocksReady * blockSize;\n\n            // Count bytes ready\n            var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);\n\n            // Process blocks\n            if (nWordsReady) {\n                for (var offset = 0; offset < nWordsReady; offset += blockSize) {\n                    // Perform concrete-algorithm logic\n                    this._doProcessBlock(dataWords, offset);\n                }\n\n                // Remove processed words\n                var processedWords = dataWords.splice(0, nWordsReady);\n                data.sigBytes -= nBytesReady;\n            }\n\n            // Return processed words\n            return new WordArray.init(processedWords, nBytesReady);\n        },\n\n        /**\n         * Creates a copy of this object.\n         *\n         * @return {Object} The clone.\n         *\n         * @example\n         *\n         *     var clone = bufferedBlockAlgorithm.clone();\n         */\n        clone: function () {\n            var clone = Base.clone.call(this);\n            clone._data = this._data.clone();\n\n            return clone;\n        },\n\n        _minBufferSize: 0\n    });\n\n    /**\n     * Abstract hasher template.\n     *\n     * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)\n     */\n    var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({\n        /**\n         * Configuration options.\n         */\n        cfg: Base.extend(),\n\n        /**\n         * Initializes a newly created hasher.\n         *\n         * @param {Object} cfg (Optional) The configuration options to use for this hash computation.\n         *\n         * @example\n         *\n         *     var hasher = CryptoJS.algo.SHA256.create();\n         */\n        init: function (cfg) {\n            // Apply config defaults\n            this.cfg = this.cfg.extend(cfg);\n\n            // Set initial values\n            this.reset();\n        },\n\n        /**\n         * Resets this hasher to its initial state.\n         *\n         * @example\n         *\n         *     hasher.reset();\n         */\n        reset: function () {\n            // Reset data buffer\n            BufferedBlockAlgorithm.reset.call(this);\n\n            // Perform concrete-hasher logic\n            this._doReset();\n        },\n\n        /**\n         * Updates this hasher with a message.\n         *\n         * @param {WordArray|string} messageUpdate The message to append.\n         *\n         * @return {Hasher} This hasher.\n         *\n         * @example\n         *\n         *     hasher.update('message');\n         *     hasher.update(wordArray);\n         */\n        update: function (messageUpdate) {\n            // Append\n            this._append(messageUpdate);\n\n            // Update the hash\n            this._process();\n\n            // Chainable\n            return this;\n        },\n\n        /**\n         * Finalizes the hash computation.\n         * Note that the finalize operation is effectively a destructive, read-once operation.\n         *\n         * @param {WordArray|string} messageUpdate (Optional) A final message update.\n         *\n         * @return {WordArray} The hash.\n         *\n         * @example\n         *\n         *     var hash = hasher.finalize();\n         *     var hash = hasher.finalize('message');\n         *     var hash = hasher.finalize(wordArray);\n         */\n        finalize: function (messageUpdate) {\n            // Final message update\n            if (messageUpdate) {\n                this._append(messageUpdate);\n            }\n\n            // Perform concrete-hasher logic\n            var hash = this._doFinalize();\n\n            return hash;\n        },\n\n        blockSize: 512/32,\n\n        /**\n         * Creates a shortcut function to a hasher's object interface.\n         *\n         * @param {Hasher} hasher The hasher to create a helper for.\n         *\n         * @return {Function} The shortcut function.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);\n         */\n        _createHelper: function (hasher) {\n            return function (message, cfg) {\n                return new hasher.init(cfg).finalize(message);\n            };\n        },\n\n        /**\n         * Creates a shortcut function to the HMAC's object interface.\n         *\n         * @param {Hasher} hasher The hasher to use in this HMAC helper.\n         *\n         * @return {Function} The shortcut function.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);\n         */\n        _createHmacHelper: function (hasher) {\n            return function (message, key) {\n                return new C_algo.HMAC.init(hasher, key).finalize(message);\n            };\n        }\n    });\n\n    /**\n     * Algorithm namespace.\n     */\n    var C_algo = C.algo = {};\n\n    return C;\n}(Math));\n"
  },
  {
    "path": "JavaScript/sm2/js/crypto-1.1.js",
    "content": "/*! crypto-1.1.5.js (c) 2013 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n/*\n * crypto.js - Cryptographic Algorithm Provider class\n *\n * Copyright (c) 2013 Kenji Urushima (kenji.urushima@gmail.com)\n *\n * This software is licensed under the terms of the MIT License.\n * http://kjur.github.com/jsrsasign/license\n *\n * The above copyright and license notice shall be \n * included in all copies or substantial portions of the Software.\n */\n\n/**\n * @fileOverview\n * @name crypto-1.1.js\n * @author Kenji Urushima kenji.urushima@gmail.com\n * @version 1.1.5 (2013-Oct-06)\n * @since jsrsasign 2.2\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\n */\n\n/** \n * kjur's class library name space\n * @name KJUR\n * @namespace kjur's class library name space\n */\nif (typeof KJUR == \"undefined\" || !KJUR) KJUR = {};\n/**\n * kjur's cryptographic algorithm provider library name space\n * <p>\n * This namespace privides following crytpgrahic classes.\n * <ul>\n * <li>{@link KJUR.crypto.MessageDigest} - Java JCE(cryptograhic extension) style MessageDigest class</li>\n * <li>{@link KJUR.crypto.Signature} - Java JCE(cryptograhic extension) style Signature class</li>\n * <li>{@link KJUR.crypto.Util} - cryptographic utility functions and properties</li>\n * </ul>\n * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.\n * </p>\n * @name KJUR.crypto\n * @namespace\n */\nif (typeof KJUR.crypto == \"undefined\" || !KJUR.crypto) KJUR.crypto = {};\n\n/**\n * static object for cryptographic function utilities\n * @name KJUR.crypto.Util\n * @class static object for cryptographic function utilities\n * @property {Array} DIGESTINFOHEAD PKCS#1 DigestInfo heading hexadecimal bytes for each hash algorithms\n * @property {Array} DEFAULTPROVIDER associative array of default provider name for each hash and signature algorithms\n * @description\n */\nKJUR.crypto.Util = new function() {\n    this.DIGESTINFOHEAD = {\n\t'sha1':      \"3021300906052b0e03021a05000414\",\n    'sha224':    \"302d300d06096086480165030402040500041c\",\n\t'sha256':    \"3031300d060960864801650304020105000420\",\n\t'sha384':    \"3041300d060960864801650304020205000430\",\n\t'sha512':    \"3051300d060960864801650304020305000440\",\n\t'md2':       \"3020300c06082a864886f70d020205000410\",\n\t'md5':       \"3020300c06082a864886f70d020505000410\",\n\t'ripemd160': \"3021300906052b2403020105000414\",\n    };\n\n    /*\n     * @since crypto 1.1.1\n     */\n    this.DEFAULTPROVIDER = {\n\t'md5':\t\t\t'cryptojs',\n\t'sha1':\t\t\t'cryptojs',\n\t'sha224':\t\t'cryptojs',\n\t'sha256':\t\t'cryptojs',\n\t'sha384':\t\t'cryptojs',\n\t'sha512':\t\t'cryptojs',\n\t'ripemd160':\t\t'cryptojs',\n\t'hmacmd5':\t\t'cryptojs',\n\t'hmacsha1':\t\t'cryptojs',\n\t'hmacsha224':\t\t'cryptojs',\n\t'hmacsha256':\t\t'cryptojs',\n\t'hmacsha384':\t\t'cryptojs',\n\t'hmacsha512':\t\t'cryptojs',\n\t'hmacripemd160':\t'cryptojs',\n\t'sm3':\t            'cryptojs',\n\n\t'MD5withRSA':\t\t'cryptojs/jsrsa',\n\t'SHA1withRSA':\t\t'cryptojs/jsrsa',\n\t'SHA224withRSA':\t'cryptojs/jsrsa',\n\t'SHA256withRSA':\t'cryptojs/jsrsa',\n\t'SHA384withRSA':\t'cryptojs/jsrsa',\n\t'SHA512withRSA':\t'cryptojs/jsrsa',\n\t'RIPEMD160withRSA':\t'cryptojs/jsrsa',\n\n\t'MD5withECDSA':\t\t'cryptojs/jsrsa',\n\t'SHA1withECDSA':\t'cryptojs/jsrsa',\n\t'SHA224withECDSA':\t'cryptojs/jsrsa',\n\t'SHA256withECDSA':\t'cryptojs/jsrsa',\n\t'SHA384withECDSA':\t'cryptojs/jsrsa',\n\t'SHA512withECDSA':\t'cryptojs/jsrsa',\n\t'RIPEMD160withECDSA':\t'cryptojs/jsrsa',\n\n\t'SHA1withDSA':\t\t'cryptojs/jsrsa',\n\t'SHA224withDSA':\t'cryptojs/jsrsa',\n\t'SHA256withDSA':\t'cryptojs/jsrsa',\n\n\t'MD5withRSAandMGF1':\t\t'cryptojs/jsrsa',\n\t'SHA1withRSAandMGF1':\t\t'cryptojs/jsrsa',\n\t'SHA224withRSAandMGF1':\t\t'cryptojs/jsrsa',\n\t'SHA256withRSAandMGF1':\t\t'cryptojs/jsrsa',\n\t'SHA384withRSAandMGF1':\t\t'cryptojs/jsrsa',\n\t'SHA512withRSAandMGF1':\t\t'cryptojs/jsrsa',\n\t'RIPEMD160withRSAandMGF1':\t'cryptojs/jsrsa',\n    };\n\n    /*\n     * @since crypto 1.1.2\n     */\n    this.CRYPTOJSMESSAGEDIGESTNAME = {\n\t'md5':\t\t'CryptoJS.algo.MD5',\n\t'sha1':\t\t'CryptoJS.algo.SHA1',\n\t'sha224':\t'CryptoJS.algo.SHA224',\n\t'sha256':\t'CryptoJS.algo.SHA256',\n\t'sha384':\t'CryptoJS.algo.SHA384',\n\t'sha512':\t'CryptoJS.algo.SHA512',\n\t'ripemd160':'CryptoJS.algo.RIPEMD160',\n\t'sm3':      'CryptoJS.algo.SM3'\n    };\n\n    /**\n     * get hexadecimal DigestInfo\n     * @name getDigestInfoHex\n     * @memberOf KJUR.crypto.Util\n     * @function\n     * @param {String} hHash hexadecimal hash value\n     * @param {String} alg hash algorithm name (ex. 'sha1')\n     * @return {String} hexadecimal string DigestInfo ASN.1 structure\n     */\n    this.getDigestInfoHex = function(hHash, alg) {\n\tif (typeof this.DIGESTINFOHEAD[alg] == \"undefined\")\n\t    throw \"alg not supported in Util.DIGESTINFOHEAD: \" + alg;\n\treturn this.DIGESTINFOHEAD[alg] + hHash;\n    };\n\n    /**\n     * get PKCS#1 padded hexadecimal DigestInfo\n     * @name getPaddedDigestInfoHex\n     * @memberOf KJUR.crypto.Util\n     * @function\n     * @param {String} hHash hexadecimal hash value of message to be signed\n     * @param {String} alg hash algorithm name (ex. 'sha1')\n     * @param {Integer} keySize key bit length (ex. 1024)\n     * @return {String} hexadecimal string of PKCS#1 padded DigestInfo\n     */\n    this.getPaddedDigestInfoHex = function(hHash, alg, keySize) {\n\tvar hDigestInfo = this.getDigestInfoHex(hHash, alg);\n\tvar pmStrLen = keySize / 4; // minimum PM length\n\n\tif (hDigestInfo.length + 22 > pmStrLen) // len(0001+ff(*8)+00+hDigestInfo)=22\n\t    throw \"key is too short for SigAlg: keylen=\" + keySize + \",\" + alg;\n\n\tvar hHead = \"0001\";\n\tvar hTail = \"00\" + hDigestInfo;\n\tvar hMid = \"\";\n\tvar fLen = pmStrLen - hHead.length - hTail.length;\n\tfor (var i = 0; i < fLen; i += 2) {\n\t    hMid += \"ff\";\n\t}\n\tvar hPaddedMessage = hHead + hMid + hTail;\n\treturn hPaddedMessage;\n    };\n\n    /**\n     * get hexadecimal hash of string with specified algorithm\n     * @name hashString\n     * @memberOf KJUR.crypto.Util\n     * @function\n     * @param {String} s input string to be hashed\n     * @param {String} alg hash algorithm name\n     * @return {String} hexadecimal string of hash value\n     * @since 1.1.1\n     */\n    this.hashString = function(s, alg) {\n        var md = new KJUR.crypto.MessageDigest({'alg': alg});\n        return md.digestString(s);\n    };\n\n    /**\n     * get hexadecimal hash of hexadecimal string with specified algorithm\n     * @name hashHex\n     * @memberOf KJUR.crypto.Util\n     * @function\n     * @param {String} sHex input hexadecimal string to be hashed\n     * @param {String} alg hash algorithm name\n     * @return {String} hexadecimal string of hash value\n     * @since 1.1.1\n     */\n    this.hashHex = function(sHex, alg) {\n        var md = new KJUR.crypto.MessageDigest({'alg': alg});\n        return md.digestHex(sHex);\n    };\n\n    /**\n     * get hexadecimal SHA1 hash of string\n     * @name sha1\n     * @memberOf KJUR.crypto.Util\n     * @function\n     * @param {String} s input string to be hashed\n     * @return {String} hexadecimal string of hash value\n     * @since 1.0.3\n     */\n    this.sha1 = function(s) {\n        var md = new KJUR.crypto.MessageDigest({'alg':'sha1', 'prov':'cryptojs'});\n        return md.digestString(s);\n    };\n\n    /**\n     * get hexadecimal SHA256 hash of string\n     * @name sha256\n     * @memberOf KJUR.crypto.Util\n     * @function\n     * @param {String} s input string to be hashed\n     * @return {String} hexadecimal string of hash value\n     * @since 1.0.3\n     */\n    this.sha256 = function(s) {\n        var md = new KJUR.crypto.MessageDigest({'alg':'sha256', 'prov':'cryptojs'});\n        return md.digestString(s);\n    };\n\n    this.sha256Hex = function(s) {\n        var md = new KJUR.crypto.MessageDigest({'alg':'sha256', 'prov':'cryptojs'});\n        return md.digestHex(s);\n    };\n\n    /**\n     * get hexadecimal SHA512 hash of string\n     * @name sha512\n     * @memberOf KJUR.crypto.Util\n     * @function\n     * @param {String} s input string to be hashed\n     * @return {String} hexadecimal string of hash value\n     * @since 1.0.3\n     */\n    this.sha512 = function(s) {\n        var md = new KJUR.crypto.MessageDigest({'alg':'sha512', 'prov':'cryptojs'});\n        return md.digestString(s);\n    };\n\n    this.sha512Hex = function(s) {\n        var md = new KJUR.crypto.MessageDigest({'alg':'sha512', 'prov':'cryptojs'});\n        return md.digestHex(s);\n    };\n\n    /**\n     * get hexadecimal MD5 hash of string\n     * @name md5\n     * @memberOf KJUR.crypto.Util\n     * @function\n     * @param {String} s input string to be hashed\n     * @return {String} hexadecimal string of hash value\n     * @since 1.0.3\n     */\n    this.md5 = function(s) {\n        var md = new KJUR.crypto.MessageDigest({'alg':'md5', 'prov':'cryptojs'});\n        return md.digestString(s);\n    };\n\n    /**\n     * get hexadecimal RIPEMD160 hash of string\n     * @name ripemd160\n     * @memberOf KJUR.crypto.Util\n     * @function\n     * @param {String} s input string to be hashed\n     * @return {String} hexadecimal string of hash value\n     * @since 1.0.3\n     */\n    this.ripemd160 = function(s) {\n        var md = new KJUR.crypto.MessageDigest({'alg':'ripemd160', 'prov':'cryptojs'});\n        return md.digestString(s);\n    };\n\n    /*\n     * @since 1.1.2\n     */\n    this.getCryptoJSMDByName = function(s) {\n\t\n    };\n};\n\n/**\n * MessageDigest class which is very similar to java.security.MessageDigest class\n * @name KJUR.crypto.MessageDigest\n * @class MessageDigest class which is very similar to java.security.MessageDigest class\n * @param {Array} params parameters for constructor\n * @description\n * <br/>\n * Currently this supports following algorithm and providers combination:\n * <ul>\n * <li>md5 - cryptojs</li>\n * <li>sha1 - cryptojs</li>\n * <li>sha224 - cryptojs</li>\n * <li>sha256 - cryptojs</li>\n * <li>sha384 - cryptojs</li>\n * <li>sha512 - cryptojs</li>\n * <li>ripemd160 - cryptojs</li>\n * <li>sha256 - sjcl (NEW from crypto.js 1.0.4)</li>\n * </ul>\n * @example\n * // CryptoJS provider sample\n * &lt;script src=\"http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/core.js\"&gt;&lt;/script&gt;\n * &lt;script src=\"http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/sha1.js\"&gt;&lt;/script&gt;\n * &lt;script src=\"crypto-1.0.js\"&gt;&lt;/script&gt;\n * var md = new KJUR.crypto.MessageDigest({alg: \"sha1\", prov: \"cryptojs\"});\n * md.updateString('aaa')\n * var mdHex = md.digest()\n *\n * // SJCL(Stanford JavaScript Crypto Library) provider sample\n * &lt;script src=\"http://bitwiseshiftleft.github.io/sjcl/sjcl.js\"&gt;&lt;/script&gt;\n * &lt;script src=\"crypto-1.0.js\"&gt;&lt;/script&gt;\n * var md = new KJUR.crypto.MessageDigest({alg: \"sha256\", prov: \"sjcl\"}); // sjcl supports sha256 only\n * md.updateString('aaa')\n * var mdHex = md.digest()\n */\nKJUR.crypto.MessageDigest = function(params) {\n    var md = null;\n    var algName = null;\n    var provName = null;\n\n    /**\n     * set hash algorithm and provider\n     * @name setAlgAndProvider\n     * @memberOf KJUR.crypto.MessageDigest\n     * @function\n     * @param {String} alg hash algorithm name\n     * @param {String} prov provider name\n     * @description\n     * @example\n     * // for SHA1\n     * md.setAlgAndProvider('sha1', 'cryptojs');\n     * // for RIPEMD160\n     * md.setAlgAndProvider('ripemd160', 'cryptojs');\n     */\n    this.setAlgAndProvider = function(alg, prov) {\n\tif (alg != null && prov === undefined) prov = KJUR.crypto.Util.DEFAULTPROVIDER[alg];\n\n\t// for cryptojs\n\tif (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:sm3:'.indexOf(alg) != -1 &&\n\t    prov == 'cryptojs') {\n\t    try {\n\t\tthis.md = eval(KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[alg]).create();\n\t    } catch (ex) {\n\t\tthrow \"setAlgAndProvider hash alg set fail alg=\" + alg + \"/\" + ex;\n\t    }\n\t    this.updateString = function(str) {\n\t\tthis.md.update(str);\n\t    };\n\t    this.updateHex = function(hex) {\n\t\tvar wHex = CryptoJS.enc.Hex.parse(hex);\n\t\tthis.md.update(wHex);\n\t    };\n\t    this.digest = function() {\n\t\tvar hash = this.md.finalize();\n\t\treturn hash.toString(CryptoJS.enc.Hex);\n\t    };\n\t    this.digestString = function(str) {\n\t\tthis.updateString(str);\n\t\treturn this.digest();\n\t    };\n\t    this.digestHex = function(hex) {\n\t\tthis.updateHex(hex);\n\t\treturn this.digest();\n\t    };\n\t}\n\tif (':sha256:'.indexOf(alg) != -1 &&\n\t    prov == 'sjcl') {\n\t    try {\n\t\tthis.md = new sjcl.hash.sha256();\n\t    } catch (ex) {\n\t\tthrow \"setAlgAndProvider hash alg set fail alg=\" + alg + \"/\" + ex;\n\t    }\n\t    this.updateString = function(str) {\n\t\tthis.md.update(str);\n\t    };\n\t    this.updateHex = function(hex) {\n\t\tvar baHex = sjcl.codec.hex.toBits(hex);\n\t\tthis.md.update(baHex);\n\t    };\n\t    this.digest = function() {\n\t\tvar hash = this.md.finalize();\n\t\treturn sjcl.codec.hex.fromBits(hash);\n\t    };\n\t    this.digestString = function(str) {\n\t\tthis.updateString(str);\n\t\treturn this.digest();\n\t    };\n\t    this.digestHex = function(hex) {\n\t\tthis.updateHex(hex);\n\t\treturn this.digest();\n\t    };\n\t}\n    };\n\n    /**\n     * update digest by specified string\n     * @name updateString\n     * @memberOf KJUR.crypto.MessageDigest\n     * @function\n     * @param {String} str string to update\n     * @description\n     * @example\n     * md.updateString('New York');\n     */\n    this.updateString = function(str) {\n\tthrow \"updateString(str) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n    };\n\n    /**\n     * update digest by specified hexadecimal string\n     * @name updateHex\n     * @memberOf KJUR.crypto.MessageDigest\n     * @function\n     * @param {String} hex hexadecimal string to update\n     * @description\n     * @example\n     * md.updateHex('0afe36');\n     */\n    this.updateHex = function(hex) {\n\tthrow \"updateHex(hex) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n    };\n\n    /**\n     * completes hash calculation and returns hash result\n     * @name digest\n     * @memberOf KJUR.crypto.MessageDigest\n     * @function\n     * @description\n     * @example\n     * md.digest()\n     */\n    this.digest = function() {\n\tthrow \"digest() not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n    };\n\n    /**\n     * performs final update on the digest using string, then completes the digest computation\n     * @name digestString\n     * @memberOf KJUR.crypto.MessageDigest\n     * @function\n     * @param {String} str string to final update\n     * @description\n     * @example\n     * md.digestString('aaa')\n     */\n    this.digestString = function(str) {\n\tthrow \"digestString(str) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n    };\n\n    /**\n     * performs final update on the digest using hexadecimal string, then completes the digest computation\n     * @name digestHex\n     * @memberOf KJUR.crypto.MessageDigest\n     * @function\n     * @param {String} hex hexadecimal string to final update\n     * @description\n     * @example\n     * md.digestHex('0f2abd')\n     */\n    this.digestHex = function(hex) {\n\tthrow \"digestHex(hex) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n    };\n\n    if (params !== undefined) {\n\tif (params['alg'] !== undefined) {\n\t    this.algName = params['alg'];\n\t    if (params['prov'] === undefined)\n\t\tthis.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];\n\t    this.setAlgAndProvider(this.algName, this.provName);\n\t}\n    }\n};\n\n/**\n * Mac(Message Authentication Code) class which is very similar to java.security.Mac class \n * @name KJUR.crypto.Mac\n * @class Mac class which is very similar to java.security.Mac class\n * @param {Array} params parameters for constructor\n * @description\n * <br/>\n * Currently this supports following algorithm and providers combination:\n * <ul>\n * <li>hmacmd5 - cryptojs</li>\n * <li>hmacsha1 - cryptojs</li>\n * <li>hmacsha224 - cryptojs</li>\n * <li>hmacsha256 - cryptojs</li>\n * <li>hmacsha384 - cryptojs</li>\n * <li>hmacsha512 - cryptojs</li>\n * </ul>\n * NOTE: HmacSHA224 and HmacSHA384 issue was fixed since jsrsasign 4.1.4.\n * Please use 'ext/cryptojs-312-core-fix*.js' instead of 'core.js' of original CryptoJS\n * to avoid those issue.\n * @example\n * var mac = new KJUR.crypto.Mac({alg: \"HmacSHA1\", prov: \"cryptojs\", \"pass\": \"pass\"});\n * mac.updateString('aaa')\n * var macHex = md.doFinal()\n */\nKJUR.crypto.Mac = function(params) {\n    var mac = null;\n    var pass = null;\n    var algName = null;\n    var provName = null;\n    var algProv = null;\n\n    this.setAlgAndProvider = function(alg, prov) {\n\tif (alg == null) alg = \"hmacsha1\";\n\n\talg = alg.toLowerCase();\n        if (alg.substr(0, 4) != \"hmac\") {\n\t    throw \"setAlgAndProvider unsupported HMAC alg: \" + alg;\n\t}\n\n\tif (prov === undefined) prov = KJUR.crypto.Util.DEFAULTPROVIDER[alg];\n\tthis.algProv = alg + \"/\" + prov;\n\n\tvar hashAlg = alg.substr(4);\n\n\t// for cryptojs\n\tif (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:'.indexOf(hashAlg) != -1 &&\n\t    prov == 'cryptojs') {\n\t    try {\n\t\tvar mdObj = eval(KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[hashAlg]);\n\t\tthis.mac = CryptoJS.algo.HMAC.create(mdObj, this.pass);\n\t    } catch (ex) {\n\t\tthrow \"setAlgAndProvider hash alg set fail hashAlg=\" + hashAlg + \"/\" + ex;\n\t    }\n\t    this.updateString = function(str) {\n\t\tthis.mac.update(str);\n\t    };\n\t    this.updateHex = function(hex) {\n\t\tvar wHex = CryptoJS.enc.Hex.parse(hex);\n\t\tthis.mac.update(wHex);\n\t    };\n\t    this.doFinal = function() {\n\t\tvar hash = this.mac.finalize();\n\t\treturn hash.toString(CryptoJS.enc.Hex);\n\t    };\n\t    this.doFinalString = function(str) {\n\t\tthis.updateString(str);\n\t\treturn this.doFinal();\n\t    };\n\t    this.doFinalHex = function(hex) {\n\t\tthis.updateHex(hex);\n\t\treturn this.doFinal();\n\t    };\n\t}\n    };\n\n    /**\n     * update digest by specified string\n     * @name updateString\n     * @memberOf KJUR.crypto.Mac\n     * @function\n     * @param {String} str string to update\n     * @description\n     * @example\n     * md.updateString('New York');\n     */\n    this.updateString = function(str) {\n\tthrow \"updateString(str) not supported for this alg/prov: \" + this.algProv;\n    };\n\n    /**\n     * update digest by specified hexadecimal string\n     * @name updateHex\n     * @memberOf KJUR.crypto.Mac\n     * @function\n     * @param {String} hex hexadecimal string to update\n     * @description\n     * @example\n     * md.updateHex('0afe36');\n     */\n    this.updateHex = function(hex) {\n\tthrow \"updateHex(hex) not supported for this alg/prov: \" + this.algProv;\n    };\n\n    /**\n     * completes hash calculation and returns hash result\n     * @name doFinal\n     * @memberOf KJUR.crypto.Mac\n     * @function\n     * @description\n     * @example\n     * md.digest()\n     */\n    this.doFinal = function() {\n\tthrow \"digest() not supported for this alg/prov: \" + this.algProv;\n    };\n\n    /**\n     * performs final update on the digest using string, then completes the digest computation\n     * @name doFinalString\n     * @memberOf KJUR.crypto.Mac\n     * @function\n     * @param {String} str string to final update\n     * @description\n     * @example\n     * md.digestString('aaa')\n     */\n    this.doFinalString = function(str) {\n\tthrow \"digestString(str) not supported for this alg/prov: \" + this.algProv;\n    };\n\n    /**\n     * performs final update on the digest using hexadecimal string, \n     * then completes the digest computation\n     * @name doFinalHex\n     * @memberOf KJUR.crypto.Mac\n     * @function\n     * @param {String} hex hexadecimal string to final update\n     * @description\n     * @example\n     * md.digestHex('0f2abd')\n     */\n    this.doFinalHex = function(hex) {\n\tthrow \"digestHex(hex) not supported for this alg/prov: \" + this.algProv;\n    };\n\n    if (params !== undefined) {\n\tif (params['pass'] !== undefined) {\n\t    this.pass = params['pass'];\n\t}\n\tif (params['alg'] !== undefined) {\n\t    this.algName = params['alg'];\n\t    if (params['prov'] === undefined)\n\t\tthis.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];\n\t    this.setAlgAndProvider(this.algName, this.provName);\n\t}\n    }\n};\n\n/**\n * Signature class which is very similar to java.security.Signature class\n * @name KJUR.crypto.Signature\n * @class Signature class which is very similar to java.security.Signature class\n * @param {Array} params parameters for constructor\n * @property {String} state Current state of this signature object whether 'SIGN', 'VERIFY' or null\n * @description\n * <br/>\n * As for params of constructor's argument, it can be specify following attributes:\n * <ul>\n * <li>alg - signature algorithm name (ex. {MD5,SHA1,SHA224,SHA256,SHA384,SHA512,RIPEMD160}with{RSA,ECDSA,DSA})</li>\n * <li>provider - currently 'cryptojs/jsrsa' only</li>\n * </ul>\n * <h4>SUPPORTED ALGORITHMS AND PROVIDERS</h4>\n * This Signature class supports following signature algorithm and provider names:\n * <ul>\n * <li>MD5withRSA - cryptojs/jsrsa</li>\n * <li>SHA1withRSA - cryptojs/jsrsa</li>\n * <li>SHA224withRSA - cryptojs/jsrsa</li>\n * <li>SHA256withRSA - cryptojs/jsrsa</li>\n * <li>SHA384withRSA - cryptojs/jsrsa</li>\n * <li>SHA512withRSA - cryptojs/jsrsa</li>\n * <li>RIPEMD160withRSA - cryptojs/jsrsa</li>\n * <li>MD5withECDSA - cryptojs/jsrsa</li>\n * <li>SHA1withECDSA - cryptojs/jsrsa</li>\n * <li>SHA224withECDSA - cryptojs/jsrsa</li>\n * <li>SHA256withECDSA - cryptojs/jsrsa</li>\n * <li>SHA384withECDSA - cryptojs/jsrsa</li>\n * <li>SHA512withECDSA - cryptojs/jsrsa</li>\n * <li>RIPEMD160withECDSA - cryptojs/jsrsa</li>\n * <li>MD5withRSAandMGF1 - cryptojs/jsrsa</li>\n * <li>SHA1withRSAandMGF1 - cryptojs/jsrsa</li>\n * <li>SHA224withRSAandMGF1 - cryptojs/jsrsa</li>\n * <li>SHA256withRSAandMGF1 - cryptojs/jsrsa</li>\n * <li>SHA384withRSAandMGF1 - cryptojs/jsrsa</li>\n * <li>SHA512withRSAandMGF1 - cryptojs/jsrsa</li>\n * <li>RIPEMD160withRSAandMGF1 - cryptojs/jsrsa</li>\n * <li>SHA1withDSA - cryptojs/jsrsa</li>\n * <li>SHA224withDSA - cryptojs/jsrsa</li>\n * <li>SHA256withDSA - cryptojs/jsrsa</li>\n * </ul>\n * Here are supported elliptic cryptographic curve names and their aliases for ECDSA:\n * <ul>\n * <li>secp256k1</li>\n * <li>secp256r1, NIST P-256, P-256, prime256v1</li>\n * <li>secp384r1, NIST P-384, P-384</li>\n * </ul>\n * NOTE1: DSA signing algorithm is also supported since crypto 1.1.5.\n * <h4>EXAMPLES</h4>\n * @example\n * // RSA signature generation\n * var sig = new KJUR.crypto.Signature({\"alg\": \"SHA1withRSA\"});\n * sig.init(prvKeyPEM);\n * sig.updateString('aaa');\n * var hSigVal = sig.sign();\n *\n * // DSA signature validation\n * var sig2 = new KJUR.crypto.Signature({\"alg\": \"SHA1withDSA\"});\n * sig2.init(certPEM);\n * sig.updateString('aaa');\n * var isValid = sig2.verify(hSigVal);\n * \n * // ECDSA signing\n * var sig = new KJUR.crypto.Signature({'alg':'SHA1withECDSA'});\n * sig.init(prvKeyPEM);\n * sig.updateString('aaa');\n * var sigValueHex = sig.sign();\n *\n * // ECDSA verifying\n * var sig2 = new KJUR.crypto.Signature({'alg':'SHA1withECDSA'});\n * sig.init(certPEM);\n * sig.updateString('aaa');\n * var isValid = sig.verify(sigValueHex);\n */\nKJUR.crypto.Signature = function(params) {\n    var prvKey = null; // RSAKey/KJUR.crypto.{ECDSA,DSA} object for signing\n    var pubKey = null; // RSAKey/KJUR.crypto.{ECDSA,DSA} object for verifying\n\n    var md = null; // KJUR.crypto.MessageDigest object\n    var sig = null;\n    var algName = null;\n    var provName = null;\n    var algProvName = null;\n    var mdAlgName = null;\n    var pubkeyAlgName = null;\t// rsa,ecdsa,rsaandmgf1(=rsapss)\n    var state = null;\n    var pssSaltLen = -1;\n    var initParams = null;\n\n    var sHashHex = null; // hex hash value for hex\n    var hDigestInfo = null;\n    var hPaddedDigestInfo = null;\n    var hSign = null;\n\n    this._setAlgNames = function() {\n\tif (this.algName.match(/^(.+)with(.+)$/)) {\n\t    this.mdAlgName = RegExp.$1.toLowerCase();\n\t    this.pubkeyAlgName = RegExp.$2.toLowerCase();\n\t}\n    };\n\n    this._zeroPaddingOfSignature = function(hex, bitLength) {\n\tvar s = \"\";\n\tvar nZero = bitLength / 4 - hex.length;\n\tfor (var i = 0; i < nZero; i++) {\n\t    s = s + \"0\";\n\t}\n\treturn s + hex;\n    };\n\n    /**\n     * set signature algorithm and provider\n     * @name setAlgAndProvider\n     * @memberOf KJUR.crypto.Signature\n     * @function\n     * @param {String} alg signature algorithm name\n     * @param {String} prov provider name\n     * @description\n     * @example\n     * md.setAlgAndProvider('SHA1withRSA', 'cryptojs/jsrsa');\n     */\n    this.setAlgAndProvider = function(alg, prov) {\n\tthis._setAlgNames();\n\tif (prov != 'cryptojs/jsrsa')\n\t    throw \"provider not supported: \" + prov;\n\n\tif (':md5:sha1:sha224:sha256:sha384:sha512:ripemd160:sm3:'.indexOf(this.mdAlgName) != -1) {\n\t    try {\n\t\tthis.md = new KJUR.crypto.MessageDigest({'alg':this.mdAlgName});\n\t    } catch (ex) {\n\t\tthrow \"setAlgAndProvider hash alg set fail alg=\" +\n                      this.mdAlgName + \"/\" + ex;\n\t    }\n\n\t    this.init = function(keyparam, pass) {\n\t\tvar keyObj = null;\n\t\ttry {\n\t\t    if (pass === undefined) {\n\t\t\tkeyObj = KEYUTIL.getKey(keyparam);\n\t\t    } else {\n\t\t\tkeyObj = KEYUTIL.getKey(keyparam, pass);\n\t\t    }\n\t\t} catch (ex) {\n\t\t    throw \"init failed:\" + ex;\n\t\t}\n\n\t\tif (keyObj.isPrivate === true) {\n\t\t    this.prvKey = keyObj;\n\t\t    this.state = \"SIGN\";\n\t\t} else if (keyObj.isPublic === true) {\n\t\t    this.pubKey = keyObj;\n\t\t    this.state = \"VERIFY\";\n\t\t} else {\n\t\t    throw \"init failed.:\" + keyObj;\n\t\t}\n\t    };\n\n\t    this.initSign = function(params) {\n\t\tif (typeof params['ecprvhex'] == 'string' &&\n                    typeof params['eccurvename'] == 'string') {\n\t\t    this.ecprvhex = params['ecprvhex'];\n\t\t    this.eccurvename = params['eccurvename'];\n\t\t} else {\n\t\t    this.prvKey = params;\n\t\t}\n\t\tthis.state = \"SIGN\";\n\t    };\n\n\t    this.initVerifyByPublicKey = function(params) {\n\t\tif (typeof params['ecpubhex'] == 'string' &&\n\t\t    typeof params['eccurvename'] == 'string') {\n\t\t    this.ecpubhex = params['ecpubhex'];\n\t\t    this.eccurvename = params['eccurvename'];\n\t\t} else if (params instanceof KJUR.crypto.ECDSA) {\n\t\t    this.pubKey = params;\n\t\t} else if (params instanceof RSAKey) {\n\t\t    this.pubKey = params;\n\t\t}\n\t\tthis.state = \"VERIFY\";\n\t    };\n\n\t    this.initVerifyByCertificatePEM = function(certPEM) {\n\t\tvar x509 = new X509();\n\t\tx509.readCertPEM(certPEM);\n\t\tthis.pubKey = x509.subjectPublicKeyRSA;\n\t\tthis.state = \"VERIFY\";\n\t    };\n\n\t    this.updateString = function(str) {\n\t\tthis.md.updateString(str);\n\t    };\n\t    this.updateHex = function(hex) {\n\t\tthis.md.updateHex(hex);\n\t    };\n\n\t    this.sign = function() {\n\t    \n\t    if(this.eccurvename != \"sm2\") {\n\t\t    this.sHashHex = this.md.digest();\n\t\t}\n\t\t\n\t\tif (typeof this.ecprvhex != \"undefined\" &&\n\t\t    typeof this.eccurvename != \"undefined\") {\n\t\t\tif(this.eccurvename == \"sm2\")\n\t\t\t{\n\t\t\t\tvar ec = new KJUR.crypto.SM3withSM2({curve: this.eccurvename});\n\t\t\t\t\n\t\t\t\tvar G = ec.ecparams['G'];\n\t\t\t\tvar Q = G.multiply(new BigInteger(this.ecprvhex, 16));\n\t\t\t\t\n\t\t\t\tvar pubKeyHex = Q.getX().toBigInteger().toRadix(16) + Q.getY().toBigInteger().toRadix(16);\n\t\t\t\t\n\t\t\t\tvar smDigest = new SM3Digest();\n\t\t\t\t\n\t\t\t\tvar z = new SM3Digest().GetZ(G, pubKeyHex);\n\t\t\t\tvar zValue = smDigest.GetWords(smDigest.GetHex(z).toString());\n\t\t\t\t\n\t\t\t\tvar rawData = CryptoJS.enc.Utf8.stringify(this.md.md._data);\n\t\t\t\trawData = CryptoJS.enc.Utf8.parse(rawData).toString();\n\t\t\t\trawData = smDigest.GetWords(rawData);\n\t\t\t\t\t\t\t\t\n                var smHash = new Array(smDigest.GetDigestSize());\n                smDigest.BlockUpdate(zValue, 0, zValue.length);\n                smDigest.BlockUpdate(rawData, 0, rawData.length);\n                smDigest.DoFinal(smHash, 0);\n\n                var hashHex = smDigest.GetHex(smHash).toString();\n\t\t\t\t\n\t\t\t\tthis.sHashHex = hashHex;\n\t\t\t\t\n\t\t    \tthis.hSign = ec.signHex(this.sHashHex, this.ecprvhex);\n\t\t\t}else {\n\t\t    \tvar ec = new KJUR.crypto.ECDSA({'curve': this.eccurvename});\n\t\t    \tthis.hSign = ec.signHex(this.sHashHex, this.ecprvhex);\n\t\t\t}\n\t\t} else if (this.pubkeyAlgName == \"rsaandmgf1\") {\n\t\t    this.hSign = this.prvKey.signWithMessageHashPSS(this.sHashHex,\n\t\t\t\t\t\t\t\t    this.mdAlgName,\n\t\t\t\t\t\t\t\t    this.pssSaltLen);\n\t\t} else if (this.pubkeyAlgName == \"rsa\") {\n\t\t    this.hSign = this.prvKey.signWithMessageHash(this.sHashHex,\n\t\t\t\t\t\t\t\t this.mdAlgName);\n\t\t} else if (this.prvKey instanceof KJUR.crypto.ECDSA) {\n\t\t    this.hSign = this.prvKey.signWithMessageHash(this.sHashHex);\n\t\t} else if (this.prvKey instanceof KJUR.crypto.DSA) {\n\t\t    this.hSign = this.prvKey.signWithMessageHash(this.sHashHex);\n\t\t} else {\n\t\t    throw \"Signature: unsupported public key alg: \" + this.pubkeyAlgName;\n\t\t}\n\t\treturn this.hSign;\n\t    };\n\t    this.signString = function(str) {\n\t\tthis.updateString(str);\n\t\tthis.sign();\n\t    };\n\t    this.signHex = function(hex) {\n\t\tthis.updateHex(hex);\n\t\tthis.sign();\n\t    };\n\t    this.verify = function(hSigVal) {\n\t    \n\t    if(this.eccurvename != \"sm2\") {\n\t        this.sHashHex = this.md.digest();\n\t    }\n\t    \n\t\tif (typeof this.ecpubhex != \"undefined\" &&\n\t\t    typeof this.eccurvename != \"undefined\") {\n\t\t\tif(this.eccurvename == \"sm2\")\n\t\t\t{\n\t\t\t\tvar ec = new KJUR.crypto.SM3withSM2({curve: this.eccurvename});\n\t\t\t\t\n\t\t\t\tvar G = ec.ecparams['G'];\n\t\t\t\t\t\t\t\t\n\t\t\t\tvar pubKeyHex = this.ecpubhex.substr(2, 128);\n\t\t\t\t\n\t\t\t\tvar smDigest = new SM3Digest();\n\t\t\t\t\n\t\t\t\tvar z = new SM3Digest().GetZ(G, pubKeyHex);\n\t\t\t\tvar zValue = smDigest.GetWords(smDigest.GetHex(z).toString());\n\t\t\t\t\n\t\t\t\tvar rawData = CryptoJS.enc.Utf8.stringify(this.md.md._data);\n\t\t\t\trawData = CryptoJS.enc.Utf8.parse(rawData).toString();\n\t\t\t\trawData = smDigest.GetWords(rawData);\n\t\t\t\t\n                var smHash = new Array(smDigest.GetDigestSize());\n                smDigest.BlockUpdate(zValue, 0, zValue.length);\n                smDigest.BlockUpdate(rawData, 0, rawData.length);\n                smDigest.DoFinal(smHash, 0);\n\n                var hashHex = smDigest.GetHex(smHash).toString();\n\t\t\t\t\n\t\t\t\tthis.sHashHex = hashHex;\n\t\t\t\t\n\t\t\t\t\n\t\t    \treturn ec.verifyHex(this.sHashHex, hSigVal, this.ecpubhex);\n\t\t\t}else {\n\t\t    \tvar ec = new KJUR.crypto.ECDSA({curve: this.eccurvename});\n\t\t    \treturn ec.verifyHex(this.sHashHex, hSigVal, this.ecpubhex);\n\t\t\t}\n\t\t} else if (this.pubkeyAlgName == \"rsaandmgf1\") {\n\t\t    return this.pubKey.verifyWithMessageHashPSS(this.sHashHex, hSigVal, \n\t\t\t\t\t\t\t\tthis.mdAlgName,\n\t\t\t\t\t\t\t\tthis.pssSaltLen);\n\t\t} else if (this.pubkeyAlgName == \"rsa\") {\n\t\t    return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal);\n\t\t} else if (this.pubKey instanceof KJUR.crypto.ECDSA) {\n\t\t    return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal);\n\t\t} else if (this.pubKey instanceof KJUR.crypto.DSA) {\n\t\t    return this.pubKey.verifyWithMessageHash(this.sHashHex, hSigVal);\n\t\t} else {\n\t\t    throw \"Signature: unsupported public key alg: \" + this.pubkeyAlgName;\n\t\t}\n\t    };\n\t}\n    };\n\n    /**\n     * Initialize this object for signing or verifying depends on key\n     * @name init\n     * @memberOf KJUR.crypto.Signature\n     * @function\n     * @param {Object} key specifying public or private key as plain/encrypted PKCS#5/8 PEM file, certificate PEM or {@link RSAKey}, {@link KJUR.crypto.DSA} or {@link KJUR.crypto.ECDSA} object\n     * @param {String} pass (OPTION) passcode for encrypted private key\n     * @since crypto 1.1.3\n     * @description\n     * This method is very useful initialize method for Signature class since\n     * you just specify key then this method will automatically initialize it\n     * using {@link KEYUTIL.getKey} method.\n     * As for 'key',  following argument type are supported:\n     * <h5>signing</h5>\n     * <ul>\n     * <li>PEM formatted PKCS#8 encrypted RSA/ECDSA private key concluding \"BEGIN ENCRYPTED PRIVATE KEY\"</li>\n     * <li>PEM formatted PKCS#5 encrypted RSA/DSA private key concluding \"BEGIN RSA/DSA PRIVATE KEY\" and \",ENCRYPTED\"</li>\n     * <li>PEM formatted PKCS#8 plain RSA/ECDSA private key concluding \"BEGIN PRIVATE KEY\"</li>\n     * <li>PEM formatted PKCS#5 plain RSA/DSA private key concluding \"BEGIN RSA/DSA PRIVATE KEY\" without \",ENCRYPTED\"</li>\n     * <li>RSAKey object of private key</li>\n     * <li>KJUR.crypto.ECDSA object of private key</li>\n     * <li>KJUR.crypto.DSA object of private key</li>\n     * </ul>\n     * <h5>verification</h5>\n     * <ul>\n     * <li>PEM formatted PKCS#8 RSA/EC/DSA public key concluding \"BEGIN PUBLIC KEY\"</li>\n     * <li>PEM formatted X.509 certificate with RSA/EC/DSA public key concluding\n     *     \"BEGIN CERTIFICATE\", \"BEGIN X509 CERTIFICATE\" or \"BEGIN TRUSTED CERTIFICATE\".</li>\n     * <li>RSAKey object of public key</li>\n     * <li>KJUR.crypto.ECDSA object of public key</li>\n     * <li>KJUR.crypto.DSA object of public key</li>\n     * </ul>\n     * @example\n     * sig.init(sCertPEM)\n     */\n    this.init = function(key, pass) {\n\tthrow \"init(key, pass) not supported for this alg:prov=\" +\n\t      this.algProvName;\n    };\n\n    /**\n     * Initialize this object for verifying with a public key\n     * @name initVerifyByPublicKey\n     * @memberOf KJUR.crypto.Signature\n     * @function\n     * @param {Object} param RSAKey object of public key or associative array for ECDSA\n     * @since 1.0.2\n     * @deprecated from crypto 1.1.5. please use init() method instead.\n     * @description\n     * Public key information will be provided as 'param' parameter and the value will be\n     * following:\n     * <ul>\n     * <li>{@link RSAKey} object for RSA verification</li>\n     * <li>associative array for ECDSA verification\n     *     (ex. <code>{'ecpubhex': '041f..', 'eccurvename': 'secp256r1'}</code>)\n     * </li>\n     * </ul>\n     * @example\n     * sig.initVerifyByPublicKey(rsaPrvKey)\n     */\n    this.initVerifyByPublicKey = function(rsaPubKey) {\n\tthrow \"initVerifyByPublicKey(rsaPubKeyy) not supported for this alg:prov=\" +\n\t      this.algProvName;\n    };\n\n    /**\n     * Initialize this object for verifying with a certficate\n     * @name initVerifyByCertificatePEM\n     * @memberOf KJUR.crypto.Signature\n     * @function\n     * @param {String} certPEM PEM formatted string of certificate\n     * @since 1.0.2\n     * @deprecated from crypto 1.1.5. please use init() method instead.\n     * @description\n     * @example\n     * sig.initVerifyByCertificatePEM(certPEM)\n     */\n    this.initVerifyByCertificatePEM = function(certPEM) {\n\tthrow \"initVerifyByCertificatePEM(certPEM) not supported for this alg:prov=\" +\n\t    this.algProvName;\n    };\n\n    /**\n     * Initialize this object for signing\n     * @name initSign\n     * @memberOf KJUR.crypto.Signature\n     * @function\n     * @param {Object} param RSAKey object of public key or associative array for ECDSA\n     * @deprecated from crypto 1.1.5. please use init() method instead.\n     * @description\n     * Private key information will be provided as 'param' parameter and the value will be\n     * following:\n     * <ul>\n     * <li>{@link RSAKey} object for RSA signing</li>\n     * <li>associative array for ECDSA signing\n     *     (ex. <code>{'ecprvhex': '1d3f..', 'eccurvename': 'secp256r1'}</code>)</li>\n     * </ul>\n     * @example\n     * sig.initSign(prvKey)\n     */\n    this.initSign = function(prvKey) {\n\tthrow \"initSign(prvKey) not supported for this alg:prov=\" + this.algProvName;\n    };\n\n    /**\n     * Updates the data to be signed or verified by a string\n     * @name updateString\n     * @memberOf KJUR.crypto.Signature\n     * @function\n     * @param {String} str string to use for the update\n     * @description\n     * @example\n     * sig.updateString('aaa')\n     */\n    this.updateString = function(str) {\n\tthrow \"updateString(str) not supported for this alg:prov=\" + this.algProvName;\n    };\n\n    /**\n     * Updates the data to be signed or verified by a hexadecimal string\n     * @name updateHex\n     * @memberOf KJUR.crypto.Signature\n     * @function\n     * @param {String} hex hexadecimal string to use for the update\n     * @description\n     * @example\n     * sig.updateHex('1f2f3f')\n     */\n    this.updateHex = function(hex) {\n\tthrow \"updateHex(hex) not supported for this alg:prov=\" + this.algProvName;\n    };\n\n    /**\n     * Returns the signature bytes of all data updates as a hexadecimal string\n     * @name sign\n     * @memberOf KJUR.crypto.Signature\n     * @function\n     * @return the signature bytes as a hexadecimal string\n     * @description\n     * @example\n     * var hSigValue = sig.sign()\n     */\n    this.sign = function() {\n\tthrow \"sign() not supported for this alg:prov=\" + this.algProvName;\n    };\n\n    /**\n     * performs final update on the sign using string, then returns the signature bytes of all data updates as a hexadecimal string\n     * @name signString\n     * @memberOf KJUR.crypto.Signature\n     * @function\n     * @param {String} str string to final update\n     * @return the signature bytes of a hexadecimal string\n     * @description\n     * @example\n     * var hSigValue = sig.signString('aaa')\n     */\n    this.signString = function(str) {\n\tthrow \"digestString(str) not supported for this alg:prov=\" + this.algProvName;\n    };\n\n    /**\n     * performs final update on the sign using hexadecimal string, then returns the signature bytes of all data updates as a hexadecimal string\n     * @name signHex\n     * @memberOf KJUR.crypto.Signature\n     * @function\n     * @param {String} hex hexadecimal string to final update\n     * @return the signature bytes of a hexadecimal string\n     * @description\n     * @example\n     * var hSigValue = sig.signHex('1fdc33')\n     */\n    this.signHex = function(hex) {\n\tthrow \"digestHex(hex) not supported for this alg:prov=\" + this.algProvName;\n    };\n\n    /**\n     * verifies the passed-in signature.\n     * @name verify\n     * @memberOf KJUR.crypto.Signature\n     * @function\n     * @param {String} str string to final update\n     * @return {Boolean} true if the signature was verified, otherwise false\n     * @description\n     * @example\n     * var isValid = sig.verify('1fbcefdca4823a7(snip)')\n     */\n    this.verify = function(hSigVal) {\n\tthrow \"verify(hSigVal) not supported for this alg:prov=\" + this.algProvName;\n    };\n\n    this.initParams = params;\n\n    if (params !== undefined) {\n\tif (params['alg'] !== undefined) {\n\t    this.algName = params['alg'];\n\t    if (params['prov'] === undefined) {\n\t\tthis.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];\n\t    } else {\n\t\tthis.provName = params['prov'];\n\t    }\n\t    this.algProvName = this.algName + \":\" + this.provName;\n\t    this.setAlgAndProvider(this.algName, this.provName);\n\t    this._setAlgNames();\n\t}\n\n\tif (params['psssaltlen'] !== undefined) this.pssSaltLen = params['psssaltlen'];\n\n\tif (params['prvkeypem'] !== undefined) {\n\t    if (params['prvkeypas'] !== undefined) {\n\t\tthrow \"both prvkeypem and prvkeypas parameters not supported\";\n\t    } else {\n\t\ttry {\n\t\t    var prvKey = new RSAKey();\n\t\t    prvKey.readPrivateKeyFromPEMString(params['prvkeypem']);\n\t\t    this.initSign(prvKey);\n\t\t} catch (ex) {\n\t\t    throw \"fatal error to load pem private key: \" + ex;\n\t\t}\n\t    }\n\t}\n    }\n};\n\n/**\n * static object for cryptographic function utilities\n * @name KJUR.crypto.OID\n * @class static object for cryptography related OIDs\n * @property {Array} oidhex2name key value of hexadecimal OID and its name\n *           (ex. '2a8648ce3d030107' and 'secp256r1')\n * @since crypto 1.1.3\n * @description\n */\n\n\nKJUR.crypto.OID = new function() {\n    this.oidhex2name = {\n\t'2a864886f70d010101': 'rsaEncryption',\n\t'2a8648ce3d0201': 'ecPublicKey',\n\t'2a8648ce380401': 'dsa',\n\t'2a8648ce3d030107': 'secp256r1',\n\t'2b8104001f': 'secp192k1',\n\t'2b81040021': 'secp224r1',\n\t'2b8104000a': 'secp256k1',\n\t'2b81040023': 'secp521r1',\n\t'2b81040022': 'secp384r1',\n\t'2a8648ce380403': 'SHA1withDSA', // 1.2.840.10040.4.3\n\t'608648016503040301': 'SHA224withDSA', // 2.16.840.1.101.3.4.3.1\n\t'608648016503040302': 'SHA256withDSA', // 2.16.840.1.101.3.4.3.2\n    };\n};\n"
  },
  {
    "path": "JavaScript/sm2/js/ec-patch.js",
    "content": "/*! (c) Stefan Thomas | https://github.com/bitcoinjs/bitcoinjs-lib\n */\n/*\n * splitted from bitcoin-lib/ecdsa.js\n *\n * version 1.0.0 is the original of bitcoin-lib/ecdsa.js\n */\nECFieldElementFp.prototype.getByteLength = function () {\n  return Math.floor((this.toBigInteger().bitLength() + 7) / 8);\n};\n\nECPointFp.prototype.getEncoded = function (compressed) {\n  var integerToBytes = function(i, len) {\n    var bytes = i.toByteArrayUnsigned();\n\n    if (len < bytes.length) {\n      bytes = bytes.slice(bytes.length-len);\n    } else while (len > bytes.length) {\n      bytes.unshift(0);\n    }\n    return bytes;\n  };\n\n  var x = this.getX().toBigInteger();\n  var y = this.getY().toBigInteger();\n\n  // Get value as a 32-byte Buffer\n  // Fixed length based on a patch by bitaddress.org and Casascius\n  var enc = integerToBytes(x, 32);\n\n  if (compressed) {\n    if (y.isEven()) {\n      // Compressed even pubkey\n      // M = 02 || X\n      enc.unshift(0x02);\n    } else {\n      // Compressed uneven pubkey\n      // M = 03 || X\n      enc.unshift(0x03);\n    }\n  } else {\n    // Uncompressed pubkey\n    // M = 04 || X || Y\n    enc.unshift(0x04);\n    enc = enc.concat(integerToBytes(y, 32));\n  }\n  return enc;\n};\n\nECPointFp.decodeFrom = function (curve, enc) {\n  var type = enc[0];\n  var dataLen = enc.length-1;\n\n  // Extract x and y as byte arrays\n  var xBa = enc.slice(1, 1 + dataLen/2);\n  var yBa = enc.slice(1 + dataLen/2, 1 + dataLen);\n\n  // Prepend zero byte to prevent interpretation as negative integer\n  xBa.unshift(0);\n  yBa.unshift(0);\n\n  // Convert to BigIntegers\n  var x = new BigInteger(xBa);\n  var y = new BigInteger(yBa);\n\n  // Return point\n  return new ECPointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y));\n};\n\n/*\n * @since ec-patch.js 1.0.1\n */\nECPointFp.decodeFromHex = function (curve, encHex) {\n  var type = encHex.substr(0, 2); // shall be \"04\"\n  var dataLen = encHex.length - 2;\n\n  // Extract x and y as byte arrays\n  var xHex = encHex.substr(2, dataLen / 2);\n  var yHex = encHex.substr(2 + dataLen / 2, dataLen / 2);\n\n  // Convert to BigIntegers\n  var x = new BigInteger(xHex, 16);\n  var y = new BigInteger(yHex, 16);\n\n  // Return point\n  return new ECPointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y));\n};\n\nECPointFp.prototype.add2D = function (b) {\n  if(this.isInfinity()) return b;\n  if(b.isInfinity()) return this;\n\n  if (this.x.equals(b.x)) {\n    if (this.y.equals(b.y)) {\n      // this = b, i.e. this must be doubled\n      return this.twice();\n    }\n    // this = -b, i.e. the result is the point at infinity\n    return this.curve.getInfinity();\n  }\n\n  var x_x = b.x.subtract(this.x);\n  var y_y = b.y.subtract(this.y);\n  var gamma = y_y.divide(x_x);\n\n  var x3 = gamma.square().subtract(this.x).subtract(b.x);\n  var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y);\n\n  return new ECPointFp(this.curve, x3, y3);\n};\n\nECPointFp.prototype.twice2D = function () {\n  if (this.isInfinity()) return this;\n  if (this.y.toBigInteger().signum() == 0) {\n    // if y1 == 0, then (x1, y1) == (x1, -y1)\n    // and hence this = -this and thus 2(x1, y1) == infinity\n    return this.curve.getInfinity();\n  }\n\n  var TWO = this.curve.fromBigInteger(BigInteger.valueOf(2));\n  var THREE = this.curve.fromBigInteger(BigInteger.valueOf(3));\n  var gamma = this.x.square().multiply(THREE).add(this.curve.a).divide(this.y.multiply(TWO));\n\n  var x3 = gamma.square().subtract(this.x.multiply(TWO));\n  var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y);\n\n  return new ECPointFp(this.curve, x3, y3);\n};\n\nECPointFp.prototype.multiply2D = function (k) {\n  if(this.isInfinity()) return this;\n  if(k.signum() == 0) return this.curve.getInfinity();\n\n  var e = k;\n  var h = e.multiply(new BigInteger(\"3\"));\n\n  var neg = this.negate();\n  var R = this;\n\n  var i;\n  for (i = h.bitLength() - 2; i > 0; --i) {\n    R = R.twice();\n\n    var hBit = h.testBit(i);\n    var eBit = e.testBit(i);\n\n    if (hBit != eBit) {\n      R = R.add2D(hBit ? this : neg);\n    }\n  }\n\n  return R;\n};\n\nECPointFp.prototype.isOnCurve = function () {\n  var x = this.getX().toBigInteger();\n  var y = this.getY().toBigInteger();\n  var a = this.curve.getA().toBigInteger();\n  var b = this.curve.getB().toBigInteger();\n  var n = this.curve.getQ();\n  var lhs = y.multiply(y).mod(n);\n  var rhs = x.multiply(x).multiply(x)\n    .add(a.multiply(x)).add(b).mod(n);\n  return lhs.equals(rhs);\n};\n\nECPointFp.prototype.toString = function () {\n  return '('+this.getX().toBigInteger().toString()+','+\n    this.getY().toBigInteger().toString()+')';\n};\n\n/**\n * Validate an elliptic curve point.\n *\n * See SEC 1, section 3.2.2.1: Elliptic Curve Public Key Validation Primitive\n */\nECPointFp.prototype.validate = function () {\n  var n = this.curve.getQ();\n\n  // Check Q != O\n  if (this.isInfinity()) {\n    throw new Error(\"Point is at infinity.\");\n  }\n\n  // Check coordinate bounds\n  var x = this.getX().toBigInteger();\n  var y = this.getY().toBigInteger();\n  if (x.compareTo(BigInteger.ONE) < 0 ||\n      x.compareTo(n.subtract(BigInteger.ONE)) > 0) {\n    throw new Error('x coordinate out of bounds');\n  }\n  if (y.compareTo(BigInteger.ONE) < 0 ||\n      y.compareTo(n.subtract(BigInteger.ONE)) > 0) {\n    throw new Error('y coordinate out of bounds');\n  }\n\n  // Check y^2 = x^3 + ax + b (mod n)\n  if (!this.isOnCurve()) {\n    throw new Error(\"Point is not on the curve.\");\n  }\n\n  // Check nQ = 0 (Q is a scalar multiple of G)\n  if (this.multiply(n).isInfinity()) {\n    // TODO: This check doesn't work - fix.\n    throw new Error(\"Point is not a scalar multiple of G.\");\n  }\n\n  return true;\n};\n"
  },
  {
    "path": "JavaScript/sm2/js/ec.js",
    "content": "/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\n// Basic Javascript Elliptic Curve implementation\n// Ported loosely from BouncyCastle's Java EC code\n// Only Fp curves implemented for now\n\n// Requires jsbn.js and jsbn2.js\n\n// ----------------\n// ECFieldElementFp\n\n// constructor\nfunction ECFieldElementFp(q,x) {\n    this.x = x;\n    // TODO if(x.compareTo(q) >= 0) error\n    this.q = q;\n}\n\nfunction feFpEquals(other) {\n    if(other == this) return true;\n    return (this.q.equals(other.q) && this.x.equals(other.x));\n}\n\nfunction feFpToBigInteger() {\n    return this.x;\n}\n\nfunction feFpNegate() {\n    return new ECFieldElementFp(this.q, this.x.negate().mod(this.q));\n}\n\nfunction feFpAdd(b) {\n    return new ECFieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q));\n}\n\nfunction feFpSubtract(b) {\n    return new ECFieldElementFp(this.q, this.x.subtract(b.toBigInteger()).mod(this.q));\n}\n\nfunction feFpMultiply(b) {\n    return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger()).mod(this.q));\n}\n\nfunction feFpSquare() {\n    return new ECFieldElementFp(this.q, this.x.square().mod(this.q));\n}\n\nfunction feFpDivide(b) {\n    return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q));\n}\n\nECFieldElementFp.prototype.equals = feFpEquals;\nECFieldElementFp.prototype.toBigInteger = feFpToBigInteger;\nECFieldElementFp.prototype.negate = feFpNegate;\nECFieldElementFp.prototype.add = feFpAdd;\nECFieldElementFp.prototype.subtract = feFpSubtract;\nECFieldElementFp.prototype.multiply = feFpMultiply;\nECFieldElementFp.prototype.square = feFpSquare;\nECFieldElementFp.prototype.divide = feFpDivide;\n\n// ----------------\n// ECPointFp\n\n// constructor\nfunction ECPointFp(curve,x,y,z) {\n    this.curve = curve;\n    this.x = x;\n    this.y = y;\n    // Projective coordinates: either zinv == null or z * zinv == 1\n    // z and zinv are just BigIntegers, not fieldElements\n    if(z == null) {\n      this.z = BigInteger.ONE;\n    }\n    else {\n      this.z = z;\n    }\n    this.zinv = null;\n    //TODO: compression flag\n}\n\nfunction pointFpGetX() {\n    if(this.zinv == null) {\n      this.zinv = this.z.modInverse(this.curve.q);\n    }\n    return this.curve.fromBigInteger(this.x.toBigInteger().multiply(this.zinv).mod(this.curve.q));\n}\n\nfunction pointFpGetY() {\n    if(this.zinv == null) {\n      this.zinv = this.z.modInverse(this.curve.q);\n    }\n    return this.curve.fromBigInteger(this.y.toBigInteger().multiply(this.zinv).mod(this.curve.q));\n}\n\nfunction pointFpEquals(other) {\n    if(other == this) return true;\n    if(this.isInfinity()) return other.isInfinity();\n    if(other.isInfinity()) return this.isInfinity();\n    var u, v;\n    // u = Y2 * Z1 - Y1 * Z2\n    u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod(this.curve.q);\n    if(!u.equals(BigInteger.ZERO)) return false;\n    // v = X2 * Z1 - X1 * Z2\n    v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod(this.curve.q);\n    return v.equals(BigInteger.ZERO);\n}\n\nfunction pointFpIsInfinity() {\n    if((this.x == null) && (this.y == null)) return true;\n    return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO);\n}\n\nfunction pointFpNegate() {\n    return new ECPointFp(this.curve, this.x, this.y.negate(), this.z);\n}\n\nfunction pointFpAdd(b) {\n    if(this.isInfinity()) return b;\n    if(b.isInfinity()) return this;\n\n    // u = Y2 * Z1 - Y1 * Z2\n    var u = b.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(b.z)).mod(this.curve.q);\n    // v = X2 * Z1 - X1 * Z2\n    var v = b.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(b.z)).mod(this.curve.q);\n\n    if(BigInteger.ZERO.equals(v)) {\n        if(BigInteger.ZERO.equals(u)) {\n            return this.twice(); // this == b, so double\n        }\n\treturn this.curve.getInfinity(); // this = -b, so infinity\n    }\n\n    var THREE = new BigInteger(\"3\");\n    var x1 = this.x.toBigInteger();\n    var y1 = this.y.toBigInteger();\n    var x2 = b.x.toBigInteger();\n    var y2 = b.y.toBigInteger();\n\n    var v2 = v.square();\n    var v3 = v2.multiply(v);\n    var x1v2 = x1.multiply(v2);\n    var zu2 = u.square().multiply(this.z);\n\n    // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3)\n    var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.q);\n    // y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3\n    var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.curve.q);\n    // z3 = v^3 * z1 * z2\n    var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.q);\n\n    return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3);\n}\n\nfunction pointFpTwice() {\n    if(this.isInfinity()) return this;\n    if(this.y.toBigInteger().signum() == 0) return this.curve.getInfinity();\n\n    // TODO: optimized handling of constants\n    var THREE = new BigInteger(\"3\");\n    var x1 = this.x.toBigInteger();\n    var y1 = this.y.toBigInteger();\n\n    var y1z1 = y1.multiply(this.z);\n    var y1sqz1 = y1z1.multiply(y1).mod(this.curve.q);\n    var a = this.curve.a.toBigInteger();\n\n    // w = 3 * x1^2 + a * z1^2\n    var w = x1.square().multiply(THREE);\n    if(!BigInteger.ZERO.equals(a)) {\n      w = w.add(this.z.square().multiply(a));\n    }\n    w = w.mod(this.curve.q);\n    // x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1)\n    var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.curve.q);\n    // y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3\n    var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.square().multiply(w)).mod(this.curve.q);\n    // z3 = 8 * (y1 * z1)^3\n    var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.q);\n\n    return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3);\n}\n\n// Simple NAF (Non-Adjacent Form) multiplication algorithm\n// TODO: modularize the multiplication algorithm\nfunction pointFpMultiply(k) {\n    if(this.isInfinity()) return this;\n    if(k.signum() == 0) return this.curve.getInfinity();\n\n    var e = k;\n    var h = e.multiply(new BigInteger(\"3\"));\n\n    var neg = this.negate();\n    var R = this;\n\n    var i;\n    for(i = h.bitLength() - 2; i > 0; --i) {\n\tR = R.twice();\n\n\tvar hBit = h.testBit(i);\n\tvar eBit = e.testBit(i);\n\n\tif (hBit != eBit) {\n\t    R = R.add(hBit ? this : neg);\n\t}\n    }\n\n    return R;\n}\n\n// Compute this*j + x*k (simultaneous multiplication)\nfunction pointFpMultiplyTwo(j,x,k) {\n  var i;\n  if(j.bitLength() > k.bitLength())\n    i = j.bitLength() - 1;\n  else\n    i = k.bitLength() - 1;\n\n  var R = this.curve.getInfinity();\n  var both = this.add(x);\n  while(i >= 0) {\n    R = R.twice();\n    if(j.testBit(i)) {\n      if(k.testBit(i)) {\n        R = R.add(both);\n      }\n      else {\n        R = R.add(this);\n      }\n    }\n    else {\n      if(k.testBit(i)) {\n        R = R.add(x);\n      }\n    }\n    --i;\n  }\n\n  return R;\n}\n\nECPointFp.prototype.getX = pointFpGetX;\nECPointFp.prototype.getY = pointFpGetY;\nECPointFp.prototype.equals = pointFpEquals;\nECPointFp.prototype.isInfinity = pointFpIsInfinity;\nECPointFp.prototype.negate = pointFpNegate;\nECPointFp.prototype.add = pointFpAdd;\nECPointFp.prototype.twice = pointFpTwice;\nECPointFp.prototype.multiply = pointFpMultiply;\nECPointFp.prototype.multiplyTwo = pointFpMultiplyTwo;\n\n// ----------------\n// ECCurveFp\n\n// constructor\nfunction ECCurveFp(q,a,b) {\n    this.q = q;\n    this.a = this.fromBigInteger(a);\n    this.b = this.fromBigInteger(b);\n    this.infinity = new ECPointFp(this, null, null);\n}\n\nfunction curveFpGetQ() {\n    return this.q;\n}\n\nfunction curveFpGetA() {\n    return this.a;\n}\n\nfunction curveFpGetB() {\n    return this.b;\n}\n\nfunction curveFpEquals(other) {\n    if(other == this) return true;\n    return(this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b));\n}\n\nfunction curveFpGetInfinity() {\n    return this.infinity;\n}\n\nfunction curveFpFromBigInteger(x) {\n    return new ECFieldElementFp(this.q, x);\n}\n\n// for now, work with hex strings because they're easier in JS\nfunction curveFpDecodePointHex(s) {\n    switch(parseInt(s.substr(0,2), 16)) { // first byte\n    case 0:\n\treturn this.infinity;\n    case 2:\n    case 3:\n\t// point compression not supported yet\n\treturn null;\n    case 4:\n    case 6:\n    case 7:\n\tvar len = (s.length - 2) / 2;\n\tvar xHex = s.substr(2, len);\n\tvar yHex = s.substr(len+2, len);\n\n\treturn new ECPointFp(this,\n\t\t\t     this.fromBigInteger(new BigInteger(xHex, 16)),\n\t\t\t     this.fromBigInteger(new BigInteger(yHex, 16)));\n\n    default: // unsupported\n\treturn null;\n    }\n}\n\nECCurveFp.prototype.getQ = curveFpGetQ;\nECCurveFp.prototype.getA = curveFpGetA;\nECCurveFp.prototype.getB = curveFpGetB;\nECCurveFp.prototype.equals = curveFpEquals;\nECCurveFp.prototype.getInfinity = curveFpGetInfinity;\nECCurveFp.prototype.fromBigInteger = curveFpFromBigInteger;\nECCurveFp.prototype.decodePointHex = curveFpDecodePointHex;\n"
  },
  {
    "path": "JavaScript/sm2/js/ecdsa-modified-1.0.js",
    "content": "/*! ecdsa-modified-1.0.4.js (c) Stephan Thomas, Kenji Urushima | github.com/bitcoinjs/bitcoinjs-lib/blob/master/LICENSE\n */\n/*\n * ecdsa-modified.js - modified Bitcoin.ECDSA class\n * \n * Copyright (c) 2013 Stefan Thomas (github.com/justmoon)\n *                    Kenji Urushima (kenji.urushima@gmail.com)\n * LICENSE\n *   https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/LICENSE\n */\n\n/**\n * @fileOverview\n * @name ecdsa-modified-1.0.js\n * @author Stefan Thomas (github.com/justmoon) and Kenji Urushima (kenji.urushima@gmail.com)\n * @version 1.0.4 (2013-Oct-06)\n * @since jsrsasign 4.0\n * @license <a href=\"https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/LICENSE\">MIT License</a>\n */\n\nif (typeof KJUR == \"undefined\" || !KJUR) KJUR = {};\nif (typeof KJUR.crypto == \"undefined\" || !KJUR.crypto) KJUR.crypto = {};\n\n/**\n * class for EC key generation,  ECDSA signing and verifcation\n * @name KJUR.crypto.ECDSA\n * @class class for EC key generation,  ECDSA signing and verifcation\n * @description\n * <p>\n * CAUTION: Most of the case, you don't need to use this class except\n * for generating an EC key pair. Please use {@link KJUR.crypto.Signature} class instead.\n * </p>\n * <p>\n * This class was originally developped by Stefan Thomas for Bitcoin JavaScript library.\n * (See {@link https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/ecdsa.js})\n * Currently this class supports following named curves and their aliases.\n * <ul>\n * <li>secp256r1, NIST P-256, P-256, prime256v1 (*)</li>\n * <li>secp256k1 (*)</li>\n * <li>secp384r1, NIST P-384, P-384 (*)</li>\n * </ul>\n * </p>\n */\nKJUR.crypto.ECDSA = function(params) {\n    var curveName = \"secp256r1\";\t// curve name default\n    var ecparams = null;\n    var prvKeyHex = null;\n    var pubKeyHex = null;\n\n    var rng = new SecureRandom();\n\n    var P_OVER_FOUR = null;\n\n    this.type = \"EC\";\n\n    function implShamirsTrick(P, k, Q, l) {\n\tvar m = Math.max(k.bitLength(), l.bitLength());\n\tvar Z = P.add2D(Q);\n\tvar R = P.curve.getInfinity();\n\n\tfor (var i = m - 1; i >= 0; --i) {\n\t    R = R.twice2D();\n\n\t    R.z = BigInteger.ONE;\n\n\t    if (k.testBit(i)) {\n\t\tif (l.testBit(i)) {\n\t\t    R = R.add2D(Z);\n\t\t} else {\n\t\t    R = R.add2D(P);\n\t\t}\n\t    } else {\n\t\tif (l.testBit(i)) {\n\t\t    R = R.add2D(Q);\n\t\t}\n\t    }\n\t}\n\t\n\treturn R;\n    };\n\n    //===========================\n    // PUBLIC METHODS\n    //===========================\n    this.getBigRandom = function (limit) {\n\treturn new BigInteger(limit.bitLength(), rng)\n\t.mod(limit.subtract(BigInteger.ONE))\n\t.add(BigInteger.ONE)\n\t;\n    };\n\n    this.setNamedCurve = function(curveName) {\n\tthis.ecparams = KJUR.crypto.ECParameterDB.getByName(curveName);\n\tthis.prvKeyHex = null;\n\tthis.pubKeyHex = null;\n\tthis.curveName = curveName;\n    }\n\n    this.setPrivateKeyHex = function(prvKeyHex) {\n        this.isPrivate = true;\n\tthis.prvKeyHex = prvKeyHex;\n    }\n\n    this.setPublicKeyHex = function(pubKeyHex) {\n        this.isPublic = true;\n\tthis.pubKeyHex = pubKeyHex;\n    }\n\n    /**\n     * generate a EC key pair\n     * @name generateKeyPairHex\n     * @memberOf KJUR.crypto.ECDSA\n     * @function\n     * @return {Array} associative array of hexadecimal string of private and public key\n     * @since ecdsa-modified 1.0.1\n     * @example\n     * var ec = KJUR.crypto.ECDSA({'curve': 'secp256r1'});\n     * var keypair = ec.generateKeyPairHex();\n     * var pubhex = keypair.ecpubhex; // hexadecimal string of EC private key (=d)\n     * var prvhex = keypair.ecprvhex; // hexadecimal string of EC public key\n     */\n    this.generateKeyPairHex = function() {\n\tvar biN = this.ecparams['n'];\n\tvar biPrv = this.getBigRandom(biN);\n\tvar epPub = this.ecparams['G'].multiply(biPrv);\n\tvar biX = epPub.getX().toBigInteger();\n\tvar biY = epPub.getY().toBigInteger();\n\n\tvar charlen = this.ecparams['keylen'] / 4;\n\tvar hPrv = (\"0000000000\" + biPrv.toString(16)).slice(- charlen);\n\tvar hX   = (\"0000000000\" + biX.toString(16)).slice(- charlen);\n\tvar hY   = (\"0000000000\" + biY.toString(16)).slice(- charlen);\n\tvar hPub = \"04\" + hX + hY;\n\n\tthis.setPrivateKeyHex(hPrv);\n\tthis.setPublicKeyHex(hPub);\n\treturn {'ecprvhex': hPrv, 'ecpubhex': hPub};\n    };\n\n    this.signWithMessageHash = function(hashHex) {\n\treturn this.signHex(hashHex, this.prvKeyHex);\n    };\n\n    /**\n     * signing to message hash\n     * @name signHex\n     * @memberOf KJUR.crypto.ECDSA\n     * @function\n     * @param {String} hashHex hexadecimal string of hash value of signing message\n     * @param {String} privHex hexadecimal string of EC private key\n     * @return {String} hexadecimal string of ECDSA signature\n     * @since ecdsa-modified 1.0.1\n     * @example\n     * var ec = KJUR.crypto.ECDSA({'curve': 'secp256r1'});\n     * var sigValue = ec.signHex(hash, prvKey);\n     */\n    this.signHex = function (hashHex, privHex) {\n\tvar d = new BigInteger(privHex, 16);\n\tvar n = this.ecparams['n'];\n\tvar e = new BigInteger(hashHex, 16);\n\n\tdo {\n\t    var k = this.getBigRandom(n);\n\t    var G = this.ecparams['G'];\n\t    var Q = G.multiply(k);\n\t    var r = Q.getX().toBigInteger().mod(n);\n\t} while (r.compareTo(BigInteger.ZERO) <= 0);\n\n\tvar s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);\n\n\treturn KJUR.crypto.ECDSA.biRSSigToASN1Sig(r, s);\n    };\n\n    this.sign = function (hash, priv) {\n\tvar d = priv;\n\tvar n = this.ecparams['n'];\n\tvar e = BigInteger.fromByteArrayUnsigned(hash);\n\n\tdo {\n\t    var k = this.getBigRandom(n);\n\t    var G = this.ecparams['G'];\n\t    var Q = G.multiply(k);\n\t    var r = Q.getX().toBigInteger().mod(n);\n\t} while (r.compareTo(BigInteger.ZERO) <= 0);\n\n\tvar s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);\n\treturn this.serializeSig(r, s);\n    };\n\n    this.verifyWithMessageHash = function(hashHex, sigHex) {\n\treturn this.verifyHex(hashHex, sigHex, this.pubKeyHex);\n    };\n\n    /**\n     * verifying signature with message hash and public key\n     * @name verifyHex\n     * @memberOf KJUR.crypto.ECDSA\n     * @function\n     * @param {String} hashHex hexadecimal string of hash value of signing message\n     * @param {String} sigHex hexadecimal string of signature value\n     * @param {String} pubkeyHex hexadecimal string of public key\n     * @return {Boolean} true if the signature is valid, otherwise false\n     * @since ecdsa-modified 1.0.1\n     * @example\n     * var ec = KJUR.crypto.ECDSA({'curve': 'secp256r1'});\n     * var result = ec.verifyHex(msgHashHex, sigHex, pubkeyHex);\n     */\n    this.verifyHex = function(hashHex, sigHex, pubkeyHex) {\n\tvar r,s;\n\n\tvar obj = KJUR.crypto.ECDSA.parseSigHex(sigHex);\n\tr = obj.r;\n\ts = obj.s;\n\n\tvar Q;\n\tQ = ECPointFp.decodeFromHex(this.ecparams['curve'], pubkeyHex);\n\tvar e = new BigInteger(hashHex, 16);\n\n\treturn this.verifyRaw(e, r, s, Q);\n    };\n\n    this.verify = function (hash, sig, pubkey) {\n\tvar r,s;\n\tif (Bitcoin.Util.isArray(sig)) {\n\t    var obj = this.parseSig(sig);\n\t    r = obj.r;\n\t    s = obj.s;\n\t} else if (\"object\" === typeof sig && sig.r && sig.s) {\n\t    r = sig.r;\n\t    s = sig.s;\n\t} else {\n\t    throw \"Invalid value for signature\";\n\t}\n\n\tvar Q;\n\tif (pubkey instanceof ECPointFp) {\n\t    Q = pubkey;\n\t} else if (Bitcoin.Util.isArray(pubkey)) {\n\t    Q = ECPointFp.decodeFrom(this.ecparams['curve'], pubkey);\n\t} else {\n\t    throw \"Invalid format for pubkey value, must be byte array or ECPointFp\";\n\t}\n\tvar e = BigInteger.fromByteArrayUnsigned(hash);\n\n\treturn this.verifyRaw(e, r, s, Q);\n    };\n\n    this.verifyRaw = function (e, r, s, Q) {\n\tvar n = this.ecparams['n'];\n\tvar G = this.ecparams['G'];\n\n\tif (r.compareTo(BigInteger.ONE) < 0 ||\n\t    r.compareTo(n) >= 0)\n\t    return false;\n\n\tif (s.compareTo(BigInteger.ONE) < 0 ||\n\t    s.compareTo(n) >= 0)\n\t    return false;\n\n\tvar c = s.modInverse(n);\n\n\tvar u1 = e.multiply(c).mod(n);\n\tvar u2 = r.multiply(c).mod(n);\n\n\t// TODO(!!!): For some reason Shamir's trick isn't working with\n\t// signed message verification!? Probably an implementation\n\t// error!\n\t//var point = implShamirsTrick(G, u1, Q, u2);\n\tvar point = G.multiply(u1).add(Q.multiply(u2));\n\n\tvar v = point.getX().toBigInteger().mod(n);\n\n\treturn v.equals(r);\n    };\n\n    /**\n     * Serialize a signature into DER format.\n     *\n     * Takes two BigIntegers representing r and s and returns a byte array.\n     */\n    this.serializeSig = function (r, s) {\n\tvar rBa = r.toByteArraySigned();\n\tvar sBa = s.toByteArraySigned();\n\n\tvar sequence = [];\n\tsequence.push(0x02); // INTEGER\n\tsequence.push(rBa.length);\n\tsequence = sequence.concat(rBa);\n\n\tsequence.push(0x02); // INTEGER\n\tsequence.push(sBa.length);\n\tsequence = sequence.concat(sBa);\n\n\tsequence.unshift(sequence.length);\n\tsequence.unshift(0x30); // SEQUENCE\n\treturn sequence;\n    };\n\n    /**\n     * Parses a byte array containing a DER-encoded signature.\n     *\n     * This function will return an object of the form:\n     *\n     * {\n     *   r: BigInteger,\n     *   s: BigInteger\n     * }\n     */\n    this.parseSig = function (sig) {\n\tvar cursor;\n\tif (sig[0] != 0x30)\n\t    throw new Error(\"Signature not a valid DERSequence\");\n\n\tcursor = 2;\n\tif (sig[cursor] != 0x02)\n\t    throw new Error(\"First element in signature must be a DERInteger\");;\n\tvar rBa = sig.slice(cursor+2, cursor+2+sig[cursor+1]);\n\n\tcursor += 2+sig[cursor+1];\n\tif (sig[cursor] != 0x02)\n\t    throw new Error(\"Second element in signature must be a DERInteger\");\n\tvar sBa = sig.slice(cursor+2, cursor+2+sig[cursor+1]);\n\n\tcursor += 2+sig[cursor+1];\n\n\t//if (cursor != sig.length)\n\t//  throw new Error(\"Extra bytes in signature\");\n\n\tvar r = BigInteger.fromByteArrayUnsigned(rBa);\n\tvar s = BigInteger.fromByteArrayUnsigned(sBa);\n\n\treturn {r: r, s: s};\n    };\n\n    this.parseSigCompact = function (sig) {\n\tif (sig.length !== 65) {\n\t    throw \"Signature has the wrong length\";\n\t}\n\n\t// Signature is prefixed with a type byte storing three bits of\n\t// information.\n\tvar i = sig[0] - 27;\n\tif (i < 0 || i > 7) {\n\t    throw \"Invalid signature type\";\n\t}\n\n\tvar n = this.ecparams['n'];\n\tvar r = BigInteger.fromByteArrayUnsigned(sig.slice(1, 33)).mod(n);\n\tvar s = BigInteger.fromByteArrayUnsigned(sig.slice(33, 65)).mod(n);\n\n\treturn {r: r, s: s, i: i};\n    };\n\n    /*\n     * Recover a public key from a signature.\n     *\n     * See SEC 1: Elliptic Curve Cryptography, section 4.1.6, \"Public\n     * Key Recovery Operation\".\n     *\n     * http://www.secg.org/download/aid-780/sec1-v2.pdf\n     */\n    /*\n    recoverPubKey: function (r, s, hash, i) {\n\t// The recovery parameter i has two bits.\n\ti = i & 3;\n\n\t// The less significant bit specifies whether the y coordinate\n\t// of the compressed point is even or not.\n\tvar isYEven = i & 1;\n\n\t// The more significant bit specifies whether we should use the\n\t// first or second candidate key.\n\tvar isSecondKey = i >> 1;\n\n\tvar n = this.ecparams['n'];\n\tvar G = this.ecparams['G'];\n\tvar curve = this.ecparams['curve'];\n\tvar p = curve.getQ();\n\tvar a = curve.getA().toBigInteger();\n\tvar b = curve.getB().toBigInteger();\n\n\t// We precalculate (p + 1) / 4 where p is if the field order\n\tif (!P_OVER_FOUR) {\n\t    P_OVER_FOUR = p.add(BigInteger.ONE).divide(BigInteger.valueOf(4));\n\t}\n\n\t// 1.1 Compute x\n\tvar x = isSecondKey ? r.add(n) : r;\n\n\t// 1.3 Convert x to point\n\tvar alpha = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(p);\n\tvar beta = alpha.modPow(P_OVER_FOUR, p);\n\n\tvar xorOdd = beta.isEven() ? (i % 2) : ((i+1) % 2);\n\t// If beta is even, but y isn't or vice versa, then convert it,\n\t// otherwise we're done and y == beta.\n\tvar y = (beta.isEven() ? !isYEven : isYEven) ? beta : p.subtract(beta);\n\n\t// 1.4 Check that nR is at infinity\n\tvar R = new ECPointFp(curve,\n\t\t\t      curve.fromBigInteger(x),\n\t\t\t      curve.fromBigInteger(y));\n\tR.validate();\n\n\t// 1.5 Compute e from M\n\tvar e = BigInteger.fromByteArrayUnsigned(hash);\n\tvar eNeg = BigInteger.ZERO.subtract(e).mod(n);\n\n\t// 1.6 Compute Q = r^-1 (sR - eG)\n\tvar rInv = r.modInverse(n);\n\tvar Q = implShamirsTrick(R, s, G, eNeg).multiply(rInv);\n\n\tQ.validate();\n\tif (!this.verifyRaw(e, r, s, Q)) {\n\t    throw \"Pubkey recovery unsuccessful\";\n\t}\n\n\tvar pubKey = new Bitcoin.ECKey();\n\tpubKey.pub = Q;\n\treturn pubKey;\n    },\n    */\n\n    /*\n     * Calculate pubkey extraction parameter.\n     *\n     * When extracting a pubkey from a signature, we have to\n     * distinguish four different cases. Rather than putting this\n     * burden on the verifier, Bitcoin includes a 2-bit value with the\n     * signature.\n     *\n     * This function simply tries all four cases and returns the value\n     * that resulted in a successful pubkey recovery.\n     */\n    /*\n    calcPubkeyRecoveryParam: function (address, r, s, hash) {\n\tfor (var i = 0; i < 4; i++) {\n\t    try {\n\t\tvar pubkey = Bitcoin.ECDSA.recoverPubKey(r, s, hash, i);\n\t\tif (pubkey.getBitcoinAddress().toString() == address) {\n\t\t    return i;\n\t\t}\n\t    } catch (e) {}\n\t}\n\tthrow \"Unable to find valid recovery factor\";\n    }\n    */\n\n    if (params !== undefined) {\n\tif (params['curve'] !== undefined) {\n\t    this.curveName = params['curve'];\n\t}\n    }\n    if (this.curveName === undefined) this.curveName = curveName;\n    this.setNamedCurve(this.curveName);\n    if (params !== undefined) {\n\tif (params['prv'] !== undefined) this.setPrivateKeyHex(params['prv']);\n\tif (params['pub'] !== undefined) this.setPublicKeyHex(params['pub']);\n    }\n};\n\n/**\n * parse ASN.1 DER encoded ECDSA signature\n * @name parseSigHex\n * @memberOf KJUR.crypto.ECDSA\n * @function\n * @static\n * @param {String} sigHex hexadecimal string of ECDSA signature value\n * @return {Array} associative array of signature field r and s of BigInteger\n * @since ecdsa-modified 1.0.1\n * @example\n * var ec = KJUR.crypto.ECDSA({'curve': 'secp256r1'});\n * var sig = ec.parseSigHex('30...');\n * var biR = sig.r; // BigInteger object for 'r' field of signature.\n * var biS = sig.s; // BigInteger object for 's' field of signature.\n */\nKJUR.crypto.ECDSA.parseSigHex = function(sigHex) {\n    var p = KJUR.crypto.ECDSA.parseSigHexInHexRS(sigHex);\n    var biR = new BigInteger(p.r, 16);\n    var biS = new BigInteger(p.s, 16);\n    \n    return {'r': biR, 's': biS};\n};\n\n/**\n * parse ASN.1 DER encoded ECDSA signature\n * @name parseSigHexInHexRS\n * @memberOf KJUR.crypto.ECDSA\n * @function\n * @static\n * @param {String} sigHex hexadecimal string of ECDSA signature value\n * @return {Array} associative array of signature field r and s in hexadecimal\n * @since ecdsa-modified 1.0.3\n * @example\n * var ec = KJUR.crypto.ECDSA({'curve': 'secp256r1'});\n * var sig = ec.parseSigHexInHexRS('30...');\n * var hR = sig.r; // hexadecimal string for 'r' field of signature.\n * var hS = sig.s; // hexadecimal string for 's' field of signature.\n */\nKJUR.crypto.ECDSA.parseSigHexInHexRS = function(sigHex) {\n    // 1. ASN.1 Sequence Check\n    if (sigHex.substr(0, 2) != \"30\")\n\tthrow \"signature is not a ASN.1 sequence\";\n\n    // 2. Items of ASN.1 Sequence Check\n    var a = ASN1HEX.getPosArrayOfChildren_AtObj(sigHex, 0);\n    if (a.length != 2)\n\tthrow \"number of signature ASN.1 sequence elements seem wrong\";\n    \n    // 3. Integer check\n    var iTLV1 = a[0];\n    var iTLV2 = a[1];\n    if (sigHex.substr(iTLV1, 2) != \"02\")\n\tthrow \"1st item of sequene of signature is not ASN.1 integer\";\n    if (sigHex.substr(iTLV2, 2) != \"02\")\n\tthrow \"2nd item of sequene of signature is not ASN.1 integer\";\n\n    // 4. getting value\n    var hR = ASN1HEX.getHexOfV_AtObj(sigHex, iTLV1);\n    var hS = ASN1HEX.getHexOfV_AtObj(sigHex, iTLV2);\n    \n    return {'r': hR, 's': hS};\n};\n\n/**\n * convert hexadecimal ASN.1 encoded signature to concatinated signature\n * @name asn1SigToConcatSig\n * @memberOf KJUR.crypto.ECDSA\n * @function\n * @static\n * @param {String} asn1Hex hexadecimal string of ASN.1 encoded ECDSA signature value\n * @return {String} r-s concatinated format of ECDSA signature value\n * @since ecdsa-modified 1.0.3\n */\nKJUR.crypto.ECDSA.asn1SigToConcatSig = function(asn1Sig) {\n    var pSig = KJUR.crypto.ECDSA.parseSigHexInHexRS(asn1Sig);\n    var hR = pSig.r;\n    var hS = pSig.s;\n\n    if (hR.substr(0, 2) == \"00\" && (((hR.length / 2) * 8) % (16 * 8)) == 8) \n\thR = hR.substr(2);\n\n    if (hS.substr(0, 2) == \"00\" && (((hS.length / 2) * 8) % (16 * 8)) == 8) \n\thS = hS.substr(2);\n\n    if ((((hR.length / 2) * 8) % (16 * 8)) != 0)\n\tthrow \"unknown ECDSA sig r length error\";\n\n    if ((((hS.length / 2) * 8) % (16 * 8)) != 0)\n\tthrow \"unknown ECDSA sig s length error\";\n\n    return hR + hS;\n};\n\n/**\n * convert hexadecimal concatinated signature to ASN.1 encoded signature\n * @name concatSigToASN1Sig\n * @memberOf KJUR.crypto.ECDSA\n * @function\n * @static\n * @param {String} concatSig r-s concatinated format of ECDSA signature value\n * @return {String} hexadecimal string of ASN.1 encoded ECDSA signature value\n * @since ecdsa-modified 1.0.3\n */\nKJUR.crypto.ECDSA.concatSigToASN1Sig = function(concatSig) {\n    if ((((concatSig.length / 2) * 8) % (16 * 8)) != 0)\n\tthrow \"unknown ECDSA concatinated r-s sig  length error\";\n\n    var hR = concatSig.substr(0, concatSig.length / 2);\n    var hS = concatSig.substr(concatSig.length / 2);\n    return KJUR.crypto.ECDSA.hexRSSigToASN1Sig(hR, hS);\n};\n\n/**\n * convert hexadecimal R and S value of signature to ASN.1 encoded signature\n * @name hexRSSigToASN1Sig\n * @memberOf KJUR.crypto.ECDSA\n * @function\n * @static\n * @param {String} hR hexadecimal string of R field of ECDSA signature value\n * @param {String} hS hexadecimal string of S field of ECDSA signature value\n * @return {String} hexadecimal string of ASN.1 encoded ECDSA signature value\n * @since ecdsa-modified 1.0.3\n */\nKJUR.crypto.ECDSA.hexRSSigToASN1Sig = function(hR, hS) {\n    var biR = new BigInteger(hR, 16);\n    var biS = new BigInteger(hS, 16);\n    return KJUR.crypto.ECDSA.biRSSigToASN1Sig(biR, biS);\n};\n\n/**\n * convert R and S BigInteger object of signature to ASN.1 encoded signature\n * @name biRSSigToASN1Sig\n * @memberOf KJUR.crypto.ECDSA\n * @function\n * @static\n * @param {BigInteger} biR BigInteger object of R field of ECDSA signature value\n * @param {BigInteger} biS BIgInteger object of S field of ECDSA signature value\n * @return {String} hexadecimal string of ASN.1 encoded ECDSA signature value\n * @since ecdsa-modified 1.0.3\n */\nKJUR.crypto.ECDSA.biRSSigToASN1Sig = function(biR, biS) {\n    var derR = new KJUR.asn1.DERInteger({'bigint': biR});\n    var derS = new KJUR.asn1.DERInteger({'bigint': biS});\n    var derSeq = new KJUR.asn1.DERSequence({'array': [derR, derS]});\n    return derSeq.getEncodedHex();\n};\n\n"
  },
  {
    "path": "JavaScript/sm2/js/ecparam-1.0.js",
    "content": "/*! ecparam-1.0.0.js (c) 2013 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n/*\n * ecparam.js - Elliptic Curve Cryptography Curve Parameter Definition class\n *\n * Copyright (c) 2013 Kenji Urushima (kenji.urushima@gmail.com)\n *\n * This software is licensed under the terms of the MIT License.\n * http://kjur.github.com/jsrsasign/license\n *\n * The above copyright and license notice shall be \n * included in all copies or substantial portions of the Software.\n */\n\n/**\n * @fileOverview\n * @name ecparam-1.1.js\n * @author Kenji Urushima kenji.urushima@gmail.com\n * @version 1.0.0 (2013-Jul-17)\n * @since jsrsasign 4.0\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\n */\n\nif (typeof KJUR == \"undefined\" || !KJUR) KJUR = {};\nif (typeof KJUR.crypto == \"undefined\" || !KJUR.crypto) KJUR.crypto = {};\n\n/**\n * static object for elliptic curve names and parameters\n * @name KJUR.crypto.ECParameterDB\n * @class static object for elliptic curve names and parameters\n * @description\n * This class provides parameters for named elliptic curves.\n * Currently it supoprts following curve names and aliases however \n * the name marked (*) are available for {@link KJUR.crypto.ECDSA} and\n * {@link KJUR.crypto.Signature} classes.\n * <ul>\n * <li>secp128r1</li>\n * <li>secp160r1</li>\n * <li>secp160k1</li>\n * <li>secp192r1</li>\n * <li>secp192k1</li>\n * <li>secp224r1</li>\n * <li>secp256r1, NIST P-256, P-256, prime256v1 (*)</li>\n * <li>secp256k1 (*)</li>\n * <li>secp384r1, NIST P-384, P-384 (*)</li>\n * <li>secp521r1, NIST P-521, P-521</li>\n * </ul>\n * You can register new curves by using 'register' method.\n */\nKJUR.crypto.ECParameterDB = new function() {\n    var db = {};\n    var aliasDB = {};\n\n    function hex2bi(hex) {\n        return new BigInteger(hex, 16);\n    }\n    \n    /**\n     * get curve inforamtion associative array for curve name or alias\n     * @name getByName\n     * @memberOf KJUR.crypto.ECParameterDB\n     * @function\n     * @param {String} nameOrAlias curve name or alias name\n     * @return {Array} associative array of curve parameters\n     * @example\n     * var param = KJUR.crypto.ECParameterDB.getByName('prime256v1');\n     * var keylen = param['keylen'];\n     * var n = param['n'];\n     */\n    this.getByName = function(nameOrAlias) {\n\tvar name = nameOrAlias;\n\tif (typeof aliasDB[name] != \"undefined\") {\n\t    name = aliasDB[nameOrAlias];\n        }\n\tif (typeof db[name] != \"undefined\") {\n\t    return db[name];\n\t}\n\tthrow \"unregistered EC curve name: \" + name;\n    };\n\n    /**\n     * register new curve\n     * @name regist\n     * @memberOf KJUR.crypto.ECParameterDB\n     * @function\n     * @param {String} name name of curve\n     * @param {Integer} keylen key length\n     * @param {String} pHex hexadecimal value of p\n     * @param {String} aHex hexadecimal value of a\n     * @param {String} bHex hexadecimal value of b\n     * @param {String} nHex hexadecimal value of n\n     * @param {String} hHex hexadecimal value of h\n     * @param {String} gxHex hexadecimal value of Gx\n     * @param {String} gyHex hexadecimal value of Gy\n     * @param {Array} aliasList array of string for curve names aliases\n     * @param {String} oid Object Identifier for the curve\n     * @param {String} info information string for the curve\n     */\n    this.regist = function(name, keylen, pHex, aHex, bHex, nHex, hHex, gxHex, gyHex, aliasList, oid, info) {\n        db[name] = {};\n\tvar p = hex2bi(pHex);\n\tvar a = hex2bi(aHex);\n\tvar b = hex2bi(bHex);\n\tvar n = hex2bi(nHex);\n\tvar h = hex2bi(hHex);\n        var curve = new ECCurveFp(p, a, b);\n        var G = curve.decodePointHex(\"04\" + gxHex + gyHex);\n\tdb[name]['name'] = name;\n\tdb[name]['keylen'] = keylen;\n        db[name]['curve'] = curve;\n        db[name]['G'] = G;\n        db[name]['n'] = n;\n        db[name]['h'] = h;\n        db[name]['oid'] = oid;\n        db[name]['info'] = info;\n\n        for (var i = 0; i < aliasList.length; i++) {\n\t    aliasDB[aliasList[i]] = name;\n        }\n    };\n};\n\nKJUR.crypto.ECParameterDB.regist(\n  \"secp128r1\", // name / p = 2^128 - 2^97 - 1\n  128,\n  \"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF\", // p\n  \"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC\", // a\n  \"E87579C11079F43DD824993C2CEE5ED3\", // b\n  \"FFFFFFFE0000000075A30D1B9038A115\", // n\n  \"1\", // h\n  \"161FF7528B899B2D0C28607CA52C5B86\", // gx\n  \"CF5AC8395BAFEB13C02DA292DDED7A83\", // gy\n  [], // alias\n  \"\", // oid (underconstruction)\n  \"secp128r1 : SECG curve over a 128 bit prime field\"); // info\n\nKJUR.crypto.ECParameterDB.regist(\n  \"secp160k1\", // name / p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1\n  160,\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73\", // p\n  \"0\", // a\n  \"7\", // b\n  \"0100000000000000000001B8FA16DFAB9ACA16B6B3\", // n\n  \"1\", // h\n  \"3B4C382CE37AA192A4019E763036F4F5DD4D7EBB\", // gx\n  \"938CF935318FDCED6BC28286531733C3F03C4FEE\", // gy\n  [], // alias\n  \"\", // oid\n  \"secp160k1 : SECG curve over a 160 bit prime field\"); // info\n\nKJUR.crypto.ECParameterDB.regist(\n  \"secp160r1\", // name / p = 2^160 - 2^31 - 1\n  160,\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF\", // p\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC\", // a\n  \"1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45\", // b\n  \"0100000000000000000001F4C8F927AED3CA752257\", // n\n  \"1\", // h\n  \"4A96B5688EF573284664698968C38BB913CBFC82\", // gx\n  \"23A628553168947D59DCC912042351377AC5FB32\", // gy\n  [], // alias\n  \"\", // oid\n  \"secp160r1 : SECG curve over a 160 bit prime field\"); // info\n\nKJUR.crypto.ECParameterDB.regist(\n  \"secp192k1\", // name / p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1\n  192,\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37\", // p\n  \"0\", // a\n  \"3\", // b\n  \"FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D\", // n\n  \"1\", // h\n  \"DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D\", // gx\n  \"9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D\", // gy\n  []); // alias\n\nKJUR.crypto.ECParameterDB.regist(\n  \"secp192r1\", // name / p = 2^192 - 2^64 - 1\n  192,\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF\", // p\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC\", // a\n  \"64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1\", // b\n  \"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831\", // n\n  \"1\", // h\n  \"188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012\", // gx\n  \"07192B95FFC8DA78631011ED6B24CDD573F977A11E794811\", // gy\n  []); // alias\n\nKJUR.crypto.ECParameterDB.regist(\n  \"secp224r1\", // name / p = 2^224 - 2^96 + 1\n  224,\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001\", // p\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE\", // a\n  \"B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4\", // b\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D\", // n\n  \"1\", // h\n  \"B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21\", // gx\n  \"BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34\", // gy\n  []); // alias\n\nKJUR.crypto.ECParameterDB.regist(\n  \"secp256k1\", // name / p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1\n  256,\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F\", // p\n  \"0\", // a\n  \"7\", // b\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141\", // n\n  \"1\", // h\n  \"79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798\", // gx\n  \"483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8\", // gy\n  []); // alias\n\nKJUR.crypto.ECParameterDB.regist(\n  \"secp256r1\", // name / p = 2^224 (2^32 - 1) + 2^192 + 2^96 - 1\n  256,\n  \"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\", // p\n  \"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC\", // a\n  \"5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B\", // b\n  \"FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551\", // n\n  \"1\", // h\n  \"6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296\", // gx\n  \"4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5\", // gy\n  [\"NIST P-256\", \"P-256\", \"prime256v1\"]); // alias\n\nKJUR.crypto.ECParameterDB.regist(\n  \"secp384r1\", // name\n  384,\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF\", // p\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC\", // a\n  \"B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF\", // b\n  \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973\", // n\n  \"1\", // h\n  \"AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7\", // gx\n  \"3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f\", // gy\n  [\"NIST P-384\", \"P-384\"]); // alias\n\nKJUR.crypto.ECParameterDB.regist(\n  \"secp521r1\", // name\n  521,\n  \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\", // p\n  \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC\", // a\n  \"051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00\", // b\n  \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409\", // n\n  \"1\", // h\n  \"C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66\", // gx\n  \"011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650\", // gy\n  [\"NIST P-521\", \"P-521\"]); // alias\n\nKJUR.crypto.ECParameterDB.regist(\n  \"sm2\", // name\n  256,\n  \"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF\", // p\n  \"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC\", // a\n  \"28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93\", // b\n  \"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123\", // n\n  \"1\", // h\n  \"32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7\", // gx\n  \"BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0\", // gy\n  [\"sm2\", \"SM2\"]); // alias\n"
  },
  {
    "path": "JavaScript/sm2/js/enc-base64.js",
    "content": "/*\nCryptoJS v3.1.2\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function () {\n    // Shortcuts\n    var C = CryptoJS;\n    var C_lib = C.lib;\n    var WordArray = C_lib.WordArray;\n    var C_enc = C.enc;\n\n    /**\n     * Base64 encoding strategy.\n     */\n    var Base64 = C_enc.Base64 = {\n        /**\n         * Converts a word array to a Base64 string.\n         *\n         * @param {WordArray} wordArray The word array.\n         *\n         * @return {string} The Base64 string.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var base64String = CryptoJS.enc.Base64.stringify(wordArray);\n         */\n        stringify: function (wordArray) {\n            // Shortcuts\n            var words = wordArray.words;\n            var sigBytes = wordArray.sigBytes;\n            var map = this._map;\n\n            // Clamp excess bits\n            wordArray.clamp();\n\n            // Convert\n            var base64Chars = [];\n            for (var i = 0; i < sigBytes; i += 3) {\n                var byte1 = (words[i >>> 2]       >>> (24 - (i % 4) * 8))       & 0xff;\n                var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;\n                var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;\n\n                var triplet = (byte1 << 16) | (byte2 << 8) | byte3;\n\n                for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) {\n                    base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));\n                }\n            }\n\n            // Add padding\n            var paddingChar = map.charAt(64);\n            if (paddingChar) {\n                while (base64Chars.length % 4) {\n                    base64Chars.push(paddingChar);\n                }\n            }\n\n            return base64Chars.join('');\n        },\n\n        /**\n         * Converts a Base64 string to a word array.\n         *\n         * @param {string} base64Str The Base64 string.\n         *\n         * @return {WordArray} The word array.\n         *\n         * @static\n         *\n         * @example\n         *\n         *     var wordArray = CryptoJS.enc.Base64.parse(base64String);\n         */\n        parse: function (base64Str) {\n            // Shortcuts\n            var base64StrLength = base64Str.length;\n            var map = this._map;\n\n            // Ignore padding\n            var paddingChar = map.charAt(64);\n            if (paddingChar) {\n                var paddingIndex = base64Str.indexOf(paddingChar);\n                if (paddingIndex != -1) {\n                    base64StrLength = paddingIndex;\n                }\n            }\n\n            // Convert\n            var words = [];\n            var nBytes = 0;\n            for (var i = 0; i < base64StrLength; i++) {\n                if (i % 4) {\n                    var bits1 = map.indexOf(base64Str.charAt(i - 1)) << ((i % 4) * 2);\n                    var bits2 = map.indexOf(base64Str.charAt(i)) >>> (6 - (i % 4) * 2);\n                    words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8);\n                    nBytes++;\n                }\n            }\n\n            return WordArray.create(words, nBytes);\n        },\n\n        _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='\n    };\n}());\n"
  },
  {
    "path": "JavaScript/sm2/js/fingerprint.js",
    "content": "/*\n* fingerprintJS 0.5.4 - Fast browser fingerprint library\n* https://github.com/Valve/fingerprintjs\n* Copyright (c) 2013 Valentin Vasilyev (valentin.vasilyev@outlook.com)\n* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.\n*\n* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n* ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\n* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n;(function (name, context, definition) {\n  if (typeof module !== 'undefined' && module.exports) { module.exports = definition(); }\n  else if (typeof define === 'function' && define.amd) { define(definition); }\n  else { context[name] = definition(); }\n})('Fingerprint', this, function () {\n  'use strict';\n\n  var Fingerprint = function (options) {\n    var nativeForEach, nativeMap;\n    nativeForEach = Array.prototype.forEach;\n    nativeMap = Array.prototype.map;\n\n    this.each = function (obj, iterator, context) {\n      if (obj === null) {\n        return;\n      }\n      if (nativeForEach && obj.forEach === nativeForEach) {\n        obj.forEach(iterator, context);\n      } else if (obj.length === +obj.length) {\n        for (var i = 0, l = obj.length; i < l; i++) {\n          if (iterator.call(context, obj[i], i, obj) === {}) return;\n        }\n      } else {\n        for (var key in obj) {\n          if (obj.hasOwnProperty(key)) {\n            if (iterator.call(context, obj[key], key, obj) === {}) return;\n          }\n        }\n      }\n    };\n\n    this.map = function(obj, iterator, context) {\n      var results = [];\n      // Not using strict equality so that this acts as a\n      // shortcut to checking for `null` and `undefined`.\n      if (obj == null) return results;\n      if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);\n      this.each(obj, function(value, index, list) {\n        results[results.length] = iterator.call(context, value, index, list);\n      });\n      return results;\n    };\n\n    if (typeof options == 'object'){\n      this.hasher = options.hasher;\n      this.screen_resolution = options.screen_resolution;\n      this.screen_orientation = options.screen_orientation;\n      this.canvas = options.canvas;\n      this.ie_activex = options.ie_activex;\n    } else if(typeof options == 'function'){\n      this.hasher = options;\n    }\n  };\n\n  Fingerprint.prototype = {\n    get: function(){\n      var keys = [];\n      keys.push(navigator.userAgent);\n      keys.push(navigator.language);\n      keys.push(screen.colorDepth);\n      if (this.screen_resolution) {\n        var resolution = this.getScreenResolution();\n        if (typeof resolution !== 'undefined'){ // headless browsers, such as phantomjs\n          keys.push(resolution.join('x'));\n        }\n      }\n      keys.push(new Date().getTimezoneOffset());\n      keys.push(this.hasSessionStorage());\n      keys.push(this.hasLocalStorage());\n      keys.push(!!window.indexedDB);\n      //body might not be defined at this point or removed programmatically\n      if(document.body){\n        keys.push(typeof(document.body.addBehavior));\n      } else {\n        keys.push(typeof undefined);\n      }\n      keys.push(typeof(window.openDatabase));\n      keys.push(navigator.cpuClass);\n      keys.push(navigator.platform);\n      keys.push(navigator.doNotTrack);\n      keys.push(this.getPluginsString());\n      if(this.canvas && this.isCanvasSupported()){\n        keys.push(this.getCanvasFingerprint());\n      }\n      if(this.hasher){\n        return this.hasher(keys.join('###'), 31);\n      } else {\n        return this.murmurhash3_32_gc(keys.join('###'), 31);\n      }\n    },\n\n    /**\n     * JS Implementation of MurmurHash3 (r136) (as of May 20, 2011)\n     *\n     * @author <a href=\"mailto:gary.court@gmail.com\">Gary Court</a>\n     * @see http://github.com/garycourt/murmurhash-js\n     * @author <a href=\"mailto:aappleby@gmail.com\">Austin Appleby</a>\n     * @see http://sites.google.com/site/murmurhash/\n     *\n     * @param {string} key ASCII only\n     * @param {number} seed Positive integer only\n     * @return {number} 32-bit positive integer hash\n     */\n\n    murmurhash3_32_gc: function(key, seed) {\n      var remainder, bytes, h1, h1b, c1, c2, k1, i;\n\n      remainder = key.length & 3; // key.length % 4\n      bytes = key.length - remainder;\n      h1 = seed;\n      c1 = 0xcc9e2d51;\n      c2 = 0x1b873593;\n      i = 0;\n\n      while (i < bytes) {\n          k1 =\n            ((key.charCodeAt(i) & 0xff)) |\n            ((key.charCodeAt(++i) & 0xff) << 8) |\n            ((key.charCodeAt(++i) & 0xff) << 16) |\n            ((key.charCodeAt(++i) & 0xff) << 24);\n        ++i;\n\n        k1 = ((((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16))) & 0xffffffff;\n        k1 = (k1 << 15) | (k1 >>> 17);\n        k1 = ((((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16))) & 0xffffffff;\n\n        h1 ^= k1;\n            h1 = (h1 << 13) | (h1 >>> 19);\n        h1b = ((((h1 & 0xffff) * 5) + ((((h1 >>> 16) * 5) & 0xffff) << 16))) & 0xffffffff;\n        h1 = (((h1b & 0xffff) + 0x6b64) + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16));\n      }\n\n      k1 = 0;\n\n      switch (remainder) {\n        case 3: k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;\n        case 2: k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;\n        case 1: k1 ^= (key.charCodeAt(i) & 0xff);\n\n        k1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;\n        k1 = (k1 << 15) | (k1 >>> 17);\n        k1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;\n        h1 ^= k1;\n      }\n\n      h1 ^= key.length;\n\n      h1 ^= h1 >>> 16;\n      h1 = (((h1 & 0xffff) * 0x85ebca6b) + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;\n      h1 ^= h1 >>> 13;\n      h1 = ((((h1 & 0xffff) * 0xc2b2ae35) + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16))) & 0xffffffff;\n      h1 ^= h1 >>> 16;\n\n      return h1 >>> 0;\n    },\n\n    // https://bugzilla.mozilla.org/show_bug.cgi?id=781447\n    hasLocalStorage: function () {\n      try{\n        return !!window.localStorage;\n      } catch(e) {\n        return true; // SecurityError when referencing it means it exists\n      }\n    },\n\n    hasSessionStorage: function () {\n      try{\n        return !!window.sessionStorage;\n      } catch(e) {\n        return true; // SecurityError when referencing it means it exists\n      }\n    },\n\n    isCanvasSupported: function () {\n      var elem = document.createElement('canvas');\n      return !!(elem.getContext && elem.getContext('2d'));\n    },\n\n    isIE: function () {\n      if(navigator.appName === 'Microsoft Internet Explorer') {\n        return true;\n      } else if(navigator.appName === 'Netscape' && /Trident/.test(navigator.userAgent)){// IE 11\n        return true;\n      }\n      return false;\n    },\n\n    getPluginsString: function () {\n      if(this.isIE() && this.ie_activex){\n        return this.getIEPluginsString();\n      } else {\n        return this.getRegularPluginsString();\n      }\n    },\n\n    getRegularPluginsString: function () {\n      return this.map(navigator.plugins, function (p) {\n        var mimeTypes = this.map(p, function(mt){\n          return [mt.type, mt.suffixes].join('~');\n        }).join(',');\n        return [p.name, p.description, mimeTypes].join('::');\n      }, this).join(';');\n    },\n\n    getIEPluginsString: function () {\n      if(window.ActiveXObject){\n        var names = ['ShockwaveFlash.ShockwaveFlash',//flash plugin\n          'AcroPDF.PDF', // Adobe PDF reader 7+\n          'PDF.PdfCtrl', // Adobe PDF reader 6 and earlier, brrr\n          'QuickTime.QuickTime', // QuickTime\n          // 5 versions of real players\n          'rmocx.RealPlayer G2 Control',\n          'rmocx.RealPlayer G2 Control.1',\n          'RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)',\n          'RealVideo.RealVideo(tm) ActiveX Control (32-bit)',\n          'RealPlayer',\n          'SWCtl.SWCtl', // ShockWave player\n          'WMPlayer.OCX', // Windows media player\n          'AgControl.AgControl', // Silverlight\n          'Skype.Detection'];\n\n        // starting to detect plugins in IE\n        return this.map(names, function(name){\n          try{\n            new ActiveXObject(name);\n            return name;\n          } catch(e){\n            return null;\n          }\n        }).join(';');\n      } else {\n        return \"\"; // behavior prior version 0.5.0, not breaking backwards compat.\n      }\n    },\n\n    getScreenResolution: function () {\n      var resolution;\n       if(this.screen_orientation){\n         resolution = (screen.height > screen.width) ? [screen.height, screen.width] : [screen.width, screen.height];\n       }else{\n         resolution = [screen.height, screen.width];\n       }\n       return resolution;\n    },\n\n    getCanvasFingerprint: function () {\n      var canvas = document.createElement('canvas');\n      var ctx = canvas.getContext('2d');\n      // https://www.browserleaks.com/canvas#how-does-it-work\n      var txt = 'http://valve.github.io';\n      ctx.textBaseline = \"top\";\n      ctx.font = \"14px 'Arial'\";\n      ctx.textBaseline = \"alphabetic\";\n      ctx.fillStyle = \"#f60\";\n      ctx.fillRect(125,1,62,20);\n      ctx.fillStyle = \"#069\";\n      ctx.fillText(txt, 2, 15);\n      ctx.fillStyle = \"rgba(102, 204, 0, 0.7)\";\n      ctx.fillText(txt, 4, 17);\n      return canvas.toDataURL();\n    }\n  };\n\n\n  return Fingerprint;\n\n});\n"
  },
  {
    "path": "JavaScript/sm2/js/jsbn.js",
    "content": "/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\n// Copyright (c) 2005  Tom Wu\n// All Rights Reserved.\n// See \"LICENSE\" for details.\n\n// Basic JavaScript BN library - subset useful for RSA encryption.\n\n// Bits per digit\nvar dbits;\n\n// JavaScript engine analysis\nvar canary = 0xdeadbeefcafe;\nvar j_lm = ((canary&0xffffff)==0xefcafe);\n\n// (public) Constructor\nfunction BigInteger(a,b,c) {\n  if(a != null)\n    if(\"number\" == typeof a) this.fromNumber(a,b,c);\n    else if(b == null && \"string\" != typeof a) this.fromString(a,256);\n    else this.fromString(a,b);\n}\n\n// return new, unset BigInteger\nfunction nbi() { return new BigInteger(null); }\n\n// am: Compute w_j += (x*this_i), propagate carries,\n// c is initial carry, returns final carry.\n// c < 3*dvalue, x < 2*dvalue, this_i < dvalue\n// We need to select the fastest one that works in this environment.\n\n// am1: use a single mult and divide to get the high bits,\n// max digit bits should be 26 because\n// max internal value = 2*dvalue^2-2*dvalue (< 2^53)\nfunction am1(i,x,w,j,c,n) {\n  while(--n >= 0) {\n    var v = x*this[i++]+w[j]+c;\n    c = Math.floor(v/0x4000000);\n    w[j++] = v&0x3ffffff;\n  }\n  return c;\n}\n// am2 avoids a big mult-and-extract completely.\n// Max digit bits should be <= 30 because we do bitwise ops\n// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)\nfunction am2(i,x,w,j,c,n) {\n  var xl = x&0x7fff, xh = x>>15;\n  while(--n >= 0) {\n    var l = this[i]&0x7fff;\n    var h = this[i++]>>15;\n    var m = xh*l+h*xl;\n    l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);\n    c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);\n    w[j++] = l&0x3fffffff;\n  }\n  return c;\n}\n// Alternately, set max digit bits to 28 since some\n// browsers slow down when dealing with 32-bit numbers.\nfunction am3(i,x,w,j,c,n) {\n  var xl = x&0x3fff, xh = x>>14;\n  while(--n >= 0) {\n    var l = this[i]&0x3fff;\n    var h = this[i++]>>14;\n    var m = xh*l+h*xl;\n    l = xl*l+((m&0x3fff)<<14)+w[j]+c;\n    c = (l>>28)+(m>>14)+xh*h;\n    w[j++] = l&0xfffffff;\n  }\n  return c;\n}\nif(j_lm && (navigator.appName == \"Microsoft Internet Explorer\")) {\n  BigInteger.prototype.am = am2;\n  dbits = 30;\n}\nelse if(j_lm && (navigator.appName != \"Netscape\")) {\n  BigInteger.prototype.am = am1;\n  dbits = 26;\n}\nelse { // Mozilla/Netscape seems to prefer am3\n  BigInteger.prototype.am = am3;\n  dbits = 28;\n}\n\nBigInteger.prototype.DB = dbits;\nBigInteger.prototype.DM = ((1<<dbits)-1);\nBigInteger.prototype.DV = (1<<dbits);\n\nvar BI_FP = 52;\nBigInteger.prototype.FV = Math.pow(2,BI_FP);\nBigInteger.prototype.F1 = BI_FP-dbits;\nBigInteger.prototype.F2 = 2*dbits-BI_FP;\n\n// Digit conversions\nvar BI_RM = \"0123456789abcdefghijklmnopqrstuvwxyz\";\nvar BI_RC = new Array();\nvar rr,vv;\nrr = \"0\".charCodeAt(0);\nfor(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;\nrr = \"a\".charCodeAt(0);\nfor(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;\nrr = \"A\".charCodeAt(0);\nfor(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;\n\nfunction int2char(n) { return BI_RM.charAt(n); }\nfunction intAt(s,i) {\n  var c = BI_RC[s.charCodeAt(i)];\n  return (c==null)?-1:c;\n}\n\n// (protected) copy this to r\nfunction bnpCopyTo(r) {\n  for(var i = this.t-1; i >= 0; --i) r[i] = this[i];\n  r.t = this.t;\n  r.s = this.s;\n}\n\n// (protected) set from integer value x, -DV <= x < DV\nfunction bnpFromInt(x) {\n  this.t = 1;\n  this.s = (x<0)?-1:0;\n  if(x > 0) this[0] = x;\n  else if(x < -1) this[0] = x+this.DV;\n  else this.t = 0;\n}\n\n// return bigint initialized to value\nfunction nbv(i) { var r = nbi(); r.fromInt(i); return r; }\n\n// (protected) set from string and radix\nfunction bnpFromString(s,b) {\n  var k;\n  if(b == 16) k = 4;\n  else if(b == 8) k = 3;\n  else if(b == 256) k = 8; // byte array\n  else if(b == 2) k = 1;\n  else if(b == 32) k = 5;\n  else if(b == 4) k = 2;\n  else { this.fromRadix(s,b); return; }\n  this.t = 0;\n  this.s = 0;\n  var i = s.length, mi = false, sh = 0;\n  while(--i >= 0) {\n    var x = (k==8)?s[i]&0xff:intAt(s,i);\n    if(x < 0) {\n      if(s.charAt(i) == \"-\") mi = true;\n      continue;\n    }\n    mi = false;\n    if(sh == 0)\n      this[this.t++] = x;\n    else if(sh+k > this.DB) {\n      this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;\n      this[this.t++] = (x>>(this.DB-sh));\n    }\n    else\n      this[this.t-1] |= x<<sh;\n    sh += k;\n    if(sh >= this.DB) sh -= this.DB;\n  }\n  if(k == 8 && (s[0]&0x80) != 0) {\n    this.s = -1;\n    if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;\n  }\n  this.clamp();\n  if(mi) BigInteger.ZERO.subTo(this,this);\n}\n\n// (protected) clamp off excess high words\nfunction bnpClamp() {\n  var c = this.s&this.DM;\n  while(this.t > 0 && this[this.t-1] == c) --this.t;\n}\n\n// (public) return string representation in given radix\nfunction bnToString(b) {\n  if(this.s < 0) return \"-\"+this.negate().toString(b);\n  var k;\n  if(b == 16) k = 4;\n  else if(b == 8) k = 3;\n  else if(b == 2) k = 1;\n  else if(b == 32) k = 5;\n  else if(b == 4) k = 2;\n  else return this.toRadix(b);\n  var km = (1<<k)-1, d, m = false, r = \"\", i = this.t;\n  var p = this.DB-(i*this.DB)%k;\n  if(i-- > 0) {\n    if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }\n    while(i >= 0) {\n      if(p < k) {\n        d = (this[i]&((1<<p)-1))<<(k-p);\n        d |= this[--i]>>(p+=this.DB-k);\n      }\n      else {\n        d = (this[i]>>(p-=k))&km;\n        if(p <= 0) { p += this.DB; --i; }\n      }\n      if(d > 0) m = true;\n      if(m) r += int2char(d);\n    }\n  }\n  return m?r:\"0\";\n}\n\n// (public) -this\nfunction bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }\n\n// (public) |this|\nfunction bnAbs() { return (this.s<0)?this.negate():this; }\n\n// (public) return + if this > a, - if this < a, 0 if equal\nfunction bnCompareTo(a) {\n  var r = this.s-a.s;\n  if(r != 0) return r;\n  var i = this.t;\n  r = i-a.t;\n  if(r != 0) return (this.s<0)?-r:r;\n  while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;\n  return 0;\n}\n\n// returns bit length of the integer x\nfunction nbits(x) {\n  var r = 1, t;\n  if((t=x>>>16) != 0) { x = t; r += 16; }\n  if((t=x>>8) != 0) { x = t; r += 8; }\n  if((t=x>>4) != 0) { x = t; r += 4; }\n  if((t=x>>2) != 0) { x = t; r += 2; }\n  if((t=x>>1) != 0) { x = t; r += 1; }\n  return r;\n}\n\n// (public) return the number of bits in \"this\"\nfunction bnBitLength() {\n  if(this.t <= 0) return 0;\n  return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));\n}\n\n// (protected) r = this << n*DB\nfunction bnpDLShiftTo(n,r) {\n  var i;\n  for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];\n  for(i = n-1; i >= 0; --i) r[i] = 0;\n  r.t = this.t+n;\n  r.s = this.s;\n}\n\n// (protected) r = this >> n*DB\nfunction bnpDRShiftTo(n,r) {\n  for(var i = n; i < this.t; ++i) r[i-n] = this[i];\n  r.t = Math.max(this.t-n,0);\n  r.s = this.s;\n}\n\n// (protected) r = this << n\nfunction bnpLShiftTo(n,r) {\n  var bs = n%this.DB;\n  var cbs = this.DB-bs;\n  var bm = (1<<cbs)-1;\n  var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;\n  for(i = this.t-1; i >= 0; --i) {\n    r[i+ds+1] = (this[i]>>cbs)|c;\n    c = (this[i]&bm)<<bs;\n  }\n  for(i = ds-1; i >= 0; --i) r[i] = 0;\n  r[ds] = c;\n  r.t = this.t+ds+1;\n  r.s = this.s;\n  r.clamp();\n}\n\n// (protected) r = this >> n\nfunction bnpRShiftTo(n,r) {\n  r.s = this.s;\n  var ds = Math.floor(n/this.DB);\n  if(ds >= this.t) { r.t = 0; return; }\n  var bs = n%this.DB;\n  var cbs = this.DB-bs;\n  var bm = (1<<bs)-1;\n  r[0] = this[ds]>>bs;\n  for(var i = ds+1; i < this.t; ++i) {\n    r[i-ds-1] |= (this[i]&bm)<<cbs;\n    r[i-ds] = this[i]>>bs;\n  }\n  if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;\n  r.t = this.t-ds;\n  r.clamp();\n}\n\n// (protected) r = this - a\nfunction bnpSubTo(a,r) {\n  var i = 0, c = 0, m = Math.min(a.t,this.t);\n  while(i < m) {\n    c += this[i]-a[i];\n    r[i++] = c&this.DM;\n    c >>= this.DB;\n  }\n  if(a.t < this.t) {\n    c -= a.s;\n    while(i < this.t) {\n      c += this[i];\n      r[i++] = c&this.DM;\n      c >>= this.DB;\n    }\n    c += this.s;\n  }\n  else {\n    c += this.s;\n    while(i < a.t) {\n      c -= a[i];\n      r[i++] = c&this.DM;\n      c >>= this.DB;\n    }\n    c -= a.s;\n  }\n  r.s = (c<0)?-1:0;\n  if(c < -1) r[i++] = this.DV+c;\n  else if(c > 0) r[i++] = c;\n  r.t = i;\n  r.clamp();\n}\n\n// (protected) r = this * a, r != this,a (HAC 14.12)\n// \"this\" should be the larger one if appropriate.\nfunction bnpMultiplyTo(a,r) {\n  var x = this.abs(), y = a.abs();\n  var i = x.t;\n  r.t = i+y.t;\n  while(--i >= 0) r[i] = 0;\n  for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);\n  r.s = 0;\n  r.clamp();\n  if(this.s != a.s) BigInteger.ZERO.subTo(r,r);\n}\n\n// (protected) r = this^2, r != this (HAC 14.16)\nfunction bnpSquareTo(r) {\n  var x = this.abs();\n  var i = r.t = 2*x.t;\n  while(--i >= 0) r[i] = 0;\n  for(i = 0; i < x.t-1; ++i) {\n    var c = x.am(i,x[i],r,2*i,0,1);\n    if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {\n      r[i+x.t] -= x.DV;\n      r[i+x.t+1] = 1;\n    }\n  }\n  if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);\n  r.s = 0;\n  r.clamp();\n}\n\n// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)\n// r != q, this != m.  q or r may be null.\nfunction bnpDivRemTo(m,q,r) {\n  var pm = m.abs();\n  if(pm.t <= 0) return;\n  var pt = this.abs();\n  if(pt.t < pm.t) {\n    if(q != null) q.fromInt(0);\n    if(r != null) this.copyTo(r);\n    return;\n  }\n  if(r == null) r = nbi();\n  var y = nbi(), ts = this.s, ms = m.s;\n  var nsh = this.DB-nbits(pm[pm.t-1]);\t// normalize modulus\n  if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }\n  else { pm.copyTo(y); pt.copyTo(r); }\n  var ys = y.t;\n  var y0 = y[ys-1];\n  if(y0 == 0) return;\n  var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);\n  var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;\n  var i = r.t, j = i-ys, t = (q==null)?nbi():q;\n  y.dlShiftTo(j,t);\n  if(r.compareTo(t) >= 0) {\n    r[r.t++] = 1;\n    r.subTo(t,r);\n  }\n  BigInteger.ONE.dlShiftTo(ys,t);\n  t.subTo(y,y);\t// \"negative\" y so we can replace sub with am later\n  while(y.t < ys) y[y.t++] = 0;\n  while(--j >= 0) {\n    // Estimate quotient digit\n    var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);\n    if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) {\t// Try it out\n      y.dlShiftTo(j,t);\n      r.subTo(t,r);\n      while(r[i] < --qd) r.subTo(t,r);\n    }\n  }\n  if(q != null) {\n    r.drShiftTo(ys,q);\n    if(ts != ms) BigInteger.ZERO.subTo(q,q);\n  }\n  r.t = ys;\n  r.clamp();\n  if(nsh > 0) r.rShiftTo(nsh,r);\t// Denormalize remainder\n  if(ts < 0) BigInteger.ZERO.subTo(r,r);\n}\n\n// (public) this mod a\nfunction bnMod(a) {\n  var r = nbi();\n  this.abs().divRemTo(a,null,r);\n  if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);\n  return r;\n}\n\n// Modular reduction using \"classic\" algorithm\nfunction Classic(m) { this.m = m; }\nfunction cConvert(x) {\n  if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);\n  else return x;\n}\nfunction cRevert(x) { return x; }\nfunction cReduce(x) { x.divRemTo(this.m,null,x); }\nfunction cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }\nfunction cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }\n\nClassic.prototype.convert = cConvert;\nClassic.prototype.revert = cRevert;\nClassic.prototype.reduce = cReduce;\nClassic.prototype.mulTo = cMulTo;\nClassic.prototype.sqrTo = cSqrTo;\n\n// (protected) return \"-1/this % 2^DB\"; useful for Mont. reduction\n// justification:\n//         xy == 1 (mod m)\n//         xy =  1+km\n//   xy(2-xy) = (1+km)(1-km)\n// x[y(2-xy)] = 1-k^2m^2\n// x[y(2-xy)] == 1 (mod m^2)\n// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2\n// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.\n// JS multiply \"overflows\" differently from C/C++, so care is needed here.\nfunction bnpInvDigit() {\n  if(this.t < 1) return 0;\n  var x = this[0];\n  if((x&1) == 0) return 0;\n  var y = x&3;\t\t// y == 1/x mod 2^2\n  y = (y*(2-(x&0xf)*y))&0xf;\t// y == 1/x mod 2^4\n  y = (y*(2-(x&0xff)*y))&0xff;\t// y == 1/x mod 2^8\n  y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff;\t// y == 1/x mod 2^16\n  // last step - calculate inverse mod DV directly;\n  // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints\n  y = (y*(2-x*y%this.DV))%this.DV;\t\t// y == 1/x mod 2^dbits\n  // we really want the negative inverse, and -DV < y < DV\n  return (y>0)?this.DV-y:-y;\n}\n\n// Montgomery reduction\nfunction Montgomery(m) {\n  this.m = m;\n  this.mp = m.invDigit();\n  this.mpl = this.mp&0x7fff;\n  this.mph = this.mp>>15;\n  this.um = (1<<(m.DB-15))-1;\n  this.mt2 = 2*m.t;\n}\n\n// xR mod m\nfunction montConvert(x) {\n  var r = nbi();\n  x.abs().dlShiftTo(this.m.t,r);\n  r.divRemTo(this.m,null,r);\n  if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);\n  return r;\n}\n\n// x/R mod m\nfunction montRevert(x) {\n  var r = nbi();\n  x.copyTo(r);\n  this.reduce(r);\n  return r;\n}\n\n// x = x/R mod m (HAC 14.32)\nfunction montReduce(x) {\n  while(x.t <= this.mt2)\t// pad x so am has enough room later\n    x[x.t++] = 0;\n  for(var i = 0; i < this.m.t; ++i) {\n    // faster way of calculating u0 = x[i]*mp mod DV\n    var j = x[i]&0x7fff;\n    var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;\n    // use am to combine the multiply-shift-add into one call\n    j = i+this.m.t;\n    x[j] += this.m.am(0,u0,x,i,0,this.m.t);\n    // propagate carry\n    while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }\n  }\n  x.clamp();\n  x.drShiftTo(this.m.t,x);\n  if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);\n}\n\n// r = \"x^2/R mod m\"; x != r\nfunction montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }\n\n// r = \"xy/R mod m\"; x,y != r\nfunction montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }\n\nMontgomery.prototype.convert = montConvert;\nMontgomery.prototype.revert = montRevert;\nMontgomery.prototype.reduce = montReduce;\nMontgomery.prototype.mulTo = montMulTo;\nMontgomery.prototype.sqrTo = montSqrTo;\n\n// (protected) true iff this is even\nfunction bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }\n\n// (protected) this^e, e < 2^32, doing sqr and mul with \"r\" (HAC 14.79)\nfunction bnpExp(e,z) {\n  if(e > 0xffffffff || e < 1) return BigInteger.ONE;\n  var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;\n  g.copyTo(r);\n  while(--i >= 0) {\n    z.sqrTo(r,r2);\n    if((e&(1<<i)) > 0) z.mulTo(r2,g,r);\n    else { var t = r; r = r2; r2 = t; }\n  }\n  return z.revert(r);\n}\n\n// (public) this^e % m, 0 <= e < 2^32\nfunction bnModPowInt(e,m) {\n  var z;\n  if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);\n  return this.exp(e,z);\n}\n\n// protected\nBigInteger.prototype.copyTo = bnpCopyTo;\nBigInteger.prototype.fromInt = bnpFromInt;\nBigInteger.prototype.fromString = bnpFromString;\nBigInteger.prototype.clamp = bnpClamp;\nBigInteger.prototype.dlShiftTo = bnpDLShiftTo;\nBigInteger.prototype.drShiftTo = bnpDRShiftTo;\nBigInteger.prototype.lShiftTo = bnpLShiftTo;\nBigInteger.prototype.rShiftTo = bnpRShiftTo;\nBigInteger.prototype.subTo = bnpSubTo;\nBigInteger.prototype.multiplyTo = bnpMultiplyTo;\nBigInteger.prototype.squareTo = bnpSquareTo;\nBigInteger.prototype.divRemTo = bnpDivRemTo;\nBigInteger.prototype.invDigit = bnpInvDigit;\nBigInteger.prototype.isEven = bnpIsEven;\nBigInteger.prototype.exp = bnpExp;\n\n// public\nBigInteger.prototype.toString = bnToString;\nBigInteger.prototype.negate = bnNegate;\nBigInteger.prototype.abs = bnAbs;\nBigInteger.prototype.compareTo = bnCompareTo;\nBigInteger.prototype.bitLength = bnBitLength;\nBigInteger.prototype.mod = bnMod;\nBigInteger.prototype.modPowInt = bnModPowInt;\n\n// \"constants\"\nBigInteger.ZERO = nbv(0);\nBigInteger.ONE = nbv(1);\n"
  },
  {
    "path": "JavaScript/sm2/js/jsbn2.js",
    "content": "/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\n// Copyright (c) 2005-2009  Tom Wu\n// All Rights Reserved.\n// See \"LICENSE\" for details.\n\n// Extended JavaScript BN functions, required for RSA private ops.\n\n// Version 1.1: new BigInteger(\"0\", 10) returns \"proper\" zero\n// Version 1.2: square() API, isProbablePrime fix\n\n// (public)\nfunction bnClone() { var r = nbi(); this.copyTo(r); return r; }\n\n// (public) return value as integer\nfunction bnIntValue() {\n  if(this.s < 0) {\n    if(this.t == 1) return this[0]-this.DV;\n    else if(this.t == 0) return -1;\n  }\n  else if(this.t == 1) return this[0];\n  else if(this.t == 0) return 0;\n  // assumes 16 < DB < 32\n  return ((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0];\n}\n\n// (public) return value as byte\nfunction bnByteValue() { return (this.t==0)?this.s:(this[0]<<24)>>24; }\n\n// (public) return value as short (assumes DB>=16)\nfunction bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; }\n\n// (protected) return x s.t. r^x < DV\nfunction bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); }\n\n// (public) 0 if this == 0, 1 if this > 0\nfunction bnSigNum() {\n  if(this.s < 0) return -1;\n  else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;\n  else return 1;\n}\n\n// (protected) convert to radix string\nfunction bnpToRadix(b) {\n  if(b == null) b = 10;\n  if(this.signum() == 0 || b < 2 || b > 36) return \"0\";\n  var cs = this.chunkSize(b);\n  var a = Math.pow(b,cs);\n  var d = nbv(a), y = nbi(), z = nbi(), r = \"\";\n  this.divRemTo(d,y,z);\n  while(y.signum() > 0) {\n    r = (a+z.intValue()).toString(b).substr(1) + r;\n    y.divRemTo(d,y,z);\n  }\n  return z.intValue().toString(b) + r;\n}\n\n// (protected) convert from radix string\nfunction bnpFromRadix(s,b) {\n  this.fromInt(0);\n  if(b == null) b = 10;\n  var cs = this.chunkSize(b);\n  var d = Math.pow(b,cs), mi = false, j = 0, w = 0;\n  for(var i = 0; i < s.length; ++i) {\n    var x = intAt(s,i);\n    if(x < 0) {\n      if(s.charAt(i) == \"-\" && this.signum() == 0) mi = true;\n      continue;\n    }\n    w = b*w+x;\n    if(++j >= cs) {\n      this.dMultiply(d);\n      this.dAddOffset(w,0);\n      j = 0;\n      w = 0;\n    }\n  }\n  if(j > 0) {\n    this.dMultiply(Math.pow(b,j));\n    this.dAddOffset(w,0);\n  }\n  if(mi) BigInteger.ZERO.subTo(this,this);\n}\n\n// (protected) alternate constructor\nfunction bnpFromNumber(a,b,c) {\n  if(\"number\" == typeof b) {\n    // new BigInteger(int,int,RNG)\n    if(a < 2) this.fromInt(1);\n    else {\n      this.fromNumber(a,c);\n      if(!this.testBit(a-1))\t// force MSB set\n        this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);\n      if(this.isEven()) this.dAddOffset(1,0); // force odd\n      while(!this.isProbablePrime(b)) {\n        this.dAddOffset(2,0);\n        if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this);\n      }\n    }\n  }\n  else {\n    // new BigInteger(int,RNG)\n    var x = new Array(), t = a&7;\n    x.length = (a>>3)+1;\n    b.nextBytes(x);\n    if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0;\n    this.fromString(x,256);\n  }\n}\n\n// (public) convert to bigendian byte array\nfunction bnToByteArray() {\n  var i = this.t, r = new Array();\n  r[0] = this.s;\n  var p = this.DB-(i*this.DB)%8, d, k = 0;\n  if(i-- > 0) {\n    if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p)\n      r[k++] = d|(this.s<<(this.DB-p));\n    while(i >= 0) {\n      if(p < 8) {\n        d = (this[i]&((1<<p)-1))<<(8-p);\n        d |= this[--i]>>(p+=this.DB-8);\n      }\n      else {\n        d = (this[i]>>(p-=8))&0xff;\n        if(p <= 0) { p += this.DB; --i; }\n      }\n      if((d&0x80) != 0) d |= -256;\n      if(k == 0 && (this.s&0x80) != (d&0x80)) ++k;\n      if(k > 0 || d != this.s) r[k++] = d;\n    }\n  }\n  return r;\n}\n\nfunction bnEquals(a) { return(this.compareTo(a)==0); }\nfunction bnMin(a) { return(this.compareTo(a)<0)?this:a; }\nfunction bnMax(a) { return(this.compareTo(a)>0)?this:a; }\n\n// (protected) r = this op a (bitwise)\nfunction bnpBitwiseTo(a,op,r) {\n  var i, f, m = Math.min(a.t,this.t);\n  for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]);\n  if(a.t < this.t) {\n    f = a.s&this.DM;\n    for(i = m; i < this.t; ++i) r[i] = op(this[i],f);\n    r.t = this.t;\n  }\n  else {\n    f = this.s&this.DM;\n    for(i = m; i < a.t; ++i) r[i] = op(f,a[i]);\n    r.t = a.t;\n  }\n  r.s = op(this.s,a.s);\n  r.clamp();\n}\n\n// (public) this & a\nfunction op_and(x,y) { return x&y; }\nfunction bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; }\n\n// (public) this | a\nfunction op_or(x,y) { return x|y; }\nfunction bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; }\n\n// (public) this ^ a\nfunction op_xor(x,y) { return x^y; }\nfunction bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; }\n\n// (public) this & ~a\nfunction op_andnot(x,y) { return x&~y; }\nfunction bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; }\n\n// (public) ~this\nfunction bnNot() {\n  var r = nbi();\n  for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i];\n  r.t = this.t;\n  r.s = ~this.s;\n  return r;\n}\n\n// (public) this << n\nfunction bnShiftLeft(n) {\n  var r = nbi();\n  if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r);\n  return r;\n}\n\n// (public) this >> n\nfunction bnShiftRight(n) {\n  var r = nbi();\n  if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r);\n  return r;\n}\n\n// return index of lowest 1-bit in x, x < 2^31\nfunction lbit(x) {\n  if(x == 0) return -1;\n  var r = 0;\n  if((x&0xffff) == 0) { x >>= 16; r += 16; }\n  if((x&0xff) == 0) { x >>= 8; r += 8; }\n  if((x&0xf) == 0) { x >>= 4; r += 4; }\n  if((x&3) == 0) { x >>= 2; r += 2; }\n  if((x&1) == 0) ++r;\n  return r;\n}\n\n// (public) returns index of lowest 1-bit (or -1 if none)\nfunction bnGetLowestSetBit() {\n  for(var i = 0; i < this.t; ++i)\n    if(this[i] != 0) return i*this.DB+lbit(this[i]);\n  if(this.s < 0) return this.t*this.DB;\n  return -1;\n}\n\n// return number of 1 bits in x\nfunction cbit(x) {\n  var r = 0;\n  while(x != 0) { x &= x-1; ++r; }\n  return r;\n}\n\n// (public) return number of set bits\nfunction bnBitCount() {\n  var r = 0, x = this.s&this.DM;\n  for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x);\n  return r;\n}\n\n// (public) true iff nth bit is set\nfunction bnTestBit(n) {\n  var j = Math.floor(n/this.DB);\n  if(j >= this.t) return(this.s!=0);\n  return((this[j]&(1<<(n%this.DB)))!=0);\n}\n\n// (protected) this op (1<<n)\nfunction bnpChangeBit(n,op) {\n  var r = BigInteger.ONE.shiftLeft(n);\n  this.bitwiseTo(r,op,r);\n  return r;\n}\n\n// (public) this | (1<<n)\nfunction bnSetBit(n) { return this.changeBit(n,op_or); }\n\n// (public) this & ~(1<<n)\nfunction bnClearBit(n) { return this.changeBit(n,op_andnot); }\n\n// (public) this ^ (1<<n)\nfunction bnFlipBit(n) { return this.changeBit(n,op_xor); }\n\n// (protected) r = this + a\nfunction bnpAddTo(a,r) {\n  var i = 0, c = 0, m = Math.min(a.t,this.t);\n  while(i < m) {\n    c += this[i]+a[i];\n    r[i++] = c&this.DM;\n    c >>= this.DB;\n  }\n  if(a.t < this.t) {\n    c += a.s;\n    while(i < this.t) {\n      c += this[i];\n      r[i++] = c&this.DM;\n      c >>= this.DB;\n    }\n    c += this.s;\n  }\n  else {\n    c += this.s;\n    while(i < a.t) {\n      c += a[i];\n      r[i++] = c&this.DM;\n      c >>= this.DB;\n    }\n    c += a.s;\n  }\n  r.s = (c<0)?-1:0;\n  if(c > 0) r[i++] = c;\n  else if(c < -1) r[i++] = this.DV+c;\n  r.t = i;\n  r.clamp();\n}\n\n// (public) this + a\nfunction bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; }\n\n// (public) this - a\nfunction bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; }\n\n// (public) this * a\nfunction bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; }\n\n// (public) this^2\nfunction bnSquare() { var r = nbi(); this.squareTo(r); return r; }\n\n// (public) this / a\nfunction bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; }\n\n// (public) this % a\nfunction bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; }\n\n// (public) [this/a,this%a]\nfunction bnDivideAndRemainder(a) {\n  var q = nbi(), r = nbi();\n  this.divRemTo(a,q,r);\n  return new Array(q,r);\n}\n\n// (protected) this *= n, this >= 0, 1 < n < DV\nfunction bnpDMultiply(n) {\n  this[this.t] = this.am(0,n-1,this,0,0,this.t);\n  ++this.t;\n  this.clamp();\n}\n\n// (protected) this += n << w words, this >= 0\nfunction bnpDAddOffset(n,w) {\n  if(n == 0) return;\n  while(this.t <= w) this[this.t++] = 0;\n  this[w] += n;\n  while(this[w] >= this.DV) {\n    this[w] -= this.DV;\n    if(++w >= this.t) this[this.t++] = 0;\n    ++this[w];\n  }\n}\n\n// A \"null\" reducer\nfunction NullExp() {}\nfunction nNop(x) { return x; }\nfunction nMulTo(x,y,r) { x.multiplyTo(y,r); }\nfunction nSqrTo(x,r) { x.squareTo(r); }\n\nNullExp.prototype.convert = nNop;\nNullExp.prototype.revert = nNop;\nNullExp.prototype.mulTo = nMulTo;\nNullExp.prototype.sqrTo = nSqrTo;\n\n// (public) this^e\nfunction bnPow(e) { return this.exp(e,new NullExp()); }\n\n// (protected) r = lower n words of \"this * a\", a.t <= n\n// \"this\" should be the larger one if appropriate.\nfunction bnpMultiplyLowerTo(a,n,r) {\n  var i = Math.min(this.t+a.t,n);\n  r.s = 0; // assumes a,this >= 0\n  r.t = i;\n  while(i > 0) r[--i] = 0;\n  var j;\n  for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t);\n  for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i);\n  r.clamp();\n}\n\n// (protected) r = \"this * a\" without lower n words, n > 0\n// \"this\" should be the larger one if appropriate.\nfunction bnpMultiplyUpperTo(a,n,r) {\n  --n;\n  var i = r.t = this.t+a.t-n;\n  r.s = 0; // assumes a,this >= 0\n  while(--i >= 0) r[i] = 0;\n  for(i = Math.max(n-this.t,0); i < a.t; ++i)\n    r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n);\n  r.clamp();\n  r.drShiftTo(1,r);\n}\n\n// Barrett modular reduction\nfunction Barrett(m) {\n  // setup Barrett\n  this.r2 = nbi();\n  this.q3 = nbi();\n  BigInteger.ONE.dlShiftTo(2*m.t,this.r2);\n  this.mu = this.r2.divide(m);\n  this.m = m;\n}\n\nfunction barrettConvert(x) {\n  if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m);\n  else if(x.compareTo(this.m) < 0) return x;\n  else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }\n}\n\nfunction barrettRevert(x) { return x; }\n\n// x = x mod m (HAC 14.42)\nfunction barrettReduce(x) {\n  x.drShiftTo(this.m.t-1,this.r2);\n  if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); }\n  this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);\n  this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);\n  while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1);\n  x.subTo(this.r2,x);\n  while(x.compareTo(this.m) >= 0) x.subTo(this.m,x);\n}\n\n// r = x^2 mod m; x != r\nfunction barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); }\n\n// r = x*y mod m; x,y != r\nfunction barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }\n\nBarrett.prototype.convert = barrettConvert;\nBarrett.prototype.revert = barrettRevert;\nBarrett.prototype.reduce = barrettReduce;\nBarrett.prototype.mulTo = barrettMulTo;\nBarrett.prototype.sqrTo = barrettSqrTo;\n\n// (public) this^e % m (HAC 14.85)\nfunction bnModPow(e,m) {\n  var i = e.bitLength(), k, r = nbv(1), z;\n  if(i <= 0) return r;\n  else if(i < 18) k = 1;\n  else if(i < 48) k = 3;\n  else if(i < 144) k = 4;\n  else if(i < 768) k = 5;\n  else k = 6;\n  if(i < 8)\n    z = new Classic(m);\n  else if(m.isEven())\n    z = new Barrett(m);\n  else\n    z = new Montgomery(m);\n\n  // precomputation\n  var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1;\n  g[1] = z.convert(this);\n  if(k > 1) {\n    var g2 = nbi();\n    z.sqrTo(g[1],g2);\n    while(n <= km) {\n      g[n] = nbi();\n      z.mulTo(g2,g[n-2],g[n]);\n      n += 2;\n    }\n  }\n\n  var j = e.t-1, w, is1 = true, r2 = nbi(), t;\n  i = nbits(e[j])-1;\n  while(j >= 0) {\n    if(i >= k1) w = (e[j]>>(i-k1))&km;\n    else {\n      w = (e[j]&((1<<(i+1))-1))<<(k1-i);\n      if(j > 0) w |= e[j-1]>>(this.DB+i-k1);\n    }\n\n    n = k;\n    while((w&1) == 0) { w >>= 1; --n; }\n    if((i -= n) < 0) { i += this.DB; --j; }\n    if(is1) {\t// ret == 1, don't bother squaring or multiplying it\n      g[w].copyTo(r);\n      is1 = false;\n    }\n    else {\n      while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; }\n      if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; }\n      z.mulTo(r2,g[w],r);\n    }\n\n    while(j >= 0 && (e[j]&(1<<i)) == 0) {\n      z.sqrTo(r,r2); t = r; r = r2; r2 = t;\n      if(--i < 0) { i = this.DB-1; --j; }\n    }\n  }\n  return z.revert(r);\n}\n\n// (public) gcd(this,a) (HAC 14.54)\nfunction bnGCD(a) {\n  var x = (this.s<0)?this.negate():this.clone();\n  var y = (a.s<0)?a.negate():a.clone();\n  if(x.compareTo(y) < 0) { var t = x; x = y; y = t; }\n  var i = x.getLowestSetBit(), g = y.getLowestSetBit();\n  if(g < 0) return x;\n  if(i < g) g = i;\n  if(g > 0) {\n    x.rShiftTo(g,x);\n    y.rShiftTo(g,y);\n  }\n  while(x.signum() > 0) {\n    if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x);\n    if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y);\n    if(x.compareTo(y) >= 0) {\n      x.subTo(y,x);\n      x.rShiftTo(1,x);\n    }\n    else {\n      y.subTo(x,y);\n      y.rShiftTo(1,y);\n    }\n  }\n  if(g > 0) y.lShiftTo(g,y);\n  return y;\n}\n\n// (protected) this % n, n < 2^26\nfunction bnpModInt(n) {\n  if(n <= 0) return 0;\n  var d = this.DV%n, r = (this.s<0)?n-1:0;\n  if(this.t > 0)\n    if(d == 0) r = this[0]%n;\n    else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n;\n  return r;\n}\n\n// (public) 1/this % m (HAC 14.61)\nfunction bnModInverse(m) {\n  var ac = m.isEven();\n  if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;\n  var u = m.clone(), v = this.clone();\n  var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);\n  while(u.signum() != 0) {\n    while(u.isEven()) {\n      u.rShiftTo(1,u);\n      if(ac) {\n        if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); }\n        a.rShiftTo(1,a);\n      }\n      else if(!b.isEven()) b.subTo(m,b);\n      b.rShiftTo(1,b);\n    }\n    while(v.isEven()) {\n      v.rShiftTo(1,v);\n      if(ac) {\n        if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); }\n        c.rShiftTo(1,c);\n      }\n      else if(!d.isEven()) d.subTo(m,d);\n      d.rShiftTo(1,d);\n    }\n    if(u.compareTo(v) >= 0) {\n      u.subTo(v,u);\n      if(ac) a.subTo(c,a);\n      b.subTo(d,b);\n    }\n    else {\n      v.subTo(u,v);\n      if(ac) c.subTo(a,c);\n      d.subTo(b,d);\n    }\n  }\n  if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;\n  if(d.compareTo(m) >= 0) return d.subtract(m);\n  if(d.signum() < 0) d.addTo(m,d); else return d;\n  if(d.signum() < 0) return d.add(m); else return d;\n}\n\nvar lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997];\nvar lplim = (1<<26)/lowprimes[lowprimes.length-1];\n\n// (public) test primality with certainty >= 1-.5^t\nfunction bnIsProbablePrime(t) {\n  var i, x = this.abs();\n  if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) {\n    for(i = 0; i < lowprimes.length; ++i)\n      if(x[0] == lowprimes[i]) return true;\n    return false;\n  }\n  if(x.isEven()) return false;\n  i = 1;\n  while(i < lowprimes.length) {\n    var m = lowprimes[i], j = i+1;\n    while(j < lowprimes.length && m < lplim) m *= lowprimes[j++];\n    m = x.modInt(m);\n    while(i < j) if(m%lowprimes[i++] == 0) return false;\n  }\n  return x.millerRabin(t);\n}\n\n// (protected) true if probably prime (HAC 4.24, Miller-Rabin)\nfunction bnpMillerRabin(t) {\n  var n1 = this.subtract(BigInteger.ONE);\n  var k = n1.getLowestSetBit();\n  if(k <= 0) return false;\n  var r = n1.shiftRight(k);\n  t = (t+1)>>1;\n  if(t > lowprimes.length) t = lowprimes.length;\n  var a = nbi();\n  for(var i = 0; i < t; ++i) {\n    //Pick bases at random, instead of starting at 2\n    a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]);\n    var y = a.modPow(r,this);\n    if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {\n      var j = 1;\n      while(j++ < k && y.compareTo(n1) != 0) {\n        y = y.modPowInt(2,this);\n        if(y.compareTo(BigInteger.ONE) == 0) return false;\n      }\n      if(y.compareTo(n1) != 0) return false;\n    }\n  }\n  return true;\n}\n\n// protected\nBigInteger.prototype.chunkSize = bnpChunkSize;\nBigInteger.prototype.toRadix = bnpToRadix;\nBigInteger.prototype.fromRadix = bnpFromRadix;\nBigInteger.prototype.fromNumber = bnpFromNumber;\nBigInteger.prototype.bitwiseTo = bnpBitwiseTo;\nBigInteger.prototype.changeBit = bnpChangeBit;\nBigInteger.prototype.addTo = bnpAddTo;\nBigInteger.prototype.dMultiply = bnpDMultiply;\nBigInteger.prototype.dAddOffset = bnpDAddOffset;\nBigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;\nBigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;\nBigInteger.prototype.modInt = bnpModInt;\nBigInteger.prototype.millerRabin = bnpMillerRabin;\n\n// public\nBigInteger.prototype.clone = bnClone;\nBigInteger.prototype.intValue = bnIntValue;\nBigInteger.prototype.byteValue = bnByteValue;\nBigInteger.prototype.shortValue = bnShortValue;\nBigInteger.prototype.signum = bnSigNum;\nBigInteger.prototype.toByteArray = bnToByteArray;\nBigInteger.prototype.equals = bnEquals;\nBigInteger.prototype.min = bnMin;\nBigInteger.prototype.max = bnMax;\nBigInteger.prototype.and = bnAnd;\nBigInteger.prototype.or = bnOr;\nBigInteger.prototype.xor = bnXor;\nBigInteger.prototype.andNot = bnAndNot;\nBigInteger.prototype.not = bnNot;\nBigInteger.prototype.shiftLeft = bnShiftLeft;\nBigInteger.prototype.shiftRight = bnShiftRight;\nBigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;\nBigInteger.prototype.bitCount = bnBitCount;\nBigInteger.prototype.testBit = bnTestBit;\nBigInteger.prototype.setBit = bnSetBit;\nBigInteger.prototype.clearBit = bnClearBit;\nBigInteger.prototype.flipBit = bnFlipBit;\nBigInteger.prototype.add = bnAdd;\nBigInteger.prototype.subtract = bnSubtract;\nBigInteger.prototype.multiply = bnMultiply;\nBigInteger.prototype.divide = bnDivide;\nBigInteger.prototype.remainder = bnRemainder;\nBigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;\nBigInteger.prototype.modPow = bnModPow;\nBigInteger.prototype.modInverse = bnModInverse;\nBigInteger.prototype.pow = bnPow;\nBigInteger.prototype.gcd = bnGCD;\nBigInteger.prototype.isProbablePrime = bnIsProbablePrime;\n\n// JSBN-specific extension\nBigInteger.prototype.square = bnSquare;\n\n// BigInteger interfaces not implemented in jsbn:\n\n// BigInteger(int signum, byte[] magnitude)\n// double doubleValue()\n// float floatValue()\n// int hashCode()\n// long longValue()\n// static BigInteger valueOf(long val)\n"
  },
  {
    "path": "JavaScript/sm2/js/md5.js",
    "content": "/*\nCryptoJS v3.1.2\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function (Math) {\n    // Shortcuts\n    var C = CryptoJS;\n    var C_lib = C.lib;\n    var WordArray = C_lib.WordArray;\n    var Hasher = C_lib.Hasher;\n    var C_algo = C.algo;\n\n    // Constants table\n    var T = [];\n\n    // Compute constants\n    (function () {\n        for (var i = 0; i < 64; i++) {\n            T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;\n        }\n    }());\n\n    /**\n     * MD5 hash algorithm.\n     */\n    var MD5 = C_algo.MD5 = Hasher.extend({\n        _doReset: function () {\n            this._hash = new WordArray.init([\n                0x67452301, 0xefcdab89,\n                0x98badcfe, 0x10325476\n            ]);\n        },\n\n        _doProcessBlock: function (M, offset) {\n            // Swap endian\n            for (var i = 0; i < 16; i++) {\n                // Shortcuts\n                var offset_i = offset + i;\n                var M_offset_i = M[offset_i];\n\n                M[offset_i] = (\n                    (((M_offset_i << 8)  | (M_offset_i >>> 24)) & 0x00ff00ff) |\n                    (((M_offset_i << 24) | (M_offset_i >>> 8))  & 0xff00ff00)\n                );\n            }\n\n            // Shortcuts\n            var H = this._hash.words;\n\n            var M_offset_0  = M[offset + 0];\n            var M_offset_1  = M[offset + 1];\n            var M_offset_2  = M[offset + 2];\n            var M_offset_3  = M[offset + 3];\n            var M_offset_4  = M[offset + 4];\n            var M_offset_5  = M[offset + 5];\n            var M_offset_6  = M[offset + 6];\n            var M_offset_7  = M[offset + 7];\n            var M_offset_8  = M[offset + 8];\n            var M_offset_9  = M[offset + 9];\n            var M_offset_10 = M[offset + 10];\n            var M_offset_11 = M[offset + 11];\n            var M_offset_12 = M[offset + 12];\n            var M_offset_13 = M[offset + 13];\n            var M_offset_14 = M[offset + 14];\n            var M_offset_15 = M[offset + 15];\n\n            // Working varialbes\n            var a = H[0];\n            var b = H[1];\n            var c = H[2];\n            var d = H[3];\n\n            // Computation\n            a = FF(a, b, c, d, M_offset_0,  7,  T[0]);\n            d = FF(d, a, b, c, M_offset_1,  12, T[1]);\n            c = FF(c, d, a, b, M_offset_2,  17, T[2]);\n            b = FF(b, c, d, a, M_offset_3,  22, T[3]);\n            a = FF(a, b, c, d, M_offset_4,  7,  T[4]);\n            d = FF(d, a, b, c, M_offset_5,  12, T[5]);\n            c = FF(c, d, a, b, M_offset_6,  17, T[6]);\n            b = FF(b, c, d, a, M_offset_7,  22, T[7]);\n            a = FF(a, b, c, d, M_offset_8,  7,  T[8]);\n            d = FF(d, a, b, c, M_offset_9,  12, T[9]);\n            c = FF(c, d, a, b, M_offset_10, 17, T[10]);\n            b = FF(b, c, d, a, M_offset_11, 22, T[11]);\n            a = FF(a, b, c, d, M_offset_12, 7,  T[12]);\n            d = FF(d, a, b, c, M_offset_13, 12, T[13]);\n            c = FF(c, d, a, b, M_offset_14, 17, T[14]);\n            b = FF(b, c, d, a, M_offset_15, 22, T[15]);\n\n            a = GG(a, b, c, d, M_offset_1,  5,  T[16]);\n            d = GG(d, a, b, c, M_offset_6,  9,  T[17]);\n            c = GG(c, d, a, b, M_offset_11, 14, T[18]);\n            b = GG(b, c, d, a, M_offset_0,  20, T[19]);\n            a = GG(a, b, c, d, M_offset_5,  5,  T[20]);\n            d = GG(d, a, b, c, M_offset_10, 9,  T[21]);\n            c = GG(c, d, a, b, M_offset_15, 14, T[22]);\n            b = GG(b, c, d, a, M_offset_4,  20, T[23]);\n            a = GG(a, b, c, d, M_offset_9,  5,  T[24]);\n            d = GG(d, a, b, c, M_offset_14, 9,  T[25]);\n            c = GG(c, d, a, b, M_offset_3,  14, T[26]);\n            b = GG(b, c, d, a, M_offset_8,  20, T[27]);\n            a = GG(a, b, c, d, M_offset_13, 5,  T[28]);\n            d = GG(d, a, b, c, M_offset_2,  9,  T[29]);\n            c = GG(c, d, a, b, M_offset_7,  14, T[30]);\n            b = GG(b, c, d, a, M_offset_12, 20, T[31]);\n\n            a = HH(a, b, c, d, M_offset_5,  4,  T[32]);\n            d = HH(d, a, b, c, M_offset_8,  11, T[33]);\n            c = HH(c, d, a, b, M_offset_11, 16, T[34]);\n            b = HH(b, c, d, a, M_offset_14, 23, T[35]);\n            a = HH(a, b, c, d, M_offset_1,  4,  T[36]);\n            d = HH(d, a, b, c, M_offset_4,  11, T[37]);\n            c = HH(c, d, a, b, M_offset_7,  16, T[38]);\n            b = HH(b, c, d, a, M_offset_10, 23, T[39]);\n            a = HH(a, b, c, d, M_offset_13, 4,  T[40]);\n            d = HH(d, a, b, c, M_offset_0,  11, T[41]);\n            c = HH(c, d, a, b, M_offset_3,  16, T[42]);\n            b = HH(b, c, d, a, M_offset_6,  23, T[43]);\n            a = HH(a, b, c, d, M_offset_9,  4,  T[44]);\n            d = HH(d, a, b, c, M_offset_12, 11, T[45]);\n            c = HH(c, d, a, b, M_offset_15, 16, T[46]);\n            b = HH(b, c, d, a, M_offset_2,  23, T[47]);\n\n            a = II(a, b, c, d, M_offset_0,  6,  T[48]);\n            d = II(d, a, b, c, M_offset_7,  10, T[49]);\n            c = II(c, d, a, b, M_offset_14, 15, T[50]);\n            b = II(b, c, d, a, M_offset_5,  21, T[51]);\n            a = II(a, b, c, d, M_offset_12, 6,  T[52]);\n            d = II(d, a, b, c, M_offset_3,  10, T[53]);\n            c = II(c, d, a, b, M_offset_10, 15, T[54]);\n            b = II(b, c, d, a, M_offset_1,  21, T[55]);\n            a = II(a, b, c, d, M_offset_8,  6,  T[56]);\n            d = II(d, a, b, c, M_offset_15, 10, T[57]);\n            c = II(c, d, a, b, M_offset_6,  15, T[58]);\n            b = II(b, c, d, a, M_offset_13, 21, T[59]);\n            a = II(a, b, c, d, M_offset_4,  6,  T[60]);\n            d = II(d, a, b, c, M_offset_11, 10, T[61]);\n            c = II(c, d, a, b, M_offset_2,  15, T[62]);\n            b = II(b, c, d, a, M_offset_9,  21, T[63]);\n\n            // Intermediate hash value\n            H[0] = (H[0] + a) | 0;\n            H[1] = (H[1] + b) | 0;\n            H[2] = (H[2] + c) | 0;\n            H[3] = (H[3] + d) | 0;\n        },\n\n        _doFinalize: function () {\n            // Shortcuts\n            var data = this._data;\n            var dataWords = data.words;\n\n            var nBitsTotal = this._nDataBytes * 8;\n            var nBitsLeft = data.sigBytes * 8;\n\n            // Add padding\n            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);\n\n            var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000);\n            var nBitsTotalL = nBitsTotal;\n            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = (\n                (((nBitsTotalH << 8)  | (nBitsTotalH >>> 24)) & 0x00ff00ff) |\n                (((nBitsTotalH << 24) | (nBitsTotalH >>> 8))  & 0xff00ff00)\n            );\n            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (\n                (((nBitsTotalL << 8)  | (nBitsTotalL >>> 24)) & 0x00ff00ff) |\n                (((nBitsTotalL << 24) | (nBitsTotalL >>> 8))  & 0xff00ff00)\n            );\n\n            data.sigBytes = (dataWords.length + 1) * 4;\n\n            // Hash final blocks\n            this._process();\n\n            // Shortcuts\n            var hash = this._hash;\n            var H = hash.words;\n\n            // Swap endian\n            for (var i = 0; i < 4; i++) {\n                // Shortcut\n                var H_i = H[i];\n\n                H[i] = (((H_i << 8)  | (H_i >>> 24)) & 0x00ff00ff) |\n                       (((H_i << 24) | (H_i >>> 8))  & 0xff00ff00);\n            }\n\n            // Return final computed hash\n            return hash;\n        },\n\n        clone: function () {\n            var clone = Hasher.clone.call(this);\n            clone._hash = this._hash.clone();\n\n            return clone;\n        }\n    });\n\n    function FF(a, b, c, d, x, s, t) {\n        var n = a + ((b & c) | (~b & d)) + x + t;\n        return ((n << s) | (n >>> (32 - s))) + b;\n    }\n\n    function GG(a, b, c, d, x, s, t) {\n        var n = a + ((b & d) | (c & ~d)) + x + t;\n        return ((n << s) | (n >>> (32 - s))) + b;\n    }\n\n    function HH(a, b, c, d, x, s, t) {\n        var n = a + (b ^ c ^ d) + x + t;\n        return ((n << s) | (n >>> (32 - s))) + b;\n    }\n\n    function II(a, b, c, d, x, s, t) {\n        var n = a + (c ^ (b | ~d)) + x + t;\n        return ((n << s) | (n >>> (32 - s))) + b;\n    }\n\n    /**\n     * Shortcut function to the hasher's object interface.\n     *\n     * @param {WordArray|string} message The message to hash.\n     *\n     * @return {WordArray} The hash.\n     *\n     * @static\n     *\n     * @example\n     *\n     *     var hash = CryptoJS.MD5('message');\n     *     var hash = CryptoJS.MD5(wordArray);\n     */\n    C.MD5 = Hasher._createHelper(MD5);\n\n    /**\n     * Shortcut function to the HMAC's object interface.\n     *\n     * @param {WordArray|string} message The message to hash.\n     * @param {WordArray|string} key The secret key.\n     *\n     * @return {WordArray} The HMAC.\n     *\n     * @static\n     *\n     * @example\n     *\n     *     var hmac = CryptoJS.HmacMD5(message, key);\n     */\n    C.HmacMD5 = Hasher._createHmacHelper(MD5);\n}(Math));\n"
  },
  {
    "path": "JavaScript/sm2/js/pkcs5pkey-1.0.js",
    "content": "/*! pkcs5pkey-1.0.5.js (c) 2013 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n/*\n * pkcs5pkey.js - reading passcode protected PKCS#5 PEM formatted RSA private key\n *\n * Copyright (c) 2013 Kenji Urushima (kenji.urushima@gmail.com)\n *\n * This software is licensed under the terms of the MIT License.\n * http://kjur.github.com/jsrsasign/license\n *\n * The above copyright and license notice shall be \n * included in all copies or substantial portions of the Software.\n */\n/**\n * @fileOverview\n * @name pkcs5pkey-1.0.js\n * @author Kenji Urushima kenji.urushima@gmail.com\n * @version pkcs5pkey 1.0.5 (2013-Aug-20)\n * @since jsrsasign 2.0.0\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\n */\n\n/**\n * @name PKCS5PKEY\n * @class class for PKCS#5 and PKCS#8 private key \n * @deprecated Since jsrsasign 4.1.3. Please use KEYUTIL class.\n * @description \n * <br/>\n * {@link PKCS5PKEY} class has following features:\n * <ul>\n * <li>read and parse PEM formatted encrypted PKCS#5 private key\n * <li>generate PEM formatted encrypted PKCS#5 private key\n * <li>read and parse PEM formatted plain PKCS#8 private key\n * <li>read and parse PEM formatted encrypted PKCS#8 private key by PBKDF2/HmacSHA1/3DES\n * </ul>\n * Currently supports only RSA private key and\n * following symmetric key algorithms to protect private key.\n * <ul>\n * <li>DES-EDE3-CBC</li>\n * <li>AES-256-CBC</li>\n * <li>AES-192-CBC</li>\n * <li>AES-128-CBC</li>\n * </ul>\n * \n * <h5>METHOD SUMMARY</h5>\n * <dl>\n * <dt><b>PKCS8 PRIVATE KEY METHODS</b><dd>\n * <ul>\n * <li>{@link PKCS5PKEY.getRSAKeyFromPlainPKCS8PEM} - convert plain PKCS8 PEM to RSAKey object</li>\n * <li>{@link PKCS5PKEY.getRSAKeyFromPlainPKCS8Hex} - convert plain PKCS8 hexadecimal data to RSAKey object</li>\n * <li>{@link PKCS5PKEY.getRSAKeyFromEncryptedPKCS8PEM} - convert encrypted PKCS8 PEM to RSAKey object</li>\n * <li>{@link PKCS5PKEY.getPlainPKCS8HexFromEncryptedPKCS8PEM} - convert encrypted PKCS8 PEM to plain PKCS8 Hex</li>\n * </ul>\n * <dt><b>PKCS5 PRIVATE KEY METHODS</b><dd>\n * <ul>\n * <li>{@link PKCS5PKEY.getRSAKeyFromEncryptedPKCS5PEM} - convert encrypted PKCS5 PEM to RSAKey object</li>\n * <li>{@link PKCS5PKEY.getEncryptedPKCS5PEMFromRSAKey} - convert RSAKey object to encryped PKCS5 PEM</li>\n * <li>{@link PKCS5PKEY.newEncryptedPKCS5PEM} - generate RSAKey and its encrypted PKCS5 PEM</li>\n * </ul>\n * <dt><b>PKCS8 PUBLIC KEY METHODS</b><dd>\n * <ul>\n * <li>{@link PKCS5PKEY.getKeyFromPublicPKCS8PEM} - convert encrypted PKCS8 PEM to RSAKey/ECDSA object</li>\n * <li>{@link PKCS5PKEY.getKeyFromPublicPKCS8Hex} - convert encrypted PKCS8 Hex to RSAKey/ECDSA object</li>\n * <li>{@link PKCS5PKEY.getRSAKeyFromPublicPKCS8PEM} - convert encrypted PKCS8 PEM to RSAKey object</li>\n * <li>{@link PKCS5PKEY.getRSAKeyFromPublicPKCS8Hex} - convert encrypted PKCS8 Hex to RSAKey object</li>\n * </ul>\n * <dt><b>UTITILIY METHODS</b><dd>\n * <ul>\n * <li>{@link PKCS5PKEY.getHexFromPEM} - convert PEM string to hexadecimal data</li>\n * <li>{@link PKCS5PKEY.getDecryptedKeyHexByKeyIV} - decrypt key by sharedKey and IV</li>\n * </ul>\n * </dl>\n * \n * @example\n * Here is an example of PEM formatted encrypted PKCS#5 private key.\n * -----BEGIN RSA PRIVATE KEY-----\n * Proc-Type: 4,ENCRYPTED\n * DEK-Info: AES-256-CBC,40555967F759530864FE022E257DE34E\n *\n * jV7uXajRw4cccDaliagcqiLOiQEUCe19l761pXRxzgQP+DH4rCi12T4puTdZyy6l\n *          ...(snip)...\n * qxLS+BASmyGm4DME6m+kltZ12LXwPgNU6+d+XQ4NXSA=\n *-----END RSA PRIVATE KEY-----\n */\nvar PKCS5PKEY = function() {\n    // *****************************************************************\n    // *** PRIVATE PROPERTIES AND METHODS *******************************\n    // *****************************************************************\n    // shared key decryption ------------------------------------------\n    var decryptAES = function(dataHex, keyHex, ivHex) {\n\treturn decryptGeneral(CryptoJS.AES, dataHex, keyHex, ivHex);\n    };\n\n    var decrypt3DES = function(dataHex, keyHex, ivHex) {\n\treturn decryptGeneral(CryptoJS.TripleDES, dataHex, keyHex, ivHex);\n    };\n\n    var decryptGeneral = function(f, dataHex, keyHex, ivHex) {\n\tvar data = CryptoJS.enc.Hex.parse(dataHex);\n\tvar key = CryptoJS.enc.Hex.parse(keyHex);\n\tvar iv = CryptoJS.enc.Hex.parse(ivHex);\n\tvar encrypted = {};\n\tencrypted.key = key;\n\tencrypted.iv = iv;\n\tencrypted.ciphertext = data;\n\tvar decrypted = f.decrypt(encrypted, key, { iv: iv });\n\treturn CryptoJS.enc.Hex.stringify(decrypted);\n    };\n\n    // shared key decryption ------------------------------------------\n    var encryptAES = function(dataHex, keyHex, ivHex) {\n\treturn encryptGeneral(CryptoJS.AES, dataHex, keyHex, ivHex);\n    };\n\n    var encrypt3DES = function(dataHex, keyHex, ivHex) {\n\treturn encryptGeneral(CryptoJS.TripleDES, dataHex, keyHex, ivHex);\n    };\n\n    var encryptGeneral = function(f, dataHex, keyHex, ivHex) {\n\tvar data = CryptoJS.enc.Hex.parse(dataHex);\n\tvar key = CryptoJS.enc.Hex.parse(keyHex);\n\tvar iv = CryptoJS.enc.Hex.parse(ivHex);\n\tvar msg = {};\n\tvar encryptedHex = f.encrypt(data, key, { iv: iv });\n        var encryptedWA = CryptoJS.enc.Hex.parse(encryptedHex.toString());\n        var encryptedB64 = CryptoJS.enc.Base64.stringify(encryptedWA);\n\treturn encryptedB64;\n    };\n\n    // other methods and properties ----------------------------------------\n    var ALGLIST = {\n\t'AES-256-CBC': { 'proc': decryptAES, 'eproc': encryptAES, keylen: 32, ivlen: 16 },\n\t'AES-192-CBC': { 'proc': decryptAES, 'eproc': encryptAES, keylen: 24, ivlen: 16 },\n\t'AES-128-CBC': { 'proc': decryptAES, 'eproc': encryptAES, keylen: 16, ivlen: 16 },\n\t'DES-EDE3-CBC': { 'proc': decrypt3DES, 'eproc': encrypt3DES, keylen: 24, ivlen: 8 }\n    };\n\n    var getFuncByName = function(algName) {\n\treturn ALGLIST[algName]['proc'];\n    };\n\n    var _generateIvSaltHex = function(numBytes) {\n\tvar wa = CryptoJS.lib.WordArray.random(numBytes);\n\tvar hex = CryptoJS.enc.Hex.stringify(wa);\n\treturn hex;\n    };\n\n    var _parsePKCS5PEM = function(sPKCS5PEM) {\n\tvar info = {};\n\tif (sPKCS5PEM.match(new RegExp(\"DEK-Info: ([^,]+),([0-9A-Fa-f]+)\", \"m\"))) {\n\t    info.cipher = RegExp.$1;\n\t    info.ivsalt = RegExp.$2;\n\t}\n\tif (sPKCS5PEM.match(new RegExp(\"-----BEGIN ([A-Z]+) PRIVATE KEY-----\"))) {\n\t    info.type = RegExp.$1;\n\t}\n\tvar i1 = -1;\n\tvar lenNEWLINE = 0;\n\tif (sPKCS5PEM.indexOf(\"\\r\\n\\r\\n\") != -1) {\n\t    i1 = sPKCS5PEM.indexOf(\"\\r\\n\\r\\n\");\n\t    lenNEWLINE = 2;\n\t}\n\tif (sPKCS5PEM.indexOf(\"\\n\\n\") != -1) {\n\t    i1 = sPKCS5PEM.indexOf(\"\\n\\n\");\n\t    lenNEWLINE = 1;\n\t}\n\tvar i2 = sPKCS5PEM.indexOf(\"-----END\");\n\tif (i1 != -1 && i2 != -1) {\n\t    var s = sPKCS5PEM.substring(i1 + lenNEWLINE * 2, i2 - lenNEWLINE);\n\t    s = s.replace(/\\s+/g, '');\n\t    info.data = s;\n\t}\n\treturn info;\n    };\n\n    var _getKeyAndUnusedIvByPasscodeAndIvsalt = function(algName, passcode, ivsaltHex) {\n\t//alert(\"ivsaltHex(2) = \" + ivsaltHex);\n\tvar saltHex = ivsaltHex.substring(0, 16);\n\t//alert(\"salt = \" + saltHex);\n\t    \n\tvar salt = CryptoJS.enc.Hex.parse(saltHex);\n\tvar data = CryptoJS.enc.Utf8.parse(passcode);\n\t//alert(\"salt = \" + salt);\n\t//alert(\"data = \" + data);\n\n\tvar nRequiredBytes = ALGLIST[algName]['keylen'] + ALGLIST[algName]['ivlen'];\n\tvar hHexValueJoined = '';\n\tvar hLastValue = null;\n\t//alert(\"nRequiredBytes = \" + nRequiredBytes);\n\tfor (;;) {\n\t    var h = CryptoJS.algo.MD5.create();\n\t    if (hLastValue != null) {\n\t\th.update(hLastValue);\n\t    }\n\t    h.update(data);\n\t    h.update(salt);\n\t    hLastValue = h.finalize();\n\t    hHexValueJoined = hHexValueJoined + CryptoJS.enc.Hex.stringify(hLastValue);\n\t    //alert(\"joined = \" + hHexValueJoined);\n\t    if (hHexValueJoined.length >= nRequiredBytes * 2) {\n\t\tbreak;\n\t    }\n\t}\n\tvar result = {};\n\tresult.keyhex = hHexValueJoined.substr(0, ALGLIST[algName]['keylen'] * 2);\n\tresult.ivhex = hHexValueJoined.substr(ALGLIST[algName]['keylen'] * 2, ALGLIST[algName]['ivlen'] * 2);\n\treturn result;\n    };\n\n    /*\n     * @param {String} privateKeyB64 base64 string of encrypted private key\n     * @param {String} sharedKeyAlgName algorithm name of shared key encryption\n     * @param {String} sharedKeyHex hexadecimal string of shared key to encrypt\n     * @param {String} ivsaltHex hexadecimal string of IV and salt\n     * @param {String} hexadecimal string of decrypted private key\n     */\n    var _decryptKeyB64 = function(privateKeyB64, sharedKeyAlgName, sharedKeyHex, ivsaltHex) {\n\tvar privateKeyWA = CryptoJS.enc.Base64.parse(privateKeyB64);\n\tvar privateKeyHex = CryptoJS.enc.Hex.stringify(privateKeyWA);\n\tvar f = ALGLIST[sharedKeyAlgName]['proc'];\n\tvar decryptedKeyHex = f(privateKeyHex, sharedKeyHex, ivsaltHex);\n\treturn decryptedKeyHex;\n    };\n    \n    /*\n     * @param {String} privateKeyHex hexadecimal string of private key\n     * @param {String} sharedKeyAlgName algorithm name of shared key encryption\n     * @param {String} sharedKeyHex hexadecimal string of shared key to encrypt\n     * @param {String} ivsaltHex hexadecimal string of IV and salt\n     * @param {String} base64 string of encrypted private key\n     */\n    var _encryptKeyHex = function(privateKeyHex, sharedKeyAlgName, sharedKeyHex, ivsaltHex) {\n\tvar f = ALGLIST[sharedKeyAlgName]['eproc'];\n\tvar encryptedKeyB64 = f(privateKeyHex, sharedKeyHex, ivsaltHex);\n\treturn encryptedKeyB64;\n    };\n\n    // *****************************************************************\n    // *** PUBLIC PROPERTIES AND METHODS *******************************\n    // *****************************************************************\n    return {\n        // -- UTILITY METHODS ------------------------------------------------------------\n\t/**\n         * decrypt private key by shared key\n\t * @name version\n\t * @memberOf PKCS5PKEY\n\t * @property {String} version\n\t * @description version string of PKCS5PKEY class\n\t */\n\tversion: \"1.0.5\",\n\n\t/**\n         * get hexacedimal string of PEM format\n\t * @name getHexFromPEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} sPEM PEM formatted string\n\t * @param {String} sHead PEM header string without BEGIN/END\n\t * @return {String} hexadecimal string data of PEM contents\n\t * @since pkcs5pkey 1.0.5\n\t */\n        getHexFromPEM: function(sPEM, sHead) {\n\t    var s = sPEM;\n\t    if (s.indexOf(\"BEGIN \" + sHead) == -1) {\n\t\tthrow \"can't find PEM header: \" + sHead;\n\t    }\n\t    s = s.replace(\"-----BEGIN \" + sHead + \"-----\", \"\");\n\t    s = s.replace(\"-----END \" + sHead + \"-----\", \"\");\n\t    var sB64 = s.replace(/\\s+/g, '');\n            var dataHex = b64tohex(sB64);\n\t    return dataHex;\n\t},\n\n\t/**\n         * decrypt private key by shared key\n\t * @name getDecryptedKeyHexByKeyIV\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} encryptedKeyHex hexadecimal string of encrypted private key\n\t * @param {String} algName name of symmetric key algorithm (ex. 'DES-EBE3-CBC')\n\t * @param {String} sharedKeyHex hexadecimal string of symmetric key\n\t * @param {String} ivHex hexadecimal string of initial vector(IV).\n\t * @return {String} hexadecimal string of decrypted privated key\n\t */\n\tgetDecryptedKeyHexByKeyIV: function(encryptedKeyHex, algName, sharedKeyHex, ivHex) {\n\t    var f1 = getFuncByName(algName);\n\t    return f1(encryptedKeyHex, sharedKeyHex, ivHex);\n\t},\n\n\t/**\n         * parse PEM formatted passcode protected PKCS#5 private key\n\t * @name parsePKCS5PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} sEncryptedPEM PEM formatted protected passcode protected PKCS#5 private key\n\t * @return {Hash} hash of key information\n\t * @description\n         * Resulted hash has following attributes.\n\t * <ul>\n\t * <li>cipher - symmetric key algorithm name (ex. 'DES-EBE3-CBC', 'AES-256-CBC')</li>\n\t * <li>ivsalt - IV used for decrypt. Its heading 8 bytes will be used for passcode salt.</li>\n\t * <li>type - asymmetric key algorithm name of private key described in PEM header.</li>\n\t * <li>data - base64 encoded encrypted private key.</li>\n\t * </ul>\n         *\n\t */\n        parsePKCS5PEM: function(sPKCS5PEM) {\n\t    return _parsePKCS5PEM(sPKCS5PEM);\n\t},\n\n\t/**\n         * the same function as OpenSSL EVP_BytsToKey to generate shared key and IV\n\t * @name getKeyAndUnusedIvByPasscodeAndIvsalt\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} algName name of symmetric key algorithm (ex. 'DES-EBE3-CBC')\n\t * @param {String} passcode passcode to decrypt private key (ex. 'password')\n\t * @param {String} hexadecimal string of IV. heading 8 bytes will be used for passcode salt\n\t * @return {Hash} hash of key and unused IV (ex. {keyhex:2fe3..., ivhex:3fad..})\n\t */\n\tgetKeyAndUnusedIvByPasscodeAndIvsalt: function(algName, passcode, ivsaltHex) {\n\t    return _getKeyAndUnusedIvByPasscodeAndIvsalt(algName, passcode, ivsaltHex);\n\t},\n\n        decryptKeyB64: function(privateKeyB64, sharedKeyAlgName, sharedKeyHex, ivsaltHex) {\n\t    return _decryptKeyB64(privateKeyB64, sharedKeyAlgName, sharedKeyHex, ivsaltHex);\n        },\n\n\t/**\n         * decrypt PEM formatted protected PKCS#5 private key with passcode\n\t * @name getDecryptedKeyHex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} sEncryptedPEM PEM formatted protected passcode protected PKCS#5 private key\n\t * @param {String} passcode passcode to decrypt private key (ex. 'password')\n\t * @return {String} hexadecimal string of decrypted RSA priavte key\n\t */\n\tgetDecryptedKeyHex: function(sEncryptedPEM, passcode) {\n\t    // 1. parse pem\n\t    var info = _parsePKCS5PEM(sEncryptedPEM);\n\t    var publicKeyAlgName = info.type;\n\t    var sharedKeyAlgName = info.cipher;\n\t    var ivsaltHex = info.ivsalt;\n\t    var privateKeyB64 = info.data;\n\t    //alert(\"ivsaltHex = \" + ivsaltHex);\n\n\t    // 2. generate shared key\n\t    var sharedKeyInfo = _getKeyAndUnusedIvByPasscodeAndIvsalt(sharedKeyAlgName, passcode, ivsaltHex);\n\t    var sharedKeyHex = sharedKeyInfo.keyhex;\n\t    //alert(\"sharedKeyHex = \" + sharedKeyHex);\n\n\t    // 3. decrypt private key\n            var decryptedKey = _decryptKeyB64(privateKeyB64, sharedKeyAlgName, sharedKeyHex, ivsaltHex);\n\t    return decryptedKey;\n\t},\n\n\t/**\n         * read PEM formatted encrypted PKCS#5 private key and returns RSAKey object\n\t * @name getRSAKeyFromEncryptedPKCS5PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} sEncryptedP5PEM PEM formatted encrypted PKCS#5 private key\n\t * @param {String} passcode passcode to decrypt private key\n\t * @return {RSAKey} loaded RSAKey object of RSA private key\n         * @since pkcs5pkey 1.0.2\n\t */\n\tgetRSAKeyFromEncryptedPKCS5PEM: function(sEncryptedP5PEM, passcode) {\n\t    var hPKey = this.getDecryptedKeyHex(sEncryptedP5PEM, passcode);\n\t    var rsaKey = new RSAKey();\n\t    rsaKey.readPrivateKeyFromASN1HexString(hPKey);\n\t    return rsaKey;\n\t},\n\n\t/**\n         * get PEM formatted encrypted PKCS#5 private key from hexadecimal string of plain private key\n\t * @name getEryptedPKCS5PEMFromPrvKeyHex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} hPrvKey hexadecimal string of plain private key\n\t * @param {String} passcode pass code to protect private key (ex. password)\n\t * @param {String} sharedKeyAlgName algorithm name to protect private key (ex. AES-256-CBC)\n\t * @param {String} ivsaltHex hexadecimal string of IV and salt\n\t * @return {String} string of PEM formatted encrypted PKCS#5 private key\n         * @since pkcs5pkey 1.0.2\n\t * @description\n\t * <br/>\n\t * generate PEM formatted encrypted PKCS#5 private key by hexadecimal string encoded\n\t * ASN.1 object of plain RSA private key.\n\t * Following arguments can be omitted.\n\t * <ul>\n\t * <li>alg - AES-256-CBC will be used if omitted.</li>\n\t * <li>ivsaltHex - automatically generate IV and salt which length depends on algorithm</li>\n\t * </ul>\n\t * @example\n\t * var pem = \n         *   PKCS5PKEY.getEryptedPKCS5PEMFromPrvKeyHex(plainKeyHex, \"password\");\n\t * var pem2 = \n         *   PKCS5PKEY.getEryptedPKCS5PEMFromPrvKeyHex(plainKeyHex, \"password\", \"AES-128-CBC\");\n\t * var pem3 = \n         *   PKCS5PKEY.getEryptedPKCS5PEMFromPrvKeyHex(plainKeyHex, \"password\", \"AES-128-CBC\", \"1f3d02...\");\n\t */\n\tgetEryptedPKCS5PEMFromPrvKeyHex: function(hPrvKey, passcode, sharedKeyAlgName, ivsaltHex) {\n\t    var sPEM = \"\";\n\n\t    // 1. set sharedKeyAlgName if undefined (default AES-256-CBC)\n\t    if (typeof sharedKeyAlgName == \"undefined\" || sharedKeyAlgName == null) {\n\t\tsharedKeyAlgName = \"AES-256-CBC\";\n\t    }\n\t    if (typeof ALGLIST[sharedKeyAlgName] == \"undefined\")\n\t\tthrow \"PKCS5PKEY unsupported algorithm: \" + sharedKeyAlgName;\n\n\t    // 2. set ivsaltHex if undefined\n\t    if (typeof ivsaltHex == \"undefined\" || ivsaltHex == null) {\n\t\tvar ivlen = ALGLIST[sharedKeyAlgName]['ivlen'];\n\t\tvar randIV = _generateIvSaltHex(ivlen);\n\t\tivsaltHex = randIV.toUpperCase();\n\t    }\n\n\t    // 3. get shared key\n            //alert(\"ivsalthex=\" + ivsaltHex);\n\t    var sharedKeyInfo = _getKeyAndUnusedIvByPasscodeAndIvsalt(sharedKeyAlgName, passcode, ivsaltHex);\n\t    var sharedKeyHex = sharedKeyInfo.keyhex;\n\t    // alert(\"sharedKeyHex = \" + sharedKeyHex);\n\n            // 3. get encrypted Key in Base64\n            var encryptedKeyB64 = _encryptKeyHex(hPrvKey, sharedKeyAlgName, sharedKeyHex, ivsaltHex);\n\n\t    var pemBody = encryptedKeyB64.replace(/(.{64})/g, \"$1\\r\\n\");\n\t    var sPEM = \"-----BEGIN RSA PRIVATE KEY-----\\r\\n\";\n\t    sPEM += \"Proc-Type: 4,ENCRYPTED\\r\\n\";\n\t    sPEM += \"DEK-Info: \" + sharedKeyAlgName + \",\" + ivsaltHex + \"\\r\\n\";\n\t    sPEM += \"\\r\\n\";\n\t    sPEM += pemBody;\n\t    sPEM += \"\\r\\n-----END RSA PRIVATE KEY-----\\r\\n\";\n\n\t    return sPEM;\n        },\n\n\t/**\n         * get PEM formatted encrypted PKCS#5 private key from RSAKey object of private key\n\t * @name getEryptedPKCS5PEMFromRSAKey\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {RSAKey} pKey RSAKey object of private key\n\t * @param {String} passcode pass code to protect private key (ex. password)\n\t * @param {String} alg algorithm name to protect private key (default AES-256-CBC)\n\t * @param {String} ivsaltHex hexadecimal string of IV and salt (default generated random IV)\n\t * @return {String} string of PEM formatted encrypted PKCS#5 private key\n         * @since pkcs5pkey 1.0.2\n\t * @description\n\t * <br/>\n\t * generate PEM formatted encrypted PKCS#5 private key by\n\t * {@link RSAKey} object of RSA private key and passcode.\n\t * Following argument can be omitted.\n\t * <ul>\n\t * <li>alg - AES-256-CBC will be used if omitted.</li>\n\t * <li>ivsaltHex - automatically generate IV and salt which length depends on algorithm</li>\n\t * </ul>\n\t * @example\n\t * var pkey = new RSAKey();\n\t * pkey.generate(1024, '10001'); // generate 1024bit RSA private key with public exponent 'x010001'\n\t * var pem = PKCS5PKEY.getEryptedPKCS5PEMFromRSAKey(pkey, \"password\");\n\t */\n        getEryptedPKCS5PEMFromRSAKey: function(pKey, passcode, alg, ivsaltHex) {\n\t    var version = new KJUR.asn1.DERInteger({'int': 0});\n\t    var n = new KJUR.asn1.DERInteger({'bigint': pKey.n});\n\t    var e = new KJUR.asn1.DERInteger({'int': pKey.e});\n\t    var d = new KJUR.asn1.DERInteger({'bigint': pKey.d});\n\t    var p = new KJUR.asn1.DERInteger({'bigint': pKey.p});\n\t    var q = new KJUR.asn1.DERInteger({'bigint': pKey.q});\n\t    var dmp1 = new KJUR.asn1.DERInteger({'bigint': pKey.dmp1});\n\t    var dmq1 = new KJUR.asn1.DERInteger({'bigint': pKey.dmq1});\n\t    var coeff = new KJUR.asn1.DERInteger({'bigint': pKey.coeff});\n\t    var seq = new KJUR.asn1.DERSequence({'array': [version, n, e, d, p, q, dmp1, dmq1, coeff]});\n\t    var hex = seq.getEncodedHex();\n\t    return this.getEryptedPKCS5PEMFromPrvKeyHex(hex, passcode, alg, ivsaltHex);\n        },\n\n\t/**\n         * generate RSAKey and PEM formatted encrypted PKCS#5 private key\n\t * @name newEncryptedPKCS5PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} passcode pass code to protect private key (ex. password)\n\t * @param {Integer} keyLen key bit length of RSA key to be generated. (default 1024)\n\t * @param {String} hPublicExponent hexadecimal string of public exponent (default 10001)\n\t * @param {String} alg shared key algorithm to encrypt private key (default AES-258-CBC)\n\t * @return {String} string of PEM formatted encrypted PKCS#5 private key\n         * @since pkcs5pkey 1.0.2\n\t * @example\n\t * var pem1 = PKCS5PKEY.newEncryptedPKCS5PEM(\"password\");           // RSA1024bit/10001/AES-256-CBC\n\t * var pem2 = PKCS5PKEY.newEncryptedPKCS5PEM(\"password\", 512);      // RSA 512bit/10001/AES-256-CBC\n\t * var pem3 = PKCS5PKEY.newEncryptedPKCS5PEM(\"password\", 512, '3'); // RSA 512bit/    3/AES-256-CBC\n\t */\n\tnewEncryptedPKCS5PEM: function(passcode, keyLen, hPublicExponent, alg) {\n\t    if (typeof keyLen == \"undefined\" || keyLen == null) {\n\t\tkeyLen = 1024;\n\t    }\n\t    if (typeof hPublicExponent == \"undefined\" || hPublicExponent == null) {\n\t\thPublicExponent = '10001';\n\t    }\n\t    var pKey = new RSAKey();\n\t    pKey.generate(keyLen, hPublicExponent);\n\t    var pem = null;\n\t    if (typeof alg == \"undefined\" || alg == null) {\n\t\tpem = this.getEncryptedPKCS5PEMFromRSAKey(pkey, passcode);\n\t    } else {\n\t\tpem = this.getEncryptedPKCS5PEMFromRSAKey(pkey, passcode, alg);\n\t    }\n\t    return pem;\n        },\n\n\t// === PKCS8 ===============================================================\n\n\t/**\n         * read PEM formatted unencrypted PKCS#8 private key and returns RSAKey object\n\t * @name getRSAKeyFromPlainPKCS8PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PEM PEM formatted unencrypted PKCS#8 private key\n\t * @return {RSAKey} loaded RSAKey object of RSA private key\n         * @since pkcs5pkey 1.0.1\n\t */\n        getRSAKeyFromPlainPKCS8PEM: function(pkcs8PEM) {\n            if (pkcs8PEM.match(/ENCRYPTED/))\n                throw \"pem shall be not ENCRYPTED\";\n            var prvKeyHex = this.getHexFromPEM(pkcs8PEM, \"PRIVATE KEY\");\n            var rsaKey = this.getRSAKeyFromPlainPKCS8Hex(prvKeyHex);\n\t    return rsaKey;\n        },\n\n\t/**\n         * provide hexadecimal string of unencrypted PKCS#8 private key and returns RSAKey object\n\t * @name getRSAKeyFromPlainPKCS8Hex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} prvKeyHex hexadecimal string of unencrypted PKCS#8 private key\n\t * @return {RSAKey} loaded RSAKey object of RSA private key\n         * @since pkcs5pkey 1.0.3\n\t */\n        getRSAKeyFromPlainPKCS8Hex: function(prvKeyHex) {\n\t    var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(prvKeyHex, 0);\n\t    if (a1.length != 3)\n\t\tthrow \"outer DERSequence shall have 3 elements: \" + a1.length;\n            var algIdTLV =ASN1HEX.getHexOfTLV_AtObj(prvKeyHex, a1[1]);\n\t    if (algIdTLV != \"300d06092a864886f70d0101010500\") // AlgId rsaEncryption\n\t\tthrow \"PKCS8 AlgorithmIdentifier is not rsaEnc: \" + algIdTLV;\n            var algIdTLV = ASN1HEX.getHexOfTLV_AtObj(prvKeyHex, a1[1]);\n\t    var octetStr = ASN1HEX.getHexOfTLV_AtObj(prvKeyHex, a1[2]);\n\t    var p5KeyHex = ASN1HEX.getHexOfV_AtObj(octetStr, 0);\n            //alert(p5KeyHex);\n\t    var rsaKey = new RSAKey();\n\t    rsaKey.readPrivateKeyFromASN1HexString(p5KeyHex);\n\t    return rsaKey;\n        },\n\n\t/**\n         * generate PBKDF2 key hexstring with specified passcode and information\n\t * @name parseHexOfEncryptedPKCS8\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} passcode passcode to decrypto private key\n\t * @return {Array} info associative array of PKCS#8 parameters\n         * @since pkcs5pkey 1.0.3\n\t * @description\n\t * The associative array which is returned by this method has following properties:\n\t * <ul>\n\t * <li>info.pbkdf2Salt - hexadecimal string of PBKDF2 salt</li>\n\t * <li>info.pkbdf2Iter - iteration count</li>\n\t * <li>info.ciphertext - hexadecimal string of encrypted private key</li>\n\t * <li>info.encryptionSchemeAlg - encryption algorithm name (currently TripleDES only)</li>\n\t * <li>info.encryptionSchemeIV - initial vector for encryption algorithm</li>\n\t * </ul>\n\t * Currently, this method only supports PKCS#5v2.0 with PBES2/PBDKF2 of HmacSHA1 and TripleDES.\n\t * <ul>\n\t * <li>keyDerivationFunc = pkcs5PBKDF2 with HmacSHA1</li>\n\t * <li>encryptionScheme = des-EDE3-CBC(i.e. TripleDES</li>\n\t * </ul>\n\t * @example\n\t * // to convert plain PKCS#5 private key to encrypted PKCS#8 private\n\t * // key with PBKDF2 with TripleDES\n\t * % openssl pkcs8 -in plain_p5.pem -topk8 -v2 -des3 -out encrypted_p8.pem\n\t */\n        parseHexOfEncryptedPKCS8: function(sHEX) {\n            var info = {};\n\t    \n\t    var a0 = ASN1HEX.getPosArrayOfChildren_AtObj(sHEX, 0);\n\t    if (a0.length != 2)\n\t\tthrow \"malformed format: SEQUENCE(0).items != 2: \" + a0.length;\n\n\t    // 1. ciphertext\n\t    info.ciphertext = ASN1HEX.getHexOfV_AtObj(sHEX, a0[1]);\n\n\t    // 2. pkcs5PBES2\n\t    var a0_0 = ASN1HEX.getPosArrayOfChildren_AtObj(sHEX, a0[0]); \n\t    if (a0_0.length != 2)\n\t\tthrow \"malformed format: SEQUENCE(0.0).items != 2: \" + a0_0.length;\n\n\t    // 2.1 check if pkcs5PBES2(1 2 840 113549 1 5 13)\n\t    if (ASN1HEX.getHexOfV_AtObj(sHEX, a0_0[0]) != \"2a864886f70d01050d\")\n\t\tthrow \"this only supports pkcs5PBES2\";\n\n\t    // 2.2 pkcs5PBES2 param\n            var a0_0_1 = ASN1HEX.getPosArrayOfChildren_AtObj(sHEX, a0_0[1]); \n\t    if (a0_0.length != 2)\n\t\tthrow \"malformed format: SEQUENCE(0.0.1).items != 2: \" + a0_0_1.length;\n\n\t    // 2.2.1 encryptionScheme\n\t    var a0_0_1_1 = ASN1HEX.getPosArrayOfChildren_AtObj(sHEX, a0_0_1[1]); \n\t    if (a0_0_1_1.length != 2)\n\t\tthrow \"malformed format: SEQUENCE(0.0.1.1).items != 2: \" + a0_0_1_1.length;\n\t    if (ASN1HEX.getHexOfV_AtObj(sHEX, a0_0_1_1[0]) != \"2a864886f70d0307\")\n\t\tthrow \"this only supports TripleDES\";\n\t    info.encryptionSchemeAlg = \"TripleDES\";\n\n\t    // 2.2.1.1 IV of encryptionScheme\n\t    info.encryptionSchemeIV = ASN1HEX.getHexOfV_AtObj(sHEX, a0_0_1_1[1]);\n\n\t    // 2.2.2 keyDerivationFunc\n\t    var a0_0_1_0 = ASN1HEX.getPosArrayOfChildren_AtObj(sHEX, a0_0_1[0]); \n\t    if (a0_0_1_0.length != 2)\n\t\tthrow \"malformed format: SEQUENCE(0.0.1.0).items != 2: \" + a0_0_1_0.length;\n\t    if (ASN1HEX.getHexOfV_AtObj(sHEX, a0_0_1_0[0]) != \"2a864886f70d01050c\")\n\t\tthrow \"this only supports pkcs5PBKDF2\";\n\n\t    // 2.2.2.1 pkcs5PBKDF2 param\n\t    var a0_0_1_0_1 = ASN1HEX.getPosArrayOfChildren_AtObj(sHEX, a0_0_1_0[1]); \n\t    if (a0_0_1_0_1.length < 2)\n\t\tthrow \"malformed format: SEQUENCE(0.0.1.0.1).items < 2: \" + a0_0_1_0_1.length;\n\n\t    // 2.2.2.1.1 PBKDF2 salt\n\t    info.pbkdf2Salt = ASN1HEX.getHexOfV_AtObj(sHEX, a0_0_1_0_1[0]);\n\n\t    // 2.2.2.1.2 PBKDF2 iter\n\t    var iterNumHex = ASN1HEX.getHexOfV_AtObj(sHEX, a0_0_1_0_1[1]);\n\t    try {\n\t\tinfo.pbkdf2Iter = parseInt(iterNumHex, 16);\n\t    } catch(ex) {\n\t\tthrow \"malformed format pbkdf2Iter: \" + iterNumHex;\n\t    }\n\n\t    return info;\n\t},\n\n\t/**\n         * generate PBKDF2 key hexstring with specified passcode and information\n\t * @name getPBKDF2KeyHexFromParam\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {Array} info result of {@link parseHexOfEncryptedPKCS8} which has preference of PKCS#8 file\n\t * @param {String} passcode passcode to decrypto private key\n\t * @return {String} hexadecimal string of PBKDF2 key\n         * @since pkcs5pkey 1.0.3\n\t * @description\n\t * As for info, this uses following properties:\n\t * <ul>\n\t * <li>info.pbkdf2Salt - hexadecimal string of PBKDF2 salt</li>\n\t * <li>info.pkbdf2Iter - iteration count</li>\n\t * </ul>\n\t * Currently, this method only supports PKCS#5v2.0 with PBES2/PBDKF2 of HmacSHA1 and TripleDES.\n\t * <ul>\n\t * <li>keyDerivationFunc = pkcs5PBKDF2 with HmacSHA1</li>\n\t * <li>encryptionScheme = des-EDE3-CBC(i.e. TripleDES</li>\n\t * </ul>\n\t * @example\n\t * // to convert plain PKCS#5 private key to encrypted PKCS#8 private\n\t * // key with PBKDF2 with TripleDES\n\t * % openssl pkcs8 -in plain_p5.pem -topk8 -v2 -des3 -out encrypted_p8.pem\n\t */\n\tgetPBKDF2KeyHexFromParam: function(info, passcode) {\n\t    var pbkdf2SaltWS = CryptoJS.enc.Hex.parse(info.pbkdf2Salt);\n\t    var pbkdf2Iter = info.pbkdf2Iter;\n\t    var pbkdf2KeyWS = CryptoJS.PBKDF2(passcode, \n\t\t\t\t\t      pbkdf2SaltWS, \n\t\t\t\t\t      { keySize: 192/32, iterations: pbkdf2Iter });\n\t    var pbkdf2KeyHex = CryptoJS.enc.Hex.stringify(pbkdf2KeyWS);\n\t    return pbkdf2KeyHex;\n\t},\n\n\t/**\n         * read PEM formatted encrypted PKCS#8 private key and returns hexadecimal string of plain PKCS#8 private key\n\t * @name getPlainPKCS8HexFromEncryptedPKCS8PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PEM PEM formatted encrypted PKCS#8 private key\n\t * @param {String} passcode passcode to decrypto private key\n\t * @return {String} hexadecimal string of plain PKCS#8 private key\n         * @since pkcs5pkey 1.0.3\n\t * @description\n\t * Currently, this method only supports PKCS#5v2.0 with PBES2/PBDKF2 of HmacSHA1 and TripleDES.\n\t * <ul>\n\t * <li>keyDerivationFunc = pkcs5PBKDF2 with HmacSHA1</li>\n\t * <li>encryptionScheme = des-EDE3-CBC(i.e. TripleDES</li>\n\t * </ul>\n\t * @example\n\t * // to convert plain PKCS#5 private key to encrypted PKCS#8 private\n\t * // key with PBKDF2 with TripleDES\n\t * % openssl pkcs8 -in plain_p5.pem -topk8 -v2 -des3 -out encrypted_p8.pem\n\t */\n\tgetPlainPKCS8HexFromEncryptedPKCS8PEM: function(pkcs8PEM, passcode) {\n\t    // 1. derHex - PKCS#8 private key encrypted by PBKDF2\n            var derHex = this.getHexFromPEM(pkcs8PEM, \"ENCRYPTED PRIVATE KEY\");\n\t    // 2. info - PKCS#5 PBES info\n\t    var info = this.parseHexOfEncryptedPKCS8(derHex);\n\t    // 3. hKey - PBKDF2 key\n\t    var pbkdf2KeyHex = PKCS5PKEY.getPBKDF2KeyHexFromParam(info, passcode);\n\t    // 4. decrypt ciphertext by PBKDF2 key\n\t    var encrypted = {};\n\t    encrypted.ciphertext = CryptoJS.enc.Hex.parse(info.ciphertext);\n\t    var pbkdf2KeyWS = CryptoJS.enc.Hex.parse(pbkdf2KeyHex);\n\t    var des3IVWS = CryptoJS.enc.Hex.parse(info.encryptionSchemeIV);\n\t    var decWS = CryptoJS.TripleDES.decrypt(encrypted, pbkdf2KeyWS, { iv: des3IVWS });\n\t    var decHex = CryptoJS.enc.Hex.stringify(decWS);\n\t    return decHex;\n\t},\n\n\t/**\n         * read PEM formatted encrypted PKCS#8 private key and returns RSAKey object\n\t * @name getRSAKeyFromEncryptedPKCS8PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PEM PEM formatted encrypted PKCS#8 private key\n\t * @param {String} passcode passcode to decrypto private key\n\t * @return {RSAKey} loaded RSAKey object of RSA private key\n         * @since pkcs5pkey 1.0.3\n\t * @description\n\t * Currently, this method only supports PKCS#5v2.0 with PBES2/PBDKF2 of HmacSHA1 and TripleDES.\n\t * <ul>\n\t * <li>keyDerivationFunc = pkcs5PBKDF2 with HmacSHA1</li>\n\t * <li>encryptionScheme = des-EDE3-CBC(i.e. TripleDES</li>\n\t * </ul>\n\t * @example\n\t * // to convert plain PKCS#5 private key to encrypted PKCS#8 private\n\t * // key with PBKDF2 with TripleDES\n\t * % openssl pkcs8 -in plain_p5.pem -topk8 -v2 -des3 -out encrypted_p8.pem\n\t */\n        getRSAKeyFromEncryptedPKCS8PEM: function(pkcs8PEM, passcode) {\n\t    var prvKeyHex = this.getPlainPKCS8HexFromEncryptedPKCS8PEM(pkcs8PEM, passcode);\n\t    var rsaKey = this.getRSAKeyFromPlainPKCS8Hex(prvKeyHex);\n\t    return rsaKey;\n        },\n\n\t/**\n         * get RSAKey/ECDSA private key object from encrypted PEM PKCS#8 private key\n\t * @name getKeyFromEncryptedPKCS8PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PEM string of PEM formatted PKCS#8 private key\n\t * @param {String} passcode passcode string to decrypt key\n\t * @return {Object} RSAKey or KJUR.crypto.ECDSA private key object\n\t * @since pkcs5pkey 1.0.5\n\t */\n        getKeyFromEncryptedPKCS8PEM: function(pkcs8PEM, passcode) {\n\t    var prvKeyHex = this.getPlainPKCS8HexFromEncryptedPKCS8PEM(pkcs8PEM, passcode);\n\t    var key = this.getKeyFromPlainPrivatePKCS8Hex(prvKeyHex);\n\t    return key;\n        },\n\n\t/**\n         * parse hexadecimal string of plain PKCS#8 private key\n\t * @name parsePlainPrivatePKCS8Hex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PrvHex hexadecimal string of PKCS#8 plain private key\n\t * @return {Array} associative array of parsed key\n\t * @since pkcs5pkey 1.0.5\n\t * @description\n\t * Resulted associative array has following properties:\n\t * <ul>\n\t * <li>algoid - hexadecimal string of OID of asymmetric key algorithm</li>\n\t * <li>algparam - hexadecimal string of OID of ECC curve name or null</li>\n\t * <li>keyidx - string starting index of key in pkcs8PrvHex</li>\n\t * </ul>\n\t */\n\tparsePlainPrivatePKCS8Hex: function(pkcs8PrvHex) {\n\t    var result = {};\n\t    result.algparam = null;\n\n\t    // 1. sequence\n\t    if (pkcs8PrvHex.substr(0, 2) != \"30\")\n\t\tthrow \"malformed plain PKCS8 private key(code:001)\"; // not sequence\n\n\t    var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(pkcs8PrvHex, 0);\n\t    if (a1.length != 3)\n\t\tthrow \"malformed plain PKCS8 private key(code:002)\";\n\n\t    // 2. AlgID\n            if (pkcs8PrvHex.substr(a1[1], 2) != \"30\")\n                throw \"malformed PKCS8 private key(code:003)\"; // AlgId not sequence\n\n            var a2 = ASN1HEX.getPosArrayOfChildren_AtObj(pkcs8PrvHex, a1[1]);\n            if (a2.length != 2)\n                throw \"malformed PKCS8 private key(code:004)\"; // AlgId not have two elements\n\n\t    // 2.1. AlgID OID\n\t    if (pkcs8PrvHex.substr(a2[0], 2) != \"06\")\n\t\tthrow \"malformed PKCS8 private key(code:005)\"; // AlgId.oid is not OID\n\n\t    result.algoid = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a2[0]);\n\n\t    // 2.2. AlgID param\n\t    if (pkcs8PrvHex.substr(a2[1], 2) == \"06\") {\n\t\tresult.algparam = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a2[1]);\n\t    }\n\n\t    // 3. Key index\n\t    if (pkcs8PrvHex.substr(a1[2], 2) != \"04\")\n\t\tthrow \"malformed PKCS8 private key(code:006)\"; // not octet string\n\n\t    result.keyidx = ASN1HEX.getStartPosOfV_AtObj(pkcs8PrvHex, a1[2]);\n\n\t    return result;\n        },\n\n\t/**\n         * get RSAKey/ECDSA private key object from PEM plain PEM PKCS#8 private key\n\t * @name getKeyFromPlainPrivatePKCS8PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PEM string of plain PEM formatted PKCS#8 private key\n\t * @return {Object} RSAKey or KJUR.crypto.ECDSA private key object\n\t * @since pkcs5pkey 1.0.5\n\t */\n\tgetKeyFromPlainPrivatePKCS8PEM: function(prvKeyPEM) {\n\t    var prvKeyHex = this.getHexFromPEM(prvKeyPEM, \"PRIVATE KEY\");\n\t    var key = this.getKeyFromPlainPrivatePKCS8Hex(prvKeyHex);\n\t    return key;\n\t},\n\n\t/**\n         * get RSAKey/ECDSA private key object from HEX plain PEM PKCS#8 private key\n\t * @name getKeyFromPlainPrivatePKCS8Hex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} prvKeyHex hexadecimal string of plain PKCS#8 private key\n\t * @return {Object} RSAKey or KJUR.crypto.ECDSA private key object\n\t * @since pkcs5pkey 1.0.5\n\t */\n\tgetKeyFromPlainPrivatePKCS8Hex: function(prvKeyHex) {\n\t    var p8 = this.parsePlainPrivatePKCS8Hex(prvKeyHex);\n\t    \n\t    if (p8.algoid == \"2a864886f70d010101\") { // RSA\n\t\tthis.parsePrivateRawRSAKeyHexAtObj(prvKeyHex, p8);\n\t\tvar k = p8.key;\n\t\tvar key = new RSAKey();\n\t\tkey.setPrivateEx(k.n, k.e, k.d, k.p, k.q, k.dp, k.dq, k.co);\n\t\treturn key;\n\t    } else if (p8.algoid == \"2a8648ce3d0201\") { // ECC\n\t\tthis.parsePrivateRawECKeyHexAtObj(prvKeyHex, p8);\n\t\tif (KJUR.crypto.OID.oidhex2name[p8.algparam] === undefined)\n\t\t    throw \"KJUR.crypto.OID.oidhex2name undefined: \" + p8.algparam;\n\t\tvar curveName = KJUR.crypto.OID.oidhex2name[p8.algparam];\n\t\tvar key = new KJUR.crypto.ECDSA({'curve': curveName, 'prv': p8.key});\n\t\treturn key;\n\t    } else {\n\t\tthrow \"unsupported private key algorithm\";\n\t    }\n\t},\n\n\t// === PKCS8 RSA Public Key ================================================\n\t/**\n         * read PEM formatted PKCS#8 public key and returns RSAKey object\n\t * @name getRSAKeyFromPublicPKCS8PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PubPEM PEM formatted PKCS#8 public key\n\t * @return {RSAKey} loaded RSAKey object of RSA public key\n         * @since pkcs5pkey 1.0.4\n\t */\n        getRSAKeyFromPublicPKCS8PEM: function(pkcs8PubPEM) {\n            var pubKeyHex = this.getHexFromPEM(pkcs8PubPEM, \"PUBLIC KEY\");\n            var rsaKey = this.getRSAKeyFromPublicPKCS8Hex(pubKeyHex);\n\t    return rsaKey;\n\t},\n\n\t/**\n         * get RSAKey/ECDSA public key object from PEM PKCS#8 public key\n\t * @name getKeyFromPublicPKCS8PEM\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcsPub8PEM string of PEM formatted PKCS#8 public key\n\t * @return {Object} RSAKey or KJUR.crypto.ECDSA private key object\n\t * @since pkcs5pkey 1.0.5\n\t */\n        getKeyFromPublicPKCS8PEM: function(pkcs8PubPEM) {\n            var pubKeyHex = this.getHexFromPEM(pkcs8PubPEM, \"PUBLIC KEY\");\n            var key = this.getKeyFromPublicPKCS8Hex(pubKeyHex);\n\t    return key;\n\t},\n\n\t/**\n         * get RSAKey/ECDSA public key object from hexadecimal string of PKCS#8 public key\n\t * @name getKeyFromPublicPKCS8Hex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcsPub8Hex hexadecimal string of PKCS#8 public key\n\t * @return {Object} RSAKey or KJUR.crypto.ECDSA private key object\n\t * @since pkcs5pkey 1.0.5\n\t */\n        getKeyFromPublicPKCS8Hex: function(pkcs8PubHex) {\n\t    var p8 = this.parsePublicPKCS8Hex(pkcs8PubHex);\n\t    \n\t    if (p8.algoid == \"2a864886f70d010101\") { // RSA\n\t\tvar aRSA = this.parsePublicRawRSAKeyHex(p8.key);\n\t\tvar key = new RSAKey();\n\t\tkey.setPublic(aRSA.n, aRSA.e);\n\t\treturn key;\n\t    } else if (p8.algoid == \"2a8648ce3d0201\") { // ECC\n\t\tif (KJUR.crypto.OID.oidhex2name[p8.algparam] === undefined)\n\t\t    throw \"KJUR.crypto.OID.oidhex2name undefined: \" + p8.algparam;\n\t\tvar curveName = KJUR.crypto.OID.oidhex2name[p8.algparam];\n\t\tvar key = new KJUR.crypto.ECDSA({'curve': curveName, 'pub': p8.key});\n\t\treturn key;\n\t    } else {\n\t\tthrow \"unsupported public key algorithm\";\n\t    }\n\t},\n\n\t/**\n         * parse hexadecimal string of plain PKCS#8 private key\n\t * @name parsePublicRawRSAKeyHex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pubRawRSAHex hexadecimal string of ASN.1 encoded PKCS#8 public key\n\t * @return {Array} associative array of parsed key\n\t * @since pkcs5pkey 1.0.5\n\t * @description\n\t * Resulted associative array has following properties:\n\t * <ul>\n\t * <li>n - hexadecimal string of public key\n\t * <li>e - hexadecimal string of public exponent\n\t * </ul>\n\t */\n\tparsePublicRawRSAKeyHex: function(pubRawRSAHex) {\n\t    var result = {};\n\t    \n\t    // 1. Sequence\n\t    if (pubRawRSAHex.substr(0, 2) != \"30\")\n\t\tthrow \"malformed RSA key(code:001)\"; // not sequence\n\t    \n\t    var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(pubRawRSAHex, 0);\n\t    if (a1.length != 2)\n\t\tthrow \"malformed RSA key(code:002)\"; // not 2 items in seq\n\n\t    // 2. public key \"N\"\n\t    if (pubRawRSAHex.substr(a1[0], 2) != \"02\")\n\t\tthrow \"malformed RSA key(code:003)\"; // 1st item is not integer\n\n\t    result.n = ASN1HEX.getHexOfV_AtObj(pubRawRSAHex, a1[0]);\n\n\t    // 3. public key \"E\"\n\t    if (pubRawRSAHex.substr(a1[1], 2) != \"02\")\n\t\tthrow \"malformed RSA key(code:004)\"; // 2nd item is not integer\n\n\t    result.e = ASN1HEX.getHexOfV_AtObj(pubRawRSAHex, a1[1]);\n\n\t    return result;\n\t},\n\n\t/**\n         * parse hexadecimal string of RSA private key\n\t * @name parsePrivateRawRSAKeyHexAtObj\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PrvHex hexadecimal string of PKCS#8 private key concluding RSA private key\n\t * @return {Array} info associative array to add parsed RSA private key information\n\t * @since pkcs5pkey 1.0.5\n\t * @description\n\t * Following properties are added to associative array 'info'\n\t * <ul>\n\t * <li>n - hexadecimal string of public key\n\t * <li>e - hexadecimal string of public exponent\n\t * <li>d - hexadecimal string of private key\n\t * <li>p - hexadecimal string\n\t * <li>q - hexadecimal string\n\t * <li>dp - hexadecimal string\n\t * <li>dq - hexadecimal string\n\t * <li>co - hexadecimal string\n\t * </ul>\n\t */\n\tparsePrivateRawRSAKeyHexAtObj: function(pkcs8PrvHex, info) {\n\t    var keyIdx = info.keyidx;\n\t    \n\t    // 1. sequence\n\t    if (pkcs8PrvHex.substr(keyIdx, 2) != \"30\")\n\t\tthrow \"malformed RSA private key(code:001)\"; // not sequence\n\n\t    var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(pkcs8PrvHex, keyIdx);\n\t    if (a1.length != 9)\n\t\tthrow \"malformed RSA private key(code:002)\"; // not sequence\n\n\t    // 2. RSA key\n\t    info.key = {};\n\t    info.key.n = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[1]);\n\t    info.key.e = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[2]);\n\t    info.key.d = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[3]);\n\t    info.key.p = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[4]);\n\t    info.key.q = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[5]);\n\t    info.key.dp = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[6]);\n\t    info.key.dq = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[7]);\n\t    info.key.co = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[8]);\n\t},\n\n\t/**\n         * parse hexadecimal string of ECC private key\n\t * @name parsePrivateRawECKeyHexAtObj\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PrvHex hexadecimal string of PKCS#8 private key concluding EC private key\n\t * @return {Array} info associative array to add parsed ECC private key information\n\t * @since pkcs5pkey 1.0.5\n\t * @description\n\t * Following properties are added to associative array 'info'\n\t * <ul>\n\t * <li>key - hexadecimal string of ECC private key\n\t * </ul>\n\t */\n\tparsePrivateRawECKeyHexAtObj: function(pkcs8PrvHex, info) {\n\t    var keyIdx = info.keyidx;\n\t    \n\t    // 1. sequence\n\t    if (pkcs8PrvHex.substr(keyIdx, 2) != \"30\")\n\t\tthrow \"malformed ECC private key(code:001)\"; // not sequence\n\n\t    var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(pkcs8PrvHex, keyIdx);\n\t    if (a1.length != 3)\n\t\tthrow \"malformed ECC private key(code:002)\"; // not sequence\n\n\t    // 2. EC private key\n\t    if (pkcs8PrvHex.substr(a1[1], 2) != \"04\")\n\t\tthrow \"malformed ECC private key(code:003)\"; // not octetstring\n\n\t    info.key = ASN1HEX.getHexOfV_AtObj(pkcs8PrvHex, a1[1]);\n\t},\n\n\t/**\n         * parse hexadecimal string of PKCS#8 public key\n\t * @name parsePublicPKCS8Hex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PubHex hexadecimal string of PKCS#8 public key\n\t * @return {Hash} hash of key information\n\t * @description\n         * Resulted hash has following attributes.\n\t * <ul>\n\t * <li>algoid - hexadecimal string of OID of asymmetric key algorithm</li>\n\t * <li>algparam - hexadecimal string of OID of ECC curve name or null</li>\n\t * <li>key - hexadecimal string of public key</li>\n\t * </ul>\n\t */\n        parsePublicPKCS8Hex: function(pkcs8PubHex) {\n\t    var result = {};\n\t    result.algparam = null;\n\n            // 1. AlgID and Key bit string\n\t    var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(pkcs8PubHex, 0);\n\t    if (a1.length != 2)\n\t\tthrow \"outer DERSequence shall have 2 elements: \" + a1.length;\n\n            // 2. AlgID\n            var idxAlgIdTLV = a1[0];\n            if (pkcs8PubHex.substr(idxAlgIdTLV, 2) != \"30\")\n                throw \"malformed PKCS8 public key(code:001)\"; // AlgId not sequence\n\n            var a2 = ASN1HEX.getPosArrayOfChildren_AtObj(pkcs8PubHex, idxAlgIdTLV);\n            if (a2.length != 2)\n                throw \"malformed PKCS8 public key(code:002)\"; // AlgId not have two elements\n\n\t    // 2.1. AlgID OID\n\t    if (pkcs8PubHex.substr(a2[0], 2) != \"06\")\n\t\tthrow \"malformed PKCS8 public key(code:003)\"; // AlgId.oid is not OID\n\n\t    result.algoid = ASN1HEX.getHexOfV_AtObj(pkcs8PubHex, a2[0]);\n\n\t    // 2.2. AlgID param\n\t    if (pkcs8PubHex.substr(a2[1], 2) == \"06\") {\n\t\tresult.algparam = ASN1HEX.getHexOfV_AtObj(pkcs8PubHex, a2[1]);\n\t    }\n\n\t    // 3. Key\n\t    if (pkcs8PubHex.substr(a1[1], 2) != \"03\")\n\t\tthrow \"malformed PKCS8 public key(code:004)\"; // Key is not bit string\n\n\t    result.key = ASN1HEX.getHexOfV_AtObj(pkcs8PubHex, a1[1]).substr(2);\n            \n\t    // 4. return result assoc array\n\t    return result;\n        },\n\n\t/**\n         * provide hexadecimal string of unencrypted PKCS#8 private key and returns RSAKey object\n\t * @name getRSAKeyFromPublicPKCS8Hex\n\t * @memberOf PKCS5PKEY\n\t * @function\n\t * @param {String} pkcs8PubHex hexadecimal string of unencrypted PKCS#8 public key\n\t * @return {RSAKey} loaded RSAKey object of RSA public key\n         * @since pkcs5pkey 1.0.4\n\t */\n        getRSAKeyFromPublicPKCS8Hex: function(pkcs8PubHex) {\n\t    var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(pkcs8PubHex, 0);\n\t    if (a1.length != 2)\n\t\tthrow \"outer DERSequence shall have 2 elements: \" + a1.length;\n\n            var algIdTLV =ASN1HEX.getHexOfTLV_AtObj(pkcs8PubHex, a1[0]);\n\t    if (algIdTLV != \"300d06092a864886f70d0101010500\") // AlgId rsaEncryption\n\t\tthrow \"PKCS8 AlgorithmId is not rsaEncryption\";\n\t    \n\t    if (pkcs8PubHex.substr(a1[1], 2) != \"03\")\n\t\tthrow \"PKCS8 Public Key is not BITSTRING encapslated.\";\n\n\t    var idxPub = ASN1HEX.getStartPosOfV_AtObj(pkcs8PubHex, a1[1]) + 2; // 2 for unused bit\n\t    \n\t    if (pkcs8PubHex.substr(idxPub, 2) != \"30\")\n\t\tthrow \"PKCS8 Public Key is not SEQUENCE.\";\n\n\t    var a2 = ASN1HEX.getPosArrayOfChildren_AtObj(pkcs8PubHex, idxPub);\n\t    if (a2.length != 2)\n\t\tthrow \"inner DERSequence shall have 2 elements: \" + a2.length;\n\n\t    if (pkcs8PubHex.substr(a2[0], 2) != \"02\") \n\t\tthrow \"N is not ASN.1 INTEGER\";\n\t    if (pkcs8PubHex.substr(a2[1], 2) != \"02\") \n\t\tthrow \"E is not ASN.1 INTEGER\";\n\t\t\n\t    var hN = ASN1HEX.getHexOfV_AtObj(pkcs8PubHex, a2[0]);\n\t    var hE = ASN1HEX.getHexOfV_AtObj(pkcs8PubHex, a2[1]);\n\n\t    var pubKey = new RSAKey();\n\t    pubKey.setPublic(hN, hE);\n\t    \n\t    return pubKey;\n\t},\n\n\t//addAlgorithm: function(functionObject, algName, keyLen, ivLen) {\n\t//}\n    };\n}();\n"
  },
  {
    "path": "JavaScript/sm2/js/prng4.js",
    "content": "/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\n// prng4.js - uses Arcfour as a PRNG\n\nfunction Arcfour() {\n  this.i = 0;\n  this.j = 0;\n  this.S = new Array();\n}\n\n// Initialize arcfour context from key, an array of ints, each from [0..255]\nfunction ARC4init(key) {\n  var i, j, t;\n  for(i = 0; i < 256; ++i)\n    this.S[i] = i;\n  j = 0;\n  for(i = 0; i < 256; ++i) {\n    j = (j + this.S[i] + key[i % key.length]) & 255;\n    t = this.S[i];\n    this.S[i] = this.S[j];\n    this.S[j] = t;\n  }\n  this.i = 0;\n  this.j = 0;\n}\n\nfunction ARC4next() {\n  var t;\n  this.i = (this.i + 1) & 255;\n  this.j = (this.j + this.S[this.i]) & 255;\n  t = this.S[this.i];\n  this.S[this.i] = this.S[this.j];\n  this.S[this.j] = t;\n  return this.S[(t + this.S[this.i]) & 255];\n}\n\nArcfour.prototype.init = ARC4init;\nArcfour.prototype.next = ARC4next;\n\n// Plug in your RNG constructor here\nfunction prng_newstate() {\n  return new Arcfour();\n}\n\n// Pool size must be a multiple of 4 and greater than 32.\n// An array of bytes the size of the pool will be passed to init()\nvar rng_psize = 256;\n"
  },
  {
    "path": "JavaScript/sm2/js/rng.js",
    "content": "/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\n// Random number generator - requires a PRNG backend, e.g. prng4.js\n\n// For best results, put code like\n// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>\n// in your main HTML document.\n\nvar rng_state;\nvar rng_pool;\nvar rng_pptr;\n\n// Mix in a 32-bit integer into the pool\nfunction rng_seed_int(x) {\n  rng_pool[rng_pptr++] ^= x & 255;\n  rng_pool[rng_pptr++] ^= (x >> 8) & 255;\n  rng_pool[rng_pptr++] ^= (x >> 16) & 255;\n  rng_pool[rng_pptr++] ^= (x >> 24) & 255;\n  if(rng_pptr >= rng_psize) rng_pptr -= rng_psize;\n}\n\n// Mix in the current time (w/milliseconds) into the pool\nfunction rng_seed_time() {\n  rng_seed_int(new Date().getTime());\n}\n\n// Initialize the pool with junk if needed.\nif(rng_pool == null) {\n  rng_pool = new Array();\n  rng_pptr = 0;\n  var t;\n  if(navigator.appName == \"Netscape\" && navigator.appVersion < \"5\" && window.crypto) {\n    // Extract entropy (256 bits) from NS4 RNG if available\n    var z = window.crypto.random(32);\n    for(t = 0; t < z.length; ++t)\n      rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;\n  }  \n  while(rng_pptr < rng_psize) {  // extract some randomness from Math.random()\n    t = Math.floor(65536 * Math.random());\n    rng_pool[rng_pptr++] = t >>> 8;\n    rng_pool[rng_pptr++] = t & 255;\n  }\n  rng_pptr = 0;\n  rng_seed_time();\n  //rng_seed_int(window.screenX);\n  //rng_seed_int(window.screenY);\n}\n\nfunction rng_get_byte() {\n  if(rng_state == null) {\n    rng_seed_time();\n    rng_state = prng_newstate();\n    rng_state.init(rng_pool);\n    for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)\n      rng_pool[rng_pptr] = 0;\n    rng_pptr = 0;\n    //rng_pool = null;\n  }\n  // TODO: allow reseeding after first request\n  return rng_state.next();\n}\n\nfunction rng_get_bytes(ba) {\n  var i;\n  for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();\n}\n\nfunction SecureRandom() {}\n\nSecureRandom.prototype.nextBytes = rng_get_bytes;\n"
  },
  {
    "path": "JavaScript/sm2/js/rsa.js",
    "content": "/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\n// Depends on jsbn.js and rng.js\n\n// Version 1.1: support utf-8 encoding in pkcs1pad2\n\n// convert a (hex) string to a bignum object\nfunction parseBigInt(str,r) {\n  return new BigInteger(str,r);\n}\n\nfunction linebrk(s,n) {\n  var ret = \"\";\n  var i = 0;\n  while(i + n < s.length) {\n    ret += s.substring(i,i+n) + \"\\n\";\n    i += n;\n  }\n  return ret + s.substring(i,s.length);\n}\n\nfunction byte2Hex(b) {\n  if(b < 0x10)\n    return \"0\" + b.toString(16);\n  else\n    return b.toString(16);\n}\n\n// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint\nfunction pkcs1pad2(s,n) {\n  if(n < s.length + 11) { // TODO: fix for utf-8\n    alert(\"Message too long for RSA\");\n    return null;\n  }\n  var ba = new Array();\n  var i = s.length - 1;\n  while(i >= 0 && n > 0) {\n    var c = s.charCodeAt(i--);\n    if(c < 128) { // encode using utf-8\n      ba[--n] = c;\n    }\n    else if((c > 127) && (c < 2048)) {\n      ba[--n] = (c & 63) | 128;\n      ba[--n] = (c >> 6) | 192;\n    }\n    else {\n      ba[--n] = (c & 63) | 128;\n      ba[--n] = ((c >> 6) & 63) | 128;\n      ba[--n] = (c >> 12) | 224;\n    }\n  }\n  ba[--n] = 0;\n  var rng = new SecureRandom();\n  var x = new Array();\n  while(n > 2) { // random non-zero pad\n    x[0] = 0;\n    while(x[0] == 0) rng.nextBytes(x);\n    ba[--n] = x[0];\n  }\n  ba[--n] = 2;\n  ba[--n] = 0;\n  return new BigInteger(ba);\n}\n\n// PKCS#1 (OAEP) mask generation function\nfunction oaep_mgf1_arr(seed, len, hash)\n{\n    var mask = '', i = 0;\n\n    while (mask.length < len)\n    {\n        mask += hash(String.fromCharCode.apply(String, seed.concat([\n                (i & 0xff000000) >> 24,\n                (i & 0x00ff0000) >> 16,\n                (i & 0x0000ff00) >> 8,\n                i & 0x000000ff])));\n        i += 1;\n    }\n\n    return mask;\n}\n\nvar SHA1_SIZE = 20;\n\n// PKCS#1 (OAEP) pad input string s to n bytes, and return a bigint\nfunction oaep_pad(s, n, hash)\n{\n    if (s.length + 2 * SHA1_SIZE + 2 > n)\n    {\n        throw \"Message too long for RSA\";\n    }\n\n    var PS = '', i;\n\n    for (i = 0; i < n - s.length - 2 * SHA1_SIZE - 2; i += 1)\n    {\n        PS += '\\x00';\n    }\n\n    var DB = rstr_sha1('') + PS + '\\x01' + s;\n    var seed = new Array(SHA1_SIZE);\n    new SecureRandom().nextBytes(seed);\n    \n    var dbMask = oaep_mgf1_arr(seed, DB.length, hash || rstr_sha1);\n    var maskedDB = [];\n\n    for (i = 0; i < DB.length; i += 1)\n    {\n        maskedDB[i] = DB.charCodeAt(i) ^ dbMask.charCodeAt(i);\n    }\n\n    var seedMask = oaep_mgf1_arr(maskedDB, seed.length, rstr_sha1);\n    var maskedSeed = [0];\n\n    for (i = 0; i < seed.length; i += 1)\n    {\n        maskedSeed[i + 1] = seed[i] ^ seedMask.charCodeAt(i);\n    }\n\n    return new BigInteger(maskedSeed.concat(maskedDB));\n}\n\n// \"empty\" RSA key constructor\nfunction RSAKey() {\n  this.n = null;\n  this.e = 0;\n  this.d = null;\n  this.p = null;\n  this.q = null;\n  this.dmp1 = null;\n  this.dmq1 = null;\n  this.coeff = null;\n}\n\n// Set the public key fields N and e from hex strings\nfunction RSASetPublic(N,E) {\n  this.isPublic = true;\n  if (typeof N !== \"string\") \n  {\n    this.n = N;\n    this.e = E;\n  }\n  else if(N != null && E != null && N.length > 0 && E.length > 0) {\n    this.n = parseBigInt(N,16);\n    this.e = parseInt(E,16);\n  }\n  else\n    alert(\"Invalid RSA public key\");\n}\n\n// Perform raw public operation on \"x\": return x^e (mod n)\nfunction RSADoPublic(x) {\n  return x.modPowInt(this.e, this.n);\n}\n\n// Return the PKCS#1 RSA encryption of \"text\" as an even-length hex string\nfunction RSAEncrypt(text) {\n  var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);\n  if(m == null) return null;\n  var c = this.doPublic(m);\n  if(c == null) return null;\n  var h = c.toString(16);\n  if((h.length & 1) == 0) return h; else return \"0\" + h;\n}\n\n// Return the PKCS#1 OAEP RSA encryption of \"text\" as an even-length hex string\nfunction RSAEncryptOAEP(text, hash) {\n  var m = oaep_pad(text, (this.n.bitLength()+7)>>3, hash);\n  if(m == null) return null;\n  var c = this.doPublic(m);\n  if(c == null) return null;\n  var h = c.toString(16);\n  if((h.length & 1) == 0) return h; else return \"0\" + h;\n}\n\n// Return the PKCS#1 RSA encryption of \"text\" as a Base64-encoded string\n//function RSAEncryptB64(text) {\n//  var h = this.encrypt(text);\n//  if(h) return hex2b64(h); else return null;\n//}\n\n// protected\nRSAKey.prototype.doPublic = RSADoPublic;\n\n// public\nRSAKey.prototype.setPublic = RSASetPublic;\nRSAKey.prototype.encrypt = RSAEncrypt;\nRSAKey.prototype.encryptOAEP = RSAEncryptOAEP;\n//RSAKey.prototype.encrypt_b64 = RSAEncryptB64;\n\nRSAKey.prototype.type = \"RSA\";\n"
  },
  {
    "path": "JavaScript/sm2/js/rsa2.js",
    "content": "/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\n// Depends on rsa.js and jsbn2.js\n\n// Version 1.1: support utf-8 decoding in pkcs1unpad2\n\n// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext\nfunction pkcs1unpad2(d,n) {\n  var b = d.toByteArray();\n  var i = 0;\n  while(i < b.length && b[i] == 0) ++i;\n  if(b.length-i != n-1 || b[i] != 2)\n    return null;\n  ++i;\n  while(b[i] != 0)\n    if(++i >= b.length) return null;\n  var ret = \"\";\n  while(++i < b.length) {\n    var c = b[i] & 255;\n    if(c < 128) { // utf-8 decode\n      ret += String.fromCharCode(c);\n    }\n    else if((c > 191) && (c < 224)) {\n      ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63));\n      ++i;\n    }\n    else {\n      ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63));\n      i += 2;\n    }\n  }\n  return ret;\n}\n\n// PKCS#1 (OAEP) mask generation function\nfunction oaep_mgf1_str(seed, len, hash)\n{\n    var mask = '', i = 0;\n\n    while (mask.length < len)\n    {\n        mask += hash(seed + String.fromCharCode.apply(String, [\n                (i & 0xff000000) >> 24,\n                (i & 0x00ff0000) >> 16,\n                (i & 0x0000ff00) >> 8,\n                i & 0x000000ff]));\n        i += 1;\n    }\n\n    return mask;\n}\n\nvar SHA1_SIZE = 20;\n\n// Undo PKCS#1 (OAEP) padding and, if valid, return the plaintext\nfunction oaep_unpad(d, n, hash)\n{\n    d = d.toByteArray();\n\n    var i;\n\n    for (i = 0; i < d.length; i += 1)\n    {\n        d[i] &= 0xff;\n    }\n\n    while (d.length < n)\n    {\n        d.unshift(0);\n    }\n\n    d = String.fromCharCode.apply(String, d);\n\n    if (d.length < 2 * SHA1_SIZE + 2)\n    {\n        throw \"Cipher too short\";\n    }\n\n    var maskedSeed = d.substr(1, SHA1_SIZE)\n    var maskedDB = d.substr(SHA1_SIZE + 1);\n\n    var seedMask = oaep_mgf1_str(maskedDB, SHA1_SIZE, hash || rstr_sha1);\n    var seed = [], i;\n\n    for (i = 0; i < maskedSeed.length; i += 1)\n    {\n        seed[i] = maskedSeed.charCodeAt(i) ^ seedMask.charCodeAt(i);\n    }\n\n    var dbMask = oaep_mgf1_str(String.fromCharCode.apply(String, seed),\n                           d.length - SHA1_SIZE, rstr_sha1);\n\n    var DB = [];\n\n    for (i = 0; i < maskedDB.length; i += 1)\n    {\n        DB[i] = maskedDB.charCodeAt(i) ^ dbMask.charCodeAt(i);\n    }\n\n    DB = String.fromCharCode.apply(String, DB);\n\n    if (DB.substr(0, SHA1_SIZE) !== rstr_sha1(''))\n    {\n        throw \"Hash mismatch\";\n    }\n\n    DB = DB.substr(SHA1_SIZE);\n\n    var first_one = DB.indexOf('\\x01');\n    var last_zero = (first_one != -1) ? DB.substr(0, first_one).lastIndexOf('\\x00') : -1;\n\n    if (last_zero + 1 != first_one)\n    {\n        throw \"Malformed data\";\n    }\n\n    return DB.substr(first_one + 1);\n}\n\n// Set the private key fields N, e, and d from hex strings\nfunction RSASetPrivate(N,E,D) {\n  this.isPrivate = true;\n  if (typeof N !== \"string\")\n  {\n    this.n = N;\n    this.e = E;\n    this.d = D;\n  }\n  else if(N != null && E != null && N.length > 0 && E.length > 0) {\n    this.n = parseBigInt(N,16);\n    this.e = parseInt(E,16);\n    this.d = parseBigInt(D,16);\n  }\n  else\n    alert(\"Invalid RSA private key\");\n}\n\n// Set the private key fields N, e, d and CRT params from hex strings\nfunction RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) {\n  this.isPrivate = true;\n  if (N == null) throw \"RSASetPrivateEx N == null\";\n  if (E == null) throw \"RSASetPrivateEx E == null\";\n  if (N.length == 0) throw \"RSASetPrivateEx N.length == 0\";\n  if (E.length == 0) throw \"RSASetPrivateEx E.length == 0\";\n\n  if (N != null && E != null && N.length > 0 && E.length > 0) {\n    this.n = parseBigInt(N,16);\n    this.e = parseInt(E,16);\n    this.d = parseBigInt(D,16);\n    this.p = parseBigInt(P,16);\n    this.q = parseBigInt(Q,16);\n    this.dmp1 = parseBigInt(DP,16);\n    this.dmq1 = parseBigInt(DQ,16);\n    this.coeff = parseBigInt(C,16);\n  } else {\n    alert(\"Invalid RSA private key in RSASetPrivateEx\");\n  }\n}\n\n// Generate a new random private key B bits long, using public expt E\nfunction RSAGenerate(B,E) {\n  var rng = new SecureRandom();\n  var qs = B>>1;\n  this.e = parseInt(E,16);\n  var ee = new BigInteger(E,16);\n  for(;;) {\n    for(;;) {\n      this.p = new BigInteger(B-qs,1,rng);\n      if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break;\n    }\n    for(;;) {\n      this.q = new BigInteger(qs,1,rng);\n      if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break;\n    }\n    if(this.p.compareTo(this.q) <= 0) {\n      var t = this.p;\n      this.p = this.q;\n      this.q = t;\n    }\n    var p1 = this.p.subtract(BigInteger.ONE);\t// p1 = p - 1\n    var q1 = this.q.subtract(BigInteger.ONE);\t// q1 = q - 1\n    var phi = p1.multiply(q1);\n    if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {\n      this.n = this.p.multiply(this.q);\t// this.n = p * q\n      this.d = ee.modInverse(phi);\t// this.d = \n      this.dmp1 = this.d.mod(p1);\t// this.dmp1 = d mod (p - 1)\n      this.dmq1 = this.d.mod(q1);\t// this.dmq1 = d mod (q - 1)\n      this.coeff = this.q.modInverse(this.p);\t// this.coeff = (q ^ -1) mod p\n      break;\n    }\n  }\n}\n\n// Perform raw private operation on \"x\": return x^d (mod n)\nfunction RSADoPrivate(x) {\n  if(this.p == null || this.q == null)\n    return x.modPow(this.d, this.n);\n\n  // TODO: re-calculate any missing CRT params\n  var xp = x.mod(this.p).modPow(this.dmp1, this.p); // xp=cp?\n  var xq = x.mod(this.q).modPow(this.dmq1, this.q); // xq=cq?\n\n  while(xp.compareTo(xq) < 0)\n    xp = xp.add(this.p);\n  // NOTE:\n  // xp.subtract(xq) => cp -cq\n  // xp.subtract(xq).multiply(this.coeff).mod(this.p) => (cp - cq) * u mod p = h\n  // xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq) => cq + (h * q) = M\n  return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);\n}\n\n// Return the PKCS#1 RSA decryption of \"ctext\".\n// \"ctext\" is an even-length hex string and the output is a plain string.\nfunction RSADecrypt(ctext) {\n  var c = parseBigInt(ctext, 16);\n  var m = this.doPrivate(c);\n  if(m == null) return null;\n  return pkcs1unpad2(m, (this.n.bitLength()+7)>>3);\n}\n\n// Return the PKCS#1 OAEP RSA decryption of \"ctext\".\n// \"ctext\" is an even-length hex string and the output is a plain string.\nfunction RSADecryptOAEP(ctext, hash) {\n  var c = parseBigInt(ctext, 16);\n  var m = this.doPrivate(c);\n  if(m == null) return null;\n  return oaep_unpad(m, (this.n.bitLength()+7)>>3, hash);\n}\n\n// Return the PKCS#1 RSA decryption of \"ctext\".\n// \"ctext\" is a Base64-encoded string and the output is a plain string.\n//function RSAB64Decrypt(ctext) {\n//  var h = b64tohex(ctext);\n//  if(h) return this.decrypt(h); else return null;\n//}\n\n// protected\nRSAKey.prototype.doPrivate = RSADoPrivate;\n\n// public\nRSAKey.prototype.setPrivate = RSASetPrivate;\nRSAKey.prototype.setPrivateEx = RSASetPrivateEx;\nRSAKey.prototype.generate = RSAGenerate;\nRSAKey.prototype.decrypt = RSADecrypt;\nRSAKey.prototype.decryptOAEP = RSADecryptOAEP;\n//RSAKey.prototype.b64_decrypt = RSAB64Decrypt;\n"
  },
  {
    "path": "JavaScript/sm2/js/rsapem-1.1.js",
    "content": "/*! rsapem-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n//\n// rsa-pem.js - adding function for reading/writing PKCS#1 PEM private key\n//              to RSAKey class.\n//\n// version: 1.1.1 (2013-Apr-12)\n//\n// Copyright (c) 2010-2013 Kenji Urushima (kenji.urushima@gmail.com)\n//\n// This software is licensed under the terms of the MIT License.\n// http://kjur.github.com/jsrsasign/license/\n//\n// The above copyright and license notice shall be \n// included in all copies or substantial portions of the Software.\n// \n//\n// Depends on:\n//\n//\n//\n// _RSApem_pemToBase64(sPEM)\n//\n//   removing PEM header, PEM footer and space characters including\n//   new lines from PEM formatted RSA private key string.\n//\n\n/**\n * @fileOverview\n * @name rsapem-1.1.js\n * @author Kenji Urushima kenji.urushima@gmail.com\n * @version 1.1\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\n */\nfunction _rsapem_pemToBase64(sPEMPrivateKey) {\n  var s = sPEMPrivateKey;\n  s = s.replace(\"-----BEGIN RSA PRIVATE KEY-----\", \"\");\n  s = s.replace(\"-----END RSA PRIVATE KEY-----\", \"\");\n  s = s.replace(/[ \\n]+/g, \"\");\n  return s;\n}\n\nfunction _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey) {\n  var a = new Array();\n  var v1 = ASN1HEX.getStartPosOfV_AtObj(hPrivateKey, 0);\n  var n1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, v1);\n  var e1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, n1);\n  var d1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, e1);\n  var p1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, d1);\n  var q1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, p1);\n  var dp1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, q1);\n  var dq1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, dp1);\n  var co1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, dq1);\n  a.push(v1, n1, e1, d1, p1, q1, dp1, dq1, co1);\n  return a;\n}\n\nfunction _rsapem_getHexValueArrayOfChildrenFromHex(hPrivateKey) {\n  var posArray = _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey);\n  var v =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[0]);\n  var n =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[1]);\n  var e =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[2]);\n  var d =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[3]);\n  var p =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[4]);\n  var q =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[5]);\n  var dp = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[6]);\n  var dq = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[7]);\n  var co = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[8]);\n  var a = new Array();\n  a.push(v, n, e, d, p, q, dp, dq, co);\n  return a;\n}\n\n/**\n * read RSA private key from a ASN.1 hexadecimal string\n * @name readPrivateKeyFromASN1HexString\n * @memberOf RSAKey#\n * @function\n * @param {String} keyHex ASN.1 hexadecimal string of PKCS#1 private key.\n * @since 1.1.1\n */\nfunction _rsapem_readPrivateKeyFromASN1HexString(keyHex) {\n  var a = _rsapem_getHexValueArrayOfChildrenFromHex(keyHex);\n  this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]);\n}\n\n/**\n * read PKCS#1 private key from a string\n * @name readPrivateKeyFromPEMString\n * @memberOf RSAKey#\n * @function\n * @param {String} keyPEM string of PKCS#1 private key.\n */\nfunction _rsapem_readPrivateKeyFromPEMString(keyPEM) {\n  var keyB64 = _rsapem_pemToBase64(keyPEM);\n  var keyHex = b64tohex(keyB64) // depends base64.js\n  var a = _rsapem_getHexValueArrayOfChildrenFromHex(keyHex);\n  this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]);\n}\n\nRSAKey.prototype.readPrivateKeyFromPEMString = _rsapem_readPrivateKeyFromPEMString;\nRSAKey.prototype.readPrivateKeyFromASN1HexString = _rsapem_readPrivateKeyFromASN1HexString;\n"
  },
  {
    "path": "JavaScript/sm2/js/rsasign-1.2.js",
    "content": "/*! rsasign-1.2.7.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n/*\n * rsa-sign.js - adding signing functions to RSAKey class.\n *\n * version: 1.2.7 (2013 Aug 25)\n *\n * Copyright (c) 2010-2013 Kenji Urushima (kenji.urushima@gmail.com)\n *\n * This software is licensed under the terms of the MIT License.\n * http://kjur.github.com/jsrsasign/license/\n *\n * The above copyright and license notice shall be \n * included in all copies or substantial portions of the Software.\n */\n\n/**\n * @fileOverview\n * @name rsasign-1.2.js\n * @author Kenji Urushima kenji.urushima@gmail.com\n * @version rsasign 1.2.7\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\n */\n\nvar _RE_HEXDECONLY = new RegExp(\"\");\n_RE_HEXDECONLY.compile(\"[^0-9a-f]\", \"gi\");\n\n// ========================================================================\n// Signature Generation\n// ========================================================================\n\nfunction _rsasign_getHexPaddedDigestInfoForString(s, keySize, hashAlg) {\n    var hashFunc = function(s) { return KJUR.crypto.Util.hashString(s, hashAlg); };\n    var sHashHex = hashFunc(s);\n\n    return KJUR.crypto.Util.getPaddedDigestInfoHex(sHashHex, hashAlg, keySize);\n}\n\nfunction _zeroPaddingOfSignature(hex, bitLength) {\n    var s = \"\";\n    var nZero = bitLength / 4 - hex.length;\n    for (var i = 0; i < nZero; i++) {\n\ts = s + \"0\";\n    }\n    return s + hex;\n}\n\n/**\n * sign for a message string with RSA private key.<br/>\n * @name signString\n * @memberOf RSAKey\n * @function\n * @param {String} s message string to be signed.\n * @param {String} hashAlg hash algorithm name for signing.<br/>\n * @return returns hexadecimal string of signature value.\n */\nfunction _rsasign_signString(s, hashAlg) {\n    var hashFunc = function(s) { return KJUR.crypto.Util.hashString(s, hashAlg); };\n    var sHashHex = hashFunc(s);\n\n    return this.signWithMessageHash(sHashHex, hashAlg);\n}\n\n/**\n * sign hash value of message to be signed with RSA private key.<br/>\n * @name signWithMessageHash\n * @memberOf RSAKey\n * @function\n * @param {String} sHashHex hexadecimal string of hash value of message to be signed.\n * @param {String} hashAlg hash algorithm name for signing.<br/>\n * @return returns hexadecimal string of signature value.\n * @since rsasign 1.2.6\n */\nfunction _rsasign_signWithMessageHash(sHashHex, hashAlg) {\n    var hPM = KJUR.crypto.Util.getPaddedDigestInfoHex(sHashHex, hashAlg, this.n.bitLength());\n    var biPaddedMessage = parseBigInt(hPM, 16);\n    var biSign = this.doPrivate(biPaddedMessage);\n    var hexSign = biSign.toString(16);\n    return _zeroPaddingOfSignature(hexSign, this.n.bitLength());\n}\n\nfunction _rsasign_signStringWithSHA1(s) {\n    return _rsasign_signString.call(this, s, 'sha1');\n}\n\nfunction _rsasign_signStringWithSHA256(s) {\n    return _rsasign_signString.call(this, s, 'sha256');\n}\n\n// PKCS#1 (PSS) mask generation function\nfunction pss_mgf1_str(seed, len, hash) {\n    var mask = '', i = 0;\n\n    while (mask.length < len) {\n        mask += hextorstr(hash(rstrtohex(seed + String.fromCharCode.apply(String, [\n                (i & 0xff000000) >> 24,\n                (i & 0x00ff0000) >> 16,\n                (i & 0x0000ff00) >> 8,\n                i & 0x000000ff]))));\n        i += 1;\n    }\n\n    return mask;\n}\n\n/**\n * sign for a message string with RSA private key by PKCS#1 PSS signing.<br/>\n * @name signStringPSS\n * @memberOf RSAKey\n * @function\n * @param {String} s message string to be signed.\n * @param {String} hashAlg hash algorithm name for signing.\n * @param {Integer} sLen salt byte length from 0 to (keybytelen - hashbytelen - 2).\n *        There are two special values:\n *        <ul>\n *        <li>-1: sets the salt length to the digest length</li>\n *        <li>-2: sets the salt length to maximum permissible value\n *           (i.e. keybytelen - hashbytelen - 2)</li>\n *        </ul>\n *        DEFAULT is -1. (NOTE: OpenSSL's default is -2.)\n * @return returns hexadecimal string of signature value.\n */\nfunction _rsasign_signStringPSS(s, hashAlg, sLen) {\n    var hashFunc = function(sHex) { return KJUR.crypto.Util.hashHex(sHex, hashAlg); } \n    var hHash = hashFunc(rstrtohex(s));\n\n    if (sLen === undefined) sLen = -1;\n    return this.signWithMessageHashPSS(hHash, hashAlg, sLen);\n}\n\n/**\n * sign hash value of message with RSA private key by PKCS#1 PSS signing.<br/>\n * @name signWithMessageHashPSS\n * @memberOf RSAKey\n * @function\n * @param {String} hHash hexadecimal hash value of message to be signed.\n * @param {String} hashAlg hash algorithm name for signing.\n * @param {Integer} sLen salt byte length from 0 to (keybytelen - hashbytelen - 2).\n *        There are two special values:\n *        <ul>\n *        <li>-1: sets the salt length to the digest length</li>\n *        <li>-2: sets the salt length to maximum permissible value\n *           (i.e. keybytelen - hashbytelen - 2)</li>\n *        </ul>\n *        DEFAULT is -1. (NOTE: OpenSSL's default is -2.)\n * @return returns hexadecimal string of signature value.\n * @since rsasign 1.2.6\n */\nfunction _rsasign_signWithMessageHashPSS(hHash, hashAlg, sLen) {\n    var mHash = hextorstr(hHash);\n    var hLen = mHash.length;\n    var emBits = this.n.bitLength() - 1;\n    var emLen = Math.ceil(emBits / 8);\n    var i;\n    var hashFunc = function(sHex) { return KJUR.crypto.Util.hashHex(sHex, hashAlg); } \n\n    if (sLen === -1 || sLen === undefined) {\n        sLen = hLen; // same as hash length\n    } else if (sLen === -2) {\n        sLen = emLen - hLen - 2; // maximum\n    } else if (sLen < -2) {\n        throw \"invalid salt length\";\n    }\n\n    if (emLen < (hLen + sLen + 2)) {\n        throw \"data too long\";\n    }\n\n    var salt = '';\n\n    if (sLen > 0) {\n        salt = new Array(sLen);\n        new SecureRandom().nextBytes(salt);\n        salt = String.fromCharCode.apply(String, salt);\n    }\n\n    var H = hextorstr(hashFunc(rstrtohex('\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00' + mHash + salt)));\n    var PS = [];\n\n    for (i = 0; i < emLen - sLen - hLen - 2; i += 1) {\n        PS[i] = 0x00;\n    }\n\n    var DB = String.fromCharCode.apply(String, PS) + '\\x01' + salt;\n    var dbMask = pss_mgf1_str(H, DB.length, hashFunc);\n    var maskedDB = [];\n\n    for (i = 0; i < DB.length; i += 1) {\n        maskedDB[i] = DB.charCodeAt(i) ^ dbMask.charCodeAt(i);\n    }\n\n    var mask = (0xff00 >> (8 * emLen - emBits)) & 0xff;\n    maskedDB[0] &= ~mask;\n\n    for (i = 0; i < hLen; i++) {\n        maskedDB.push(H.charCodeAt(i));\n    }\n\n    maskedDB.push(0xbc);\n\n    return _zeroPaddingOfSignature(this.doPrivate(new BigInteger(maskedDB)).toString(16),\n\t\t\t\t   this.n.bitLength());\n}\n\n// ========================================================================\n// Signature Verification\n// ========================================================================\n\nfunction _rsasign_getDecryptSignatureBI(biSig, hN, hE) {\n    var rsa = new RSAKey();\n    rsa.setPublic(hN, hE);\n    var biDecryptedSig = rsa.doPublic(biSig);\n    return biDecryptedSig;\n}\n\nfunction _rsasign_getHexDigestInfoFromSig(biSig, hN, hE) {\n    var biDecryptedSig = _rsasign_getDecryptSignatureBI(biSig, hN, hE);\n    var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');\n    return hDigestInfo;\n}\n\nfunction _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo) {\n    for (var algName in KJUR.crypto.Util.DIGESTINFOHEAD) {\n\tvar head = KJUR.crypto.Util.DIGESTINFOHEAD[algName];\n\tvar len = head.length;\n\tif (hDigestInfo.substring(0, len) == head) {\n\t    var a = [algName, hDigestInfo.substring(len)];\n\t    return a;\n\t}\n    }\n    return [];\n}\n\nfunction _rsasign_verifySignatureWithArgs(sMsg, biSig, hN, hE) {\n    var hDigestInfo = _rsasign_getHexDigestInfoFromSig(biSig, hN, hE);\n    var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);\n    if (digestInfoAry.length == 0) return false;\n    var algName = digestInfoAry[0];\n    var diHashValue = digestInfoAry[1];\n    var ff = function(s) { return KJUR.crypto.Util.hashString(s, algName); };\n    var msgHashValue = ff(sMsg);\n    return (diHashValue == msgHashValue);\n}\n\nfunction _rsasign_verifyHexSignatureForMessage(hSig, sMsg) {\n    var biSig = parseBigInt(hSig, 16);\n    var result = _rsasign_verifySignatureWithArgs(sMsg, biSig,\n\t\t\t\t\t\t  this.n.toString(16),\n\t\t\t\t\t\t  this.e.toString(16));\n    return result;\n}\n\n/**\n * verifies a sigature for a message string with RSA public key.<br/>\n * @name verifyString\n * @memberOf RSAKey#\n * @function\n * @param {String} sMsg message string to be verified.\n * @param {String} hSig hexadecimal string of siganture.<br/>\n *                 non-hexadecimal charactors including new lines will be ignored.\n * @return returns 1 if valid, otherwise 0\n */\nfunction _rsasign_verifyString(sMsg, hSig) {\n    hSig = hSig.replace(_RE_HEXDECONLY, '');\n    hSig = hSig.replace(/[ \\n]+/g, \"\");\n    var biSig = parseBigInt(hSig, 16);\n    if (biSig.bitLength() > this.n.bitLength()) return 0;\n    var biDecryptedSig = this.doPublic(biSig);\n    var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');\n    var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);\n  \n    if (digestInfoAry.length == 0) return false;\n    var algName = digestInfoAry[0];\n    var diHashValue = digestInfoAry[1];\n    var ff = function(s) { return KJUR.crypto.Util.hashString(s, algName); };\n    var msgHashValue = ff(sMsg);\n    return (diHashValue == msgHashValue);\n}\n\n/**\n * verifies a sigature for a message string with RSA public key.<br/>\n * @name verifyWithMessageHash\n * @memberOf RSAKey\n * @function\n * @param {String} sHashHex hexadecimal hash value of message to be verified.\n * @param {String} hSig hexadecimal string of siganture.<br/>\n *                 non-hexadecimal charactors including new lines will be ignored.\n * @return returns 1 if valid, otherwise 0\n * @since rsasign 1.2.6\n */\nfunction _rsasign_verifyWithMessageHash(sHashHex, hSig) {\n    hSig = hSig.replace(_RE_HEXDECONLY, '');\n    hSig = hSig.replace(/[ \\n]+/g, \"\");\n    var biSig = parseBigInt(hSig, 16);\n    if (biSig.bitLength() > this.n.bitLength()) return 0;\n    var biDecryptedSig = this.doPublic(biSig);\n    var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');\n    var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);\n  \n    if (digestInfoAry.length == 0) return false;\n    var algName = digestInfoAry[0];\n    var diHashValue = digestInfoAry[1];\n    return (diHashValue == sHashHex);\n}\n\n/**\n * verifies a sigature for a message string with RSA public key by PKCS#1 PSS sign.<br/>\n * @name verifyStringPSS\n * @memberOf RSAKey\n * @function\n * @param {String} sMsg message string to be verified.\n * @param {String} hSig hexadecimal string of signature value\n * @param {String} hashAlg hash algorithm name\n * @param {Integer} sLen salt byte length from 0 to (keybytelen - hashbytelen - 2).\n *        There are two special values:\n *        <ul>\n *        <li>-1: sets the salt length to the digest length</li>\n *        <li>-2: sets the salt length to maximum permissible value\n *           (i.e. keybytelen - hashbytelen - 2)</li>\n *        </ul>\n *        DEFAULT is -1. (NOTE: OpenSSL's default is -2.)\n * @return returns true if valid, otherwise false\n */\nfunction _rsasign_verifyStringPSS(sMsg, hSig, hashAlg, sLen) {\n    var hashFunc = function(sHex) { return KJUR.crypto.Util.hashHex(sHex, hashAlg); };\n    var hHash = hashFunc(rstrtohex(sMsg));\n\n    if (sLen === undefined) sLen = -1;\n    return this.verifyWithMessageHashPSS(hHash, hSig, hashAlg, sLen);\n}\n\n/**\n * verifies a sigature for a hash value of message string with RSA public key by PKCS#1 PSS sign.<br/>\n * @name verifyWithMessageHashPSS\n * @memberOf RSAKey\n * @function\n * @param {String} hHash hexadecimal hash value of message string to be verified.\n * @param {String} hSig hexadecimal string of signature value\n * @param {String} hashAlg hash algorithm name\n * @param {Integer} sLen salt byte length from 0 to (keybytelen - hashbytelen - 2).\n *        There are two special values:\n *        <ul>\n *        <li>-1: sets the salt length to the digest length</li>\n *        <li>-2: sets the salt length to maximum permissible value\n *           (i.e. keybytelen - hashbytelen - 2)</li>\n *        </ul>\n *        DEFAULT is -1 (NOTE: OpenSSL's default is -2.)\n * @return returns true if valid, otherwise false\n * @since rsasign 1.2.6\n */\nfunction _rsasign_verifyWithMessageHashPSS(hHash, hSig, hashAlg, sLen) {\n    var biSig = new BigInteger(hSig, 16);\n\n    if (biSig.bitLength() > this.n.bitLength()) {\n        return false;\n    }\n\n    var hashFunc = function(sHex) { return KJUR.crypto.Util.hashHex(sHex, hashAlg); };\n    var mHash = hextorstr(hHash);\n    var hLen = mHash.length;\n    var emBits = this.n.bitLength() - 1;\n    var emLen = Math.ceil(emBits / 8);\n    var i;\n\n    if (sLen === -1 || sLen === undefined) {\n        sLen = hLen; // same as hash length\n    } else if (sLen === -2) {\n        sLen = emLen - hLen - 2; // recover\n    } else if (sLen < -2) {\n        throw \"invalid salt length\";\n    }\n\n    if (emLen < (hLen + sLen + 2)) {\n        throw \"data too long\";\n    }\n\n    var em = this.doPublic(biSig).toByteArray();\n\n    for (i = 0; i < em.length; i += 1) {\n        em[i] &= 0xff;\n    }\n\n    while (em.length < emLen) {\n        em.unshift(0);\n    }\n\n    if (em[emLen -1] !== 0xbc) {\n        throw \"encoded message does not end in 0xbc\";\n    }\n\n    em = String.fromCharCode.apply(String, em);\n\n    var maskedDB = em.substr(0, emLen - hLen - 1);\n    var H = em.substr(maskedDB.length, hLen);\n\n    var mask = (0xff00 >> (8 * emLen - emBits)) & 0xff;\n\n    if ((maskedDB.charCodeAt(0) & mask) !== 0) {\n        throw \"bits beyond keysize not zero\";\n    }\n\n    var dbMask = pss_mgf1_str(H, maskedDB.length, hashFunc);\n    var DB = [];\n\n    for (i = 0; i < maskedDB.length; i += 1) {\n        DB[i] = maskedDB.charCodeAt(i) ^ dbMask.charCodeAt(i);\n    }\n\n    DB[0] &= ~mask;\n\n    var checkLen = emLen - hLen - sLen - 2;\n\n    for (i = 0; i < checkLen; i += 1) {\n        if (DB[i] !== 0x00) {\n            throw \"leftmost octets not zero\";\n        }\n    }\n\n    if (DB[checkLen] !== 0x01) {\n        throw \"0x01 marker not found\";\n    }\n\n    return H === hextorstr(hashFunc(rstrtohex('\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00' + mHash +\n\t\t\t\t     String.fromCharCode.apply(String, DB.slice(-sLen)))));\n}\n\nRSAKey.prototype.signWithMessageHash = _rsasign_signWithMessageHash;\nRSAKey.prototype.signString = _rsasign_signString;\nRSAKey.prototype.signStringWithSHA1 = _rsasign_signStringWithSHA1;\nRSAKey.prototype.signStringWithSHA256 = _rsasign_signStringWithSHA256;\nRSAKey.prototype.sign = _rsasign_signString;\nRSAKey.prototype.signWithSHA1 = _rsasign_signStringWithSHA1;\nRSAKey.prototype.signWithSHA256 = _rsasign_signStringWithSHA256;\n\nRSAKey.prototype.signWithMessageHashPSS = _rsasign_signWithMessageHashPSS;\nRSAKey.prototype.signStringPSS = _rsasign_signStringPSS;\nRSAKey.prototype.signPSS = _rsasign_signStringPSS;\nRSAKey.SALT_LEN_HLEN = -1;\nRSAKey.SALT_LEN_MAX = -2;\n\nRSAKey.prototype.verifyWithMessageHash = _rsasign_verifyWithMessageHash;\nRSAKey.prototype.verifyString = _rsasign_verifyString;\nRSAKey.prototype.verifyHexSignatureForMessage = _rsasign_verifyHexSignatureForMessage;\nRSAKey.prototype.verify = _rsasign_verifyString;\nRSAKey.prototype.verifyHexSignatureForByteArrayMessage = _rsasign_verifyHexSignatureForMessage;\n\nRSAKey.prototype.verifyWithMessageHashPSS = _rsasign_verifyWithMessageHashPSS;\nRSAKey.prototype.verifyStringPSS = _rsasign_verifyStringPSS;\nRSAKey.prototype.verifyPSS = _rsasign_verifyStringPSS;\nRSAKey.SALT_LEN_RECOVER = -2;\n\n/**\n * @name RSAKey\n * @class key of RSA public key algorithm\n * @description Tom Wu's RSA Key class and extension\n */\n"
  },
  {
    "path": "JavaScript/sm2/js/sha1.js",
    "content": "/*\nCryptoJS v3.1.2\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function () {\n    // Shortcuts\n    var C = CryptoJS;\n    var C_lib = C.lib;\n    var WordArray = C_lib.WordArray;\n    var Hasher = C_lib.Hasher;\n    var C_algo = C.algo;\n\n    // Reusable object\n    var W = [];\n\n    /**\n     * SHA-1 hash algorithm.\n     */\n    var SHA1 = C_algo.SHA1 = Hasher.extend({\n        _doReset: function () {\n            this._hash = new WordArray.init([\n                0x67452301, 0xefcdab89,\n                0x98badcfe, 0x10325476,\n                0xc3d2e1f0\n            ]);\n        },\n\n        _doProcessBlock: function (M, offset) {\n            // Shortcut\n            var H = this._hash.words;\n\n            // Working variables\n            var a = H[0];\n            var b = H[1];\n            var c = H[2];\n            var d = H[3];\n            var e = H[4];\n\n            // Computation\n            for (var i = 0; i < 80; i++) {\n                if (i < 16) {\n                    W[i] = M[offset + i] | 0;\n                } else {\n                    var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];\n                    W[i] = (n << 1) | (n >>> 31);\n                }\n\n                var t = ((a << 5) | (a >>> 27)) + e + W[i];\n                if (i < 20) {\n                    t += ((b & c) | (~b & d)) + 0x5a827999;\n                } else if (i < 40) {\n                    t += (b ^ c ^ d) + 0x6ed9eba1;\n                } else if (i < 60) {\n                    t += ((b & c) | (b & d) | (c & d)) - 0x70e44324;\n                } else /* if (i < 80) */ {\n                    t += (b ^ c ^ d) - 0x359d3e2a;\n                }\n\n                e = d;\n                d = c;\n                c = (b << 30) | (b >>> 2);\n                b = a;\n                a = t;\n            }\n\n            // Intermediate hash value\n            H[0] = (H[0] + a) | 0;\n            H[1] = (H[1] + b) | 0;\n            H[2] = (H[2] + c) | 0;\n            H[3] = (H[3] + d) | 0;\n            H[4] = (H[4] + e) | 0;\n        },\n\n        _doFinalize: function () {\n            // Shortcuts\n            var data = this._data;\n            var dataWords = data.words;\n\n            var nBitsTotal = this._nDataBytes * 8;\n            var nBitsLeft = data.sigBytes * 8;\n\n            // Add padding\n            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);\n            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);\n            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;\n            data.sigBytes = dataWords.length * 4;\n\n            // Hash final blocks\n            this._process();\n\n            // Return final computed hash\n            return this._hash;\n        },\n\n        clone: function () {\n            var clone = Hasher.clone.call(this);\n            clone._hash = this._hash.clone();\n\n            return clone;\n        }\n    });\n\n    /**\n     * Shortcut function to the hasher's object interface.\n     *\n     * @param {WordArray|string} message The message to hash.\n     *\n     * @return {WordArray} The hash.\n     *\n     * @static\n     *\n     * @example\n     *\n     *     var hash = CryptoJS.SHA1('message');\n     *     var hash = CryptoJS.SHA1(wordArray);\n     */\n    C.SHA1 = Hasher._createHelper(SHA1);\n\n    /**\n     * Shortcut function to the HMAC's object interface.\n     *\n     * @param {WordArray|string} message The message to hash.\n     * @param {WordArray|string} key The secret key.\n     *\n     * @return {WordArray} The HMAC.\n     *\n     * @static\n     *\n     * @example\n     *\n     *     var hmac = CryptoJS.HmacSHA1(message, key);\n     */\n    C.HmacSHA1 = Hasher._createHmacHelper(SHA1);\n}());\n"
  },
  {
    "path": "JavaScript/sm2/js/sha256.js",
    "content": "/*\nCryptoJS v3.1.2\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function (Math) {\n    // Shortcuts\n    var C = CryptoJS;\n    var C_lib = C.lib;\n    var WordArray = C_lib.WordArray;\n    var Hasher = C_lib.Hasher;\n    var C_algo = C.algo;\n\n    // Initialization and round constants tables\n    var H = [];\n    var K = [];\n\n    // Compute constants\n    (function () {\n        function isPrime(n) {\n            var sqrtN = Math.sqrt(n);\n            for (var factor = 2; factor <= sqrtN; factor++) {\n                if (!(n % factor)) {\n                    return false;\n                }\n            }\n\n            return true;\n        }\n\n        function getFractionalBits(n) {\n            return ((n - (n | 0)) * 0x100000000) | 0;\n        }\n\n        var n = 2;\n        var nPrime = 0;\n        while (nPrime < 64) {\n            if (isPrime(n)) {\n                if (nPrime < 8) {\n                    H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2));\n                }\n                K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3));\n\n                nPrime++;\n            }\n\n            n++;\n        }\n    }());\n\n    // Reusable object\n    var W = [];\n\n    /**\n     * SHA-256 hash algorithm.\n     */\n    var SHA256 = C_algo.SHA256 = Hasher.extend({\n        _doReset: function () {\n            this._hash = new WordArray.init(H.slice(0));\n        },\n\n        _doProcessBlock: function (M, offset) {\n            // Shortcut\n            var H = this._hash.words;\n\n            // Working variables\n            var a = H[0];\n            var b = H[1];\n            var c = H[2];\n            var d = H[3];\n            var e = H[4];\n            var f = H[5];\n            var g = H[6];\n            var h = H[7];\n\n            // Computation\n            for (var i = 0; i < 64; i++) {\n                if (i < 16) {\n                    W[i] = M[offset + i] | 0;\n                } else {\n                    var gamma0x = W[i - 15];\n                    var gamma0  = ((gamma0x << 25) | (gamma0x >>> 7))  ^\n                                  ((gamma0x << 14) | (gamma0x >>> 18)) ^\n                                   (gamma0x >>> 3);\n\n                    var gamma1x = W[i - 2];\n                    var gamma1  = ((gamma1x << 15) | (gamma1x >>> 17)) ^\n                                  ((gamma1x << 13) | (gamma1x >>> 19)) ^\n                                   (gamma1x >>> 10);\n\n                    W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16];\n                }\n\n                var ch  = (e & f) ^ (~e & g);\n                var maj = (a & b) ^ (a & c) ^ (b & c);\n\n                var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22));\n                var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7)  | (e >>> 25));\n\n                var t1 = h + sigma1 + ch + K[i] + W[i];\n                var t2 = sigma0 + maj;\n\n                h = g;\n                g = f;\n                f = e;\n                e = (d + t1) | 0;\n                d = c;\n                c = b;\n                b = a;\n                a = (t1 + t2) | 0;\n            }\n\n            // Intermediate hash value\n            H[0] = (H[0] + a) | 0;\n            H[1] = (H[1] + b) | 0;\n            H[2] = (H[2] + c) | 0;\n            H[3] = (H[3] + d) | 0;\n            H[4] = (H[4] + e) | 0;\n            H[5] = (H[5] + f) | 0;\n            H[6] = (H[6] + g) | 0;\n            H[7] = (H[7] + h) | 0;\n        },\n\n        _doFinalize: function () {\n            // Shortcuts\n            var data = this._data;\n            var dataWords = data.words;\n\n            var nBitsTotal = this._nDataBytes * 8;\n            var nBitsLeft = data.sigBytes * 8;\n\n            // Add padding\n            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);\n            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);\n            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;\n            data.sigBytes = dataWords.length * 4;\n\n            // Hash final blocks\n            this._process();\n\n            // Return final computed hash\n            return this._hash;\n        },\n\n        clone: function () {\n            var clone = Hasher.clone.call(this);\n            clone._hash = this._hash.clone();\n\n            return clone;\n        }\n    });\n\n    /**\n     * Shortcut function to the hasher's object interface.\n     *\n     * @param {WordArray|string} message The message to hash.\n     *\n     * @return {WordArray} The hash.\n     *\n     * @static\n     *\n     * @example\n     *\n     *     var hash = CryptoJS.SHA256('message');\n     *     var hash = CryptoJS.SHA256(wordArray);\n     */\n    C.SHA256 = Hasher._createHelper(SHA256);\n\n    /**\n     * Shortcut function to the HMAC's object interface.\n     *\n     * @param {WordArray|string} message The message to hash.\n     * @param {WordArray|string} key The secret key.\n     *\n     * @return {WordArray} The HMAC.\n     *\n     * @static\n     *\n     * @example\n     *\n     *     var hmac = CryptoJS.HmacSHA256(message, key);\n     */\n    C.HmacSHA256 = Hasher._createHmacHelper(SHA256);\n}(Math));\n"
  },
  {
    "path": "JavaScript/sm2/js/sm2-guomi.js",
    "content": "function SM2Cipher(cipherMode) {\n    this.ct = 1;\n    this.p2 = null;\n    this.sm3keybase = null;\n    this.sm3c3 = null;\n    this.key = new Array(32);\n    this.keyOff = 0;\n    if (typeof(cipherMode) != 'undefined') {\n        this.cipherMode = cipherMode\n    } else {\n        this.cipherMode = SM2CipherMode.C1C3C2\n    }\n}\nSM2Cipher.prototype = {\n    Reset: function() {\n        this.sm3keybase = new SM3Digest();\n        this.sm3c3 = new SM3Digest();\n        var xWords = this.GetWords(this.p2.getX().toBigInteger().toRadix(16));\n        var yWords = this.GetWords(this.p2.getY().toBigInteger().toRadix(16));\n        this.sm3keybase.BlockUpdate(xWords, 0, xWords.length);\n        this.sm3c3.BlockUpdate(xWords, 0, xWords.length);\n        this.sm3keybase.BlockUpdate(yWords, 0, yWords.length);\n        this.ct = 1;\n        this.NextKey()\n    },\n    NextKey: function() {\n        var sm3keycur = new SM3Digest(this.sm3keybase);\n        sm3keycur.Update((this.ct >> 24 & 0x00ff));\n        sm3keycur.Update((this.ct >> 16 & 0x00ff));\n        sm3keycur.Update((this.ct >> 8 & 0x00ff));\n        sm3keycur.Update((this.ct & 0x00ff));\n        sm3keycur.DoFinal(this.key, 0);\n        this.keyOff = 0;\n        this.ct++\n    },\n    InitEncipher: function(userKey) {\n        var k = null;\n        var c1 = null;\n        var ec = new KJUR.crypto.ECDSA({\n            \"curve\": \"sm2\"\n        });\n        var keypair = ec.generateKeyPairHex();\n        k = new BigInteger(keypair.ecprvhex, 16);\n        var pubkeyHex = keypair.ecpubhex;\n        c1 = ECPointFp.decodeFromHex(ec.ecparams['curve'], pubkeyHex);\n        this.p2 = userKey.multiply(k);\n        this.Reset();\n        return c1\n    },\n    EncryptBlock: function(data) {\n        this.sm3c3.BlockUpdate(data, 0, data.length);\n        for (var i = 0; i < data.length; i++) {\n            if (this.keyOff == this.key.length) {\n                this.NextKey()\n            }\n            data[i] ^= this.key[this.keyOff++]\n        }\n    },\n    InitDecipher: function(userD, c1) {\n        this.p2 = c1.multiply(userD);\n        this.Reset()\n    },\n    DecryptBlock: function(data) {\n        for (var i = 0; i < data.length; i++) {\n            if (this.keyOff == this.key.length) {\n                this.NextKey()\n            }\n            data[i] ^= this.key[this.keyOff++]\n        }\n        this.sm3c3.BlockUpdate(data, 0, data.length)\n    },\n    Dofinal: function(c3) {\n        var yWords = this.GetWords(this.p2.getY().toBigInteger().toRadix(16));\n        this.sm3c3.BlockUpdate(yWords, 0, yWords.length);\n        this.sm3c3.DoFinal(c3, 0);\n        this.Reset()\n    },\n    Encrypt: function(pubKey, plaintext) {\n        var data = new Array(plaintext.length);\n        Array.Copy(plaintext, 0, data, 0, plaintext.length);\n        var c1 = this.InitEncipher(pubKey);\n        this.EncryptBlock(data);\n        var c3 = new Array(32);\n        this.Dofinal(c3);\n        var hexString = c1.getX().toBigInteger().toRadix(16) + c1.getY().toBigInteger().toRadix(16) + this.GetHex(data).toString() + this.GetHex(c3).toString();\n        if (this.cipherMode == SM2CipherMode.C1C3C2) {\n            hexString = c1.getX().toBigInteger().toRadix(16) + c1.getY().toBigInteger().toRadix(16) + this.GetHex(c3).toString() + this.GetHex(data).toString()\n        }\n        return hexString\n    },\n    GetWords: function(hexStr) {\n        var words = [];\n        var hexStrLength = hexStr.length;\n        for (var i = 0; i < hexStrLength; i += 2) {\n            words[words.length] = parseInt(hexStr.substr(i, 2), 16)\n        }\n        return words\n    },\n    GetHex: function(arr) {\n        var words = [];\n        var j = 0;\n        for (var i = 0; i < arr.length * 2; i += 2) {\n            words[i >>> 3] |= parseInt(arr[j]) << (24 - (i % 8) * 4);\n            j++\n        }\n        var wordArray = new CryptoJS.lib.WordArray.init(words, arr.length);\n        return wordArray\n    },\n    Decrypt: function(privateKey, ciphertext) {\n        var hexString = ciphertext;\n        var c1X = hexString.substr(0, 64);\n        var c1Y = hexString.substr(0 + c1X.length, 64);\n        var encrypData = hexString.substr(c1X.length + c1Y.length, hexString.length - c1X.length - c1Y.length - 64);\n        var c3 = hexString.substr(hexString.length - 64);\n        if (this.cipherMode == SM2CipherMode.C1C3C2) {\n            c3 = hexString.substr(c1X.length + c1Y.length, 64);\n            encrypData = hexString.substr(c1X.length + c1Y.length + 64)\n        }\n        var data = this.GetWords(encrypData);\n        var c1 = this.CreatePoint(c1X, c1Y);\n        this.InitDecipher(privateKey, c1);\n        this.DecryptBlock(data);\n        var c3_ = new Array(32);\n        this.Dofinal(c3_);\n        var isDecrypt = this.GetHex(c3_).toString() == c3;\n        if (isDecrypt) {\n            var wordArray = this.GetHex(data);\n            var decryptData = CryptoJS.enc.Utf8.stringify(wordArray);\n            return decryptData\n        } else {\n            return ''\n        }\n    },\n    CreatePoint: function(x, y) {\n        var ec = new KJUR.crypto.ECDSA({\n            \"curve\": \"sm2\"\n        });\n        var ecc_curve = ec.ecparams['curve'];\n        var pubkeyHex = '04' + x + y;\n        var point = ECPointFp.decodeFromHex(ec.ecparams['curve'], pubkeyHex);\n        return point\n    }\n};\nwindow.SM2CipherMode = {\n    C1C2C3: '0',\n    C1C3C2: '1'\n};"
  },
  {
    "path": "JavaScript/sm2/js/sm2.js",
    "content": "function SM2Cipher(cipherMode){this.ct=1;this.p2=null;this.sm3keybase=null;this.sm3c3=null;this.key=new Array(32);this.keyOff=0;if(typeof(cipherMode)!='undefined'){this.cipherMode=cipherMode}else{this.cipherMode=SM2CipherMode.C1C3C2}}SM2Cipher.prototype={Reset:function(){this.sm3keybase=new SM3Digest();this.sm3c3=new SM3Digest();var xWords=this.GetWords(this.p2.getX().toBigInteger().toRadix(16));var yWords=this.GetWords(this.p2.getY().toBigInteger().toRadix(16));this.sm3keybase.BlockUpdate(xWords,0,xWords.length);this.sm3c3.BlockUpdate(xWords,0,xWords.length);this.sm3keybase.BlockUpdate(yWords,0,yWords.length);this.ct=1;this.NextKey()},NextKey:function(){var sm3keycur=new SM3Digest(this.sm3keybase);sm3keycur.Update((this.ct>>24&0x00ff));sm3keycur.Update((this.ct>>16&0x00ff));sm3keycur.Update((this.ct>>8&0x00ff));sm3keycur.Update((this.ct&0x00ff));sm3keycur.DoFinal(this.key,0);this.keyOff=0;this.ct++},InitEncipher:function(userKey){var k=null;var c1=null;var ec=new KJUR.crypto.ECDSA({\"curve\":\"sm2\"});var keypair=ec.generateKeyPairHex();k=new BigInteger(keypair.ecprvhex,16);var pubkeyHex=keypair.ecpubhex;c1=ECPointFp.decodeFromHex(ec.ecparams['curve'],pubkeyHex);this.p2=userKey.multiply(k);this.Reset();return c1},EncryptBlock:function(data){this.sm3c3.BlockUpdate(data,0,data.length);for(var i=0;i<data.length;i++){if(this.keyOff==this.key.length){this.NextKey()}data[i]^=this.key[this.keyOff++]}},InitDecipher:function(userD,c1){this.p2=c1.multiply(userD);this.Reset()},DecryptBlock:function(data){for(var i=0;i<data.length;i++){if(this.keyOff==this.key.length){this.NextKey()}data[i]^=this.key[this.keyOff++]}this.sm3c3.BlockUpdate(data,0,data.length)},Dofinal:function(c3){var yWords=this.GetWords(this.p2.getY().toBigInteger().toRadix(16));this.sm3c3.BlockUpdate(yWords,0,yWords.length);this.sm3c3.DoFinal(c3,0);this.Reset()},Encrypt:function(pubKey,plaintext){var data=new Array(plaintext.length);Array.Copy(plaintext,0,data,0,plaintext.length);var c1=this.InitEncipher(pubKey);this.EncryptBlock(data);var c3=new Array(32);this.Dofinal(c3);var hexString=c1.getX().toBigInteger().toRadix(16)+c1.getY().toBigInteger().toRadix(16)+this.GetHex(data).toString()+this.GetHex(c3).toString();if(this.cipherMode==SM2CipherMode.C1C3C2){hexString=c1.getX().toBigInteger().toRadix(16)+c1.getY().toBigInteger().toRadix(16)+this.GetHex(c3).toString()+this.GetHex(data).toString()}return hexString},GetWords:function(hexStr){var words=[];var hexStrLength=hexStr.length;for(var i=0;i<hexStrLength;i+=2){words[words.length]=parseInt(hexStr.substr(i,2),16)}return words},GetHex:function(arr){var words=[];var j=0;for(var i=0;i<arr.length*2;i+=2){words[i>>>3]|=parseInt(arr[j])<<(24-(i%8)*4);j++}var wordArray=new CryptoJS.lib.WordArray.init(words,arr.length);return wordArray},Decrypt:function(privateKey,ciphertext){var hexString=ciphertext;var c1X=hexString.substr(0,64);var c1Y=hexString.substr(0+c1X.length,64);var encrypData=hexString.substr(c1X.length+c1Y.length,hexString.length-c1X.length-c1Y.length-64);var c3=hexString.substr(hexString.length-64);if(this.cipherMode==SM2CipherMode.C1C3C2){c3=hexString.substr(c1X.length+c1Y.length,64);encrypData=hexString.substr(c1X.length+c1Y.length+64)}var data=this.GetWords(encrypData);var c1=this.CreatePoint(c1X,c1Y);this.InitDecipher(privateKey,c1);this.DecryptBlock(data);var c3_=new Array(32);this.Dofinal(c3_);var isDecrypt=this.GetHex(c3_).toString()==c3;if(isDecrypt){var wordArray=this.GetHex(data);var decryptData=CryptoJS.enc.Utf8.stringify(wordArray);return decryptData}else{return''}},CreatePoint:function(x,y){var ec=new KJUR.crypto.ECDSA({\"curve\":\"sm2\"});var ecc_curve=ec.ecparams['curve'];var pubkeyHex='04'+x+y;var point=ECPointFp.decodeFromHex(ec.ecparams['curve'],pubkeyHex);return point}};window.SM2CipherMode={C1C2C3:'0',C1C3C2:'1'};"
  },
  {
    "path": "JavaScript/sm2/js/sm3-guomi.js",
    "content": "(function() {\n    var C = CryptoJS;\n    var C_lib = C.lib;\n    var WordArray = C_lib.WordArray;\n    var Hasher = C_lib.Hasher;\n    var C_algo = C.algo;\n    var W = [];\n    var SM3 = C_algo.SM3 = Hasher.extend({\n        _doReset: function() {\n            this._hash = new WordArray.init([0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e])\n        },\n        _doProcessBlock: function(M, offset) {\n            var H = this._hash.words;\n            var a = H[0];\n            var b = H[1];\n            var c = H[2];\n            var d = H[3];\n            var e = H[4];\n            for (var i = 0; i < 80; i++) {\n                if (i < 16) {\n                    W[i] = M[offset + i] | 0\n                } else {\n                    var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];\n                    W[i] = (n << 1) | (n >>> 31)\n                }\n                var t = ((a << 5) | (a >>> 27)) + e + W[i];\n                if (i < 20) {\n                    t += ((b & c) | (~b & d)) + 0x5a827999\n                } else if (i < 40) {\n                    t += (b ^ c ^ d) + 0x6ed9eba1\n                } else if (i < 60) {\n                    t += ((b & c) | (b & d) | (c & d)) - 0x70e44324\n                } else {\n                    t += (b ^ c ^ d) - 0x359d3e2a\n                }\n                e = d;\n                d = c;\n                c = (b << 30) | (b >>> 2);\n                b = a;\n                a = t\n            }\n            H[0] = (H[0] + a) | 0;\n            H[1] = (H[1] + b) | 0;\n            H[2] = (H[2] + c) | 0;\n            H[3] = (H[3] + d) | 0;\n            H[4] = (H[4] + e) | 0\n        },\n        _doFinalize: function() {\n            var data = this._data;\n            var dataWords = data.words;\n            var nBitsTotal = this._nDataBytes * 8;\n            var nBitsLeft = data.sigBytes * 8;\n            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);\n            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);\n            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;\n            data.sigBytes = dataWords.length * 4;\n            this._process();\n            return this._hash\n        },\n        clone: function() {\n            var clone = Hasher.clone.call(this);\n            clone._hash = this._hash.clone();\n            return clone\n        }\n    });\n    C.SM3 = Hasher._createHelper(SM3);\n    C.HmacSM3 = Hasher._createHmacHelper(SM3)\n}());\n\nfunction SM3Digest() {\n    this.BYTE_LENGTH = 64;\n    this.xBuf = new Array();\n    this.xBufOff = 0;\n    this.byteCount = 0;\n    this.DIGEST_LENGTH = 32;\n    this.v0 = [0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e];\n    this.v0 = [0x7380166f, 0x4914b2b9, 0x172442d7, -628488704, -1452330820, 0x163138aa, -477237683, -1325724082];\n    this.v = new Array(8);\n    this.v_ = new Array(8);\n    this.X0 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n    this.X = new Array(68);\n    this.xOff = 0;\n    this.T_00_15 = 0x79cc4519;\n    this.T_16_63 = 0x7a879d8a;\n    if (arguments.length > 0) {\n        this.InitDigest(arguments[0])\n    } else {\n        this.Init()\n    }\n}\nSM3Digest.prototype = {\n    Init: function() {\n        this.xBuf = new Array(4);\n        this.Reset()\n    },\n    InitDigest: function(t) {\n        this.xBuf = new Array(t.xBuf.length);\n        Array.Copy(t.xBuf, 0, this.xBuf, 0, t.xBuf.length);\n        this.xBufOff = t.xBufOff;\n        this.byteCount = t.byteCount;\n        Array.Copy(t.X, 0, this.X, 0, t.X.length);\n        this.xOff = t.xOff;\n        Array.Copy(t.v, 0, this.v, 0, t.v.length)\n    },\n    GetDigestSize: function() {\n        return this.DIGEST_LENGTH\n    },\n    Reset: function() {\n        this.byteCount = 0;\n        this.xBufOff = 0;\n        Array.Clear(this.xBuf, 0, this.xBuf.length);\n        Array.Copy(this.v0, 0, this.v, 0, this.v0.length);\n        this.xOff = 0;\n        Array.Copy(this.X0, 0, this.X, 0, this.X0.length)\n    },\n    GetByteLength: function() {\n        return this.BYTE_LENGTH\n    },\n    ProcessBlock: function() {\n        var i;\n        var ww = this.X;\n        var ww_ = new Array(64);\n        for (i = 16; i < 68; i++) {\n            ww[i] = this.P1(ww[i - 16] ^ ww[i - 9] ^ (this.ROTATE(ww[i - 3], 15))) ^ (this.ROTATE(ww[i - 13], 7)) ^ ww[i - 6]\n        }\n        for (i = 0; i < 64; i++) {\n            ww_[i] = ww[i] ^ ww[i + 4]\n        }\n        var vv = this.v;\n        var vv_ = this.v_;\n        Array.Copy(vv, 0, vv_, 0, this.v0.length);\n        var SS1, SS2, TT1, TT2, aaa;\n        for (i = 0; i < 16; i++) {\n            aaa = this.ROTATE(vv_[0], 12);\n            SS1 = Int32.parse(Int32.parse(aaa + vv_[4]) + this.ROTATE(this.T_00_15, i));\n            SS1 = this.ROTATE(SS1, 7);\n            SS2 = SS1 ^ aaa;\n            TT1 = Int32.parse(Int32.parse(this.FF_00_15(vv_[0], vv_[1], vv_[2]) + vv_[3]) + SS2) + ww_[i];\n            TT2 = Int32.parse(Int32.parse(this.GG_00_15(vv_[4], vv_[5], vv_[6]) + vv_[7]) + SS1) + ww[i];\n            vv_[3] = vv_[2];\n            vv_[2] = this.ROTATE(vv_[1], 9);\n            vv_[1] = vv_[0];\n            vv_[0] = TT1;\n            vv_[7] = vv_[6];\n            vv_[6] = this.ROTATE(vv_[5], 19);\n            vv_[5] = vv_[4];\n            vv_[4] = this.P0(TT2)\n        }\n        for (i = 16; i < 64; i++) {\n            aaa = this.ROTATE(vv_[0], 12);\n            SS1 = Int32.parse(Int32.parse(aaa + vv_[4]) + this.ROTATE(this.T_16_63, i));\n            SS1 = this.ROTATE(SS1, 7);\n            SS2 = SS1 ^ aaa;\n            TT1 = Int32.parse(Int32.parse(this.FF_16_63(vv_[0], vv_[1], vv_[2]) + vv_[3]) + SS2) + ww_[i];\n            TT2 = Int32.parse(Int32.parse(this.GG_16_63(vv_[4], vv_[5], vv_[6]) + vv_[7]) + SS1) + ww[i];\n            vv_[3] = vv_[2];\n            vv_[2] = this.ROTATE(vv_[1], 9);\n            vv_[1] = vv_[0];\n            vv_[0] = TT1;\n            vv_[7] = vv_[6];\n            vv_[6] = this.ROTATE(vv_[5], 19);\n            vv_[5] = vv_[4];\n            vv_[4] = this.P0(TT2)\n        }\n        for (i = 0; i < 8; i++) {\n            vv[i] ^= Int32.parse(vv_[i])\n        }\n        this.xOff = 0;\n        Array.Copy(this.X0, 0, this.X, 0, this.X0.length)\n    },\n    ProcessWord: function(in_Renamed, inOff) {\n        var n = in_Renamed[inOff] << 24;\n        n |= (in_Renamed[++inOff] & 0xff) << 16;\n        n |= (in_Renamed[++inOff] & 0xff) << 8;\n        n |= (in_Renamed[++inOff] & 0xff);\n        this.X[this.xOff] = n;\n        if (++this.xOff == 16) {\n            this.ProcessBlock()\n        }\n    },\n    ProcessLength: function(bitLength) {\n        if (this.xOff > 14) {\n            this.ProcessBlock()\n        }\n        this.X[14] = (this.URShiftLong(bitLength, 32));\n        this.X[15] = (bitLength & (0xffffffff))\n    },\n    IntToBigEndian: function(n, bs, off) {\n        bs[off] = Int32.parseByte(this.URShift(n, 24));\n        bs[++off] = Int32.parseByte(this.URShift(n, 16));\n        bs[++off] = Int32.parseByte(this.URShift(n, 8));\n        bs[++off] = Int32.parseByte(n)\n    },\n    DoFinal: function(out_Renamed, outOff) {\n        this.Finish();\n        for (var i = 0; i < 8; i++) {\n            this.IntToBigEndian(this.v[i], out_Renamed, outOff + i * 4)\n        }\n        this.Reset();\n        return this.DIGEST_LENGTH\n    },\n    Update: function(input) {\n        this.xBuf[this.xBufOff++] = input;\n        if (this.xBufOff == this.xBuf.length) {\n            this.ProcessWord(this.xBuf, 0);\n            this.xBufOff = 0\n        }\n        this.byteCount++\n    },\n    BlockUpdate: function(input, inOff, length) {\n        while ((this.xBufOff != 0) && (length > 0)) {\n            this.Update(input[inOff]);\n            inOff++;\n            length--\n        }\n        while (length > this.xBuf.length) {\n            this.ProcessWord(input, inOff);\n            inOff += this.xBuf.length;\n            length -= this.xBuf.length;\n            this.byteCount += this.xBuf.length\n        }\n        while (length > 0) {\n            this.Update(input[inOff]);\n            inOff++;\n            length--\n        }\n    },\n    Finish: function() {\n        var bitLength = (this.byteCount << 3);\n        this.Update((128));\n        while (this.xBufOff != 0) this.Update((0));\n        this.ProcessLength(bitLength);\n        this.ProcessBlock()\n    },\n    ROTATE: function(x, n) {\n        return (x << n) | (this.URShift(x, (32 - n)))\n    },\n    P0: function(X) {\n        return ((X) ^ this.ROTATE((X), 9) ^ this.ROTATE((X), 17))\n    },\n    P1: function(X) {\n        return ((X) ^ this.ROTATE((X), 15) ^ this.ROTATE((X), 23))\n    },\n    FF_00_15: function(X, Y, Z) {\n        return (X ^ Y ^ Z)\n    },\n    FF_16_63: function(X, Y, Z) {\n        return ((X & Y) | (X & Z) | (Y & Z))\n    },\n    GG_00_15: function(X, Y, Z) {\n        return (X ^ Y ^ Z)\n    },\n    GG_16_63: function(X, Y, Z) {\n        return ((X & Y) | (~X & Z))\n    },\n    URShift: function(number, bits) {\n        if (number > Int32.maxValue || number < Int32.minValue) {\n            number = Int32.parse(number)\n        }\n        if (number >= 0) {\n            return number >> bits\n        } else {\n            return (number >> bits) + (2 << ~bits)\n        }\n    },\n    URShiftLong: function(number, bits) {\n        var returnV;\n        var big = new BigInteger();\n        big.fromInt(number);\n        if (big.signum() >= 0) {\n            returnV = big.shiftRight(bits).intValue()\n        } else {\n            var bigAdd = new BigInteger();\n            bigAdd.fromInt(2);\n            var shiftLeftBits = ~bits;\n            var shiftLeftNumber = '';\n            if (shiftLeftBits < 0) {\n                var shiftRightBits = 64 + shiftLeftBits;\n                for (var i = 0; i < shiftRightBits; i++) {\n                    shiftLeftNumber += '0'\n                }\n                var shiftLeftNumberBigAdd = new BigInteger();\n                shiftLeftNumberBigAdd.fromInt(number >> bits);\n                var shiftLeftNumberBig = new BigInteger(\"10\" + shiftLeftNumber, 2);\n                shiftLeftNumber = shiftLeftNumberBig.toRadix(10);\n                var r = shiftLeftNumberBig.add(shiftLeftNumberBigAdd);\n                returnV = r.toRadix(10)\n            } else {\n                shiftLeftNumber = bigAdd.shiftLeft((~bits)).intValue();\n                returnV = (number >> bits) + shiftLeftNumber\n            }\n        }\n        return returnV\n    },\n    GetZ: function(g, pubKeyHex) {\n        var userId = CryptoJS.enc.Utf8.parse(\"1234567812345678\");\n        var len = userId.words.length * 4 * 8;\n        this.Update((len >> 8 & 0x00ff));\n        this.Update((len & 0x00ff));\n        var userIdWords = this.GetWords(userId.toString());\n        this.BlockUpdate(userIdWords, 0, userIdWords.length);\n        var aWords = this.GetWords(g.curve.a.toBigInteger().toRadix(16));\n        var bWords = this.GetWords(g.curve.b.toBigInteger().toRadix(16));\n        var gxWords = this.GetWords(g.getX().toBigInteger().toRadix(16));\n        var gyWords = this.GetWords(g.getY().toBigInteger().toRadix(16));\n        var pxWords = this.GetWords(pubKeyHex.substr(0, 64));\n        var pyWords = this.GetWords(pubKeyHex.substr(64, 64));\n        this.BlockUpdate(aWords, 0, aWords.length);\n        this.BlockUpdate(bWords, 0, bWords.length);\n        this.BlockUpdate(gxWords, 0, gxWords.length);\n        this.BlockUpdate(gyWords, 0, gyWords.length);\n        this.BlockUpdate(pxWords, 0, pxWords.length);\n        this.BlockUpdate(pyWords, 0, pyWords.length);\n        var md = new Array(this.GetDigestSize());\n        this.DoFinal(md, 0);\n        return md\n    },\n    GetWords: function(hexStr) {\n        var words = [];\n        var hexStrLength = hexStr.length;\n        for (var i = 0; i < hexStrLength; i += 2) {\n            words[words.length] = parseInt(hexStr.substr(i, 2), 16)\n        }\n        return words\n    },\n    GetHex: function(arr) {\n        var words = [];\n        var j = 0;\n        for (var i = 0; i < arr.length * 2; i += 2) {\n            words[i >>> 3] |= parseInt(arr[j]) << (24 - (i % 8) * 4);\n            j++\n        }\n        var wordArray = new CryptoJS.lib.WordArray.init(words, arr.length);\n        return wordArray\n    }\n};\nArray.Clear = function(destinationArray, destinationIndex, length) {\n    for (elm in destinationArray) {\n        destinationArray[elm] = null\n    }\n};\nArray.Copy = function(sourceArray, sourceIndex, destinationArray, destinationIndex, length) {\n    var cloneArray = sourceArray.slice(sourceIndex, sourceIndex + length);\n    for (var i = 0; i < cloneArray.length; i++) {\n        destinationArray[destinationIndex] = cloneArray[i];\n        destinationIndex++\n    }\n};\nwindow.Int32 = {\n    minValue: -parseInt('10000000000000000000000000000000', 2),\n    maxValue: parseInt('1111111111111111111111111111111', 2),\n    parse: function(n) {\n        if (n < this.minValue) {\n            var bigInteger = new Number(-n);\n            var bigIntegerRadix = bigInteger.toString(2);\n            var subBigIntegerRadix = bigIntegerRadix.substr(bigIntegerRadix.length - 31, 31);\n            var reBigIntegerRadix = '';\n            for (var i = 0; i < subBigIntegerRadix.length; i++) {\n                var subBigIntegerRadixItem = subBigIntegerRadix.substr(i, 1);\n                reBigIntegerRadix += subBigIntegerRadixItem == '0' ? '1' : '0'\n            }\n            var result = parseInt(reBigIntegerRadix, 2);\n            return (result + 1)\n        } else if (n > this.maxValue) {\n            var bigInteger = Number(n);\n            var bigIntegerRadix = bigInteger.toString(2);\n            var subBigIntegerRadix = bigIntegerRadix.substr(bigIntegerRadix.length - 31, 31);\n            var reBigIntegerRadix = '';\n            for (var i = 0; i < subBigIntegerRadix.length; i++) {\n                var subBigIntegerRadixItem = subBigIntegerRadix.substr(i, 1);\n                reBigIntegerRadix += subBigIntegerRadixItem == '0' ? '1' : '0'\n            }\n            var result = parseInt(reBigIntegerRadix, 2);\n            return -(result + 1)\n        } else {\n            return n\n        }\n    },\n    parseByte: function(n) {\n        if (n < 0) {\n            var bigInteger = new Number(-n);\n            var bigIntegerRadix = bigInteger.toString(2);\n            var subBigIntegerRadix = bigIntegerRadix.substr(bigIntegerRadix.length - 8, 8);\n            var reBigIntegerRadix = '';\n            for (var i = 0; i < subBigIntegerRadix.length; i++) {\n                var subBigIntegerRadixItem = subBigIntegerRadix.substr(i, 1);\n                reBigIntegerRadix += subBigIntegerRadixItem == '0' ? '1' : '0'\n            }\n            var result = parseInt(reBigIntegerRadix, 2);\n            return (result + 1)\n        } else if (n > 255) {\n            var bigInteger = Number(n);\n            var bigIntegerRadix = bigInteger.toString(2);\n            return parseInt(bigIntegerRadix.substr(bigIntegerRadix.length - 8, 8), 2)\n        } else {\n            return n\n        }\n    }\n};"
  },
  {
    "path": "JavaScript/sm2/js/sm3-sm2-1.0.js",
    "content": "/*! sm3-sm2-1.0.js (c) Jonllen Peng | http://www.jonllen.com/\n */\n/*\n * sm3-sm2-1.0.js\n * \n * Copyright (c) 2014 Jonllen Peng (www.jonllen.com)\n */\n/**\n * @fileOverview\n * @name sm3-sm2-1.0.js\n * @author Jonllen (www.jonllen.com)\n * @version 1.0.0 (2014-06-18)\n */\n\nif (typeof KJUR == \"undefined\" || !KJUR) KJUR = {};\nif (typeof KJUR.crypto == \"undefined\" || !KJUR.crypto) KJUR.crypto = {};\n\n/**\n * class for SM2 key generation,  sm3WithSM2 signing and verifcation\n * @name KJUR.crypto.SM3withSM2\n * @class class for SM2 key generation,  SM2 signing and verifcation\n * @description\n * <p>\n * CAUTION: Most of the case, you don't need to use this class except\n * for generating an SM2 key pair. Please use {@link KJUR.crypto.Signature} class instead.\n * </p>\n * <p>\n * This class was originally developped by Stefan Thomas for Bitcoin JavaScript library.\n * Currently this class supports following named curves and their aliases.\n * <ul>\n * <li>secp256r1, NIST P-256, P-256, prime256v1 (*)</li>\n * <li>secp256k1 (*)</li>\n * <li>secp384r1, NIST P-384, P-384 (*)</li>\n  * <li>sm2</li>\n * </ul>\n * </p>\n */\nKJUR.crypto.SM3withSM2 = function(params) {\n    var curveName = \"sm2\";\t// curve name default\n    var ecparams = null;\n    var prvKeyHex = null;\n    var pubKeyHex = null;\n\n    var rng = new SecureRandom();\n\n    var P_OVER_FOUR = null;\n\n    this.type = \"SM2\";\n\n    function implShamirsTrick(P, k, Q, l) {\n\tvar m = Math.max(k.bitLength(), l.bitLength());\n\tvar Z = P.add2D(Q);\n\tvar R = P.curve.getInfinity();\n\n\tfor (var i = m - 1; i >= 0; --i) {\n\t    R = R.twice2D();\n\n\t    R.z = BigInteger.ONE;\n\n\t    if (k.testBit(i)) {\n\t\tif (l.testBit(i)) {\n\t\t    R = R.add2D(Z);\n\t\t} else {\n\t\t    R = R.add2D(P);\n\t\t}\n\t    } else {\n\t\tif (l.testBit(i)) {\n\t\t    R = R.add2D(Q);\n\t\t}\n\t    }\n\t}\n\t\n\treturn R;\n    };\n\n    //===========================\n    // PUBLIC METHODS\n    //===========================\n    this.getBigRandom = function (limit) {\n\treturn new BigInteger(limit.bitLength(), rng)\n\t.mod(limit.subtract(BigInteger.ONE))\n\t.add(BigInteger.ONE)\n\t;\n    };\n\n    this.setNamedCurve = function(curveName) {\n\tthis.ecparams = KJUR.crypto.ECParameterDB.getByName(curveName);\n\tthis.prvKeyHex = null;\n\tthis.pubKeyHex = null;\n\tthis.curveName = curveName;\n    }\n\n    this.setPrivateKeyHex = function(prvKeyHex) {\n        this.isPrivate = true;\n\tthis.prvKeyHex = prvKeyHex;\n    }\n\n    this.setPublicKeyHex = function(pubKeyHex) {\n        this.isPublic = true;\n\tthis.pubKeyHex = pubKeyHex;\n    }\n\n    /**\n     * generate a EC key pair\n     * @name generateKeyPairHex\n     * @memberOf KJUR.crypto.ECDSA\n     * @function\n     * @return {Array} associative array of hexadecimal string of private and public key\n     * @since ecdsa-modified 1.0.1\n     * @example\n     * var ec = KJUR.crypto.ECDSA({'curve': 'sm2'});\n     * var keypair = ec.generateKeyPairHex();\n     * var pubhex = keypair.ecpubhex; // hexadecimal string of EC private key (=d)\n     * var prvhex = keypair.ecprvhex; // hexadecimal string of EC public key\n     */\n    this.generateKeyPairHex = function() {\n\tvar biN = this.ecparams['n'];\n\tvar biPrv = this.getBigRandom(biN);\n\tvar epPub = this.ecparams['G'].multiply(biPrv);\n\tvar biX = epPub.getX().toBigInteger();\n\tvar biY = epPub.getY().toBigInteger();\n\n\tvar charlen = this.ecparams['keylen'] / 4;\n\tvar hPrv = (\"0000000000\" + biPrv.toString(16)).slice(- charlen);\n\tvar hX   = (\"0000000000\" + biX.toString(16)).slice(- charlen);\n\tvar hY   = (\"0000000000\" + biY.toString(16)).slice(- charlen);\n\tvar hPub = \"04\" + hX + hY;\n\n\tthis.setPrivateKeyHex(hPrv);\n\tthis.setPublicKeyHex(hPub);\n\treturn {'ecprvhex': hPrv, 'ecpubhex': hPub};\n    };\n\n    this.signWithMessageHash = function(hashHex) {\n\treturn this.signHex(hashHex, this.prvKeyHex);\n    };\n\n    /**\n     * signing to message hash\n     * @name signHex\n     * @memberOf KJUR.crypto.SM3withSM2\n     * @function\n     * @param {String} hashHex hexadecimal string of hash value of signing message\n     * @param {String} privHex hexadecimal string of EC private key\n     * @return {String} hexadecimal string of ECDSA signature\n     * @since ecdsa-modified 1.0.1\n     * @example\n     * var ec = KJUR.crypto.SM3withSM2({'curve': 'sm2'});\n     * var sigValue = ec.signHex(hash, prvKey);\n     */\n    this.signHex = function (hashHex, privHex) {\n\tvar d = new BigInteger(privHex, 16);\n\tvar n = this.ecparams['n'];\n\tvar e = new BigInteger(hashHex, 16);\n\t\n\t// k BigInteger\n    var k = null;\n    var kp = null;\n    var r = null;\n    var s = null;\n    var userD = d;\n    \n    do\n    {\n        do\n        {\n\t\t\t\n\t\t\tvar keypair = this.generateKeyPairHex();\n\t\t\t\n\t\t\tk = new BigInteger(keypair.ecprvhex, 16);\n\t\t\tvar pubkeyHex = keypair.ecpubhex;\n\t\t\t\n  \t\t\tkp = ECPointFp.decodeFromHex(this.ecparams['curve'], pubkeyHex);\n\n            // r\n            r = e.add(kp.getX().toBigInteger());\n            r = r.mod(n);\n        }\n        while (r.equals(BigInteger.ZERO) || r.add(k).equals(n));\n\n        // (1 + dA)~-1\n        var da_1 = userD.add(BigInteger.ONE);\n        da_1 = da_1.modInverse(n);\n        // s\n        s = r.multiply(userD);\n        s = k.subtract(s).mod(n);\n        s = da_1.multiply(s).mod(n);\n    }\n    while (s.equals(BigInteger.ZERO));\n    \n\n\treturn KJUR.crypto.ECDSA.biRSSigToASN1Sig(r, s);\n    };\n\n    this.sign = function (hash, priv) {\n\tvar d = priv;\n\tvar n = this.ecparams['n'];\n\tvar e = BigInteger.fromByteArrayUnsigned(hash);\n\n\tdo {\n\t    var k = this.getBigRandom(n);\n\t    var G = this.ecparams['G'];\n\t    var Q = G.multiply(k);\n\t    var r = Q.getX().toBigInteger().mod(n);\n\t} while (r.compareTo(BigInteger.ZERO) <= 0);\n\n\tvar s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);\n\treturn this.serializeSig(r, s);\n    };\n\n    this.verifyWithMessageHash = function(hashHex, sigHex) {\n\treturn this.verifyHex(hashHex, sigHex, this.pubKeyHex);\n    };\n\n    /**\n     * verifying signature with message hash and public key\n     * @name verifyHex\n     * @memberOf KJUR.crypto.SM3withSM2\n     * @function\n     * @param {String} hashHex hexadecimal string of hash value of signing message\n     * @param {String} sigHex hexadecimal string of signature value\n     * @param {String} pubkeyHex hexadecimal string of public key\n     * @return {Boolean} true if the signature is valid, otherwise false\n     * @since ecdsa-modified 1.0.1\n     * @example\n     * var ec = KJUR.crypto.SM3withSM2({'curve': 'sm2'});\n     * var result = ec.verifyHex(msgHashHex, sigHex, pubkeyHex);\n     */\n    this.verifyHex = function(hashHex, sigHex, pubkeyHex) {\n\tvar r,s;\n\n\tvar obj = KJUR.crypto.ECDSA.parseSigHex(sigHex);\n\tr = obj.r;\n\ts = obj.s;\n\n\tvar Q;\n\tQ = ECPointFp.decodeFromHex(this.ecparams['curve'], pubkeyHex);\n\tvar e = new BigInteger(hashHex, 16);\n\n\treturn this.verifyRaw(e, r, s, Q);\n    };\n\n    this.verify = function (hash, sig, pubkey) {\n\tvar r,s;\n\tif (Bitcoin.Util.isArray(sig)) {\n\t    var obj = this.parseSig(sig);\n\t    r = obj.r;\n\t    s = obj.s;\n\t} else if (\"object\" === typeof sig && sig.r && sig.s) {\n\t    r = sig.r;\n\t    s = sig.s;\n\t} else {\n\t    throw \"Invalid value for signature\";\n\t}\n\n\tvar Q;\n\tif (pubkey instanceof ECPointFp) {\n\t    Q = pubkey;\n\t} else if (Bitcoin.Util.isArray(pubkey)) {\n\t    Q = ECPointFp.decodeFrom(this.ecparams['curve'], pubkey);\n\t} else {\n\t    throw \"Invalid format for pubkey value, must be byte array or ECPointFp\";\n\t}\n\tvar e = BigInteger.fromByteArrayUnsigned(hash);\n\n\treturn this.verifyRaw(e, r, s, Q);\n    };\n\n    this.verifyRaw = function (e, r, s, Q) {\n\tvar n = this.ecparams['n'];\n\tvar G = this.ecparams['G'];\n\t\n\tvar t = r.add(s).mod(n);\n    if (t.equals(BigInteger.ZERO))\n        return false;\n        \n    var x1y1 = G.multiply(s);\n    x1y1 = x1y1.add(Q.multiply(t));\n\n    var R = e.add(x1y1.getX().toBigInteger()).mod(n);\n    return r.equals(R);\n    };\n\n    /**\n     * Serialize a signature into DER format.\n     *\n     * Takes two BigIntegers representing r and s and returns a byte array.\n     */\n    this.serializeSig = function (r, s) {\n\tvar rBa = r.toByteArraySigned();\n\tvar sBa = s.toByteArraySigned();\n\n\tvar sequence = [];\n\tsequence.push(0x02); // INTEGER\n\tsequence.push(rBa.length);\n\tsequence = sequence.concat(rBa);\n\n\tsequence.push(0x02); // INTEGER\n\tsequence.push(sBa.length);\n\tsequence = sequence.concat(sBa);\n\n\tsequence.unshift(sequence.length);\n\tsequence.unshift(0x30); // SEQUENCE\n\treturn sequence;\n    };\n\n    /**\n     * Parses a byte array containing a DER-encoded signature.\n     *\n     * This function will return an object of the form:\n     *\n     * {\n     *   r: BigInteger,\n     *   s: BigInteger\n     * }\n     */\n    this.parseSig = function (sig) {\n\tvar cursor;\n\tif (sig[0] != 0x30)\n\t    throw new Error(\"Signature not a valid DERSequence\");\n\n\tcursor = 2;\n\tif (sig[cursor] != 0x02)\n\t    throw new Error(\"First element in signature must be a DERInteger\");;\n\tvar rBa = sig.slice(cursor+2, cursor+2+sig[cursor+1]);\n\n\tcursor += 2+sig[cursor+1];\n\tif (sig[cursor] != 0x02)\n\t    throw new Error(\"Second element in signature must be a DERInteger\");\n\tvar sBa = sig.slice(cursor+2, cursor+2+sig[cursor+1]);\n\n\tcursor += 2+sig[cursor+1];\n\n\t//if (cursor != sig.length)\n\t//  throw new Error(\"Extra bytes in signature\");\n\n\tvar r = BigInteger.fromByteArrayUnsigned(rBa);\n\tvar s = BigInteger.fromByteArrayUnsigned(sBa);\n\n\treturn {r: r, s: s};\n    };\n\n    this.parseSigCompact = function (sig) {\n\tif (sig.length !== 65) {\n\t    throw \"Signature has the wrong length\";\n\t}\n\n\t// Signature is prefixed with a type byte storing three bits of\n\t// information.\n\tvar i = sig[0] - 27;\n\tif (i < 0 || i > 7) {\n\t    throw \"Invalid signature type\";\n\t}\n\n\tvar n = this.ecparams['n'];\n\tvar r = BigInteger.fromByteArrayUnsigned(sig.slice(1, 33)).mod(n);\n\tvar s = BigInteger.fromByteArrayUnsigned(sig.slice(33, 65)).mod(n);\n\n\treturn {r: r, s: s, i: i};\n    };\n\n    if (params !== undefined) {\n\tif (params['curve'] !== undefined) {\n\t    this.curveName = params['curve'];\n\t}\n    }\n    if (this.curveName === undefined) this.curveName = curveName;\n    this.setNamedCurve(this.curveName);\n    if (params !== undefined) {\n\tif (params['prv'] !== undefined) this.setPrivateKeyHex(params['prv']);\n\tif (params['pub'] !== undefined) this.setPublicKeyHex(params['pub']);\n    }\n};\n"
  },
  {
    "path": "JavaScript/sm2/js/sm3.js",
    "content": "(function(){var C=CryptoJS;var C_lib=C.lib;var WordArray=C_lib.WordArray;var Hasher=C_lib.Hasher;var C_algo=C.algo;var W=[];var SM3=C_algo.SM3=Hasher.extend({_doReset:function(){this._hash=new WordArray.init([0x7380166f,0x4914b2b9,0x172442d7,0xda8a0600,0xa96f30bc,0x163138aa,0xe38dee4d,0xb0fb0e4e])},_doProcessBlock:function(M,offset){var H=this._hash.words;var a=H[0];var b=H[1];var c=H[2];var d=H[3];var e=H[4];for(var i=0;i<80;i++){if(i<16){W[i]=M[offset+i]|0}else{var n=W[i-3]^W[i-8]^W[i-14]^W[i-16];W[i]=(n<<1)|(n>>>31)}var t=((a<<5)|(a>>>27))+e+W[i];if(i<20){t+=((b&c)|(~b&d))+0x5a827999}else if(i<40){t+=(b^c^d)+0x6ed9eba1}else if(i<60){t+=((b&c)|(b&d)|(c&d))-0x70e44324}else{t+=(b^c^d)-0x359d3e2a}e=d;d=c;c=(b<<30)|(b>>>2);b=a;a=t}H[0]=(H[0]+a)|0;H[1]=(H[1]+b)|0;H[2]=(H[2]+c)|0;H[3]=(H[3]+d)|0;H[4]=(H[4]+e)|0},_doFinalize:function(){var data=this._data;var dataWords=data.words;var nBitsTotal=this._nDataBytes*8;var nBitsLeft=data.sigBytes*8;dataWords[nBitsLeft>>>5]|=0x80<<(24-nBitsLeft%32);dataWords[(((nBitsLeft+64)>>>9)<<4)+14]=Math.floor(nBitsTotal/0x100000000);dataWords[(((nBitsLeft+64)>>>9)<<4)+15]=nBitsTotal;data.sigBytes=dataWords.length*4;this._process();return this._hash},clone:function(){var clone=Hasher.clone.call(this);clone._hash=this._hash.clone();return clone}});C.SM3=Hasher._createHelper(SM3);C.HmacSM3=Hasher._createHmacHelper(SM3)}());function SM3Digest(){this.BYTE_LENGTH=64;this.xBuf=new Array();this.xBufOff=0;this.byteCount=0;this.DIGEST_LENGTH=32;this.v0=[0x7380166f,0x4914b2b9,0x172442d7,0xda8a0600,0xa96f30bc,0x163138aa,0xe38dee4d,0xb0fb0e4e];this.v0=[0x7380166f,0x4914b2b9,0x172442d7,-628488704,-1452330820,0x163138aa,-477237683,-1325724082];this.v=new Array(8);this.v_=new Array(8);this.X0=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];this.X=new Array(68);this.xOff=0;this.T_00_15=0x79cc4519;this.T_16_63=0x7a879d8a;if(arguments.length>0){this.InitDigest(arguments[0])}else{this.Init()}}SM3Digest.prototype={Init:function(){this.xBuf=new Array(4);this.Reset()},InitDigest:function(t){this.xBuf=new Array(t.xBuf.length);Array.Copy(t.xBuf,0,this.xBuf,0,t.xBuf.length);this.xBufOff=t.xBufOff;this.byteCount=t.byteCount;Array.Copy(t.X,0,this.X,0,t.X.length);this.xOff=t.xOff;Array.Copy(t.v,0,this.v,0,t.v.length)},GetDigestSize:function(){return this.DIGEST_LENGTH},Reset:function(){this.byteCount=0;this.xBufOff=0;Array.Clear(this.xBuf,0,this.xBuf.length);Array.Copy(this.v0,0,this.v,0,this.v0.length);this.xOff=0;Array.Copy(this.X0,0,this.X,0,this.X0.length)},GetByteLength:function(){return this.BYTE_LENGTH},ProcessBlock:function(){var i;var ww=this.X;var ww_=new Array(64);for(i=16;i<68;i++){ww[i]=this.P1(ww[i-16]^ww[i-9]^(this.ROTATE(ww[i-3],15)))^(this.ROTATE(ww[i-13],7))^ww[i-6]}for(i=0;i<64;i++){ww_[i]=ww[i]^ww[i+4]}var vv=this.v;var vv_=this.v_;Array.Copy(vv,0,vv_,0,this.v0.length);var SS1,SS2,TT1,TT2,aaa;for(i=0;i<16;i++){aaa=this.ROTATE(vv_[0],12);SS1=Int32.parse(Int32.parse(aaa+vv_[4])+this.ROTATE(this.T_00_15,i));SS1=this.ROTATE(SS1,7);SS2=SS1^aaa;TT1=Int32.parse(Int32.parse(this.FF_00_15(vv_[0],vv_[1],vv_[2])+vv_[3])+SS2)+ww_[i];TT2=Int32.parse(Int32.parse(this.GG_00_15(vv_[4],vv_[5],vv_[6])+vv_[7])+SS1)+ww[i];vv_[3]=vv_[2];vv_[2]=this.ROTATE(vv_[1],9);vv_[1]=vv_[0];vv_[0]=TT1;vv_[7]=vv_[6];vv_[6]=this.ROTATE(vv_[5],19);vv_[5]=vv_[4];vv_[4]=this.P0(TT2)}for(i=16;i<64;i++){aaa=this.ROTATE(vv_[0],12);SS1=Int32.parse(Int32.parse(aaa+vv_[4])+this.ROTATE(this.T_16_63,i));SS1=this.ROTATE(SS1,7);SS2=SS1^aaa;TT1=Int32.parse(Int32.parse(this.FF_16_63(vv_[0],vv_[1],vv_[2])+vv_[3])+SS2)+ww_[i];TT2=Int32.parse(Int32.parse(this.GG_16_63(vv_[4],vv_[5],vv_[6])+vv_[7])+SS1)+ww[i];vv_[3]=vv_[2];vv_[2]=this.ROTATE(vv_[1],9);vv_[1]=vv_[0];vv_[0]=TT1;vv_[7]=vv_[6];vv_[6]=this.ROTATE(vv_[5],19);vv_[5]=vv_[4];vv_[4]=this.P0(TT2)}for(i=0;i<8;i++){vv[i]^=Int32.parse(vv_[i])}this.xOff=0;Array.Copy(this.X0,0,this.X,0,this.X0.length)},ProcessWord:function(in_Renamed,inOff){var n=in_Renamed[inOff]<<24;n|=(in_Renamed[++inOff]&0xff)<<16;n|=(in_Renamed[++inOff]&0xff)<<8;n|=(in_Renamed[++inOff]&0xff);this.X[this.xOff]=n;if(++this.xOff==16){this.ProcessBlock()}},ProcessLength:function(bitLength){if(this.xOff>14){this.ProcessBlock()}this.X[14]=(this.URShiftLong(bitLength,32));this.X[15]=(bitLength&(0xffffffff))},IntToBigEndian:function(n,bs,off){bs[off]=Int32.parseByte(this.URShift(n,24));bs[++off]=Int32.parseByte(this.URShift(n,16));bs[++off]=Int32.parseByte(this.URShift(n,8));bs[++off]=Int32.parseByte(n)},DoFinal:function(out_Renamed,outOff){this.Finish();for(var i=0;i<8;i++){this.IntToBigEndian(this.v[i],out_Renamed,outOff+i*4)}this.Reset();return this.DIGEST_LENGTH},Update:function(input){this.xBuf[this.xBufOff++]=input;if(this.xBufOff==this.xBuf.length){this.ProcessWord(this.xBuf,0);this.xBufOff=0}this.byteCount++},BlockUpdate:function(input,inOff,length){while((this.xBufOff!=0)&&(length>0)){this.Update(input[inOff]);inOff++;length--}while(length>this.xBuf.length){this.ProcessWord(input,inOff);inOff+=this.xBuf.length;length-=this.xBuf.length;this.byteCount+=this.xBuf.length}while(length>0){this.Update(input[inOff]);inOff++;length--}},Finish:function(){var bitLength=(this.byteCount<<3);this.Update((128));while(this.xBufOff!=0)this.Update((0));this.ProcessLength(bitLength);this.ProcessBlock()},ROTATE:function(x,n){return(x<<n)|(this.URShift(x,(32-n)))},P0:function(X){return((X)^this.ROTATE((X),9)^this.ROTATE((X),17))},P1:function(X){return((X)^this.ROTATE((X),15)^this.ROTATE((X),23))},FF_00_15:function(X,Y,Z){return(X^Y^Z)},FF_16_63:function(X,Y,Z){return((X&Y)|(X&Z)|(Y&Z))},GG_00_15:function(X,Y,Z){return(X^Y^Z)},GG_16_63:function(X,Y,Z){return((X&Y)|(~X&Z))},URShift:function(number,bits){if(number>Int32.maxValue||number<Int32.minValue){number=Int32.parse(number)}if(number>=0){return number>>bits}else{return(number>>bits)+(2<<~bits)}},URShiftLong:function(number,bits){var returnV;var big=new BigInteger();big.fromInt(number);if(big.signum()>=0){returnV=big.shiftRight(bits).intValue()}else{var bigAdd=new BigInteger();bigAdd.fromInt(2);var shiftLeftBits=~bits;var shiftLeftNumber='';if(shiftLeftBits<0){var shiftRightBits=64+shiftLeftBits;for(var i=0;i<shiftRightBits;i++){shiftLeftNumber+='0'}var shiftLeftNumberBigAdd=new BigInteger();shiftLeftNumberBigAdd.fromInt(number>>bits);var shiftLeftNumberBig=new BigInteger(\"10\"+shiftLeftNumber,2);shiftLeftNumber=shiftLeftNumberBig.toRadix(10);var r=shiftLeftNumberBig.add(shiftLeftNumberBigAdd);returnV=r.toRadix(10)}else{shiftLeftNumber=bigAdd.shiftLeft((~bits)).intValue();returnV=(number>>bits)+shiftLeftNumber}}return returnV},GetZ:function(g,pubKeyHex){var userId=CryptoJS.enc.Utf8.parse(\"1234567812345678\");var len=userId.words.length*4*8;this.Update((len>>8&0x00ff));this.Update((len&0x00ff));var userIdWords=this.GetWords(userId.toString());this.BlockUpdate(userIdWords,0,userIdWords.length);var aWords=this.GetWords(g.curve.a.toBigInteger().toRadix(16));var bWords=this.GetWords(g.curve.b.toBigInteger().toRadix(16));var gxWords=this.GetWords(g.getX().toBigInteger().toRadix(16));var gyWords=this.GetWords(g.getY().toBigInteger().toRadix(16));var pxWords=this.GetWords(pubKeyHex.substr(0,64));var pyWords=this.GetWords(pubKeyHex.substr(64,64));this.BlockUpdate(aWords,0,aWords.length);this.BlockUpdate(bWords,0,bWords.length);this.BlockUpdate(gxWords,0,gxWords.length);this.BlockUpdate(gyWords,0,gyWords.length);this.BlockUpdate(pxWords,0,pxWords.length);this.BlockUpdate(pyWords,0,pyWords.length);var md=new Array(this.GetDigestSize());this.DoFinal(md,0);return md},GetWords:function(hexStr){var words=[];var hexStrLength=hexStr.length;for(var i=0;i<hexStrLength;i+=2){words[words.length]=parseInt(hexStr.substr(i,2),16)}return words},GetHex:function(arr){var words=[];var j=0;for(var i=0;i<arr.length*2;i+=2){words[i>>>3]|=parseInt(arr[j])<<(24-(i%8)*4);j++}var wordArray=new CryptoJS.lib.WordArray.init(words,arr.length);return wordArray}};Array.Clear=function(destinationArray,destinationIndex,length){for(elm in destinationArray){destinationArray[elm]=null}};Array.Copy=function(sourceArray,sourceIndex,destinationArray,destinationIndex,length){var cloneArray=sourceArray.slice(sourceIndex,sourceIndex+length);for(var i=0;i<cloneArray.length;i++){destinationArray[destinationIndex]=cloneArray[i];destinationIndex++}};window.Int32={minValue:-parseInt('10000000000000000000000000000000',2),maxValue:parseInt('1111111111111111111111111111111',2),parse:function(n){if(n<this.minValue){var bigInteger=new Number(-n);var bigIntegerRadix=bigInteger.toString(2);var subBigIntegerRadix=bigIntegerRadix.substr(bigIntegerRadix.length-31,31);var reBigIntegerRadix='';for(var i=0;i<subBigIntegerRadix.length;i++){var subBigIntegerRadixItem=subBigIntegerRadix.substr(i,1);reBigIntegerRadix+=subBigIntegerRadixItem=='0'?'1':'0'}var result=parseInt(reBigIntegerRadix,2);return(result+1)}else if(n>this.maxValue){var bigInteger=Number(n);var bigIntegerRadix=bigInteger.toString(2);var subBigIntegerRadix=bigIntegerRadix.substr(bigIntegerRadix.length-31,31);var reBigIntegerRadix='';for(var i=0;i<subBigIntegerRadix.length;i++){var subBigIntegerRadixItem=subBigIntegerRadix.substr(i,1);reBigIntegerRadix+=subBigIntegerRadixItem=='0'?'1':'0'}var result=parseInt(reBigIntegerRadix,2);return-(result+1)}else{return n}},parseByte:function(n){if(n<0){var bigInteger=new Number(-n);var bigIntegerRadix=bigInteger.toString(2);var subBigIntegerRadix=bigIntegerRadix.substr(bigIntegerRadix.length-8,8);var reBigIntegerRadix='';for(var i=0;i<subBigIntegerRadix.length;i++){var subBigIntegerRadixItem=subBigIntegerRadix.substr(i,1);reBigIntegerRadix+=subBigIntegerRadixItem=='0'?'1':'0'}var result=parseInt(reBigIntegerRadix,2);return(result+1)}else if(n>255){var bigInteger=Number(n);var bigIntegerRadix=bigInteger.toString(2);return parseInt(bigIntegerRadix.substr(bigIntegerRadix.length-8,8),2)}else{return n}}};"
  },
  {
    "path": "JavaScript/sm2/js/tripledes.js",
    "content": "/*\nCryptoJS v3.1.2\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function () {\n    // Shortcuts\n    var C = CryptoJS;\n    var C_lib = C.lib;\n    var WordArray = C_lib.WordArray;\n    var BlockCipher = C_lib.BlockCipher;\n    var C_algo = C.algo;\n\n    // Permuted Choice 1 constants\n    var PC1 = [\n        57, 49, 41, 33, 25, 17, 9,  1,\n        58, 50, 42, 34, 26, 18, 10, 2,\n        59, 51, 43, 35, 27, 19, 11, 3,\n        60, 52, 44, 36, 63, 55, 47, 39,\n        31, 23, 15, 7,  62, 54, 46, 38,\n        30, 22, 14, 6,  61, 53, 45, 37,\n        29, 21, 13, 5,  28, 20, 12, 4\n    ];\n\n    // Permuted Choice 2 constants\n    var PC2 = [\n        14, 17, 11, 24, 1,  5,\n        3,  28, 15, 6,  21, 10,\n        23, 19, 12, 4,  26, 8,\n        16, 7,  27, 20, 13, 2,\n        41, 52, 31, 37, 47, 55,\n        30, 40, 51, 45, 33, 48,\n        44, 49, 39, 56, 34, 53,\n        46, 42, 50, 36, 29, 32\n    ];\n\n    // Cumulative bit shift constants\n    var BIT_SHIFTS = [1,  2,  4,  6,  8,  10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28];\n\n    // SBOXes and round permutation constants\n    var SBOX_P = [\n        {\n            0x0: 0x808200,\n            0x10000000: 0x8000,\n            0x20000000: 0x808002,\n            0x30000000: 0x2,\n            0x40000000: 0x200,\n            0x50000000: 0x808202,\n            0x60000000: 0x800202,\n            0x70000000: 0x800000,\n            0x80000000: 0x202,\n            0x90000000: 0x800200,\n            0xa0000000: 0x8200,\n            0xb0000000: 0x808000,\n            0xc0000000: 0x8002,\n            0xd0000000: 0x800002,\n            0xe0000000: 0x0,\n            0xf0000000: 0x8202,\n            0x8000000: 0x0,\n            0x18000000: 0x808202,\n            0x28000000: 0x8202,\n            0x38000000: 0x8000,\n            0x48000000: 0x808200,\n            0x58000000: 0x200,\n            0x68000000: 0x808002,\n            0x78000000: 0x2,\n            0x88000000: 0x800200,\n            0x98000000: 0x8200,\n            0xa8000000: 0x808000,\n            0xb8000000: 0x800202,\n            0xc8000000: 0x800002,\n            0xd8000000: 0x8002,\n            0xe8000000: 0x202,\n            0xf8000000: 0x800000,\n            0x1: 0x8000,\n            0x10000001: 0x2,\n            0x20000001: 0x808200,\n            0x30000001: 0x800000,\n            0x40000001: 0x808002,\n            0x50000001: 0x8200,\n            0x60000001: 0x200,\n            0x70000001: 0x800202,\n            0x80000001: 0x808202,\n            0x90000001: 0x808000,\n            0xa0000001: 0x800002,\n            0xb0000001: 0x8202,\n            0xc0000001: 0x202,\n            0xd0000001: 0x800200,\n            0xe0000001: 0x8002,\n            0xf0000001: 0x0,\n            0x8000001: 0x808202,\n            0x18000001: 0x808000,\n            0x28000001: 0x800000,\n            0x38000001: 0x200,\n            0x48000001: 0x8000,\n            0x58000001: 0x800002,\n            0x68000001: 0x2,\n            0x78000001: 0x8202,\n            0x88000001: 0x8002,\n            0x98000001: 0x800202,\n            0xa8000001: 0x202,\n            0xb8000001: 0x808200,\n            0xc8000001: 0x800200,\n            0xd8000001: 0x0,\n            0xe8000001: 0x8200,\n            0xf8000001: 0x808002\n        },\n        {\n            0x0: 0x40084010,\n            0x1000000: 0x4000,\n            0x2000000: 0x80000,\n            0x3000000: 0x40080010,\n            0x4000000: 0x40000010,\n            0x5000000: 0x40084000,\n            0x6000000: 0x40004000,\n            0x7000000: 0x10,\n            0x8000000: 0x84000,\n            0x9000000: 0x40004010,\n            0xa000000: 0x40000000,\n            0xb000000: 0x84010,\n            0xc000000: 0x80010,\n            0xd000000: 0x0,\n            0xe000000: 0x4010,\n            0xf000000: 0x40080000,\n            0x800000: 0x40004000,\n            0x1800000: 0x84010,\n            0x2800000: 0x10,\n            0x3800000: 0x40004010,\n            0x4800000: 0x40084010,\n            0x5800000: 0x40000000,\n            0x6800000: 0x80000,\n            0x7800000: 0x40080010,\n            0x8800000: 0x80010,\n            0x9800000: 0x0,\n            0xa800000: 0x4000,\n            0xb800000: 0x40080000,\n            0xc800000: 0x40000010,\n            0xd800000: 0x84000,\n            0xe800000: 0x40084000,\n            0xf800000: 0x4010,\n            0x10000000: 0x0,\n            0x11000000: 0x40080010,\n            0x12000000: 0x40004010,\n            0x13000000: 0x40084000,\n            0x14000000: 0x40080000,\n            0x15000000: 0x10,\n            0x16000000: 0x84010,\n            0x17000000: 0x4000,\n            0x18000000: 0x4010,\n            0x19000000: 0x80000,\n            0x1a000000: 0x80010,\n            0x1b000000: 0x40000010,\n            0x1c000000: 0x84000,\n            0x1d000000: 0x40004000,\n            0x1e000000: 0x40000000,\n            0x1f000000: 0x40084010,\n            0x10800000: 0x84010,\n            0x11800000: 0x80000,\n            0x12800000: 0x40080000,\n            0x13800000: 0x4000,\n            0x14800000: 0x40004000,\n            0x15800000: 0x40084010,\n            0x16800000: 0x10,\n            0x17800000: 0x40000000,\n            0x18800000: 0x40084000,\n            0x19800000: 0x40000010,\n            0x1a800000: 0x40004010,\n            0x1b800000: 0x80010,\n            0x1c800000: 0x0,\n            0x1d800000: 0x4010,\n            0x1e800000: 0x40080010,\n            0x1f800000: 0x84000\n        },\n        {\n            0x0: 0x104,\n            0x100000: 0x0,\n            0x200000: 0x4000100,\n            0x300000: 0x10104,\n            0x400000: 0x10004,\n            0x500000: 0x4000004,\n            0x600000: 0x4010104,\n            0x700000: 0x4010000,\n            0x800000: 0x4000000,\n            0x900000: 0x4010100,\n            0xa00000: 0x10100,\n            0xb00000: 0x4010004,\n            0xc00000: 0x4000104,\n            0xd00000: 0x10000,\n            0xe00000: 0x4,\n            0xf00000: 0x100,\n            0x80000: 0x4010100,\n            0x180000: 0x4010004,\n            0x280000: 0x0,\n            0x380000: 0x4000100,\n            0x480000: 0x4000004,\n            0x580000: 0x10000,\n            0x680000: 0x10004,\n            0x780000: 0x104,\n            0x880000: 0x4,\n            0x980000: 0x100,\n            0xa80000: 0x4010000,\n            0xb80000: 0x10104,\n            0xc80000: 0x10100,\n            0xd80000: 0x4000104,\n            0xe80000: 0x4010104,\n            0xf80000: 0x4000000,\n            0x1000000: 0x4010100,\n            0x1100000: 0x10004,\n            0x1200000: 0x10000,\n            0x1300000: 0x4000100,\n            0x1400000: 0x100,\n            0x1500000: 0x4010104,\n            0x1600000: 0x4000004,\n            0x1700000: 0x0,\n            0x1800000: 0x4000104,\n            0x1900000: 0x4000000,\n            0x1a00000: 0x4,\n            0x1b00000: 0x10100,\n            0x1c00000: 0x4010000,\n            0x1d00000: 0x104,\n            0x1e00000: 0x10104,\n            0x1f00000: 0x4010004,\n            0x1080000: 0x4000000,\n            0x1180000: 0x104,\n            0x1280000: 0x4010100,\n            0x1380000: 0x0,\n            0x1480000: 0x10004,\n            0x1580000: 0x4000100,\n            0x1680000: 0x100,\n            0x1780000: 0x4010004,\n            0x1880000: 0x10000,\n            0x1980000: 0x4010104,\n            0x1a80000: 0x10104,\n            0x1b80000: 0x4000004,\n            0x1c80000: 0x4000104,\n            0x1d80000: 0x4010000,\n            0x1e80000: 0x4,\n            0x1f80000: 0x10100\n        },\n        {\n            0x0: 0x80401000,\n            0x10000: 0x80001040,\n            0x20000: 0x401040,\n            0x30000: 0x80400000,\n            0x40000: 0x0,\n            0x50000: 0x401000,\n            0x60000: 0x80000040,\n            0x70000: 0x400040,\n            0x80000: 0x80000000,\n            0x90000: 0x400000,\n            0xa0000: 0x40,\n            0xb0000: 0x80001000,\n            0xc0000: 0x80400040,\n            0xd0000: 0x1040,\n            0xe0000: 0x1000,\n            0xf0000: 0x80401040,\n            0x8000: 0x80001040,\n            0x18000: 0x40,\n            0x28000: 0x80400040,\n            0x38000: 0x80001000,\n            0x48000: 0x401000,\n            0x58000: 0x80401040,\n            0x68000: 0x0,\n            0x78000: 0x80400000,\n            0x88000: 0x1000,\n            0x98000: 0x80401000,\n            0xa8000: 0x400000,\n            0xb8000: 0x1040,\n            0xc8000: 0x80000000,\n            0xd8000: 0x400040,\n            0xe8000: 0x401040,\n            0xf8000: 0x80000040,\n            0x100000: 0x400040,\n            0x110000: 0x401000,\n            0x120000: 0x80000040,\n            0x130000: 0x0,\n            0x140000: 0x1040,\n            0x150000: 0x80400040,\n            0x160000: 0x80401000,\n            0x170000: 0x80001040,\n            0x180000: 0x80401040,\n            0x190000: 0x80000000,\n            0x1a0000: 0x80400000,\n            0x1b0000: 0x401040,\n            0x1c0000: 0x80001000,\n            0x1d0000: 0x400000,\n            0x1e0000: 0x40,\n            0x1f0000: 0x1000,\n            0x108000: 0x80400000,\n            0x118000: 0x80401040,\n            0x128000: 0x0,\n            0x138000: 0x401000,\n            0x148000: 0x400040,\n            0x158000: 0x80000000,\n            0x168000: 0x80001040,\n            0x178000: 0x40,\n            0x188000: 0x80000040,\n            0x198000: 0x1000,\n            0x1a8000: 0x80001000,\n            0x1b8000: 0x80400040,\n            0x1c8000: 0x1040,\n            0x1d8000: 0x80401000,\n            0x1e8000: 0x400000,\n            0x1f8000: 0x401040\n        },\n        {\n            0x0: 0x80,\n            0x1000: 0x1040000,\n            0x2000: 0x40000,\n            0x3000: 0x20000000,\n            0x4000: 0x20040080,\n            0x5000: 0x1000080,\n            0x6000: 0x21000080,\n            0x7000: 0x40080,\n            0x8000: 0x1000000,\n            0x9000: 0x20040000,\n            0xa000: 0x20000080,\n            0xb000: 0x21040080,\n            0xc000: 0x21040000,\n            0xd000: 0x0,\n            0xe000: 0x1040080,\n            0xf000: 0x21000000,\n            0x800: 0x1040080,\n            0x1800: 0x21000080,\n            0x2800: 0x80,\n            0x3800: 0x1040000,\n            0x4800: 0x40000,\n            0x5800: 0x20040080,\n            0x6800: 0x21040000,\n            0x7800: 0x20000000,\n            0x8800: 0x20040000,\n            0x9800: 0x0,\n            0xa800: 0x21040080,\n            0xb800: 0x1000080,\n            0xc800: 0x20000080,\n            0xd800: 0x21000000,\n            0xe800: 0x1000000,\n            0xf800: 0x40080,\n            0x10000: 0x40000,\n            0x11000: 0x80,\n            0x12000: 0x20000000,\n            0x13000: 0x21000080,\n            0x14000: 0x1000080,\n            0x15000: 0x21040000,\n            0x16000: 0x20040080,\n            0x17000: 0x1000000,\n            0x18000: 0x21040080,\n            0x19000: 0x21000000,\n            0x1a000: 0x1040000,\n            0x1b000: 0x20040000,\n            0x1c000: 0x40080,\n            0x1d000: 0x20000080,\n            0x1e000: 0x0,\n            0x1f000: 0x1040080,\n            0x10800: 0x21000080,\n            0x11800: 0x1000000,\n            0x12800: 0x1040000,\n            0x13800: 0x20040080,\n            0x14800: 0x20000000,\n            0x15800: 0x1040080,\n            0x16800: 0x80,\n            0x17800: 0x21040000,\n            0x18800: 0x40080,\n            0x19800: 0x21040080,\n            0x1a800: 0x0,\n            0x1b800: 0x21000000,\n            0x1c800: 0x1000080,\n            0x1d800: 0x40000,\n            0x1e800: 0x20040000,\n            0x1f800: 0x20000080\n        },\n        {\n            0x0: 0x10000008,\n            0x100: 0x2000,\n            0x200: 0x10200000,\n            0x300: 0x10202008,\n            0x400: 0x10002000,\n            0x500: 0x200000,\n            0x600: 0x200008,\n            0x700: 0x10000000,\n            0x800: 0x0,\n            0x900: 0x10002008,\n            0xa00: 0x202000,\n            0xb00: 0x8,\n            0xc00: 0x10200008,\n            0xd00: 0x202008,\n            0xe00: 0x2008,\n            0xf00: 0x10202000,\n            0x80: 0x10200000,\n            0x180: 0x10202008,\n            0x280: 0x8,\n            0x380: 0x200000,\n            0x480: 0x202008,\n            0x580: 0x10000008,\n            0x680: 0x10002000,\n            0x780: 0x2008,\n            0x880: 0x200008,\n            0x980: 0x2000,\n            0xa80: 0x10002008,\n            0xb80: 0x10200008,\n            0xc80: 0x0,\n            0xd80: 0x10202000,\n            0xe80: 0x202000,\n            0xf80: 0x10000000,\n            0x1000: 0x10002000,\n            0x1100: 0x10200008,\n            0x1200: 0x10202008,\n            0x1300: 0x2008,\n            0x1400: 0x200000,\n            0x1500: 0x10000000,\n            0x1600: 0x10000008,\n            0x1700: 0x202000,\n            0x1800: 0x202008,\n            0x1900: 0x0,\n            0x1a00: 0x8,\n            0x1b00: 0x10200000,\n            0x1c00: 0x2000,\n            0x1d00: 0x10002008,\n            0x1e00: 0x10202000,\n            0x1f00: 0x200008,\n            0x1080: 0x8,\n            0x1180: 0x202000,\n            0x1280: 0x200000,\n            0x1380: 0x10000008,\n            0x1480: 0x10002000,\n            0x1580: 0x2008,\n            0x1680: 0x10202008,\n            0x1780: 0x10200000,\n            0x1880: 0x10202000,\n            0x1980: 0x10200008,\n            0x1a80: 0x2000,\n            0x1b80: 0x202008,\n            0x1c80: 0x200008,\n            0x1d80: 0x0,\n            0x1e80: 0x10000000,\n            0x1f80: 0x10002008\n        },\n        {\n            0x0: 0x100000,\n            0x10: 0x2000401,\n            0x20: 0x400,\n            0x30: 0x100401,\n            0x40: 0x2100401,\n            0x50: 0x0,\n            0x60: 0x1,\n            0x70: 0x2100001,\n            0x80: 0x2000400,\n            0x90: 0x100001,\n            0xa0: 0x2000001,\n            0xb0: 0x2100400,\n            0xc0: 0x2100000,\n            0xd0: 0x401,\n            0xe0: 0x100400,\n            0xf0: 0x2000000,\n            0x8: 0x2100001,\n            0x18: 0x0,\n            0x28: 0x2000401,\n            0x38: 0x2100400,\n            0x48: 0x100000,\n            0x58: 0x2000001,\n            0x68: 0x2000000,\n            0x78: 0x401,\n            0x88: 0x100401,\n            0x98: 0x2000400,\n            0xa8: 0x2100000,\n            0xb8: 0x100001,\n            0xc8: 0x400,\n            0xd8: 0x2100401,\n            0xe8: 0x1,\n            0xf8: 0x100400,\n            0x100: 0x2000000,\n            0x110: 0x100000,\n            0x120: 0x2000401,\n            0x130: 0x2100001,\n            0x140: 0x100001,\n            0x150: 0x2000400,\n            0x160: 0x2100400,\n            0x170: 0x100401,\n            0x180: 0x401,\n            0x190: 0x2100401,\n            0x1a0: 0x100400,\n            0x1b0: 0x1,\n            0x1c0: 0x0,\n            0x1d0: 0x2100000,\n            0x1e0: 0x2000001,\n            0x1f0: 0x400,\n            0x108: 0x100400,\n            0x118: 0x2000401,\n            0x128: 0x2100001,\n            0x138: 0x1,\n            0x148: 0x2000000,\n            0x158: 0x100000,\n            0x168: 0x401,\n            0x178: 0x2100400,\n            0x188: 0x2000001,\n            0x198: 0x2100000,\n            0x1a8: 0x0,\n            0x1b8: 0x2100401,\n            0x1c8: 0x100401,\n            0x1d8: 0x400,\n            0x1e8: 0x2000400,\n            0x1f8: 0x100001\n        },\n        {\n            0x0: 0x8000820,\n            0x1: 0x20000,\n            0x2: 0x8000000,\n            0x3: 0x20,\n            0x4: 0x20020,\n            0x5: 0x8020820,\n            0x6: 0x8020800,\n            0x7: 0x800,\n            0x8: 0x8020000,\n            0x9: 0x8000800,\n            0xa: 0x20800,\n            0xb: 0x8020020,\n            0xc: 0x820,\n            0xd: 0x0,\n            0xe: 0x8000020,\n            0xf: 0x20820,\n            0x80000000: 0x800,\n            0x80000001: 0x8020820,\n            0x80000002: 0x8000820,\n            0x80000003: 0x8000000,\n            0x80000004: 0x8020000,\n            0x80000005: 0x20800,\n            0x80000006: 0x20820,\n            0x80000007: 0x20,\n            0x80000008: 0x8000020,\n            0x80000009: 0x820,\n            0x8000000a: 0x20020,\n            0x8000000b: 0x8020800,\n            0x8000000c: 0x0,\n            0x8000000d: 0x8020020,\n            0x8000000e: 0x8000800,\n            0x8000000f: 0x20000,\n            0x10: 0x20820,\n            0x11: 0x8020800,\n            0x12: 0x20,\n            0x13: 0x800,\n            0x14: 0x8000800,\n            0x15: 0x8000020,\n            0x16: 0x8020020,\n            0x17: 0x20000,\n            0x18: 0x0,\n            0x19: 0x20020,\n            0x1a: 0x8020000,\n            0x1b: 0x8000820,\n            0x1c: 0x8020820,\n            0x1d: 0x20800,\n            0x1e: 0x820,\n            0x1f: 0x8000000,\n            0x80000010: 0x20000,\n            0x80000011: 0x800,\n            0x80000012: 0x8020020,\n            0x80000013: 0x20820,\n            0x80000014: 0x20,\n            0x80000015: 0x8020000,\n            0x80000016: 0x8000000,\n            0x80000017: 0x8000820,\n            0x80000018: 0x8020820,\n            0x80000019: 0x8000020,\n            0x8000001a: 0x8000800,\n            0x8000001b: 0x0,\n            0x8000001c: 0x20800,\n            0x8000001d: 0x820,\n            0x8000001e: 0x20020,\n            0x8000001f: 0x8020800\n        }\n    ];\n\n    // Masks that select the SBOX input\n    var SBOX_MASK = [\n        0xf8000001, 0x1f800000, 0x01f80000, 0x001f8000,\n        0x0001f800, 0x00001f80, 0x000001f8, 0x8000001f\n    ];\n\n    /**\n     * DES block cipher algorithm.\n     */\n    var DES = C_algo.DES = BlockCipher.extend({\n        _doReset: function () {\n            // Shortcuts\n            var key = this._key;\n            var keyWords = key.words;\n\n            // Select 56 bits according to PC1\n            var keyBits = [];\n            for (var i = 0; i < 56; i++) {\n                var keyBitPos = PC1[i] - 1;\n                keyBits[i] = (keyWords[keyBitPos >>> 5] >>> (31 - keyBitPos % 32)) & 1;\n            }\n\n            // Assemble 16 subkeys\n            var subKeys = this._subKeys = [];\n            for (var nSubKey = 0; nSubKey < 16; nSubKey++) {\n                // Create subkey\n                var subKey = subKeys[nSubKey] = [];\n\n                // Shortcut\n                var bitShift = BIT_SHIFTS[nSubKey];\n\n                // Select 48 bits according to PC2\n                for (var i = 0; i < 24; i++) {\n                    // Select from the left 28 key bits\n                    subKey[(i / 6) | 0] |= keyBits[((PC2[i] - 1) + bitShift) % 28] << (31 - i % 6);\n\n                    // Select from the right 28 key bits\n                    subKey[4 + ((i / 6) | 0)] |= keyBits[28 + (((PC2[i + 24] - 1) + bitShift) % 28)] << (31 - i % 6);\n                }\n\n                // Since each subkey is applied to an expanded 32-bit input,\n                // the subkey can be broken into 8 values scaled to 32-bits,\n                // which allows the key to be used without expansion\n                subKey[0] = (subKey[0] << 1) | (subKey[0] >>> 31);\n                for (var i = 1; i < 7; i++) {\n                    subKey[i] = subKey[i] >>> ((i - 1) * 4 + 3);\n                }\n                subKey[7] = (subKey[7] << 5) | (subKey[7] >>> 27);\n            }\n\n            // Compute inverse subkeys\n            var invSubKeys = this._invSubKeys = [];\n            for (var i = 0; i < 16; i++) {\n                invSubKeys[i] = subKeys[15 - i];\n            }\n        },\n\n        encryptBlock: function (M, offset) {\n            this._doCryptBlock(M, offset, this._subKeys);\n        },\n\n        decryptBlock: function (M, offset) {\n            this._doCryptBlock(M, offset, this._invSubKeys);\n        },\n\n        _doCryptBlock: function (M, offset, subKeys) {\n            // Get input\n            this._lBlock = M[offset];\n            this._rBlock = M[offset + 1];\n\n            // Initial permutation\n            exchangeLR.call(this, 4,  0x0f0f0f0f);\n            exchangeLR.call(this, 16, 0x0000ffff);\n            exchangeRL.call(this, 2,  0x33333333);\n            exchangeRL.call(this, 8,  0x00ff00ff);\n            exchangeLR.call(this, 1,  0x55555555);\n\n            // Rounds\n            for (var round = 0; round < 16; round++) {\n                // Shortcuts\n                var subKey = subKeys[round];\n                var lBlock = this._lBlock;\n                var rBlock = this._rBlock;\n\n                // Feistel function\n                var f = 0;\n                for (var i = 0; i < 8; i++) {\n                    f |= SBOX_P[i][((rBlock ^ subKey[i]) & SBOX_MASK[i]) >>> 0];\n                }\n                this._lBlock = rBlock;\n                this._rBlock = lBlock ^ f;\n            }\n\n            // Undo swap from last round\n            var t = this._lBlock;\n            this._lBlock = this._rBlock;\n            this._rBlock = t;\n\n            // Final permutation\n            exchangeLR.call(this, 1,  0x55555555);\n            exchangeRL.call(this, 8,  0x00ff00ff);\n            exchangeRL.call(this, 2,  0x33333333);\n            exchangeLR.call(this, 16, 0x0000ffff);\n            exchangeLR.call(this, 4,  0x0f0f0f0f);\n\n            // Set output\n            M[offset] = this._lBlock;\n            M[offset + 1] = this._rBlock;\n        },\n\n        keySize: 64/32,\n\n        ivSize: 64/32,\n\n        blockSize: 64/32\n    });\n\n    // Swap bits across the left and right words\n    function exchangeLR(offset, mask) {\n        var t = ((this._lBlock >>> offset) ^ this._rBlock) & mask;\n        this._rBlock ^= t;\n        this._lBlock ^= t << offset;\n    }\n\n    function exchangeRL(offset, mask) {\n        var t = ((this._rBlock >>> offset) ^ this._lBlock) & mask;\n        this._lBlock ^= t;\n        this._rBlock ^= t << offset;\n    }\n\n    /**\n     * Shortcut functions to the cipher's object interface.\n     *\n     * @example\n     *\n     *     var ciphertext = CryptoJS.DES.encrypt(message, key, cfg);\n     *     var plaintext  = CryptoJS.DES.decrypt(ciphertext, key, cfg);\n     */\n    C.DES = BlockCipher._createHelper(DES);\n\n    /**\n     * Triple-DES block cipher algorithm.\n     */\n    var TripleDES = C_algo.TripleDES = BlockCipher.extend({\n        _doReset: function () {\n            // Shortcuts\n            var key = this._key;\n            var keyWords = key.words;\n\n            // Create DES instances\n            this._des1 = DES.createEncryptor(WordArray.create(keyWords.slice(0, 2)));\n            this._des2 = DES.createEncryptor(WordArray.create(keyWords.slice(2, 4)));\n            this._des3 = DES.createEncryptor(WordArray.create(keyWords.slice(4, 6)));\n        },\n\n        encryptBlock: function (M, offset) {\n            this._des1.encryptBlock(M, offset);\n            this._des2.decryptBlock(M, offset);\n            this._des3.encryptBlock(M, offset);\n        },\n\n        decryptBlock: function (M, offset) {\n            this._des3.decryptBlock(M, offset);\n            this._des2.encryptBlock(M, offset);\n            this._des1.decryptBlock(M, offset);\n        },\n\n        keySize: 192/32,\n\n        ivSize: 64/32,\n\n        blockSize: 64/32\n    });\n\n    /**\n     * Shortcut functions to the cipher's object interface.\n     *\n     * @example\n     *\n     *     var ciphertext = CryptoJS.TripleDES.encrypt(message, key, cfg);\n     *     var plaintext  = CryptoJS.TripleDES.decrypt(ciphertext, key, cfg);\n     */\n    C.TripleDES = BlockCipher._createHelper(TripleDES);\n}());\n"
  },
  {
    "path": "JavaScript/sm2/js/x509-1.1.js",
    "content": "/*! x509-1.1.2.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n/* \n * x509.js - X509 class to read subject public key from certificate.\n *\n * Copyright (c) 2010-2013 Kenji Urushima (kenji.urushima@gmail.com)\n *\n * This software is licensed under the terms of the MIT License.\n * http://kjur.github.com/jsrsasign/license\n *\n * The above copyright and license notice shall be \n * included in all copies or substantial portions of the Software.\n */\n\n/**\n * @fileOverview\n * @name x509-1.1.js\n * @author Kenji Urushima kenji.urushima@gmail.com\n * @version x509 1.1.2 (2013-Oct-06)\n * @since jsrsasign 1.x.x\n * @license <a href=\"http://kjur.github.io/jsrsasign/license/\">MIT License</a>\n */\n\n/*\n * Depends:\n *   base64.js\n *   rsa.js\n *   asn1hex.js\n */\n\n/**\n * X.509 certificate class.<br/>\n * @class X.509 certificate class\n * @property {RSAKey} subjectPublicKeyRSA Tom Wu's RSAKey object\n * @property {String} subjectPublicKeyRSA_hN hexadecimal string for modulus of RSA public key\n * @property {String} subjectPublicKeyRSA_hE hexadecimal string for public exponent of RSA public key\n * @property {String} hex hexacedimal string for X.509 certificate.\n * @author Kenji Urushima\n * @version 1.0.1 (08 May 2012)\n * @see <a href=\"http://kjur.github.com/jsrsasigns/\">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a>\n */\nfunction X509() {\n    this.subjectPublicKeyRSA = null;\n    this.subjectPublicKeyRSA_hN = null;\n    this.subjectPublicKeyRSA_hE = null;\n    this.hex = null;\n\n    // ===== get basic fields from hex =====================================\n\n    /**\n     * get hexadecimal string of serialNumber field of certificate.<br/>\n     * @name getSerialNumberHex\n     * @memberOf X509#\n     * @function\n     */\n    this.getSerialNumberHex = function() {\n\treturn ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 1]);\n    };\n\n    /**\n     * get hexadecimal string of issuer field of certificate.<br/>\n     * @name getIssuerHex\n     * @memberOf X509#\n     * @function\n     */\n    this.getIssuerHex = function() {\n\treturn ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]);\n    };\n\n    /**\n     * get string of issuer field of certificate.<br/>\n     * @name getIssuerString\n     * @memberOf X509#\n     * @function\n     */\n    this.getIssuerString = function() {\n\treturn X509.hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]));\n    };\n\n    /**\n     * get hexadecimal string of subject field of certificate.<br/>\n     * @name getSubjectHex\n     * @memberOf X509#\n     * @function\n     */\n    this.getSubjectHex = function() {\n\treturn ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]);\n    };\n\n    /**\n     * get string of subject field of certificate.<br/>\n     * @name getSubjectString\n     * @memberOf X509#\n     * @function\n     */\n    this.getSubjectString = function() {\n\treturn X509.hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]));\n    };\n\n    /**\n     * get notBefore field string of certificate.<br/>\n     * @name getNotBefore\n     * @memberOf X509#\n     * @function\n     */\n    this.getNotBefore = function() {\n\tvar s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 0]);\n\ts = s.replace(/(..)/g, \"%$1\");\n\ts = decodeURIComponent(s);\n\treturn s;\n    };\n\n    /**\n     * get notAfter field string of certificate.<br/>\n     * @name getNotAfter\n     * @memberOf X509#\n     * @function\n     */\n    this.getNotAfter = function() {\n\tvar s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 1]);\n\ts = s.replace(/(..)/g, \"%$1\");\n\ts = decodeURIComponent(s);\n\treturn s;\n    };\n\n    // ===== read certificate public key ==========================\n\n    // ===== read certificate =====================================\n    /**\n     * read PEM formatted X.509 certificate from string.<br/>\n     * @name readCertPEM\n     * @memberOf X509#\n     * @function\n     * @param {String} sCertPEM string for PEM formatted X.509 certificate\n     */\n    this.readCertPEM = function(sCertPEM) {\n\tvar hCert = X509.pemToHex(sCertPEM);\n\tvar a = X509.getPublicKeyHexArrayFromCertHex(hCert);\n\tvar rsa = new RSAKey();\n\trsa.setPublic(a[0], a[1]);\n\tthis.subjectPublicKeyRSA = rsa;\n\tthis.subjectPublicKeyRSA_hN = a[0];\n\tthis.subjectPublicKeyRSA_hE = a[1];\n\tthis.hex = hCert;\n    };\n\n    this.readCertPEMWithoutRSAInit = function(sCertPEM) {\n\tvar hCert = X509.pemToHex(sCertPEM);\n\tvar a = X509.getPublicKeyHexArrayFromCertHex(hCert);\n\tthis.subjectPublicKeyRSA.setPublic(a[0], a[1]);\n\tthis.subjectPublicKeyRSA_hN = a[0];\n\tthis.subjectPublicKeyRSA_hE = a[1];\n\tthis.hex = hCert;\n    };\n};\n\nX509.pemToBase64 = function(sCertPEM) {\n    var s = sCertPEM;\n    s = s.replace(\"-----BEGIN CERTIFICATE-----\", \"\");\n    s = s.replace(\"-----END CERTIFICATE-----\", \"\");\n    s = s.replace(/[ \\n]+/g, \"\");\n    return s;\n};\n\nX509.pemToHex = function(sCertPEM) {\n    var b64Cert = X509.pemToBase64(sCertPEM);\n    var hCert = b64tohex(b64Cert);\n    return hCert;\n};\n\n// NOTE: Without BITSTRING encapsulation.\nX509.getSubjectPublicKeyPosFromCertHex = function(hCert) {\n    var pInfo = X509.getSubjectPublicKeyInfoPosFromCertHex(hCert);\n    if (pInfo == -1) return -1;    \n    var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pInfo); \n    if (a.length != 2) return -1;\n    var pBitString = a[1];\n    if (hCert.substring(pBitString, pBitString + 2) != '03') return -1;\n    var pBitStringV = ASN1HEX.getStartPosOfV_AtObj(hCert, pBitString);\n    \n    if (hCert.substring(pBitStringV, pBitStringV + 2) != '00') return -1;\n    return pBitStringV + 2;\n};\n\n// NOTE: privateKeyUsagePeriod field of X509v2 not supported.\n// NOTE: v1 and v3 supported\nX509.getSubjectPublicKeyInfoPosFromCertHex = function(hCert) {\n    var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);\n    var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pTbsCert); \n    if (a.length < 1) return -1;\n    if (hCert.substring(a[0], a[0] + 10) == \"a003020102\") { // v3\n\tif (a.length < 6) return -1;\n\treturn a[6];\n    } else {\n\tif (a.length < 5) return -1;\n\treturn a[5];\n    }\n};\n\nX509.getPublicKeyHexArrayFromCertHex = function(hCert) {\n    var p = X509.getSubjectPublicKeyPosFromCertHex(hCert);\n    var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, p); \n    if (a.length != 2) return [];\n    var hN = ASN1HEX.getHexOfV_AtObj(hCert, a[0]);\n    var hE = ASN1HEX.getHexOfV_AtObj(hCert, a[1]);\n    if (hN != null && hE != null) {\n\treturn [hN, hE];\n    } else {\n\treturn [];\n    }\n};\n\nX509.getHexTbsCertificateFromCert = function(hCert) {\n    var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);\n    return pTbsCert;\n};\n\nX509.getPublicKeyHexArrayFromCertPEM = function(sCertPEM) {\n    var hCert = X509.pemToHex(sCertPEM);\n    var a = X509.getPublicKeyHexArrayFromCertHex(hCert);\n    return a;\n};\n\nX509.hex2dn = function(hDN) {\n    var s = \"\";\n    var a = ASN1HEX.getPosArrayOfChildren_AtObj(hDN, 0);\n    for (var i = 0; i < a.length; i++) {\n\tvar hRDN = ASN1HEX.getHexOfTLV_AtObj(hDN, a[i]);\n\ts = s + \"/\" + X509.hex2rdn(hRDN);\n    }\n    return s;\n};\n\nX509.hex2rdn = function(hRDN) {\n    var hType = ASN1HEX.getDecendantHexTLVByNthList(hRDN, 0, [0, 0]);\n    var hValue = ASN1HEX.getDecendantHexVByNthList(hRDN, 0, [0, 1]);\n    var type = \"\";\n    try { type = X509.DN_ATTRHEX[hType]; } catch (ex) { type = hType; }\n    hValue = hValue.replace(/(..)/g, \"%$1\");\n    var value = decodeURIComponent(hValue);\n    return type + \"=\" + value;\n};\n\nX509.DN_ATTRHEX = {\n    \"0603550406\": \"C\",\n    \"060355040a\": \"O\",\n    \"060355040b\": \"OU\",\n    \"0603550403\": \"CN\",\n    \"0603550405\": \"SN\",\n    \"0603550408\": \"ST\",\n    \"0603550407\": \"L\",\n};\n\n/**\n * get RSAKey/ECDSA public key object from PEM certificate string\n * @name getPublicKeyFromCertPEM\n * @memberOf X509\n * @function\n * @param {String} sCertPEM PEM formatted RSA/ECDSA/DSA X.509 certificate\n * @return returns RSAKey/KJUR.crypto.{ECDSA,DSA} object of public key\n * @since x509 1.1.1\n * @description\n * NOTE: DSA is also supported since x509 1.1.2.\n */\nX509.getPublicKeyFromCertPEM = function(sCertPEM) {\n    var info = X509.getPublicKeyInfoPropOfCertPEM(sCertPEM);\n\n    if (info.algoid == \"2a864886f70d010101\") { // RSA\n\tvar aRSA = KEYUTIL.parsePublicRawRSAKeyHex(info.keyhex);\n\tvar key = new RSAKey();\n\tkey.setPublic(aRSA.n, aRSA.e);\n\treturn key;\n    } else if (info.algoid == \"2a8648ce3d0201\") { // ECC\n\tvar curveName = KJUR.crypto.OID.oidhex2name[info.algparam];\n\tvar key = new KJUR.crypto.ECDSA({'curve': curveName, 'info': info.keyhex});\n        key.setPublicKeyHex(info.keyhex);\n\treturn key;\n    } else if (info.algoid == \"2a8648ce380401\") { // DSA 1.2.840.10040.4.1\n\tvar p = ASN1HEX.getVbyList(info.algparam, 0, [0], \"02\");\n\tvar q = ASN1HEX.getVbyList(info.algparam, 0, [1], \"02\");\n\tvar g = ASN1HEX.getVbyList(info.algparam, 0, [2], \"02\");\n\tvar y = ASN1HEX.getHexOfV_AtObj(info.keyhex, 0);\n\ty = y.substr(2);\n\tvar key = new KJUR.crypto.DSA();\n\tkey.setPublic(new BigInteger(p, 16),\n\t\t      new BigInteger(q, 16),\n\t\t      new BigInteger(g, 16),\n\t\t      new BigInteger(y, 16));\n\treturn key;\n    } else {\n\tthrow \"unsupported key\";\n    }\n};\n\n/**\n * get public key information from PEM certificate\n * @name getPublicKeyInfoPropOfCertPEM\n * @memberOf X509\n * @function\n * @param {String} sCertPEM string of PEM formatted certificate\n * @return {Hash} hash of information for public key\n * @since x509 1.1.1\n * @description\n * Resulted associative array has following properties:\n * <ul>\n * <li>algoid - hexadecimal string of OID of asymmetric key algorithm</li>\n * <li>algparam - hexadecimal string of OID of ECC curve name or null</li>\n * <li>keyhex - hexadecimal string of key in the certificate</li>\n * </ul>\n * @since x509 1.1.1\n */\nX509.getPublicKeyInfoPropOfCertPEM = function(sCertPEM) {\n    var result = {};\n    result.algparam = null;\n    var hCert = X509.pemToHex(sCertPEM);\n\n    // 1. Certificate ASN.1\n    var a1 = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, 0); \n    if (a1.length != 3)\n\tthrow \"malformed X.509 certificate PEM (code:001)\"; // not 3 item of seq Cert\n\n    // 2. tbsCertificate\n    if (hCert.substr(a1[0], 2) != \"30\")\n\tthrow \"malformed X.509 certificate PEM (code:002)\"; // tbsCert not seq \n\n    var a2 = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, a1[0]); \n\n    // 3. subjectPublicKeyInfo\n    if (a2.length < 7)\n\tthrow \"malformed X.509 certificate PEM (code:003)\"; // no subjPubKeyInfo\n\n    var a3 = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, a2[6]); \n\n    if (a3.length != 2)\n\tthrow \"malformed X.509 certificate PEM (code:004)\"; // not AlgId and PubKey\n\n    // 4. AlgId\n    var a4 = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, a3[0]); \n\n    if (a4.length != 2)\n\tthrow \"malformed X.509 certificate PEM (code:005)\"; // not 2 item in AlgId\n\n    result.algoid = ASN1HEX.getHexOfV_AtObj(hCert, a4[0]);\n\n    if (hCert.substr(a4[1], 2) == \"06\") { // EC\n\tresult.algparam = ASN1HEX.getHexOfV_AtObj(hCert, a4[1]);\n    } else if (hCert.substr(a4[1], 2) == \"30\") { // DSA\n\tresult.algparam = ASN1HEX.getHexOfTLV_AtObj(hCert, a4[1]);\n    }\n\n    // 5. Public Key Hex\n    if (hCert.substr(a3[1], 02) != \"03\")\n\tthrow \"malformed X.509 certificate PEM (code:006)\"; // not bitstring\n\n    var unusedBitAndKeyHex = ASN1HEX.getHexOfV_AtObj(hCert, a3[1]);\n    result.keyhex = unusedBitAndKeyHex.substr(2);\n\n    return result;\n};\n\n/*\nX509.prototype.readCertPEM = _x509_readCertPEM;\nX509.prototype.readCertPEMWithoutRSAInit = _x509_readCertPEMWithoutRSAInit;\nX509.prototype.getSerialNumberHex = _x509_getSerialNumberHex;\nX509.prototype.getIssuerHex = _x509_getIssuerHex;\nX509.prototype.getSubjectHex = _x509_getSubjectHex;\nX509.prototype.getIssuerString = _x509_getIssuerString;\nX509.prototype.getSubjectString = _x509_getSubjectString;\nX509.prototype.getNotBefore = _x509_getNotBefore;\nX509.prototype.getNotAfter = _x509_getNotAfter;\n*/\n"
  },
  {
    "path": "JavaScript/sm2/js/yahoo-min.js",
    "content": "/*\nCopyright (c) 2011, Yahoo! Inc. All rights reserved.\nCode licensed under the BSD License:\nhttp://developer.yahoo.com/yui/license.html\nversion: 2.9.0\n*/\nif(typeof YAHOO==\"undefined\"||!YAHOO){var YAHOO={};}YAHOO.namespace=function(){var b=arguments,g=null,e,c,f;for(e=0;e<b.length;e=e+1){f=(\"\"+b[e]).split(\".\");g=YAHOO;for(c=(f[0]==\"YAHOO\")?1:0;c<f.length;c=c+1){g[f[c]]=g[f[c]]||{};g=g[f[c]];}}return g;};YAHOO.log=function(d,a,c){var b=YAHOO.widget.Logger;if(b&&b.log){return b.log(d,a,c);}else{return false;}};YAHOO.register=function(a,f,e){var k=YAHOO.env.modules,c,j,h,g,d;if(!k[a]){k[a]={versions:[],builds:[]};}c=k[a];j=e.version;h=e.build;g=YAHOO.env.listeners;c.name=a;c.version=j;c.build=h;c.versions.push(j);c.builds.push(h);c.mainClass=f;for(d=0;d<g.length;d=d+1){g[d](c);}if(f){f.VERSION=j;f.BUILD=h;}else{YAHOO.log(\"mainClass is undefined for module \"+a,\"warn\");}};YAHOO.env=YAHOO.env||{modules:[],listeners:[]};YAHOO.env.getVersion=function(a){return YAHOO.env.modules[a]||null;};YAHOO.env.parseUA=function(d){var e=function(i){var j=0;return parseFloat(i.replace(/\\./g,function(){return(j++==1)?\"\":\".\";}));},h=navigator,g={ie:0,opera:0,gecko:0,webkit:0,chrome:0,mobile:null,air:0,ipad:0,iphone:0,ipod:0,ios:null,android:0,webos:0,caja:h&&h.cajaVersion,secure:false,os:null},c=d||(navigator&&navigator.userAgent),f=window&&window.location,b=f&&f.href,a;g.secure=b&&(b.toLowerCase().indexOf(\"https\")===0);if(c){if((/windows|win32/i).test(c)){g.os=\"windows\";}else{if((/macintosh/i).test(c)){g.os=\"macintosh\";}else{if((/rhino/i).test(c)){g.os=\"rhino\";}}}if((/KHTML/).test(c)){g.webkit=1;}a=c.match(/AppleWebKit\\/([^\\s]*)/);if(a&&a[1]){g.webkit=e(a[1]);if(/ Mobile\\//.test(c)){g.mobile=\"Apple\";a=c.match(/OS ([^\\s]*)/);if(a&&a[1]){a=e(a[1].replace(\"_\",\".\"));}g.ios=a;g.ipad=g.ipod=g.iphone=0;a=c.match(/iPad|iPod|iPhone/);if(a&&a[0]){g[a[0].toLowerCase()]=g.ios;}}else{a=c.match(/NokiaN[^\\/]*|Android \\d\\.\\d|webOS\\/\\d\\.\\d/);if(a){g.mobile=a[0];}if(/webOS/.test(c)){g.mobile=\"WebOS\";a=c.match(/webOS\\/([^\\s]*);/);if(a&&a[1]){g.webos=e(a[1]);}}if(/ Android/.test(c)){g.mobile=\"Android\";a=c.match(/Android ([^\\s]*);/);if(a&&a[1]){g.android=e(a[1]);}}}a=c.match(/Chrome\\/([^\\s]*)/);if(a&&a[1]){g.chrome=e(a[1]);}else{a=c.match(/AdobeAIR\\/([^\\s]*)/);if(a){g.air=a[0];}}}if(!g.webkit){a=c.match(/Opera[\\s\\/]([^\\s]*)/);if(a&&a[1]){g.opera=e(a[1]);a=c.match(/Version\\/([^\\s]*)/);if(a&&a[1]){g.opera=e(a[1]);}a=c.match(/Opera Mini[^;]*/);if(a){g.mobile=a[0];}}else{a=c.match(/MSIE\\s([^;]*)/);if(a&&a[1]){g.ie=e(a[1]);}else{a=c.match(/Gecko\\/([^\\s]*)/);if(a){g.gecko=1;a=c.match(/rv:([^\\s\\)]*)/);if(a&&a[1]){g.gecko=e(a[1]);}}}}}}return g;};YAHOO.env.ua=YAHOO.env.parseUA();(function(){YAHOO.namespace(\"util\",\"widget\",\"example\");if(\"undefined\"!==typeof YAHOO_config){var b=YAHOO_config.listener,a=YAHOO.env.listeners,d=true,c;if(b){for(c=0;c<a.length;c++){if(a[c]==b){d=false;break;}}if(d){a.push(b);}}}})();YAHOO.lang=YAHOO.lang||{};(function(){var f=YAHOO.lang,a=Object.prototype,c=\"[object Array]\",h=\"[object Function]\",i=\"[object Object]\",b=[],g={\"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#x27;\",\"/\":\"&#x2F;\",\"`\":\"&#x60;\"},d=[\"toString\",\"valueOf\"],e={isArray:function(j){return a.toString.apply(j)===c;},isBoolean:function(j){return typeof j===\"boolean\";},isFunction:function(j){return(typeof j===\"function\")||a.toString.apply(j)===h;},isNull:function(j){return j===null;},isNumber:function(j){return typeof j===\"number\"&&isFinite(j);},isObject:function(j){return(j&&(typeof j===\"object\"||f.isFunction(j)))||false;},isString:function(j){return typeof j===\"string\";},isUndefined:function(j){return typeof j===\"undefined\";},_IEEnumFix:(YAHOO.env.ua.ie)?function(l,k){var j,n,m;for(j=0;j<d.length;j=j+1){n=d[j];m=k[n];if(f.isFunction(m)&&m!=a[n]){l[n]=m;}}}:function(){},escapeHTML:function(j){return j.replace(/[&<>\"'\\/`]/g,function(k){return g[k];});},extend:function(m,n,l){if(!n||!m){throw new Error(\"extend failed, please check that \"+\"all dependencies are included.\");}var k=function(){},j;k.prototype=n.prototype;m.prototype=new k();m.prototype.constructor=m;m.superclass=n.prototype;if(n.prototype.constructor==a.constructor){n.prototype.constructor=n;}if(l){for(j in l){if(f.hasOwnProperty(l,j)){m.prototype[j]=l[j];}}f._IEEnumFix(m.prototype,l);}},augmentObject:function(n,m){if(!m||!n){throw new Error(\"Absorb failed, verify dependencies.\");}var j=arguments,l,o,k=j[2];if(k&&k!==true){for(l=2;l<j.length;l=l+1){n[j[l]]=m[j[l]];}}else{for(o in m){if(k||!(o in n)){n[o]=m[o];}}f._IEEnumFix(n,m);}return n;},augmentProto:function(m,l){if(!l||!m){throw new Error(\"Augment failed, verify dependencies.\");}var j=[m.prototype,l.prototype],k;for(k=2;k<arguments.length;k=k+1){j.push(arguments[k]);}f.augmentObject.apply(this,j);return m;},dump:function(j,p){var l,n,r=[],t=\"{...}\",k=\"f(){...}\",q=\", \",m=\" => \";if(!f.isObject(j)){return j+\"\";}else{if(j instanceof Date||(\"nodeType\" in j&&\"tagName\" in j)){return j;}else{if(f.isFunction(j)){return k;}}}p=(f.isNumber(p))?p:3;if(f.isArray(j)){r.push(\"[\");for(l=0,n=j.length;l<n;l=l+1){if(f.isObject(j[l])){r.push((p>0)?f.dump(j[l],p-1):t);}else{r.push(j[l]);}r.push(q);}if(r.length>1){r.pop();}r.push(\"]\");}else{r.push(\"{\");for(l in j){if(f.hasOwnProperty(j,l)){r.push(l+m);if(f.isObject(j[l])){r.push((p>0)?f.dump(j[l],p-1):t);}else{r.push(j[l]);}r.push(q);}}if(r.length>1){r.pop();}r.push(\"}\");}return r.join(\"\");},substitute:function(x,y,E,l){var D,C,B,G,t,u,F=[],p,z=x.length,A=\"dump\",r=\" \",q=\"{\",m=\"}\",n,w;for(;;){D=x.lastIndexOf(q,z);if(D<0){break;}C=x.indexOf(m,D);if(D+1>C){break;}p=x.substring(D+1,C);G=p;u=null;B=G.indexOf(r);if(B>-1){u=G.substring(B+1);G=G.substring(0,B);}t=y[G];if(E){t=E(G,t,u);}if(f.isObject(t)){if(f.isArray(t)){t=f.dump(t,parseInt(u,10));}else{u=u||\"\";n=u.indexOf(A);if(n>-1){u=u.substring(4);}w=t.toString();if(w===i||n>-1){t=f.dump(t,parseInt(u,10));}else{t=w;}}}else{if(!f.isString(t)&&!f.isNumber(t)){t=\"~-\"+F.length+\"-~\";F[F.length]=p;}}x=x.substring(0,D)+t+x.substring(C+1);if(l===false){z=D-1;}}for(D=F.length-1;D>=0;D=D-1){x=x.replace(new RegExp(\"~-\"+D+\"-~\"),\"{\"+F[D]+\"}\",\"g\");}return x;},trim:function(j){try{return j.replace(/^\\s+|\\s+$/g,\"\");}catch(k){return j;\n}},merge:function(){var n={},k=arguments,j=k.length,m;for(m=0;m<j;m=m+1){f.augmentObject(n,k[m],true);}return n;},later:function(t,k,u,n,p){t=t||0;k=k||{};var l=u,s=n,q,j;if(f.isString(u)){l=k[u];}if(!l){throw new TypeError(\"method undefined\");}if(!f.isUndefined(n)&&!f.isArray(s)){s=[n];}q=function(){l.apply(k,s||b);};j=(p)?setInterval(q,t):setTimeout(q,t);return{interval:p,cancel:function(){if(this.interval){clearInterval(j);}else{clearTimeout(j);}}};},isValue:function(j){return(f.isObject(j)||f.isString(j)||f.isNumber(j)||f.isBoolean(j));}};f.hasOwnProperty=(a.hasOwnProperty)?function(j,k){return j&&j.hasOwnProperty&&j.hasOwnProperty(k);}:function(j,k){return !f.isUndefined(j[k])&&j.constructor.prototype[k]!==j[k];};e.augmentObject(f,e,true);YAHOO.util.Lang=f;f.augment=f.augmentProto;YAHOO.augment=f.augmentProto;YAHOO.extend=f.extend;})();YAHOO.register(\"yahoo\",YAHOO,{version:\"2.9.0\",build:\"2800\"});"
  },
  {
    "path": "JavaScript/sm2/sm2.html",
    "content": "<!DOCTYPE html>\n<!-- saved from url=(0075)http://www.jonllen.com/upload/jonllen/case/jsrsasign-master/sample-sm2.html -->\n<html lang=\"zh-CN\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>SM2 sample</title>\n    <!-- for pkcs5pkey -->\n    <script src=\"./js/core.js\"></script>\n    <script src=\"./js/cipher-core.js\"></script>\n    <script src=\"./js/md5.js\"></script>\n    <script src=\"./js/tripledes.js\"></script>\n    <script src=\"./js/enc-base64.js\"></script>\n    <!-- for crypto -->\n    <script src=\"./js/sha1.js\"></script>\n    <script src=\"./js/sha256.js\"></script>\n    <!-- for crypto, asn1, asn1x509 -->\n    <script src=\"./js/yahoo-min.js\"></script>\n    <!-- for asn1x509(stohex)\n    <script src=\"http://kjur.github.io/jsjws/base64x-1.1.min.js\"></script> -->\n\n    <script src=\"./js/jsbn.js\"></script>\n    <script src=\"./js/jsbn2.js\"></script>\n    <script src=\"./js/prng4.js\"></script>\n    <script src=\"./js/rng.js\"></script>\n    <script src=\"./js/rsa.js\"></script>\n    <script src=\"./js/rsa2.js\"></script>\n    <script src=\"./js/base64.js\"></script>\n    <script src=\"./js/asn1hex-1.1.js\"></script>\n    <script src=\"./js/rsapem-1.1.js\"></script>\n    <script src=\"./js/rsasign-1.2.js\"></script>\n    <script src=\"./js/x509-1.1.js\"></script>\n    <script src=\"./js/pkcs5pkey-1.0.js\"></script>\n    <script src=\"./js/asn1-1.0.js\"></script>\n    <script src=\"./js/asn1x509-1.0.js\"></script>\n    <script src=\"./js/crypto-1.1.js\"></script>\n\n    <script src=\"./js/ec.js\"></script>\n    <script src=\"./js/ec-patch.js\"></script>\n    <script src=\"./js/ecdsa-modified-1.0.js\"></script>\n    <script src=\"./js/sm3.js\"></script>\n    <script src=\"./js/sm3-sm2-1.0.js\"></script>\n    <script src=\"./js/ecparam-1.0.js\"></script>\n    <script>\n    function doGenerate() {\n      var f1 = document.form1;\n      var curve = f1.curve1.value;\n      var ec = new KJUR.crypto.ECDSA({\"curve\": curve});\n      var keypair = ec.generateKeyPairHex();\n\n      f1.prvkey1.value = keypair.ecprvhex;\n      f1.pubkey1.value = keypair.ecpubhex;\n    }\n\n    function doSign() {\n      var f1 = document.form1;\n      var prvkey = f1.prvkey1.value;\n      var curve = f1.curve1.value;\n      var sigalg = f1.sigalg1.value;\n      var msg1 = f1.msg1.value;\n\n      var sig = new KJUR.crypto.Signature({\"alg\": sigalg, \"prov\": \"cryptojs/jsrsa\"});\n      sig.initSign({'ecprvhex': prvkey, 'eccurvename': curve});\n      sig.updateString(msg1);\n      var sigValueHex = sig.sign();\n      \n      f1.sigval1.value = sigValueHex;\n    }\n\n    function doVerify() {\n      var f1 = document.form1;\n      var pubkey = f1.pubkey1.value;\n      var curve = f1.curve1.value;\n      var sigalg = f1.sigalg1.value;\n      var msg1 = f1.msg1.value;\n      var sigval = f1.sigval1.value;\n\n      var sig = new KJUR.crypto.Signature({\"alg\": sigalg, \"prov\": \"cryptojs/jsrsa\"});\n      sig.initVerifyByPublicKey({'ecpubhex': pubkey, 'eccurvename': curve});\n      sig.updateString(msg1);\n      var result = sig.verify(sigval);\n      if (result) {\n        alert(\"valid signature\");\n      } else {\n        alert(\"invalid signature\");\n      }\n    }\n    </script>\n</head>\n<body>\n    <!-- HEADER -->\n    <div id=\"header_wrap\" class=\"outer\">\n        <header class=\"inner\">\n          <h1 id=\"project_title\">SM2 sample</h1>\n          <h2 id=\"project_tagline\">generating SM2 keypair, signing and verifying SM3withSM2 signature</h2>\n\n          <a href=\"http://kjur.github.io/jsrsasign/\" target=\"_blank\">GitHub jsrsasign</a> | \n          <a href=\"http://www.jonllen.com/upload/jonllen/case/jsrsasign-master/sample-sm2_tool.html\" target=\"_blank\">SM2 Cert Verifcation</a>\n        </header>\n    </div>\n\n    <!-- MAIN CONTENT -->\n    <div id=\"main_content_wrap\" class=\"outer\">\n      <section id=\"main_content\" class=\"inner\">\n\n    <!-- now editing -->\n    <form name=\"form1\">\n    <h4>(Step1) choose supported EC curve name and generate key pair</h4>\n    ECC curve name: \n    <select name=\"curve1\">\n    <option value=\"sm2\">SM2\n    </option><option value=\"secp256r1\">secp256r1 (= NIST P-256, P-256, prime256v1)\n    </option><option value=\"secp256k1\">secp256k1\n    </option><option value=\"secp384r1\">secp384r1 (= NIST P-384, P-384)\n    </option></select><br>\n    <input type=\"button\" value=\"generate EC key pair\" onclick=\"doGenerate();\"><br>\n    <p>\n    EC private key (hex): <input type=\"text\" name=\"prvkey1\" value=\"\" size=\"100\"><br>\n    EC public key (hex): <input type=\"text\" name=\"pubkey1\" value=\"\" size=\"100\"><br>\n    </p>\n\n    <!-- ============================================================== -->\n\n    <h4>(Step2) Sign message</h4>\n    Signature Algorithm: \n    <select name=\"sigalg1\">\n    <option value=\"SM3withSM2\">SM3withSM2\n    </option><option value=\"SHA256withECDSA\">SHA256withECDSA\n    </option><option value=\"SHA1withECDSA\">SHA1withECDSA\n    </option></select><br>\n\n    Message string to be signed: \n    <input type=\"text\" name=\"msg1\" value=\"jonllen\" size=\"100\"><br>\n    <input type=\"button\" value=\"sign message\" onclick=\"doSign();\"><br>\n    <p>\n    Signature value (hex): <input type=\"text\" name=\"sigval1\" value=\"\" size=\"100\"><br>\n    </p>\n\n    <h4>(Step3) Verify signature</h4>\n    <input type=\"button\" value=\"verify it!\" onclick=\"doVerify();\">\n    <input type=\"reset\" value=\"reset\">\n\n    </form>\n    <!-- now editing -->\n\n      </section>\n    </div>\n\n    <!-- FOOTER  -->\n    <div id=\"footer_wrap\" class=\"outer\">\n      <footer class=\"inner\">\n        <p class=\"copyright\">jsrsasign maintained by <a href=\"https://github.com/kjur\" target=\"_blank\">kjur</a></p>\n        <p>Powered By <a href=\"http://www.jonllen.com/\" target=\"_blank\">Jonllen</a></p>\n      </footer>\n    </div>\n</body>\n</html>"
  },
  {
    "path": "JavaScript/sm2/sm2_decrypt.html",
    "content": "<!DOCTYPE html>\n<!-- saved from url=(0081)http://www.jonllen.com/upload/jonllen/case/jsrsasign-master/sample-sm2_crypt.html -->\n<html lang=\"zh-CN\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>SM2 sample</title>\n    <!-- for pkcs5pkey -->\n    <script src=\"./js/core.js\"></script>\n    <script src=\"./js/cipher-core.js\"></script>\n    <script src=\"./js/md5.js\"></script>\n    <script src=\"./js/tripledes.js\"></script>\n    <script src=\"./js/enc-base64.js\"></script>\n    <!-- for crypto -->\n    <script src=\"./js/sha1.js\"></script>\n    <script src=\"./js/sha256.js\"></script>\n    <!-- for crypto, asn1, asn1x509 -->\n    <script src=\"./js/yahoo-min.js\"></script>\n    <!-- for asn1x509(stohex)\n    <script src=\"http://kjur.github.io/jsjws/base64x-1.1.min.js\"></script> -->\n\n    <script src=\"./js/jsbn.js\"></script>\n    <script src=\"./js/jsbn2.js\"></script>\n    <script src=\"./js/prng4.js\"></script>\n    <script src=\"./js/rng.js\"></script>\n    <script src=\"./js/rsa.js\"></script>\n    <script src=\"./js/rsa2.js\"></script>\n    <script src=\"./js/base64.js\"></script>\n    <script src=\"./js/asn1hex-1.1.js\"></script>\n    <script src=\"./js/rsapem-1.1.js\"></script>\n    <script src=\"./js/rsasign-1.2.js\"></script>\n    <script src=\"./js/x509-1.1.js\"></script>\n    <script src=\"./js/pkcs5pkey-1.0.js\"></script>\n    <script src=\"./js/asn1-1.0.js\"></script>\n    <script src=\"./js/asn1x509-1.0.js\"></script>\n    <script src=\"./js/crypto-1.1.js\"></script>\n\n    <script src=\"./js/ec.js\"></script>\n    <script src=\"./js/ec-patch.js\"></script>\n    <script src=\"./js/ecdsa-modified-1.0.js\"></script>\n    <script src=\"./js/sm3.js\"></script>\n    <script src=\"./js/sm3-sm2-1.0.js\"></script>\n    <script src=\"./js/ecparam-1.0.js\"></script>\n    <script src=\"./js/sm2.js\"></script>\n    <script>\n    function doGenerate() {\n      var f1 = document.form1;\n      var curve = f1.curve1.value;\n      var ec = new KJUR.crypto.ECDSA({\"curve\": curve});\n      var keypair = ec.generateKeyPairHex();\n\n      f1.prvkey1.value = keypair.ecprvhex;\n      f1.pubkey1.value = keypair.ecpubhex;\n    }\n\n    function doCrypt() {\n        var f1 = document.form1;\n        \n        var curve = f1.curve1.value;\n        var msg = f1.msg1.value;\n        var msgData = CryptoJS.enc.Utf8.parse(msg);\n\n        var pubkeyHex = f1.pubkey1.value;\n        if (pubkeyHex.length > 64 * 2) {\n            pubkeyHex = pubkeyHex.substr(pubkeyHex.length - 64 * 2);\n        }\n\n        var xHex = pubkeyHex.substr(0, 64);\n        var yHex = pubkeyHex.substr(64);\n      \n      var cipherMode = f1.cipherMode.value;\n        \n        var cipher = new SM2Cipher(cipherMode);\n        var userKey = cipher.CreatePoint(xHex, yHex);\n      \n      msgData = cipher.GetWords(msgData.toString());\n      \n        var encryptData = cipher.Encrypt(userKey, msgData);\n        f1.sigval1.value = encryptData;\n    }\n\n    function doDecrypt() {\n        var f1 = document.form1;\n        var prvkey = f1.prvkey1.value;\n        var encryptData = f1.sigval1.value;\n        \n        var privateKey = new BigInteger(prvkey, 16);\n      \n      var cipherMode = f1.cipherMode.value;\n            \n        var cipher = new SM2Cipher(cipherMode);\n        var data = cipher.Decrypt(privateKey, encryptData);\n      \n        alert(data ? '解密成功，原文：' + data : '解密失败！');\n    }\n\n    function certCrypt() {\n        var certData = document.getElementById('txtCertData').value;\n        if( certData != \"\") {\n          var key = X509.getPublicKeyFromCertPEM(certData);\n        document.getElementById('txtPubKey').value = key.pubKeyHex;\n        }\n\n        var pubkey = document.getElementById('txtPubKey').value.replace(/\\s/g,'');\n      \n      \n        var pubkeyHex = pubkey;\n        if (pubkeyHex.length > 64 * 2) {\n            pubkeyHex = pubkeyHex.substr(pubkeyHex.length - 64 * 2);\n        }\n\n        var xHex = pubkeyHex.substr(0, 64);\n        var yHex = pubkeyHex.substr(64);\n      \n      var cipherMode = document.getElementById('cipherMode').value;\n        \n        var cipher = new SM2Cipher(cipherMode);\n        var userKey = cipher.CreatePoint(xHex, yHex);\n      \n      var msg = document.getElementById('txtRawData').value;\n      var msgData = CryptoJS.enc.Utf8.parse(msg);\n      msgData = cipher.GetWords(msgData.toString());\n      \n        var encryptData = cipher.Encrypt(userKey, msgData);\n        document.getElementById('txtCryptData').value = hex2b64(encryptData);\n    }\n    </script>\n</head>\n<body>\n\n    <!-- HEADER -->\n    <div id=\"header_wrap\" class=\"outer\">\n        <header class=\"inner\">\n          <h1 id=\"project_title\">SM2 Algorithm Encryption and Decryption sample</h1>\n          <h2 id=\"project_tagline\">generating SM2 keypair, SM2 Algorithm Encryption and Decryption</h2>\n      <a href=\"http://www.jonllen.com/\">Home</a> | \n          <a href=\"http://www.jonllen.com/upload/jonllen/case/jsrsasign-master/sample-sm2.html\">SM2 sample</a> | \n          <a href=\"http://www.jonllen.com/upload/jonllen/case/jsrsasign-master/sample-sm2_tool.html\">SM2 Cert Verifcation</a> | \n          <a href=\"http://www.jonllen.com/upload/jonllen/case/jsrsasign-master/sample-sm2_crypt.html\">SM2 Encryption and Decryption sample</a>\n        </header>\n    </div>\n\n    <!-- MAIN CONTENT -->\n    <div id=\"main_content_wrap\" class=\"outer\">\n      <section id=\"main_content\" class=\"inner\">\n\n<script type=\"text/javascript\">\n  if(/msie/.test( navigator.userAgent.toLowerCase() )){ document.write(\"<p><em>若IE浏览器下提示停止运行此脚本，请选择<b>否(N)</b>继续运行。</em></p>\");}\n</script>\n  \n<!-- now editing -->\n<form name=\"form1\">\n<h4>(Step1) choose supported EC curve name and generate key pair</h4>\nECC curve name: \n<select name=\"curve1\">\n<option value=\"sm2\">SM2\n</option><option value=\"secp256r1\">secp256r1 (= NIST P-256, P-256, prime256v1)\n</option><option value=\"secp256k1\">secp256k1\n</option><option value=\"secp384r1\">secp384r1 (= NIST P-384, P-384)\n</option></select><br>\n<input type=\"button\" value=\"generate EC key pair\" onclick=\"doGenerate();\"><br>\n<p>\nEC private key (hex): <input type=\"text\" name=\"prvkey1\" value=\"\" size=\"100\"><br>\nEC public key (hex): <input type=\"text\" name=\"pubkey1\" value=\"\" size=\"100\"><br>\n</p>\n\n<!-- ============================================================== -->\n\n<h4>(Step2) Crypt message</h4>\nCrypt Options: \n<select id=\"cipherMode\" name=\"cipherMode\">\n<option value=\"1\" selected=\"selected\">C1C3C2\n</option><option value=\"0\">C1C2C3\n</option></select><br>\n\nMessage string to be Crypted: \n<input type=\"text\" name=\"msg1\" value=\"jonllen\" size=\"100\"><br>\n<input type=\"button\" value=\"Crypt message\" onclick=\"doCrypt();\"><br>\n<p>\nCrypt value (hex): <input type=\"text\" id=\"sigval1\" name=\"sigval1\" value=\"\" size=\"100\"><br>\n</p>\n\n<h4>(Step3) Decrypt message</h4>\n<input type=\"button\" value=\"decrypt it!\" onclick=\"doDecrypt();\">\n<input type=\"reset\" value=\"reset\">\n\n</form>\n<!-- now editing -->\n\n      </section>\n    \n    <section class=\"inner\">\n      <hr size=\"1\">\n      <h4>SM2 Certificate Encryption</h4>\n        <fieldset>\n            <legend>SM2证书加密</legend>\n            <ul>\n                <li>\n                    <label>原始数据：<input type=\"text\" id=\"txtRawData\" size=\"80\" value=\"jonllen\"></label>\n                </li>\n        <li>\n                    <label>证书数据：<textarea id=\"txtCertData\" style=\"width: 522px; height: 188px; margin: 0px;\">MIICQDCCAeWgAwIBAgIQG2THdO0arf/KaLKoTVlCOzAMBggqgRzPVQGDdQUAMB8xEDAOBgNVBAMMB1NNMlJPT1QxCzAJBgNVBAYTAkNOMB4XDTE0MDYxODEzNTgzNVoXDTE2MDYxODEzNTgzNVowZTEiMCAGCSqGSIb3DQEJARYTam9ubGxlbkBob3RtYWlsLmNvbTEPMA0GA1UEBwwG6ZW/5rKZMQ8wDQYDVQQIDAbmuZbljZcxCzAJBgNVBAYTAkNOMRAwDgYDVQQDDAdKb25sbGVuMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEXLAuT39XB5LJmTprFiGLPfqZl5tyGm1n9oXSVDrGRP2RfQRJOqD6cH6PEvmGhM1ydJv0iQMg2mvh6PjAlm58W6OBujCBtzAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQstXX3UIwlBK9k70GJYGM8mjG6gTAfBgNVHSMEGDAWgBQ/LpOmNnAJt7mAwIZpsX3cnqlkqjBCBggrBgEFBQcBAQQ2MDQwMgYIKwYBBQUHMAKGJmh0dHA6Ly9sb2NhbGhvc3QvUEtJL2NlcnRzL0RTQVJPT1QuY3J0MA4GA1UdDwEB/wQEAwIE8DATBgNVHSUEDDAKBggrBgEFBQcDAjAMBggqgRzPVQGDdQUAA0cAMEQCIBJO7K/XDt+igzKkWSkbRKZRtQKsS1i2Fmdp2Ar5EEL+AiA759mE/uINaEC7sMXOoqzTzkLCMIHGyLi80j0dG5pjow==</textarea>\n            <em>base64编码格式</em>\n          </label>\n                </li>\n                <li style=\"display:none\">\n                    <label>证书公钥：<input type=\"text\" id=\"txtPubKey\" size=\"120\" value=\"\"></label>\n                </li>\n        <li>\n          <input type=\"button\" value=\"加密\" onclick=\"certCrypt();\">\n        </li>\n                <li>\n                    <label>加密后数据：<textarea id=\"txtCryptData\" readonly=\"readonly\" style=\"width: 500px; height: 82px; margin-top: 0px; margin-bottom: 0px;\"></textarea><em>base64编码格式</em>\n           </label>\n                </li>\n        \n            </ul>\n            <div>\n                \n            </div>\n        </fieldset>\n      </section>\n    \n    </div>\n\n    <!-- FOOTER  -->\n    <div id=\"footer_wrap\" class=\"outer\">\n      <footer class=\"inner\">\n        <p>Powered By <a href=\"http://www.jonllen.com/\" target=\"_blank\">Jonllen</a></p>\n      </footer>\n    </div>\n</body>\n</html>"
  },
  {
    "path": "JavaScript/sm4.html",
    "content": "<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>SM4 国密算法实现</title>\n\n    <!-- sm4 -->\n    <script src=\"js/sm4.js\"></script>\n    <script src=\"js/utils.js\"></script>\n    <script>\n        message = new Array(0x01234567, 0x89abcdef, 0xfedcba98, 0x76543210);\n        key = new Array(0x01234567, 0x89abcdef, 0xfedcba98, 0x76543210);\n        ciphertext = KJUR_encrypt_sm4(message, key)\n        console.log(ciphertext)\n        for (var j = 0; j < ciphertext.length ; j++ ) {\n            ciphertext[j] = parseInt(ciphertext[j], 16)\n        }\n        console.log(KJUR_decrypt_sm4(ciphertext,key))\n        var start = new Date().getTime();\n        for (var x=0; x < 1; x++){\n            ciphertext = KJUR_encrypt_sm4(message,key);\n            for (var i = ciphertext.length - 1; i >= 0; i--) {\n                message[i] = parseInt(ciphertext[i], 16)\n            };\n        };\n        console.log(ciphertext);\n        // console.log(KJUR_decrypt_sm4(ciphertext,key));\n        var end = new Date().getTime();\n        console.log((end-start)/1000);\n    </script>\n</head>\n<body>\n    \n</body>\n</html>\n"
  },
  {
    "path": "Python/sm4.py",
    "content": "# coding=utf-8\n# time:2016-11-20\n# author:windard\n\nimport time\n\nSboxTable = [\n[0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05],\n[0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99],\n[0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62],\n[0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6],\n[0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8],\n[0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35],\n[0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87],\n[0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e],\n[0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1],\n[0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3],\n[0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f],\n[0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51],\n[0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8],\n[0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0],\n[0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84],\n[0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48]\n]\n\nFK = [0xa3b1bac6, 0x56AA3350, 0x677d9197, 0xb27022dc]\n\nCK =[\n0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,\n0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,\n0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,\n0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,\n0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,\n0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,\n0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,\n0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279\n]\n\n# def leftshift(a, n, size=32):\n# \ta = list(bin(a)[2:])\n# \ta = [\"0\"]*(size - len(a)) + a\n# \tb = ['0']*32\n# \tfor i,x in enumerate(a):\n# \t\tb[(i-n)%32] = a[i]\n# \treturn int(\"\".join(b), 2)\n\ndef leftshift(a, n, size=32):\n\tn = n % size\n\treturn (a << n) | (a >> (size - n))\n\ndef PUT_ULONG_BE(b):\n\tb = sm4Sbox(b)\n\treturn b ^ (leftshift(b, 13)) ^ (leftshift(b, 23))\n\ndef GET_ULONG_BE(b):\n\tb = sm4Sbox(b)\n\treturn b ^ (leftshift(b, 2)) ^ (leftshift(b, 10)) ^ (leftshift(b, 18)) ^ (leftshift(b, 24))\n\n# def sm4Sbox(a):\n# \ta1 = (\"%08x\"%a)[0:2]\n# \ta2 = (\"%08x\"%a)[2:4]\n# \ta3 = (\"%08x\"%a)[4:6]\n# \ta4 = (\"%08x\"%a)[6:8]\n# \tb1 = SboxTable[int(a1[0], 16)][int(a1[1], 16)]\n# \tb2 = SboxTable[int(a2[0], 16)][int(a2[1], 16)]\n# \tb3 = SboxTable[int(a3[0], 16)][int(a3[1], 16)]\n# \tb4 = SboxTable[int(a4[0], 16)][int(a4[1], 16)]\n# \treturn int(\"%02x%02x%02x%02x\"%(b1,b2,b3,b4), 16)\n\ndef sm4Sbox(a):\n\tb1 = SboxTable[(a & 0xf0000000) >> 28][(a & 0x0f000000) >> 24]\n\tb2 = SboxTable[(a & 0x00f00000) >> 20][(a & 0x000f0000) >> 16]\n\tb3 = SboxTable[(a & 0x0000f000) >> 12][(a & 0x00000f00) >>  8]\n\tb4 = SboxTable[(a & 0x000000f0) >>  4][(a & 0x0000000f) >>  0]\n\treturn (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4 << 0)\n\ndef generate_key(MK):\n\tK  = [0] *36\n\trk = [0] *32\n\n\tK[0] = MK[0] ^ FK[0]\n\tK[1] = MK[1] ^ FK[1]\n\tK[2] = MK[2] ^ FK[2]\n\tK[3] = MK[3] ^ FK[3]\n\n\tfor i in xrange(32):\n\t\tK[i+4] = K[i] ^ PUT_ULONG_BE(K[i+1] ^ K[i+2] ^ K[i+3] ^ CK[i])\n\t\trk[i] = K[i+4]\n\treturn rk\n\ndef sm4_encrypt(message, key, method='cbc'):\n\tMK = key\n\tX  = message + [0]*32\n\trk = generate_key(MK)\n\n\tfor i in xrange(32):\n\t\tX[i+4] = X[i] ^ GET_ULONG_BE(X[i+1] ^ X[i+2] ^ X[i+3] ^ rk[i])\n\n\t# Y = [hex(X[35]), hex(X[34]), hex(X[33]), hex(X[32])]\n\tY = [X[35], X[34], X[33], X[32]]\n\treturn Y\n\ndef sm4_decrypt(crphertext, key, method='cbc'):\n\tMK = key\n\tX  = crphertext + [0]*32\n\trk = generate_key(MK)\n\n\trk.reverse()\n\t\n\tfor i in xrange(32):\n\t\tX[i+4] = X[i] ^ GET_ULONG_BE(X[i+1] ^ X[i+2] ^ X[i+3] ^ rk[i])\n\n\t# Y = [hex(X[35]), hex(X[34]), hex(X[33]), hex(X[32])]\n\n\tY = [X[35], X[34], X[33], X[32]]\n\treturn Y\n\nif __name__ == '__main__':\n\ttime.clock()\n\tmessage = [0x01234567,0x89abcdef,0xfedcba98,0x76543210]\n\tkey = [0x01234567,0x89abcdef,0xfedcba98,0x76543210]\n\tfor x in xrange(10000):\n\t\tciphertext = sm4_encrypt(message, key)\n\t\t# message = map(lambda x:int(x[:-1], 16), ciphertext)\n\t# print ciphertext\n\tprint time.clock()\n\t# ciphertext = [0x681edf34, 0xd206965e, 0x86b3e94f, 0x536e4246]\n\t# print sm4_decrypt(ciphertext, key)\n\t# 10000 times 61.7811434009 s \n\t# 10000 times 7.86056015746 s\n\t# 10000 times 5.46304156202 s\n\n"
  },
  {
    "path": "README.md",
    "content": "\n## 国密算法\n\n因最近一个项目需要用到国密算法，所以在网上找了一下国密算法的相关资料。国密算法并不是特指一种算法，而是指国家密码局认定的国产密码算法。它包括 SM2,SM3,SM4 祖冲之算法等一系列算法，可以参考~~[这篇公告](http://www.oscca.gov.cn/News/201204/News_1228.htm)~~，[国家密码管理局关于发布\n《祖冲之序列密码算法》等6项密码行业标准公告](http://www.sca.gov.cn/sca/xwdt/2012-03/21/content_1002392.shtml)说明。\n\n> 建议先阅读了解一下关于现代密码的基础知识。[密码发展史之近现代密码](http://www.sca.gov.cn/sca/zxfw/2017-04/24/content_1011711.shtml)\n\n在网上也有不少国密算法的实现，比如说 北京大学信息安全实验室 开发和维护的 [GmSSL](http://gmssl.org/) ，它是支持国密算法和标准的 openSSL 分支，其代码托管在 [https://github.com/guanzhi/GmSSL](https://github.com/guanzhi/GmSSL) 上。\n\n### sm2\n\n国密算法 SM2 是公钥算法，即非对称加密算法，类似于 RSA，不过 RSA 是基于大素数分解问题，SM2 是基于椭圆曲线问题。\n\n[国家密码管理局关于发布\n《SM2椭圆曲线公钥密码算法》公告](http://www.oscca.gov.cn/sca/xxgk/2010-12/17/content_1002386.shtml)\n\n### sm3\n\nSM3 是消息摘要算法，类似于 md5 或 SHA-1 算法，不过 md5 和 SHA-1 都在 2005 年被中国山东大学的 王小云 教授破解，不建议使用。\n\n[国家密码管理局关于发布《SM3密码杂凑算法》公告](http://www.oscca.gov.cn/sca/xxgk/2010-12/17/content_1002389.shtml)\n\n### sm4\n\nSM4 是传统的对称加密算法， 采用分组加密，类似于 DES 或 AES。\n\n可以在~~[这篇文章](http://www.wtoutiao.com/a/844743.html)~~里看到这些算法之间的简单比较，更加深入的研究请参考论文。\n\n网上已有 JavaScript 实现的 [SM2 算法](http://www.jonllen.com/jonllen/js/178.aspx)，其参考引用了很多 [jsrsasign](http://kjur.github.io/jsrsasign/) 的实现，这是一个用 JavaScript 做加密解密的库，实现了很多的加密解密算法。\n\nJavaScript 本身是有很多缺陷的，数字只有 int 类型，虽然说是 64 位的，但是在做移位运算的时候它会被自动转换为 32 位，这就很尴尬，32 位的移位运算，一不小心就越界了，而且移位也只有左移，而没有循环移位。虽然说 Python 也是只有 int 型，不过它是真真的64 位，不会缺斤少两，网上也有文章详细的提到 JavaScript 的[移位操作的缺陷](http://jerryzou.com/posts/do-you-really-want-use-bit-operators-in-JavaScript/)。\n\nJavaScript 没有循环左移，只有左移，右移和无符号位右移。JavaScript 的复数的值等于 - （值的逆 + 1），比如说 -977410425 的二进制表示为 `11000101101111011110011010000111` ，它的逆为 `00111010010000100001100101111000` ,它的值的逆加1为 `00111010010000100001100101111001` ，所以在 JavaScript 中就会表示为 `-111010010000100001100101111001`，即 `x = -(~x + 1)`\n\n```\na=-977410425\n-977410425\na.toString(2)\n\"-111010010000100001100101111001\"\n(a>>0).toString(2)\n\"-111010010000100001100101111001\"\n(a>>>0).toString(2)\n\"11000101101111011110011010000111\"\n```\n\n关于 SM4 算法流程，国家密码局是已经公开了的，可以找到一份 PDF 文档，写的清清楚楚，明明白白，比我想象的要简单一些，这里就展示一下我自己实现的 循环左移 之类的函数，为什么一直在提循环左移呢？肯定是因为算法里面会用到的吖。\n\n<object data=\"/software/sm4.pdf\" height=\"525\" type=\"application/pdf\" width=\"680\" internalinstanceid=\"7\">\n    <embed src=\"/software/sm4.pdf\"><br>\n</object>\n\n\n[点击下载](/software/sm4.pdf)\n\n\nJavaScript 版\n\n```\nfunction leftshift(a, n, size=32) {\n    n = n % size\n    return (a << n) | (a >>> (size - n))\n}\n```\n\nPyhton 版\n\n```\ndef leftshift(a, n, size=32):\n    n = n % size\n    return (a << n) | (a >> (size - n))\n```\n\n或许也是因为这些不优雅的代码，使得代码的执行效率不高，或者说非常低，在官方文档中提供了一个 1000000 遍的加密样例，然而我的 JavaScript 10000 遍就需要近一分钟，Python 10000 遍近 10 秒，这样下来就需要一个多小时了，可是网上找到的 C语言 和 Java 实现的 SM4 对 1000000 遍加密只需要近一秒钟即可，或许跟代码质量也有关吧，但还是可怕的性能差异。\n\n还有一个地方是 S 盒代换的部分，也改进了一下，速度略有提升，但是差距较大。\n\nJavaScript 版\n\n```\nfunction sm4Sbox(a) {\n    var b1 = SboxTable[(a & 0xf0000000) >>> 28][(a & 0x0f000000) >>> 24]\n    var b2 = SboxTable[(a & 0x00f00000) >>> 20][(a & 0x000f0000) >>> 16]\n    var b3 = SboxTable[(a & 0x0000f000) >>> 12][(a & 0x00000f00) >>>  8]\n    var b4 = SboxTable[(a & 0x000000f0) >>>  4][(a & 0x0000000f) >>>  0]\n    return (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4 << 0)\n}\n```\n\npython 版\n\n```\ndef sm4Sbox(a):\n    b1 = SboxTable[(a & 0xf0000000) >> 28][(a & 0x0f000000) >> 24]\n    b2 = SboxTable[(a & 0x00f00000) >> 20][(a & 0x000f0000) >> 16]\n    b3 = SboxTable[(a & 0x0000f000) >> 12][(a & 0x00000f00) >>  8]\n    b4 = SboxTable[(a & 0x000000f0) >>  4][(a & 0x0000000f) >>  0]\n    return (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4 << 0)\n\n```\n\n代码都在 [https://github.com/windard/sm4](https://github.com/windard/sm4) 了，打包下载在[这里](https://github.com/windard/sm4/archive/master.zip)。\n\n## 性能\n\n或许是自己的代码太渣，实现的 sm4 性能不太行。\n\n在 `/JavaScript/demo` 中有性能测试。\n\n![performance](/JavaScript/demo/performance.jpg)\n"
  }
]