Reputation: 22171
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
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