Hello, I’m building an application that does custody verification of cryptographic keys and I’ve been able to create keys and sign messages with @dfinity/identity npm module. Using as follows:
// Key Generation
var [pubKey, privKey] = identity.Ed25519KeyIdentity.generate().toJSON();
// Sign Message
var privArrayBuff = fromHexString(privKey);
var keyIdObject = identity.Ed25519KeyIdentity.fromSecretKey(privArrayBuff);
var msgArrayBuff = fromHexString(msg);
var sig = await keyIdObject.sign(msgArrayBuff);
return toHexString(sig);
// Verify?
const msgArrayBuff = new Uint8Array(fromHexString(msg));
const sigArrayBuff = new Uint8Array(fromHexString(sig));
const pubKeyArrayBuff = new Uint8Array(fromHexString(pubKey));
var isVerified = blsVerify(msgArrayBuff, sigArrayBuff, pubKeyArrayBuff); // from @dfinity/agent
(node:11812) UnhandledPromiseRejectionWarning: RuntimeError: unreachable
at <anonymous>:wasm-function[51]:0x9f87
at <anonymous>:wasm-function[113]:0xb201
at <anonymous>:wasm-function[104]:0xb03f
at <anonymous>:wasm-function[112]:0xb1c2
at <anonymous>:wasm-function[60]:0xa35c
at <anonymous>:wasm-function[0]:0xd5a
at bls_verify (<anonymous>:wasm-function[39]:0x9947)
I am trying to run this application on a node app, is there a way to handle the yield without using WASM? Thanks!
Where does msg come from? Can you provide me with an example case so I can verify your setup?
I also noticed that you’re declaring then overwriting msgArrayBuff here - I assume this is because these snippets are from multiple functions in your codebase
I ran into that error a couple of times when working with the rust-wasm-bls code, try checking the lengths of each parameter right before it calls the wasm function. I think the bls code will throw if one or some of the parameters (message,key, and signature ) have an invalid length.
You’re not going to get around the call to the BLS wasm - it’s vastly more efficient than a JS-implemented solution, and we don’t currently allow for skipping the signature checking. I suppose we could, by allowing for some kind of DANGEROUS_BYPASS_VALIDATION flag, which might also be useful for mobile development.
Node.js is fully supported for BLS validation though; we run all our tests in node. I’d investigate your inputs, and suggest developing in TypeScript, to let the compiler help you catch any assumptions that don’t line up.
Thanks for the info - I did build my app in typescript and seem to be able to work with the test data you all used on the bls.test.js. The pk variable passed is a primary key - but I would expect it to be the public key. Are these examples generated from the @dfinity/identity module getKeyPair and sign methods?
Your code is trying to verify an Ed25519 signature with a bls12381 verify function. These are two different cryptography-schemes. The bls is for the verification of the IC’s-single-public-key (I think 48 bytes) , the Ed25519 (I think 32 bytes) is the scheme that is used for the authorization of a call by a user-caller.
How would I then verify an ED25519 signature? I know that the public and private keys generation and signing is dependent on the tweetnacl node package - does Dfinity not provide a way to do this in one of their packages already?
For anyone finding themselves with a similar issue, look at the ED25519 @dfinity/Identity package for the keygen and sign functions and how they implement tweetnacl - then use tweetnacl for the verify as well.
Can this be added to the identity and agent packages please ? I think it’s weird that you can create signatures but can’t verify them out of the box. Or am I missing something @kpeacock
It should be doable - wrapping the library’s verify methods is outside the core flows required for talking to the IC, but we could lift that up and make it easier for devs