How to sign a transaction

GXChain Signature

In How to generate key pair, we introduce the public-private key pair of GXChain based on the elliptic curve cryptography (ECC) and secp256k1 curves, so the signature of GXChain is based on the elliptic curve digital signature algorithm (ECDSA), consists of a 1-byte recover_id, a 32-byte r value, and a 32-byte s value.

function ec_sign(message, private_key){
    let sha256_buffer = sha256(message);
    ECSignature ecsig = ECDSA.sign_compact(sha256_buffer, private_key);
    byte[32] r = ecsig.r;
    byte[32] s = ecsig.s;
    int i = ecsig.recovery_id + 4 +27; // compressed public key
    byte[65] signature = Buffer.concat(i,r,s);
    return signature;
}

Signature malleability

In order to prevent the double-spend problem, in addition to the requirements of BIP62, GXChain imposes stricter restrictions on the values ​​of r and s:

function isCanonical(r,s){
    return !(r[0] & 0x80)
        && !(r[0] == 0 && !(r[1] & 0x80))
        && !(s[0] & 0x80)
        && !(s[0] == 0 && !(s[1] & 0x80))
}

That is, the range of r and s is [2^247, 2^255)

After the judgment of isCanonical, the sign method is like this:

function sign(message, private_key){
    byte[65] signature = ec_sign(message,private_key);
    while(!isCanonical(signature.slice(1,33),signature.slice(33,65))){
        signature = ec_sign(message,private_key);
    }
    return signature;
}

Discussion and Reference

Code Reference

Last Updated: 2/26/2019, 5:08:41 PM