multiformats / multicodec

Compact self-describing codecs. Save space by using predefined multicodec tables.
MIT License
340 stars 205 forks source link

add SM2 pub key. #267

Closed xicilion closed 2 years ago

xicilion commented 2 years ago

SM2 is a set of cryptographic algorithms based on elliptic curve cryptography, including a digital signature, public key encryption and key exchange scheme.

xicilion commented 2 years ago

After actual testing, we can use the same algorithm as https://stackoverflow.com/questions/17171542/algorithm-for-elliptic-curve-point-compression to compress the SM2 public key and recover it successfully.

In our case, the compressed sm2 public key zEPJcWxWVMvrRvSLt4WsPekiqt89YVFRYxSkHbNRjaPfZWTPs will be uncompressed as follows:

{
  "kty": "EC",
  "crv": "SM2",
  "x": "4_1l5yuoHlvhmCsYzfYCLJXFU8-uv5464mWmC-tdyx4",
  "y": "mJoxCEVBRMrgL4B544mhN85kpjXkwXY_HEb_SltPWh0"
}
xicilion commented 2 years ago

The algorithm code used for recovery is as follows:

const bigInt = require("big-integer");

// Consts for SM2 curve.
const two = new bigInt(2),
    prime = new bigInt('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF', 16),
    b = new bigInt('28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93', 16),
    // Pre-computed value, or literal
    pIdent = prime.add(1).divide(4);

function pad_with_zeroes(number, length) {
    var retval = '' + number;
    while (retval.length < length) {
        retval = '0' + retval;
    }
    return retval;
}

/**
 * Point decompress SM2 curve
 * @param {string} Compressed representation in hex string
 * @return {string} Uncompressed representation in hex string
 */
function ECPointDecompress(comp) {
    var signY = new Number(comp[1]) - 2;
    var x = new bigInt(comp.substring(2), 16);
    // y^2 = x^3 - 3x + b
    var y = x.pow(3).subtract(x.multiply(3)).add(b).modPow(pIdent, prime);
    // If the parity doesn't match it's the *other* root
    if (y.mod(2).toJSNumber() !== signY) {
        // y = prime - y
        y = prime.subtract(y);
    }
    return '04' + pad_with_zeroes(x.toString(16), 64) + pad_with_zeroes(y.toString(16), 64);
}

Examples:

ECPointDecompress('03e3fd65e72ba81e5be1982b18cdf6022c95c553cfaebf9e3ae265a60beb5dcb1e')

returns:

04e3fd65e72ba81e5be1982b18cdf6022c95c553cfaebf9e3ae265a60beb5dcb1e989a3108454144cae02f8079e389a137ce64a635e4c1763f1c46ff4a5b4f5a1d
rvagg commented 2 years ago

seems reasonable to me, I'll leave this open till tomorrow in case others have input but will then merge it for you; this thread should serve as background for anyone that comes along wanting to know more about the entry

xicilion commented 2 years ago

This request was not merged. :)

rvagg commented 2 years ago
Screenshot 2022-05-19 at 2 56 45 pm

that's a bit weird, doesn't say who closed it, was that you @xicilion? I'm happy to merge this if it's still wanted? sorry for being slow on getting to it.

xicilion commented 2 years ago

Didn't you close it? I'm also confused about this. This request is still expected to be merged, thank you very much.

rvagg commented 2 years ago

Nope, I didn't close it, it doesn't say who or why, it's just closed! I'll sort it out though.

xicilion commented 2 years ago

thank you very much.