mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-07 17:06:25 +08:00
Update JavaScript lib
This commit is contained in:
111
js/base64.js
Normal file
111
js/base64.js
Normal 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
613
js/sm2.js
Normal 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>
|
||||
30
js/sm3.js
30
js/sm3.js
@@ -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 = [
|
||||
|
||||
Reference in New Issue
Block a user