-
Notifications
You must be signed in to change notification settings - Fork 17
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
Examples of library usage #12
Comments
This is one of the top Google results for this problem. I couldn't find a library that did this in Rust the way that I wanted; I'm sure there is one. Say you have this flow in your client application: const address = await lucid.wallet.address();
const foo = await lucid.wallet.signMessage(address, fromText("test"));
const help = lucid.verifyMessage(address, fromText("test"), foo); The equivalent of pub fn verify_message(
address: &str,
key: &str,
payload: &str,
signature: &str,
) -> bool {
let input_address = C::address::Address::from_bech32(address).expect("Input address should have been in bech32 format.");
let signature_bytes = hex::decode(signature).expect("Signature was not valid hex.");
let signature = COSESign1::from_bytes(signature_bytes).expect("Signature was not valid COSE.");
let key_bytes = hex::decode(key).expect("Public key was not valid hex.");
let cose_key = COSEKey::from_bytes(key_bytes).expect("Key was not valid COSE.");
let protected_headers = signature.headers().protected().deserialized_headers();
let signed_address = protected_headers.header(&M::Label::new_text(String::from("address")))
.expect("No address found in the headers of the signature.");
let signed_address_bytes = signed_address.as_bytes()
.expect("Signature contained an address that could not be interpreted as bytes.");
let cose_algorithm = protected_headers.algorithm_id()
.expect("Signature did not specify a COSE algorithm_id.")
.as_int()
.expect("Signature's specified COSE algorithm_id was not an integer.")
.as_i32()
.expect("Could not parse signature COSE algorithm as i32.");
let key_algorithm = cose_key.algorithm_id()
.expect("Key did not specify a COSE algorithm_id.")
.as_int()
.expect("Key's specified COSE algorithm_id was not an integer.")
.as_i32()
.expect("Could not parse key COSE algorithm as i32.");
let key_curve = cose_key.header(&M::Label::new_int(
&M::utils::Int::new_negative(
M::utils::BigNum::from_str("1").unwrap())
))
.expect("Could not derive key curve from key.")
.as_int()
.expect("Key's specified curve was not an integer.")
.as_i32()
.expect("Could not parse key COSE algorithm as i32.");
let key_type = cose_key.key_type().as_int()
.expect("Could not derive key type from key.")
.as_i32()
.expect("Could not parse key COSE algorithm as i32.");
let public_key_bytes = cose_key.header(&M::Label::new_int(
&M::utils::Int::new_negative(
M::utils::BigNum::from_str("2").unwrap())
)
)
.expect("Could not get public key curve from key.")
.as_bytes()
.expect("Could not interpret public key header as bytes.");
let public_key = C::crypto::PublicKey::from_bytes(&public_key_bytes).expect("Could not interpret public key as PublicKey.");
let cose_payload = signature.payload().expect("No payload included in signed message.");
let ed25519 = C::crypto::Ed25519Signature::from_bytes(signature.signature())
.expect("Could not parse Ed25519 signature from signature's signature. (Oof.)");
let data = signature.signed_data(None, None)
.expect("There should have been data in the signature's signed data.")
.to_bytes();
let input_address_hex = hex::encode(input_address.to_bytes());
let signed_address_hex = hex::encode(signed_address_bytes);
let input_address_keyhash = input_address.payment_cred().or_else(|| input_address.staking_cred())
.expect("Could not derive credentials from address.")
.to_keyhash()
.expect("Could not derive keyhash from address.")
.to_hex();
let signed_address_keyhash = public_key.hash().to_hex();
return
signed_address_hex == input_address_hex &&
signed_address_keyhash == input_address_keyhash &&
cose_algorithm == key_algorithm &&
cose_algorithm == -8 &&
key_curve == 6 &&
key_type == 1 &&
cose_payload == payload.as_bytes() &&
public_key.verify(&data, &ed25519)
} I am not sure on the accuracy of the specifics here, and I bet there are constants somewhere in the library to handle those magic numbers, but this works for me. I lifted the implementation directly from Lucid; just translated it to Rust. If you were to need the reverse, I would suggest cannibalizing the Lucid code as I did. Hope this helps someone... |
Hi, sorry if this is not the best place for such questions but I'm struggling to find any examples on how to achieve something with this library.
I'm looking to verify the signature of a payload signed with the dApp injected API function
signData(address, payload)
. When I run this method I get an output of an object like this:Now on a server I want to validate this signature as a means of proof of address ownership.
Anyway, I found this example linked from the CIP-0008 readme.
So firstly I tried to do something similar to construct an instance of
PublicKey
, on a presumption thatkey
from the JSON above is indeed a public key, trying:Unfortunately this creates an error of
Invalid Public Key size
. For good measure I also triedfrom_bech32
on the string itself, but that results inMalformed public key
.There is one other example linked, which seems to outline how to then verify a signature after getting an instance of
PublicKey
, but that example constructs the key from a private key - which in my case I don't have.I believe I'll also need to use
PublicKey
to check that the address belongs to the key, as well verifying the signature, but I don't think I saw any examples of that unless I missed something.I may well just be making a really stupid mistake here - as I am new to Rust, Cose, CBOR and all Cardano development beyond the injected dApp APIs. I appreciate that it's very early days for a library like this to have fleshed out documentation with detailed examples, however I'd be very grateful if anyone was able to offer any pointers. Thanks.
The text was updated successfully, but these errors were encountered: