I would like to create an ECDSA_P256 signature in offchain and verify it in Cadence.
So I have tried the following code using Node.js, but the result fails (false
returns).
Can you please tell me what is wrong with this code and how I can sign it correctly in JavaScript (or Golang)? Am I missing something?
js:
const { SHA3 } = require('sha3');
const EC = require('elliptic').ec;
const ec = new EC('p256');
function signWithKey(privateKey, msg) {
const key = ec.keyFromPrivate(Buffer.from(privateKey, 'hex'));
console.log('publicKey:', key.getPublic('hex').replace(/^04/, ''))
const sig = key.sign(hashMsg(msg));
const n = 32;
const r = sig.r.toArrayLike(Buffer, 'be', n);
const s = sig.s.toArrayLike(Buffer, 'be', n);
return Buffer.concat([r, s]).toString('hex');
};
function hashMsg(msg) {
const sha = new SHA3(256);
sha.update(Buffer.from(msg, 'hex'));
return sha.digest();
};
const privateKey = '9a5080ac4d1323609357a29a755254f770c3e9dcb5e2becdbe8f13f4edd688f5'
const message = '666f6f'; // 'foo'
const signature = signWithKey(privateKey, message);
console.log('signature:', signature);
Cadence script:
import Crypto
pub fun main(): Bool {
let keyList = Crypto.KeyList()
let publicKeyA = Crypto.PublicKey(
publicKey: "8653bdf116189ef4963a6250ba9f1d25daaa028e39569547976a545ca5ff72d31b6bd54955ce51ce579c583a8e10aef12d4b53037660b2fe2b12df0876789ece".decodeHex(),
signatureAlgorithm: Crypto.ECDSA_P256
)
keyList.add(publicKeyA, hashAlgorithm: Crypto.SHA3_256, weight: 1.0)
let signatureSet = [
Crypto.KeyListSignature(
keyIndex: 0,
signature: "d82b75754be1593c0ab4344e62f83b43df7ef854c198181de547e3b4ba320ae2f97160445b6364a6557a1768064c3e45e1c17a9ccfb22183b2135eaf7c989b19".decodeHex()
)
]
// "foo", encoded as UTF-8, in hex representation
let signedData = "666f6f".decodeHex()
let isValid = keyList.isValid(signatureSet: signatureSet, signedData: signedData)
return isValid
}
*Note that this key pair was generated by the flow keys generate
command.