Mik378
Mik378

Reputation: 22171

Is it possible to sign a message with a base58 secret key with Tweetnacl library?

I've generated a key pair using Tweetnacl.js:

const base58KeyPairGenerator = (seed: Uint8Array) => ({
    publicKey: keyToPublicIdentityKey(nacl.sign.keyPair.fromSeed(seed).publicKey),
    secretKey: seedToSecretIdentityKey(seed)
});

const keyToPublicIdentityKey = (key) => {
    return keyToIdentityKey(key, 'idpub');
};

const seedToSecretIdentityKey = (seed) => {
    return keyToIdentityKey(seed, 'idsec');
};

const keyToIdentityKey = (key, prefix) => {
    const keyBuffer = Buffer.from(key, 'hex');
    if (keyBuffer.length !== 32) {
        throw new Error('Key/seed must be 32 bytes long.');
    }
    const address = Buffer.concat([prefix, keyBuffer]);
    const checksum = sha256d(address).slice(0, 4);
    return base58.encode(Buffer.concat([address, checksum]));
};

const sha256d = (data) => {
    return Buffer.from(
        sha256()
            .update(
                sha256()
                    .update(data)
                    .digest()
            )
            .digest()
    );
};

const keyPair = base58KeyPairGenerator(nacl.randomBytes(32));

Now that I have a base58 key pair (public key and secret key in base58), I want to sign a message with the secret key like this:

nacl.sign(
          Buffer.from(someStringMessage, 'hex'),
          base58.decode(keyPair.secretKey)
        )

base58 here is from this library.

However I get this error:

bad secret key size

      at Object.<anonymous>.nacl.sign (node_modules/tweetnacl/nacl-fast.js:2257:11)

Indeed, the nacl.sign function expects a 64bits secret key and that's not the case of my base58 version.

Is there a way to fix it while keeping base58 or should I use the original Ed25519 format generated by nacl.randomBytes(32), meaning the not- transformed one?

Upvotes: 2

Views: 1621

Answers (1)

Frank Denis
Frank Denis

Reputation: 1501

That being said, NaCl signing keys are 64 bytes, not 32. Hence the error you get.

In the base58KeyPairGenerator function, the secret key must be the output of nacl.sign.keyPair.fromSeed(seed).secretKey (or .privateKey or whatever it's called), not just the seed.

Upvotes: 4

Related Questions