-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat: Add a way to verify signature inside the Ts SDK (#135)
* Feat: messages signatures can't be only verified on the Aleph's Network Solution: Add a way to verify signatures directly in the SDK * Feat: signature can't be verified without an instanced account Solution: move verify method into utils/signature * Feat: Add signature verification for Solana inside the ts sdk * Feat: Add signature verification for Substrate inside the ts sdk * Feat: Add signature verification for Tezos inside the ts sdk * verifCosmos script added without test * fix imports * rename "verif" to "verify" everywhere * use default import for verify functions --------- Co-authored-by: leirbag95 <[email protected]> Co-authored-by: mhh <[email protected]>
- Loading branch information
1 parent
dc5a82e
commit 32caa63
Showing
20 changed files
with
534 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
import * as accounts from "./accounts/index"; | ||
import * as messages from "./messages"; | ||
import * as Ledger from "./accounts/providers/Ledger"; | ||
import * as utils from "./utils/signature"; | ||
|
||
export { accounts, Ledger, messages }; | ||
export { accounts, Ledger, messages, utils }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import verifyEthereum from "./verifyEthereum"; | ||
import verifyAvalanche from "./verifyAvalanche"; | ||
import verifySolana from "./verifySolana"; | ||
import verifySubstrate from "./verifySubstrate"; | ||
import verifyTezos from "./verifyTezos"; | ||
import verifyCosmos from "./verifyCosmos"; | ||
|
||
export { verifyEthereum, verifyAvalanche, verifySolana, verifySubstrate, verifyTezos, verifyCosmos }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { BaseMessage } from "../../messages/types"; | ||
import { GetVerificationBuffer } from "../../messages"; | ||
import { Avalanche, BinTools, Buffer as AvaBuff } from "avalanche"; | ||
import shajs from "sha.js"; | ||
|
||
async function digestMessage(message: Buffer) { | ||
const msgSize = Buffer.alloc(4); | ||
msgSize.writeUInt32BE(message.length, 0); | ||
const msgStr = message.toString("utf-8"); | ||
const msgBuf = Buffer.from(`\x1AAvalanche Signed Message:\n${msgSize}${msgStr}`, "utf8"); | ||
|
||
return new shajs.sha256().update(msgBuf).digest(); | ||
} | ||
|
||
/** | ||
* Provide a way to verify the authenticity of a signature associated with a given message. | ||
* This method rely on the Keypair.recover() implementation. | ||
* | ||
* @param message The content of the signature to verify. It can be the result of GetVerificationBuffer() or directly a BaseMessage object. | ||
* @param signature The signature associated with the first params of this method. | ||
* @param signerPKey Optional, The publicKey associated with the signature to verify. It Needs to be under a hex serialized string. | ||
*/ | ||
async function verifyAvalanche(message: Buffer | BaseMessage, signature: string, signerPKey: string): Promise<boolean> { | ||
if (!(message instanceof Buffer)) message = GetVerificationBuffer(message); | ||
const ava = new Avalanche(); | ||
const keyPair = ava.XChain().keyChain().makeKey(); | ||
|
||
const bintools = BinTools.getInstance(); | ||
const readableSignature = bintools.cb58Decode(signature); | ||
|
||
const digest = await digestMessage(message); | ||
const digestHex = digest.toString("hex"); | ||
const digestBuff = AvaBuff.from(digestHex, "hex"); | ||
|
||
const recovered = keyPair.recover(digestBuff, readableSignature); | ||
return signerPKey === recovered.toString("hex"); | ||
} | ||
|
||
export default verifyAvalanche; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { BaseMessage } from "../../messages/types"; | ||
import { GetVerificationBuffer } from "../../messages"; | ||
import elliptic from "elliptic"; | ||
|
||
/** | ||
* Provide a way to verify the authenticity of a signature associated with a given message. | ||
* This method rely on the ethers.utils.verifyMessage() implementation. | ||
* | ||
* @param message The content of the signature to verify. It can be the result of GetVerificationBuffer() or directly a BaseMessage object. | ||
* @param serializedSignature The signature associated with the first params of this method. | ||
*/ | ||
async function verifyCosmos(message: Buffer | BaseMessage, serializedSignature: string): Promise<boolean> { | ||
if (!(message instanceof Buffer)) message = GetVerificationBuffer(message); | ||
|
||
const { signature, pub_key } = JSON.parse(serializedSignature); | ||
const secp256k1 = new elliptic.ec("secp256k1"); | ||
|
||
// unsupported curve checking | ||
if (pub_key?.type !== "tendermint/PubKeySecp256k1") return false; | ||
|
||
// Decode the Base64-encoded signature | ||
const publicKey = Buffer.from(pub_key.value, "base64"); | ||
const signatureBuffer = Buffer.from(signature, "base64"); | ||
|
||
// Extract the r and s values from the signature | ||
const r = signatureBuffer.slice(0, 32); | ||
const s = signatureBuffer.slice(32, 64); | ||
|
||
// Create a signature object with the r and s values | ||
const signatureObj = { r, s }; | ||
|
||
try { | ||
const key = secp256k1.keyFromPublic(publicKey); | ||
return key.verify(message, signatureObj); | ||
} catch (e: unknown) { | ||
return false; | ||
} | ||
} | ||
|
||
export default verifyCosmos; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { BaseMessage } from "../../messages/types"; | ||
import { GetVerificationBuffer } from "../../messages"; | ||
import { ethers } from "ethers"; | ||
|
||
/** | ||
* Provide a way to verify the authenticity of a signature associated with a given message. | ||
* This method rely on the ethers.utils.verifyMessage() implementation. | ||
* | ||
* @param message The content of the signature to verify. It can be the result of GetVerificationBuffer() or directly a BaseMessage object. | ||
* @param signature The signature associated with the first params of this method. | ||
* @param signerAddress Optional, The address associated with the signature to verify. The current account address is used by default. | ||
*/ | ||
function verifyEthereum(message: Buffer | BaseMessage, signature: string, signerAddress: string): boolean { | ||
if (!(message instanceof Buffer)) message = GetVerificationBuffer(message); | ||
|
||
try { | ||
const address = ethers.utils.verifyMessage(message, signature); | ||
return address === signerAddress; | ||
} catch (e: unknown) { | ||
return false; | ||
} | ||
} | ||
|
||
export default verifyEthereum; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { BaseMessage } from "../../messages/types"; | ||
import { GetVerificationBuffer } from "../../messages"; | ||
import nacl from "tweetnacl"; | ||
import bs58 from "bs58"; | ||
|
||
/** | ||
* Provide a way to verify the authenticity of a signature associated with a given message. | ||
* This method rely on the nacl.sign.detached.verify() implementation. | ||
* | ||
* @param message The content of the signature to verify. It can be the result of GetVerificationBuffer() or directly a BaseMessage object. | ||
* @param serializedSignature The signature associated with the first params of this method. | ||
*/ | ||
function verifySolana(message: Buffer | BaseMessage, serializedSignature: string): boolean { | ||
if (!(message instanceof Buffer)) message = GetVerificationBuffer(message); | ||
const { signature, publicKey } = JSON.parse(serializedSignature); | ||
|
||
try { | ||
return nacl.sign.detached.verify(message, bs58.decode(signature), bs58.decode(publicKey)); | ||
} catch (e: unknown) { | ||
return false; | ||
} | ||
} | ||
|
||
export default verifySolana; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { BaseMessage } from "../../messages/types"; | ||
import { GetVerificationBuffer } from "../../messages"; | ||
import { signatureVerify } from "@polkadot/util-crypto"; | ||
|
||
/** | ||
* Provide a way to verify the authenticity of a signature associated with a given message. | ||
* This method rely on the signatureVerify() implementation from @polkadot/util-crypto. | ||
* | ||
* @param message The content of the signature to verify. It can be the result of GetVerificationBuffer() or directly a BaseMessage object. | ||
* @param signature The signature associated with the first params of this method. | ||
* @param signerAddress Optional, The address associated with the signature to verify. The current account address is used by default. | ||
*/ | ||
function verifySubstrate(message: Buffer | BaseMessage, signature: string, signerAddress: string): boolean { | ||
if (!(message instanceof Buffer)) message = GetVerificationBuffer(message); | ||
const parsedSignature = JSON.parse(signature); | ||
|
||
try { | ||
const result = signatureVerify(message, parsedSignature.data, signerAddress); | ||
|
||
return result.isValid; | ||
} catch (e: unknown) { | ||
return false; | ||
} | ||
} | ||
|
||
export default verifySubstrate; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { BaseMessage } from "../../messages/types"; | ||
import { GetVerificationBuffer } from "../../messages"; | ||
import { char2Bytes, verifySignature } from "@taquito/utils"; | ||
|
||
/** | ||
* Provide a way to verify the authenticity of a signature associated with a given message. | ||
* This method rely on the verifySignature() implementation from taquito/utils. | ||
* | ||
* @param message The content of the signature to verify. It needs to be a BaseMessage object. | ||
* @param signature The signature associated with the first params of this method. | ||
*/ | ||
function verifyTezos(message: BaseMessage, signature: string): boolean { | ||
const { signature: parsedSignature, publicKey, dAppUrl } = JSON.parse(signature); | ||
|
||
const buffer = GetVerificationBuffer(message); | ||
const ISO8601formattedTimestamp = new Date(message.time).toISOString(); | ||
const formattedInput: string = [ | ||
"Tezos Signed Message:", | ||
dAppUrl, | ||
ISO8601formattedTimestamp, | ||
buffer.toString(), | ||
].join(" "); | ||
const bytes = char2Bytes(formattedInput); | ||
const payloadBytes = "05" + "0100" + char2Bytes(String(bytes.length)) + bytes; | ||
|
||
return verifySignature(payloadBytes, publicKey, parsedSignature); | ||
} | ||
|
||
export default verifyTezos; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.