Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

signer-cli generates bad signature #175

Open
robin-crypto-com opened this issue Oct 6, 2020 · 12 comments
Open

signer-cli generates bad signature #175

robin-crypto-com opened this issue Oct 6, 2020 · 12 comments
Milestone

Comments

@robin-crypto-com
Copy link

robin-crypto-com commented Oct 6, 2020

See my previous comment for reference: #174 (comment)

After some digging,
here's how the api generates a signature from an extrinsicPayload:
const { signature } = extrinsicPayload.sign(myKeyringPair);
which is equal to:

const extrinsicPayloadU8a = extrinsicPayload.toU8a({ method: true });
const encoded = extrinsicPayloadU8a.length > 256 ? api.registry.hash(extrinsicPayloadU8a) : extrinsicPayloadU8a;
const signatureU8a = fromKeysPair.sign(encoded, { withType: true });
const signature = u8aToHex(signatureU8a);

the signer-cli is doing it this way:

import { hexToU8a, u8aToHex, u8aConcat } from "@polkadot/util";
const payloadU8a = hexToU8a(extrinsicPayloadHex);
const signatureU8a = fromKeysPair.sign(payloadU8a);
const prefix = new Uint8Array([0]); // [0] keyring type ed25519 or [1] keyring type sr25519
const signatureU8aWithPrefix = u8aConcat(prefix, signatureU8a);
const signature = u8aToHex(signatureU8aWithPrefix);

I think it should be something like that instead:

const payloadU8a = extrinsicPayload.toU8a({ method: true });
const rawSignatureU8a = fromKeysPair.sign(payloadU8a, { withType: true });
const signatureHex = u8aToHex(rawSignatureU8a);
@jacogr
Copy link
Member

jacogr commented Oct 6, 2020

Yes, certainly not sure why the cli would not use the withType, it should. (Believe this probably precedes withType). Additionally, if it doesn't apply the hashing on large payloads, it should.

Having said that, the concat is sane (although it should not be here), since it mirrors https://github.com/polkadot-js/common/blob/master/packages/keyring/src/pair/index.ts#L173-L178

@pavelrib
Copy link

I don't know if it's the same issue, but I'm too using an ed25519 key and I receive 1010: Invalid Transaction: Transaction has a bad signature.

Run:
polkadot-js-signer submit --account <source_account>  --ws wss://rpc.polkadot.io/  balances.transfer <dest_account> 1020000000
Payload: 0x0500c8deea5a67504d644b16bf91b733b9b89a5ae1a9a067ee9a8fe03f6e9c9e3f5202dc2ff3450108001a0000000500000091b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c378ac8eb5f8d4fe99e726fd5d19a2e19cf730d888a65e3ceaf25af2c01b83325d

Run:
polkadot-js-signer sign --account <source_account> --seed <source_account_key_hex> --type ed25519 0x0500c8deea5a67504d644b16bf91b733b9b89a5ae1a9a067ee9a8fe03f6e9c9e3f5202dc2ff3450108001a0000000500000091b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c378ac8eb5f8d4fe99e726fd5d19a2e19cf730d888a65e3ceaf25af2c01b83325d
Signature: 0x00a04fb36f3d69bf761d7a68f4387b13329e215422ac6e7c68697b3cdc2eac8f2c9d701a3c96e8d8068d8dbaff733ff93b6ede2f7e5e1733761969e342a1e99a0a

Adding signature:
Signature> 0x00a04fb36f3d69bf761d7a68f4387b13329e215422ac6e7c68697b3cdc2eac8f2c9d701a3c96e8d8068d8dbaff733ff93b6ede2f7e5e1733761969e342a1e99a0a

Was it tested recently with this type of key?

@jacogr
Copy link
Member

jacogr commented Jan 25, 2021

Which chain is this? Polkadot/Kusama/other?

EDIT: Re-reading, that was a very stupid question, everybody can see the --ws param.

@pavelrib
Copy link

Polkadot

@jacogr
Copy link
Member

jacogr commented Jan 26, 2021

Very strange, exact same does work for me on both sr25519 and sr25519 keys. (2 different accounts). How long was the delay between creation of the payload and submission of the signature? (Just wondering if the 5 minute mortal era comes into play here)

@pavelrib
Copy link

pavelrib commented Jan 26, 2021

No, I send it almost instantaneously.
If I sign the payload with my local eddsa signing script and paste the output into the submit script, I get this error:

Signature> 0x939bd75a06d1d2e2964c39a971c40c6d29a537aa3553c4c96f23bef23039c70243554cd5bc18d66cbb019bb7571ecea6552c00ab24ebe5b3f3caf55afe942305
REGISTRY: Error: Unable to create Enum via index 147, in Ed25519, Sr25519, Ecdsa
    at assert (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/util/assert.js:34:11)
    at createFromValue (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/types/codec/Enum.js:45:20)
    at decodeFromValue (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/types/codec/Enum.js:74:12)
    at decodeFromString (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/types/codec/Enum.js:69:5)
    at decodeFromValue (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/types/codec/Enum.js:78:12)
    at decodeEnum (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/types/codec/Enum.js:98:10)
    at new Enum (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/types/codec/Enum.js:145:21)
    at new <anonymous> (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/types/codec/Enum.js:157:9)
    at new Type (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/types/create/registry.js:340:16)
    at new Type (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/types/create/registry.js:340:16)
