diff --git a/packages/native-utils/common/src/serde.rs b/packages/native-utils/common/src/serde.rs index 8730813..57693b1 100644 --- a/packages/native-utils/common/src/serde.rs +++ b/packages/native-utils/common/src/serde.rs @@ -36,12 +36,6 @@ impl<'de> Deserialize<'de> for RecoverableSignature { D: Deserializer<'de>, { let bytes: Bytes = Deserialize::deserialize(deserializer)?; - assert_eq!(65,bytes.0.len()); - let mut a: [u8; 64] = [0; 64]; - a.copy_from_slice(&bytes.0[0..64]); - Ok(RecoverableSignature( - Signature::parse(&a), - RecoveryId::parse(bytes.0[64] - 27).map_err(D::Error::custom)? - )) + Ok(RecoverableSignature::from_bytes(bytes).map_err(D::Error::custom)?) } } diff --git a/packages/native-utils/common/src/state.rs b/packages/native-utils/common/src/state.rs index 15dd3aa..4da0bb6 100644 --- a/packages/native-utils/common/src/state.rs +++ b/packages/native-utils/common/src/state.rs @@ -263,6 +263,16 @@ impl RecoverableSignature { v.push(self.1.serialize()); Bytes(v) } + + pub fn from_bytes(bytes: Bytes) -> Result { + assert_eq!(65,bytes.0.len()); + let mut a: [u8; 64] = [0; 64]; + a.copy_from_slice(&bytes.0[0..64]); + Ok(RecoverableSignature( + Signature::parse(&a), + RecoveryId::parse(bytes.0[64] - 27).map_err(|_| "Invalid recovery ID")? + )) + } } #[derive(Serialize)] diff --git a/packages/native-utils/lib/index.d.ts b/packages/native-utils/lib/index.d.ts index 8a8f4f7..a5c1c95 100644 --- a/packages/native-utils/lib/index.d.ts +++ b/packages/native-utils/lib/index.d.ts @@ -79,3 +79,11 @@ export function signState(state: State, privateKey: string): StateWithHashAndSig * @param signature A signature resulting from a previous call to `signState`. */ export function recoverAddress(state: State, signature: string): string + +/** + * Verifies a signature. + * + * @param state A Nitro state. + * @param signature A signature resulting from a previous call to `signState`. + */ + export function verifySignature(state: State, signature: string): boolean diff --git a/packages/native-utils/lib/index.native.js b/packages/native-utils/lib/index.native.js index 7ccaa96..8f9725e 100644 --- a/packages/native-utils/lib/index.native.js +++ b/packages/native-utils/lib/index.native.js @@ -10,6 +10,7 @@ const { signState, recoverAddress, + verifySignature, } = require('../native/index.node') function unwrapResult({ Ok, Err }) { @@ -40,4 +41,6 @@ module.exports = { }, recoverAddress: (state, signature) => unwrapResult(recoverAddress(state, signature)), + + verifySignature: (state, signature) => unwrapResult(verifySignature(state, signature)), } diff --git a/packages/native-utils/native/src/lib.rs b/packages/native-utils/native/src/lib.rs index ed63212..054f437 100644 --- a/packages/native-utils/native/src/lib.rs +++ b/packages/native-utils/native/src/lib.rs @@ -37,4 +37,8 @@ export! { fn recoverAddress(state: State, signature: Bytes) -> Result { state.recover_address(signature) } + + fn verifySignature(state: State, signature: Bytes) -> Result { + state.verify(RecoverableSignature::from_bytes(signature)?) + } } diff --git a/packages/native-utils/tests/sign.test.ts b/packages/native-utils/tests/sign.test.ts index 7122443..91675fe 100644 --- a/packages/native-utils/tests/sign.test.ts +++ b/packages/native-utils/tests/sign.test.ts @@ -99,6 +99,9 @@ describe('Sign state', () => { expect(nativeSignature).toStrictEqual(oldSignature) expect(wasmSignature).toStrictEqual(oldSignature) + + expect(native.verifySignature(state, nativeSignature)).toBe(true) + expect(native.verifySignature(state, wasmSignature)).toBe(true) }) test('Catches invalid private key', async () => {