Update JavaScript lib

This commit is contained in:
Zhi Guan
2020-05-30 11:39:37 +08:00
parent 644386fab6
commit 2929a689a3
3 changed files with 754 additions and 0 deletions

111
js/base64.js Normal file
View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 2014 - 2020 The GmSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
const BASE64_MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function base64_encode(bytes) {
var i = 0; j = 0;
var append = bytes.length % 3 > 0 ? 3 - bytes.length % 3 : 0;
for (i = 0; i < append; i++) {
bytes[bytes.length] = 0;
}
var b64 = "";
for (i = 0; j < bytes.length; j += 3) {
if (j > 0 && j % 57 == 0) {
b64 += '\n';
}
b64 += BASE64_MAP[bytes[j] >> 2]
+ BASE64_MAP[(bytes[j] & 3) << 4 | bytes[j+1] >> 4]
+ BASE64_MAP[(bytes[j+1] & 15) << 2 | bytes[j+2] >> 6]
+ BASE64_MAP[bytes[j+2] & 63];
}
for (i = 0; i < append; i++) {
b64 += '=';
}
return b64;
}
function base64_decode(input) {
var i = 0, j = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
var append = input.length % 4;
if (append > 2) {
return null;
}
for (i = 0; i < append; i++) {
if (input.charAt(input.length - i - 1) != '=') {
return null;
}
}
var output = new Array((input.length - append) * 3 / 4);
var enc1, enc2, enc3, enc4;
for (i = 0, j = 0; j < output.length;) {
enc1 = BASE64_MAP.indexOf(input.charAt(i++));
enc2 = BASE64_MAP.indexOf(input.charAt(i++));
enc3 = BASE64_MAP.indexOf(input.charAt(i++));
enc4 = BASE64_MAP.indexOf(input.charAt(i++));
output[j++] = (enc1 << 2) | (enc2 >> 4);
output[j++] = ((enc2 & 15) << 4) | (enc3 >> 2);
output[j++] = ((enc3 & 3) << 6) | enc4;
}
for (i = 0; i < append; i++) {
if (output.pop() != 0) {
return null;
}
}
return output;
}
function base64_test() {
var bin = [1, 2, 3, 4, 5];
var b64 = base64_encode(bin);
var buf = base64_decode(b64);
console.log(b64);
console.log(buf);
}

613
js/sm2.js Normal file
View File

