Comparing version 0.3.10 to 0.3.11
@@ -0,1 +1,5 @@ | ||
## 0.3.11 | ||
* sm2 支持压缩公钥 | ||
## 0.3.10 | ||
@@ -2,0 +6,0 @@ |
{ | ||
"name": "sm-crypto", | ||
"version": "0.3.10", | ||
"version": "0.3.11", | ||
"description": "sm-crypto", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
@@ -27,2 +27,6 @@ # sm-crypto | ||
// 默认生成公钥 130 位太长,可以压缩公钥到 66 位 | ||
const compressedPublicKey = sm2.compressPublicKeyHex(publicKey) // compressedPublicKey 和 publicKey 等价 | ||
sm2.comparePublicKeyHex(publicKey, compressedPublicKey) // 判断公钥是否等价 | ||
// 自定义随机数,参数会直接透传给 jsbn 库的 BigInteger 构造器 | ||
@@ -34,2 +38,3 @@ // 注意:开发者使用自定义随机数,需要自行确保传入的随机数符合密码学安全 | ||
let verifyResult = sm2.verifyPublicKey(publicKey) // 验证公钥 | ||
verifyResult = sm2.verifyPublicKey(compressedPublicKey) // 验证公钥 | ||
``` | ||
@@ -36,0 +41,0 @@ |
@@ -12,2 +12,3 @@ /* eslint-disable no-case-declarations, max-len */ | ||
const TWO = new BigInteger('2') | ||
const THREE = new BigInteger('3') | ||
@@ -299,4 +300,17 @@ | ||
case 3: | ||
// 不支持的压缩方式 | ||
return null | ||
// 压缩 | ||
const x = this.fromBigInteger(new BigInteger(s.substr(2), 16)) | ||
// 对 p ≡ 3 (mod4),即存在正整数 u,使得 p = 4u + 3 | ||
// 计算 y = (√ (x^3 + ax + b) % p)^(u + 1) modp | ||
let y = this.fromBigInteger(x.multiply(x.square()).add( | ||
x.multiply(this.a) | ||
).add(this.b).toBigInteger() | ||
.modPow( | ||
this.q.divide(new BigInteger('4')).add(BigInteger.ONE), this.q | ||
)) | ||
// 算出结果 2 进制最后 1 位不等于第 1 个字节减 2 则取反 | ||
if (!y.toBigInteger().mod(TWO).equals(new BigInteger(s.substr(0, 2), 16).subtract(TWO))) { | ||
y = y.negate() | ||
} | ||
return new ECPointFp(this, x, y) | ||
case 4: | ||
@@ -303,0 +317,0 @@ case 6: |
@@ -205,5 +205,12 @@ /* eslint-disable no-use-before-define */ | ||
const gy = _.leftPad(G.getY().toBigInteger().toRadix(16), 64) | ||
if (publicKey.length > 128) publicKey = publicKey.substr(2, 128) // 干掉 '04' | ||
const px = publicKey.substr(0, 64) | ||
const py = publicKey.substr(64, 64) | ||
let px | ||
let py | ||
if (publicKey.length === 128) { | ||
px = publicKey.substr(0, 64) | ||
py = publicKey.substr(64, 64) | ||
} else { | ||
const point = G.curve.decodePointHex(publicKey) | ||
px = _.leftPad(point.getX().toBigInteger().toRadix(16), 64) | ||
py = _.leftPad(point.getY().toBigInteger().toRadix(16), 64) | ||
} | ||
const data = _.hexToArray(userId + a + b + gx + gy + px + py) | ||
@@ -246,2 +253,4 @@ | ||
generateKeyPairHex: _.generateKeyPairHex, | ||
compressPublicKeyHex: _.compressPublicKeyHex, | ||
comparePublicKeyHex: _.comparePublicKeyHex, | ||
doEncrypt, | ||
@@ -248,0 +257,0 @@ doDecrypt, |
@@ -52,2 +52,18 @@ /* eslint-disable no-bitwise, no-mixed-operators, no-use-before-define, max-len */ | ||
/** | ||
* 生成压缩公钥 | ||
*/ | ||
function compressPublicKeyHex(s) { | ||
if (s.length !== 130) throw new Error('Invalid public key to compress') | ||
const len = (s.length - 2) / 2 | ||
const xHex = s.substr(2, len) | ||
const y = new BigInteger(s.substr(len + 2, len), 16) | ||
let prefix = '03' | ||
if (y.mod(new BigInteger('2')).equals(BigInteger.ZERO)) prefix = '02' | ||
return prefix + xHex | ||
} | ||
/** | ||
* utf8串转16进制串 | ||
@@ -154,2 +170,15 @@ */ | ||
/** | ||
* 验证公钥是否等价,等价返回true | ||
*/ | ||
function comparePublicKeyHex(publicKey1, publicKey2) { | ||
const point1 = curve.decodePointHex(publicKey1) | ||
if (!point1) return false | ||
const point2 = curve.decodePointHex(publicKey2) | ||
if (!point2) return false | ||
return point1.equals(point2) | ||
} | ||
module.exports = { | ||
@@ -159,2 +188,3 @@ getGlobalCurve, | ||
generateKeyPairHex, | ||
compressPublicKeyHex, | ||
utf8ToHex, | ||
@@ -166,2 +196,3 @@ leftPad, | ||
verifyPublicKey, | ||
comparePublicKeyHex, | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
99630
1529
161