PlatON-Go icon indicating copy to clipboard operation
PlatON-Go copied to clipboard

Support sha256 to verify ECDSA signature

Open wuyahuang opened this issue 4 years ago • 5 comments

  1. A lot of platforms like intel SGX only support sha256 to sign messages.
  2. A lot of blockchain networks only support sha256 to sign messages, even ethereum is moving from Keccak to sha256 for ETH2.0.

The platon_ecrecover of chain_impl.hpp only supports Keccak-256. I think support sha256 is good for developers to build cross chain or cross platform applications.

wuyahuang avatar Jul 16 '21 08:07 wuyahuang

Changing the underlying algorithm to sha256 is difficult to implement, it involves forking, data migration, etc. So platon_ecrecover can not change to use sha256. At the application level, the WASM virtual machine has implemented external function for the sha256 algorithm, code

benbaley avatar Jul 16 '21 09:07 benbaley

After some tests, the platon_ecrecover of chain_impl.hpp is support sha256 to recover public key.

let's say we use secp256k1 private key to sign a message.

const Bytes = require("./bytes");
const elliptic = require("elliptic");
const secp256k1 = new elliptic.ec("secp256k1"); 

const encodeSignature = ([v, r, s]) => Bytes.flatten([r, s, v]);

const makeSigner = () => (hash, privateKey) => {
  const signature = secp256k1.keyFromPrivate(new Buffer(privateKey.slice(2), "hex")).sign(new Buffer(hash.slice(2), "hex"), { canonical: true });
  return encodeSignature([signature.recoveryParam == 0 ? "0x00" : "0x01", Bytes.pad(32, Bytes.fromNat("0x" + signature.r.toString(16))), Bytes.pad(32, Bytes.fromNat("0x" + signature.s.toString(16)))]);
};

const sign = makeSigner(); // v=0|1 instead of 27|28...

const text = "Hello World";
const privateKey = "0x4940cf212544505a0fad3e3932734220af101da915321489708f69bc908fda65"; // private key, Testnet only
const hash = "0x" + require("crypto").createHash("sha256").update(text).digest("hex");

var signature = sign(hash, privateKey);
console.log({ text, hash, signature });

Output:

{ text: 'Hello World',
  hash:
   '0xa591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e',
  signature:
  '0x6218ff2883e9ee97e29da6a3d6fe0f59081c2de9143b8dee336059c67fc249d965dbc3e5f6d3f0ae598d6be97c39a7a204d0636e50b0d56677eec7d84267c92801' }

Now, we just need submit text and signature to wasm contract to recover the public key.

byte hashed_value[32];
platon::platon_sha256(asBytes("Hello World"), hashed_value);
Address recovered_address;
auto ret = platon::platon_ecrecover(h256(hashed_value, sizeof(hashed_value)), fromHex("0x6218ff2883e9ee97e29da6a3d6fe0f59081c2de9143b8dee336059c67fc249d965dbc3e5f6d3f0ae598d6be97c39a7a204d0636e50b0d56677eec7d84267c92801"), recovered_address);
DEBUG(ret);
DEBUG(recovered_address.toString());

Output:

0
lat1qavfd7zwaknrxyx0drcmv0vr5zehgthhaqq6ul

The descriptions of platon_ecrecover needs to be updated, not only sha3, but also sha256.

wuyahuang avatar Jul 23 '21 02:07 wuyahuang

Thank you for your suggestion, can you submit a PR to https://github.com/PlatONnetwork/PlatON-CDT/tree/feature/wasm

TraceBundy avatar Jul 23 '21 07:07 TraceBundy

https://github.com/PlatONnetwork/PlatON-CDT/pull/192 @TraceBundy

wuyahuang avatar Jul 23 '21 08:07 wuyahuang

Cool! 👍 Thank you very much

benbaley avatar Jul 23 '21 08:07 benbaley

close by done

benbaley avatar Oct 14 '22 02:10 benbaley