@@ -0,0 +1,613 @@
<html>
<body>
<h1>SM4</h1>
<script>
const SM2_P = [
0xffff, 0xffff, 0xffff, 0xffff,
0x0000, 0x0000, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xfffe, 0xffff,
];
const SM2_B = [
0x0e93, 0x4d94, 0xbd41, 0xddbc,
0x8f92, 0x15ab, 0x89f5, 0xf397,
0x09a7, 0xcf65, 0x9e4b, 0x4d5a,
0x5e34, 0x9d9f, 0xfa9e, 0x28e9,
];
const SM2_G = {
X : [
0x74c7, 0x334c, 0x4589, 0x715a,
0x0be1, 0xf266, 0x0bbf, 0x8fe3,
0xc994, 0x6a39, 0x0446, 0x5f99,
0x8119, 0x1f19, 0xae2c, 0x32c4],
Y : [
0xf0a0, 0x2139, 0x32e5, 0x02df,
0x4740, 0xc62a, 0x877c, 0xd0a9,
0x2153, 0x6b69, 0xcee3, 0x59bd,
0x779c, 0xf4f6, 0x36a2, 0xbc37],
Z: [
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
};
const SM2_N = [
0x4123, 0x39d5, 0xf409, 0x53bb,
0x052b, 0x21c6, 0xdf6b, 0x7203,
0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xfffe, 0xffff,
];
function bn_new() {
return [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
}
function bn_free(a) {
bn_set_zero(a);
delete a;
}
function bn_is_zero(a) {
for (var i = 0; i < 16; i++) {
if (a[i] != 0)
return 0;
}
return 1;
}
function bn_is_one(a) {
if (a[0] != 1)
return 0;
for (var i = 1; i < 16; i++) {
if (a[i] != 0)
return 0;
}
return 1;
}
function bn_to_bytes(a, buf, offset) {
for (var i = 15; i >= 0; i--) {
buf[offset++] = Math.floor(a[i]/256);
buf[offset++] = a[i] % 256;
}
}
function bn_set_bytes(a, buf, offset) {
for (var i = 15; i >= 0; i--) {
a[i] = buf[offset++] * 256;
a[i] += buf[offset++];
}
}
function bn_cmp(a, b) {
for (var i = 15; i >= 0; i--) {
if (a[i] > b[i])
return 1;
if (a[i] < b[i])
return -1;
}
return 0;
}
function bn_set_word(a, word) {
a[0] = word;
for (var i = 1; i < 16; i++) {
a[i] = 0;
}
}
function bn_set_zero(a) {
bn_set_word(a, 0);
}
function bn_set_one(a) {
bn_set_word(a, 1);
}
function bn_copy(r, a) {
for (var i = 0; i < 16; i++) {
r[i] = a[i];
}
}
function bn_to_bits(a) {
var bits = new Array(256);
for (var i = 0; i < 16; i++) {
var w = a[i];
for (var j = 0; j < 16; j++) {
bits[i*16 + j] = w % 2;
w = Math.floor(w/2);
}
}
return bits.reverse();
}
function bn_add(r, a, b) {
r[0] = a[0] + b[0];
for (var i = 1; i < 16; i++) {
r[i] = a[i] + b[i] + Math.floor(r[i-1] / 65536);
}
for (var i = 0; i < 15; i++) {
r[i] %= 65536;
}
}
function bn_sub(r, a, b) {
var borrow = 0;
for (var i = 0; i < 16; i++) {
r[i] = a[i] - b[i] - borrow;
borrow = 0;
if (r[i] < 0) {
r[i] += 65536;
borrow = 1;
}
}
}
function fp_add(r, a, b) {
bn_add(r, a, b);
if (bn_cmp(r, SM2_P) >= 0) {
return bn_sub(r, r, SM2_P);
}
}
function fp_sub(r, a, b) {
if (bn_cmp(a, b) >= 0) {
bn_sub(r, a, b);
} else {
// FIXME: remove t,
// it need there is no fp_sub(b, a, b)
// which is used in point_double()
var t = bn_new();
bn_add(t, a, SM2_P);
bn_sub(r, t, b);
}
}
function fp_dbl(r, a) {
return fp_add(r, a, a);
}
function fp_tri(r, a) {
var t = bn_new();
fp_dbl(t, a);
fp_add(r, t, a);
}
function fp_div2(r, a) {
bn_copy(r, a);
if (r[0] % 2) {
bn_add(r, r, SM2_P);
}
var i;
for (i = 0; i < 15; i++) {
r[i] = Math.floor(r[i] / 2);
r[i] += (r[i + 1] % 2) * 32768;
}
r[i] = Math.floor(r[i] / 2);
}
function fp_neg(r, a) {
if (bn_is_zero(a)) {
bn_set_zero(r);
} else {
bn_sub(r, SM2_P, a);
}
}
function fp_mul(r, a, b) {
var ab = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]
for (var i = 0; i < 16; i++) {
for (var j = 0; j < 16; j++) {
ab[i + j] += a[i] * b[j];
}
}
for (var i = 0; i < 31; i++) {
ab[i + 1] += Math.floor(ab[i] / 65536);
ab[i] = ab[i] % 65536;
}
s = ab.slice(16, 32);
r[ 0] = ab[ 0] + s[0] + s[ 2] + s[ 4] + s[ 6] + s[ 8] + 2 * (s[10] + s[12] + s[14]);
r[ 1] = ab[ 1] + s[1] + s[ 3] + s[ 5] + s[ 7] + s[ 9] + 2 * (s[11] + s[13] + s[15]);
r[ 2] = ab[ 2] + s[2] + s[ 4] + s[ 6] + s[ 8] + s[10] + 2 * (s[12] + s[14]);
r[ 3] = ab[ 3] + s[3] + s[ 5] + s[ 7] + s[ 9] + s[11] + 2 * (s[13] + s[15]);
r[ 4] = ab[ 4];
r[ 5] = ab[ 5];
r[ 6] = ab[ 6] + s[0] + s[ 6] + s[ 8] + s[12] + s[14] + 2 * s[10];
r[ 7] = ab[ 7] + s[1] + s[ 7] + s[ 9] + s[13] + s[15] + 2 * s[11];
r[ 8] = ab[ 8] + s[2] + s[ 8] + s[10] + s[14] + 2 * s[12];
r[ 9] = ab[ 9] + s[3] + s[ 9] + s[11] + s[15] + 2 * s[13];
r[10] = ab[10] + s[4] + s[10] + s[12] + 2 * s[14];
r[11] = ab[11] + s[5] + s[11] + s[13] + 2 * s[15];
r[12] = ab[12] + s[6] + s[12] + s[14];
r[13] = ab[13] + s[7] + s[13] + s[15];
r[14] = ab[14] + s[0] + s[ 2] + s[ 4] + s[ 6] + s[14] + 2 * (s[8] + s[10] + s[12] + s[14]);
r[15] = ab[15] + s[1] + s[ 3] + s[ 5] + s[ 7] + s[15] + 2 * (s[9] + s[11] + s[13] + s[15]);
for (var i = 0; i < 15; i++) {
r[i + 1] += Math.floor(r[i] / 65536);
r[i] %= 65536
}
var d = [0,0,0,0,s[0]+s[2]+s[10]+s[12],s[1]+s[3]+s[11]+s[13],0,0,0,0,0,0,0,0,0,0];
for (var i = 0; i < 15; i++) {
d[i + 1] += Math.floor(d[i] / 65536);
d[i] %= 65536
}
bn_sub(r, r, d);
while (bn_cmp(r, SM2_P) >= 0) {
bn_sub(r, r, SM2_P);
}
}
function fp_sqr(r, a) {
fp_mul(r, a, a);
}
function fp_inv(r, a) {
var a1 = bn_new();
var a2 = bn_new();
var a3 = bn_new();
var a4 = bn_new();
var a5 = bn_new();
fp_sqr(a1, a);
fp_mul(a2, a1, a);
fp_sqr(a3, a2);
fp_sqr(a3, a3);
fp_mul(a3, a3, a2);
fp_sqr(a4, a3);
fp_sqr(a4, a4);
fp_sqr(a4, a4);
fp_sqr(a4, a4);
fp_mul(a4, a4, a3);
fp_sqr(a5, a4);
for (i = 1; i < 8; i++)
fp_sqr(a5, a5);
fp_mul(a5, a5, a4);
for (i = 0; i < 8; i++)
fp_sqr(a5, a5);
fp_mul(a5, a5, a4);
for (i = 0; i < 4; i++)
fp_sqr(a5, a5);
fp_mul(a5, a5, a3);
fp_sqr(a5, a5);
fp_sqr(a5, a5);
fp_mul(a5, a5, a2);
fp_sqr(a5, a5);
fp_mul(a5, a5, a);
fp_sqr(a4, a5);
fp_mul(a3, a4, a1);
fp_sqr(a5, a4);
for (i = 1; i< 31; i++)
fp_sqr(a5, a5);
fp_mul(a4, a5, a4);
fp_sqr(a4, a4);
fp_mul(a4, a4, a);
fp_mul(a3, a4, a2);
for (i = 0; i < 33; i++)
fp_sqr(a5, a5);
fp_mul(a2, a5, a3);
fp_mul(a3, a2, a3);
for (i = 0; i < 32; i++)
fp_sqr(a5, a5);
fp_mul(a2, a5, a3);
fp_mul(a3, a2, a3);
fp_mul(a4, a2, a4);
for (i = 0; i < 32; i++)
fp_sqr(a5, a5);
fp_mul(a2, a5, a3);
fp_mul(a3, a2, a3);
fp_mul(a4, a2, a4);
for (i = 0; i < 32; i++)
fp_sqr(a5, a5);
fp_mul(a2, a5, a3);
fp_mul(a3, a2, a3);
fp_mul(a4, a2, a4);
for (i = 0; i < 32; i++)
fp_sqr(a5, a5);
fp_mul(a2, a5, a3);
fp_mul(a3, a2, a3);
fp_mul(a4, a2, a4);
for (i = 0; i < 32; i++)
fp_sqr(a5, a5)
fp_mul(r, a4, a5);
bn_free(a1);
bn_free(a2);
bn_free(a3);
bn_free(a4);
bn_free(a5);
}
function sm2_point_new() {
var point = {
X : [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
Y : [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
Z : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
}
return point;
}
function sm2_point_free(P) {
bn_set_zero(P.X);
bn_set_zero(P.Y);
bn_set_zero(P.Z);
delete P;
}
function sm2_point_copy(R, P) {
bn_copy(R.X, P.X);
bn_copy(R.Y, P.Y);
bn_copy(R.Z, P.Z);
}
function sm2_point_is_at_infinity(P) {
return bn_is_zero(P.Z);
}
function sm2_point_set_infinity(R) {
bn_set_one(R.X);
bn_set_one(R.Y);
bn_set_zero(R.Z);
}
function sm2_point_get_affine(R, P) {
sm2_point_copy(R, P);
if (bn_is_zero(R.Z) || bn_is_one(R.Z))
return;
fp_inv(R.Z, R.Z);
fp_mul(R.Y, R.Y, R.Z);
fp_sqr(R.Z, R.Z);
fp_mul(R.X, R.X, R.Z);
fp_mul(R.Y, R.Y, R.Z);
bn_set_one(R.Z);
}
function sm2_point_set_bytes(P, buf, offset) {
bn_set_bytes(P.X, buf, offset);
bn_set_bytes(P.Y, buf, offset + 32);
bn_set_one(P.Z);
}
function sm2_point_to_bytes(P, buf, offset) {
var A = sm2_point_new();
sm2_point_get_affine(A, P);
bn_to_bytes(A.X, buf, offset);
bn_to_bytes(A.Y, buf, offset + 32);
}
function sm2_point_is_on_curve(P) {
var t0 = bn_new();
var t1 = bn_new();
var t2 = bn_new();
if (bn_is_one(P.Z)) {
fp_sqr(t0, P.Y);
fp_add(t0, t0, P.X);
fp_add(t0, t0, P.X);
fp_add(t0, t0, P.X);
fp_sqr(t1, P.X);
fp_mul(t1, t1, P.X);
fp_add(t1, t1, SM2_B);
} else {
fp_sqr(t0, P.Y);
fp_sqr(t1, P.Z);
fp_sqr(t2, t1);
fp_mul(t1, t1, t2);
fp_mul(t1, t1, SM2_B);
fp_mul(t2, t2, P.X);
fp_add(t0, t0, t2);
fp_add(t0, t0, t2);
fp_add(t0, t0, t2);
fp_sqr(t2, P.X);
fp_mul(t2, t2, P.X);
fp_add(t1, t1, t2);
}
return (bn_cmp(t0, t1) == 0);
}
function sm2_point_neg(R, P) {
bn_copy(R.X, P.X);
fp_neg(R.Y, P.Y);
bn_copy(R.Z, P.Z);
}
function sm2_point_double(R, P) {
if (sm2_point_is_at_infinity(P)) {
return sm2_point_copy(R, P);
}
var X1 = P.X;
var Y1 = P.Y;
var Z1 = P.Z;
var T1 = bn_new();
var T2 = bn_new();
var T3 = bn_new();
var X3 = bn_new();
var Y3 = bn_new();
var Z3 = bn_new();
fp_sqr(T1, Z1);
fp_sub(T2, X1, T1);
fp_add(T1, X1, T1);
fp_mul(T2, T2, T1);
fp_tri(T2, T2);
fp_dbl(Y3, Y1);
fp_mul(Z3, Y3, Z1);
fp_sqr(Y3, Y3);
fp_mul(T3, Y3, X1);
fp_sqr(Y3, Y3);
fp_div2(Y3, Y3);
fp_sqr(X3, T2);
fp_dbl(T1, T3);
fp_sub(X3, X3, T1);
fp_sub(T1, T3, X3);
fp_mul(T1, T1, T2);
fp_sub(Y3, T1, Y3);
bn_copy(R.X, X3);
bn_copy(R.Y, Y3);
bn_copy(R.Z, Z3);
}
function sm2_point_add(R, P, Q) {
if (sm2_point_is_at_infinity(Q)) {
sm2_point_copy(R, P);
return;
}
if (sm2_point_is_at_infinity(P)) {
sm2_point_copy(R, Q);
return;
}
var X1 = P.X;
var Y1 = P.Y;
var Z1 = P.Z;
var x2 = Q.X;
var y2 = Q.Y;
var T1 = bn_new();
var T2 = bn_new();
var T3 = bn_new();
var T4 = bn_new();
var X3 = bn_new();
var Y3 = bn_new();
var Z3 = bn_new();
fp_sqr(T1, Z1);
fp_mul(T2, T1, Z1);
fp_mul(T1, T1, x2);
fp_mul(T2, T2, y2);
fp_sub(T1, T1, X1);
fp_sub(T2, T2, Y1);
if (bn_is_zero(T1)) {
if (bn_is_zero(T2)) {
return sm2_point_double(R, Q);
} else {
return sm2_point_set_infinity(R);
}
}
fp_mul(Z3, Z1, T1);
fp_sqr(T3, T1);
fp_mul(T4, T3, T1);
fp_mul(T3, T3, X1);
fp_dbl(T1, T3);
fp_sqr(X3, T2);
fp_sub(X3, X3, T1);
fp_sub(X3, X3, T4);
fp_sub(T3, T3, X3);
fp_mul(T3, T3, T2);
fp_mul(T4, T4, Y1);
fp_sub(Y3, T3, T4);
bn_copy(R.X, X3);
bn_copy(R.Y, Y3);
bn_copy(R.Z, Z3);
}
function sm2_point_mul(R, k, P) {
var bits = bn_to_bits(k);
var Q = sm2_point_new();
for (var i = 0; i < bits.length; i++) {
sm2_point_double(Q, Q);
if (bits[i] == 1) {
sm2_point_add(Q, Q, P);
}
}
sm2_point_copy(R, Q);
}
function sm2_point_mul_G(R, k) {
return sm2_point_mul(R, k, SM2_G);
}
function sm2_sig_new() {
var sig {
r: bn_new(),
s: bn_new(),
};
return sig;
}
function sm2_do_verify(dgst, sig, P) {
if (dgst.length < 32
|| bn_is_zero(sig.r)
|| bn_cmp(sig.r, SM2_N) >= 0
|| bn_is_zero(sig.s)
|| bn_cmp(sig.s, SM2_N) >= 0) {
return false;
}
var e = bn_new();
bn_set_bytes(e, dgst, 0);
if (bn_cmp(e, SM2_N) >= 0) {
bn_sub(e, e, SM2_N);
}
var t = bn_new();
bn_add(t, sig.r, sig.s);
if (bn_cmp(t, SM2_N) == 0) {
return false;
}
var Q1 = sm2_point_new();
var Q2 = sm2_point_new();
sm2_point_mul_G(Q1, s1);
sm2_point_mul(Q2, t, P);
sm2_point_add(Q1, Q1, Q2);
sm2_point_get_affine(Q1, Q1);
bn_add(e, e, Q1.X);
if (bn_cmp(e, SM2_N)) {
bn_sub(e, e, SM2_N);
}
if (bn_cmp(e, SM2_N)) {
bn_sub(e, e, SM2_N);
}
return bn_cmp(e, sig.r) == 0;
}
function sm2_point_test() {
var P = sm2_point_new();
/*
sm2_point_double(P, SM2_G);
sm2_point_double(P, P);
sm2_point_add(P, P, SM2_G);
sm2_point_get_affine(P, P);
console.log(P);
*/
var k = bn_new();
bn_set_word(k, 11);
console.log("mul");
sm2_point_mul(P, SM2_B, SM2_G);
sm2_point_get_affine(P, P);
console.log(P.X);
console.log(P.Y);
console.log(P.Z);
}
</script>
</html>

View File

@@ -318,6 +318,36 @@ function sm3(m) {
return digest;
}
function sm3_compute_z(z, id, pk) {
const Z_CONST = [
0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
0x28, 0xE9, 0xFA, 0x9E, 0x9D, 0x9F, 0x5E, 0x34,
0x4D, 0x5A, 0x9E, 0x4B, 0xCF, 0x65, 0x09, 0xA7,
0xF3, 0x97, 0x89, 0xF5, 0x15, 0xAB, 0x8F, 0x92,
0xDD, 0xBC, 0xBD, 0x41, 0x4D, 0x94, 0x0E, 0x93,
0x32, 0xC4, 0xAE, 0x2C, 0x1F, 0x19, 0x81, 0x19,
0x5F, 0x99, 0x04, 0x46, 0x6A, 0x39, 0xC9, 0x94,
0x8F, 0xE3, 0x0B, 0xBF, 0xF2, 0x66, 0x0B, 0xE1,
0x71, 0x5A, 0x45, 0x89, 0x33, 0x4C, 0x74, 0xC7,
0xBC, 0x37, 0x36, 0xA2, 0xF4, 0xF6, 0x77, 0x9C,
0x59, 0xBD, 0xCE, 0xE3, 0x6B, 0x69, 0x21, 0x53,
0xD0, 0xA9, 0x87, 0x7C, 0xC6, 0x2A, 0x47, 0x40,
0x02, 0xDF, 0x32, 0xE5, 0x21, 0x39, 0xF0, 0xA0,
];
var ctx = sm3_ctx_new();
sm3_init(ctx);
sm3_update(ctx, [Math.floor(id.length / 65536), id.length % 65536]);
sm3_update(ctx, id);
sm3_update(ctx, Z_CONST);
sm3_update(ctx, pk);
sm3_final(ctx, z);
sm3_ctx_free(ctx);
}
function sm3_test() {
const test1 = [0x61, 0x62, 0x63];
const test2 = [