Skip to content

Commit

Permalink
add sign and verify challenge to wasm lib
Browse files Browse the repository at this point in the history
  • Loading branch information
OBorce committed Aug 28, 2024
1 parent d498c0f commit a5f7ec6
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
23 changes: 23 additions & 0 deletions wasm-wrappers/js-bindings/wasm_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ import {
effective_pool_balance,
Amount,
encode_output_issue_nft,
sign_challenge,
verify_challenge,
} from "../pkg/wasm_wrappers.js";

function assert_eq_arrays(arr1, arr2) {
Expand Down Expand Up @@ -103,6 +105,27 @@ export async function run_test() {
console.log("Tested invalid menemonic successfully");
}

{
let challenge = sign_challenge(priv_key, message);
let address = pubkey_to_pubkeyhash_address(pub_key, Network.Testnet);
let result = verify_challenge(address, Network.Testnet, challenge, message);
if (!result) {
throw new Error("Invalid sing and verify challenge");
}

const different_priv_key = make_private_key();
const different_pub_key = public_key_from_private_key(different_priv_key);
let different_address = pubkey_to_pubkeyhash_address(different_pub_key, Network.Testnet);
try {
verify_challenge(different_address, Network.Testnet, challenge, message);
} catch (e) {
if (!e.includes("Public key to address mismatch")) {
throw e;
}
console.log("Tested verify with different address successfully");
}
}

try {
make_receiving_address(bad_priv_key, 0);
throw new Error("Invalid private key worked somehow!");
Expand Down
36 changes: 36 additions & 0 deletions wasm-wrappers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ use common::{
output_value::OutputValue::{self, Coin, TokenV1},
signature::{
inputsig::{
arbitrary_message::{produce_message_challenge, ArbitraryMessageSignature},
authorize_hashed_timelock_contract_spend::AuthorizedHashedTimelockContractSpend,
authorize_pubkeyhash_spend::AuthorizedPublicKeyHashSpend,
classical_multisig::authorize_classical_multisig::{
sign_classical_multisig_spending, AuthorizedClassicalMultisigSpend,
},
Expand Down Expand Up @@ -340,6 +342,40 @@ pub fn verify_signature_for_spending(
Ok(verifcation_result)
}

/// Given a message and a private key, create and sign a challenge with the given private key
/// This kind of signature is to be used when signing challenges.
#[wasm_bindgen]
pub fn sign_challenge(private_key: &[u8], message: &[u8]) -> Result<Vec<u8>, Error> {
let private_key = PrivateKey::decode_all(&mut &private_key[..])
.map_err(|_| Error::InvalidPrivateKeyEncoding)?;

let challenge = produce_message_challenge(message);
let public_key = PublicKey::from_private_key(&private_key);

let signature = private_key.sign_message(&challenge.encode(), randomness::make_true_rng())?;
let signature = AuthorizedPublicKeyHashSpend::new(public_key, signature);
Ok(signature.encode())
}

/// Given a signed challenge, an address and a message. Verify that
/// the signature is produced by signing the message with the private key
/// that derived the given public key.
/// Note that this function is used for verifying messages related challenges.
#[wasm_bindgen]
pub fn verify_challenge(
address: &str,
network: Network,
signed_challenge: &[u8],
message: &[u8],
) -> Result<bool, Error> {
let chain_config = Builder::new(network.into()).build();
let destination = parse_addressable::<Destination>(&chain_config, address)?;
let message_challenge = produce_message_challenge(&message);
let sig = ArbitraryMessageSignature::from_data(signed_challenge.to_vec());
sig.verify_signature(&chain_config, &destination, &message_challenge)?;
Ok(true)
}

fn parse_addressable<T: Addressable>(
chain_config: &ChainConfig,
address: &str,
Expand Down

0 comments on commit a5f7ec6

Please sign in to comment.