Error: createType(ExtrinsicSignature):: Unable to create Enum via index 147, in Ed25519, Sr25519, Ecdsa
    at createTypeUnsafe (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/types/create/createType.js:72:11)
    at createType (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/types/create/createType.js:84:10)
    at TypeRegistry.createType (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/types/create/registry.js:297:39)
    at Map.addSignature (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/types/extrinsic/v4/ExtrinsicSignature.js:151:93)
    at Map.addSignature (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/types/extrinsic/v4/Extrinsic.js:94:20)
    at Submittable.addSignature (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/types/extrinsic/Extrinsic.js:241:15)
    at Submittable.value (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/api/submittable/createClass.js:220:17)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async MergeMapSubscriber.project (/Users/pavelr/.nvm/versions/node/v14.15.1/lib/node_modules/@polkadot/signer-cli/node_modules/@polkadot/api/submittable/createClass.js:148:26)

It should be a legitimate ed25519 signature, any reason why this happens?

@jacogr
Copy link
Member

jacogr commented Jan 26, 2021

The above signature is not correct. For the Substrate signatures (MultiSiginature type) it is always 65/66 bytes in length. The first byte is always 00, 01 or 02, (00 = ed25519, 01 = sr25519, 02 = ecdsa), the reaming bytes contain the actual signature data. (64 following for sr/ed, 65 for ecdsa)

@pavelrib
Copy link

I see.. missed it. The transaction is submitted ok now, thanks!
Not sure then why it doesn't work with the signer-cli...

@joelamouche
Copy link
Contributor

Is this still an issue @pavelrib ?

@polariseye
Copy link

polariseye commented Jul 6, 2021

@pavelrib could you please tell me how to fix it? my code happed too~

import type { Signer, SignerResult } from '@polkadot/api/types';
import type { SignerPayloadRaw } from '@polkadot/types/types';
import { KeyringPair } from "@polkadot/keyring/types";
import { assert, isHex,u8aToHex } from '@polkadot/util';
import { blake2AsHex } from '@polkadot/util-crypto';
import { ApiPromise,WsProvider } from "@polkadot/api";
import { cryptoWaitReady, mnemonicGenerate } from '@polkadot/util-crypto';
import { Keyring } from "@polkadot/keyring";
import type { SignerOptions } from '@polkadot/api/submittable/types';

export default class RawSigner implements Signer {
    alice:KeyringPair ;
    constructor(alice:KeyringPair){
        this.alice=alice;
    }
    public async signRaw ({ data }: SignerPayloadRaw): Promise<SignerResult> {
        const hashed = (data.length > (256 + 1) * 2)
        ? blake2AsHex(data)
        : data;
        console.log(`unsigned:${data}`)
    
        try{
            let sigVal = this.alice.sign(hashed);
            return {id:1,signature:u8aToHex(sigVal)};
        }catch(err){
            console.log("error:",err)
            throw err;
        }
  }
}

async function main() {
    await cryptoWaitReady();

    const wsProvider = new WsProvider('wss://westend-rpc.polkadot.io');
    const api = await ApiPromise.create({ provider: wsProvider });

    let keyring= new Keyring({
        type:"sr25519",
    });

    const Alice = keyring.addFromUri("//Alice");
    let from = Alice.address;
    let to = "5H2Dq1m8Cg7qsMaADCxnPDf3mk3CePDiVdVF6nyNeRbKWjc3";
    let amount = BigInt(12345);

    const options: Partial<SignerOptions> = { signer: new RawSigner(Alice) };

    const accountInfo = await api.query.system.account(from);
    let signedBlock = await api.rpc.chain.getBlock();

    options.nonce = accountInfo.nonce;
    options.blockHash = signedBlock.hash;    
    options.era = 0;

    const tx = api.tx.balances.transfer(to, amount);
    let signResult = await tx.signAndSend(from,options);
    console.log(`tx:${signResult.hash}`)

    //let remoteHash = await signResult.send()
    //console.log(`remote tx:${remoteHash}`)
}

main().catch(console.log).finally(()=>{ console.log("finished") })

@ahmetk77
Copy link

How do I disable or code signing?
keeps giving error while signing transaction.

@jacogr
Copy link
Member

jacogr commented Mar 12, 2022

@polariseye Your sign is incorrect - you need to pass the flag to add the identification byte. (See the sign options on the keyring)

@jacogr jacogr added this to the todo milestone Mar 14, 2023
@jacogr jacogr removed the -size-xs label Mar 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants