4

I'm having some trouble to understand how am I supposed to verify if a signed data was really signed by a specific address.

Checking this CBOR

845846A201276761646472657373583900E922E8166852073D6C1C9BE0736530404C9C26D9BA1773E11D32D11C0F7B2C7F8924528D797A8F86D8210D6276E09F47B82ECD53A24900E7A166686173686564F44B68656C6C6F20776F726C645840D1FCCD8B340A46FD9573FE6A0F6BFC8373562019E9FCD8BDFD7A7D08A89FE98BF28E6736BAE823C024C7B20081C6D30FC4676D2A314299F22CB0264EE7E6AB04

That I got from signing a "hello world" message payload:

[h'A201276761646472657373583900E922E8166852073D6C1C9BE0736530404C9C26D9BA1773E11D32D11C0F7B2C7F8924528D797A8F86D8210D6276E09F47B82ECD53A24900E7', {"hashed": false}, h'68656C6C6F20776F726C64', h'D1FCCD8B340A46FD9573FE6A0F6BFC8373562019E9FCD8BDFD7A7D08A89FE98BF28E6736BAE823C024C7B20081C6D30FC4676D2A314299F22CB0264EE7E6AB04']

I see that I have the address in the headers and I also have the ed25519 signature, but I'm not sure how am I supposed to determine the public key for this and I obviously don't have access to the secret at that point. I was trying something like:

import { eddsa } from "elliptic";

const EdDSA = new eddsa("ed25519");

const key = EdDSA.keyFromPublic(
    ? // what do I put here? Is there a way I can get the public key from the address hex?
);

const verifies = key.verify(
  "hello world",
  "D1FCCD8B340A46FD9573FE6A0F6BFC8373562019E9FCD8BDFD7A7D08A89FE98BF28E6736BAE823C024C7B20081C6D30FC4676D2A314299F22CB0264EE7E6AB04"
);

console.log("Valid:", verifies);

Thanks in advance for your time!

1 Answer 1

3

To start with, Message Signing in Cardano follows CIP-0008 https://github.com/cardano-foundation/CIPs/tree/master/CIP-0008

Reading this would give a more idea around message signing.

Answer to your question, How to verify this signature,

From the CBOR you have pasted, This CBOR is CIP-0008 followed COSE_SIGN1 structure, and most probably created from Nami Wallet.

Further decoding first array item from decoded CBOR, you can see the following Map,

{1: -8, "address": h'00E922E8166852073D6C1C9BE0736530404C9C26D9BA1773E11D32D11C0F7B2C7F8924528D797A8F86D8210D6276E09F47B82ECD53A24900E7'}

This contains address as one property, This map is also supposed to contain one more attribute 4 with publicKey of corresponding privateKey that signed the message unfortunately is missing.

So if you have public key in that, You can follow CIP-0008 to verify the message, but as it is missing, only option you have is to ask publicKey from whom you received this message, if you got this CBOR from Nami Wallet then you might have got publicKey as well.

More details on how to verify this CBOR can be found in CIP-0008.

Updates

You can also use @stricahq/cip08 javascript library to to create/verify signature.

import { CoseSign1 } from "@stricahq/cip08";

const messageCBOR = "<message cbor received from wallet>";
const builder = CoseSign1.fromCbor(messageCBOR);

// If message cbor contains publicKey, it will try to verify the
// signature and return true/false
const verified = builder.verifySignature();

// if you want publicKey and address
const publicKeyBuffer = builder.getPublicKey();
const addressBuffer = builder.getAddress();
1
  • 1
    Thanks for the clarification! I do believe Nami wallet sends the public key in the headers, but I believe Eternl wallet still doesn't :(
    – glneto
    Mar 28, 2022 at 16:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.