38 lines
1.4 KiB
JavaScript
38 lines
1.4 KiB
JavaScript
const bigInt = require("big-integer");
|
|
|
|
// Consts for P256 curve. Adjust accordingly
|
|
const two = new bigInt(2),
|
|
// 115792089210356248762697446949407573530086143415290314195533631308867097853951
|
|
prime = two.pow(256).subtract( two.pow(224) ).add( two.pow(192) ).add( two.pow(96) ).subtract(1),
|
|
b = new bigInt( '41058363725152142129326129780047268409114441015993725554835256314039467401291' ),
|
|
// Pre-computed value, or literal
|
|
// 28948022302589062190674361737351893382521535853822578548883407827216774463488
|
|
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 NIST 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);
|
|
}
|
|
|
|
console.log(ECPointDecompress('035d77c1e3eac37f685aeea2ae872c4e7e4d159756e57601db3bcccbc549f360b2')) |