Skip to content

Commit

Permalink
Add verify ed25519 and evm signatures to old bindings (#595)
Browse files Browse the repository at this point in the history
* Allow SecretManage to be extensible

* fix type

* more feature gating

* Fix stronghold backup/restore

* Fix backup restore bugs

* clippy

* feature 🐊

* LINE PIECE |

Co-authored-by: Thibault Martinez <[email protected]>

* imports

* fix merge

* PR suggestions

* changelog

* cleanup

* fix merge

* fix borked merge

* nit

* Remove Debug requirement from StorageManage

* comment

* clippy

* Remove generate addresses that is not needed

* remove more generate addresses

* Add verify ed25519 and evm signatures to old bindings

* Remove accidentally left in code

* todo and camelCase

* clippy

* change file

* rename

* fmt

* Update naming

* Fix verify fns and rename EvmSignature

* Update sdk/src/wallet/message_interface/account_method.rs

Co-authored-by: Thibault Martinez <[email protected]>

* PR suggestions

* Use Secp256k1EcdsaSignature

* Fix .change

* Fix doc

* Update sdk/src/wallet/message_interface/account_method.rs

Co-authored-by: Thoralf-M <[email protected]>

---------

Co-authored-by: Thibault Martinez <[email protected]>
Co-authored-by: Thoralf-M <[email protected]>
  • Loading branch information
3 people authored Jun 19, 2023
1 parent f5287ee commit c4231e5
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changes/verify-signatures.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wallet-nodejs-binding": patch
---

Add `Account::verifyEd25519Signature` and `verifySecp256k1EcdsaSignature` methods. Add `Secp256k1EcdsaSignature` to types.
4 changes: 4 additions & 0 deletions sdk/src/types/block/signature/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ impl Ed25519Signature {
&self.signature
}

pub fn verify(&self, message: &[u8]) -> Result<bool, Error> {
Ok(PublicKey::try_from_bytes(self.public_key)?.verify(&Signature::from_bytes(self.signature), message))
}

/// Verifies the [`Ed25519Signature`] for a message against an [`Ed25519Address`].
pub fn is_valid(&self, message: &[u8], address: &Ed25519Address) -> Result<(), Error> {
let signature_address: [u8; Self::PUBLIC_KEY_LENGTH] = Blake2b256::digest(self.public_key).into();
Expand Down
42 changes: 42 additions & 0 deletions sdk/src/wallet/bindings/nodejs/lib/Account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import type {
ParticipationEventMap,
GenerateAddressesOptions,
Secp256k1EcdsaSignature,
Ed25519Signature,
} from '../types';
import type { SignedTransactionEssence } from '../types/signedTransactionEssence';
import type {
Expand Down Expand Up @@ -394,6 +395,47 @@ export class Account {
return JSON.parse(response).payload;
}

/**
* Verifies an ed25519 signature against a message.
*/
async verifyEd25519Signature(
signature: Ed25519Signature,
message: HexEncodedString,
): Promise<boolean> {
const response = await this.messageHandler.callAccountMethod(
this.meta.index,
{
name: 'verifyEd25519Signature',
data: {
signature,
message,
},
},
);
return JSON.parse(response).payload;
}

/**
* Verifies a Secp256k1Ecdsa signature against a message.
*/
async verifySecp256k1EcdsaSignature(
signature: Secp256k1EcdsaSignature,
message: HexEncodedString,
): Promise<boolean> {
const response = await this.messageHandler.callAccountMethod(
this.meta.index,
{
name: 'verifySecp256k1EcdsaSignature',
data: {
publicKey: signature.publicKey,
signature: signature.signature,
message,
},
},
);
return JSON.parse(response).payload;
}

/**
* Signs a message with a Secp256k1Ecdsa private key.
*/
Expand Down
18 changes: 18 additions & 0 deletions sdk/src/wallet/bindings/nodejs/types/bridge/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import type {
ParticipationEventRegistrationOptions,
ParticipationEventType,
} from '../participation';
import { Ed25519Signature } from '../secretManager';

export type __BuildAliasOutputMethod__ = {
name: 'buildAliasOutput';
Expand Down Expand Up @@ -141,6 +142,23 @@ export type __GenerateEvmAddressesMethod__ = {
};
};

export type __VerifyEd25519SignatureMethod__ = {
name: 'verifyEd25519Signature';
data: {
signature: Ed25519Signature;
message: HexEncodedString;
};
};

export type __VerifySecp256k1EcdsaSignatureMethod__ = {
name: 'verifySecp256k1EcdsaSignature';
data: {
publicKey: HexEncodedString;
signature: HexEncodedString;
message: HexEncodedString;
};
};

export type __SignSecp256k1EcdsaMethod__ = {
name: 'signSecp256k1Ecdsa';
data: {
Expand Down
4 changes: 4 additions & 0 deletions sdk/src/wallet/bindings/nodejs/types/bridge/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import type {
__DeregisterParticipationEventMethod__,
__GenerateEd25519AddressesMethod__,
__GenerateEvmAddressesMethod__,
__VerifyEd25519SignatureMethod__,
__VerifySecp256k1EcdsaSignatureMethod__,
__SignSecp256k1EcdsaMethod__,
__GetBalanceMethod__,
__GetOutputMethod__,
Expand Down Expand Up @@ -103,6 +105,8 @@ export type __AccountMethod__ =
| __DestroyFoundryMethod__
| __GenerateEd25519AddressesMethod__
| __GenerateEvmAddressesMethod__
| __VerifyEd25519SignatureMethod__
| __VerifySecp256k1EcdsaSignatureMethod__
| __SignSecp256k1EcdsaMethod__
| __GetBalanceMethod__
| __GetOutputMethod__
Expand Down
11 changes: 11 additions & 0 deletions sdk/src/wallet/bindings/nodejs/types/secretManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,14 @@ export interface Secp256k1EcdsaSignature {
*/
signature: HexEncodedString;
}

export interface Ed25519Signature {
/**
* The public key.
*/
publicKey: HexEncodedString;
/**
* The signature.
*/
signature: HexEncodedString;
}
17 changes: 17 additions & 0 deletions sdk/src/wallet/message_interface/account_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use crate::{
AliasId, FoundryId, NativeToken, NftId, OutputId, TokenId,
},
payload::transaction::TransactionId,
signature::dto::Ed25519SignatureDto,
},
wallet::{
account::{
Expand Down Expand Up @@ -171,6 +172,22 @@ pub enum AccountMethod {
/// Expected response:
/// [`GeneratedEvmAddresses`](crate::wallet::message_interface::Response::GeneratedEvmAddresses)
GenerateEvmAddresses { options: GetAddressesOptions },
/// Verify an ed25519 signature against a message.
/// Expected response:
/// [`Bool`](crate::wallet::message_interface::Response::Bool)
VerifyEd25519Signature {
signature: Ed25519SignatureDto,
message: String,
},
/// Verify a Secp256k1Ecdsa signature against a message.
/// Expected response:
/// [`Bool`](crate::wallet::message_interface::Response::Bool)
#[serde(rename_all = "camelCase")]
VerifySecp256k1EcdsaSignature {
public_key: String,
signature: String,
message: String,
},
/// Signs a message with an Secp256k1Ecdsa private key.
SignSecp256k1Ecdsa {
/// The message to sign, hex encoded String
Expand Down
21 changes: 20 additions & 1 deletion sdk/src/wallet/message_interface/message_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use crate::{
dto::{OutputBuilderAmountDto, OutputDto},
AliasOutput, BasicOutput, FoundryOutput, NativeToken, NftOutput, Output, Rent,
},
signature::Ed25519Signature,
ConvertTo, Error,
},
wallet::{
Expand Down Expand Up @@ -182,7 +183,7 @@ impl WalletMessageHandler {
Message::IsStrongholdPasswordAvailable => {
convert_async_panics(|| async {
let is_available = self.wallet.is_stronghold_password_available().await?;
Ok(Response::StrongholdPasswordIsAvailable(is_available))
Ok(Response::Bool(is_available))
})
.await
}
Expand Down Expand Up @@ -576,6 +577,24 @@ impl WalletMessageHandler {
.await?;
Ok(Response::GeneratedEvmAddresses(addresses))
}
AccountMethod::VerifyEd25519Signature { signature, message } => {
let signature = Ed25519Signature::try_from(signature)?;
let message: Vec<u8> = prefix_hex::decode(message).map_err(crate::client::Error::from)?;
Ok(Response::Bool(signature.verify(&message)?))
}
AccountMethod::VerifySecp256k1EcdsaSignature {
public_key,
signature,
message,
} => {
use crypto::signatures::secp256k1_ecdsa;
let public_key = prefix_hex::decode(public_key).map_err(|_| Error::InvalidField("publicKey"))?;
let public_key = secp256k1_ecdsa::PublicKey::try_from_bytes(&public_key)?;
let signature = prefix_hex::decode(signature).map_err(|_| Error::InvalidField("signature"))?;
let signature = secp256k1_ecdsa::Signature::try_from_bytes(&signature)?;
let message: Vec<u8> = prefix_hex::decode(message).map_err(crate::client::Error::from)?;
Ok(Response::Bool(public_key.verify(&signature, &message)))
}
AccountMethod::SignSecp256k1Ecdsa { message, chain } => {
let msg: Vec<u8> = prefix_hex::decode(message).map_err(crate::client::Error::from)?;
let (public_key, signature) = account
Expand Down
8 changes: 5 additions & 3 deletions sdk/src/wallet/message_interface/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,9 @@ pub enum Response {
MintTokenTransaction(MintTokenTransactionDto),
/// Response for
/// [`IsStrongholdPasswordAvailable`](crate::wallet::message_interface::Message::IsStrongholdPasswordAvailable)
StrongholdPasswordIsAvailable(bool),
/// [`VerifyEd25519Signature`](crate::wallet::message_interface::account_method::AccountMethod::VerifyEd25519Signature)
/// [`VerifySecp256k1EcdsaSignature`](crate::wallet::message_interface::account_method::AccountMethod::VerifySecp256k1EcdsaSignature)
Bool(bool),
/// An error occurred.
Error(Error),
/// A panic occurred.
Expand Down Expand Up @@ -230,8 +232,8 @@ impl Debug for Response {
Self::MintTokenTransaction(mint_transaction) => {
write!(f, "MintTokenTransaction({mint_transaction:?})")
}
Self::StrongholdPasswordIsAvailable(is_available) => {
write!(f, "StrongholdPasswordIsAvailable({is_available:?})")
Self::Bool(b) => {
write!(f, "Bool({b})")
}
Self::Error(error) => write!(f, "Error({error:?})"),
Self::Panic(panic_msg) => write!(f, "Panic({panic_msg:?})"),
Expand Down

0 comments on commit c4231e5

Please sign in to comment.