1+ import { ISr25519VERIFY_ADDRESS , ISr25519VerifyABI , ETH_LOCAL_URL } from '../src/config'
2+ import { getPublicClient } from "../src/utils" ;
3+ import { toHex , toBytes , keccak256 , PublicClient } from 'viem'
4+ import { Keyring } from "@polkadot/keyring" ;
5+ import * as assert from "assert" ;
6+
7+ describe ( "Verfication of sr25519 signature" , ( ) => {
8+ // init eth part
9+ let ethClient : PublicClient ;
10+
11+ before ( async ( ) => {
12+ ethClient = await getPublicClient ( ETH_LOCAL_URL ) ;
13+ } ) ;
14+
15+ it ( "Verification of sr25519 works" , async ( ) => {
16+ const keyring = new Keyring ( { type : "sr25519" } ) ;
17+ const alice = keyring . addFromUri ( "//Alice" ) ;
18+
19+ //////////////////////////////////////////////////////////////////////
20+ // Generate a signature
21+
22+ // Your message to sign
23+ const message = "Sign this message" ;
24+ const messageU8a = new TextEncoder ( ) . encode ( message ) ;
25+ const messageHex = toHex ( messageU8a ) ; // Convert message to hex string
26+ const messageHash = keccak256 ( messageHex ) ; // Hash the message to fit into bytes32
27+ console . log ( `messageHash = ${ messageHash } ` ) ;
28+ const hashedMessageBytes = toBytes ( messageHash ) ;
29+ console . log ( `hashedMessageBytes = ${ hashedMessageBytes } ` ) ;
30+
31+ // Sign the message
32+ const signature = await alice . sign ( hashedMessageBytes ) ;
33+ console . log ( `Signature: ${ toHex ( signature ) } ` ) ;
34+
35+ // Verify the signature locally
36+ const isValid = alice . verify (
37+ hashedMessageBytes ,
38+ signature ,
39+ alice . publicKey
40+ ) ;
41+ console . log ( `Is the signature valid? ${ isValid } ` ) ;
42+
43+ //////////////////////////////////////////////////////////////////////
44+ // Verify the signature using the precompile contract
45+
46+ const publicKeyBytes = toHex ( alice . publicKey ) ;
47+ console . log ( `publicKeyBytes = ${ publicKeyBytes } ` ) ;
48+
49+ // Split signture into Commitment (R) and response (s)
50+ let r = signature . slice ( 0 , 32 ) ; // Commitment, a.k.a. "r" - first 32 bytes
51+ let s = signature . slice ( 32 , 64 ) ; // Response, a.k.a. "s" - second 32 bytes
52+ let rBytes = toHex ( r ) ;
53+ let sBytes = toHex ( s ) ;
54+
55+ const isPrecompileValid = await ethClient . readContract ( {
56+ address : ISr25519VERIFY_ADDRESS ,
57+ abi : ISr25519VerifyABI ,
58+ functionName : "verify" ,
59+ args : [ messageHash ,
60+ publicKeyBytes ,
61+ rBytes ,
62+ sBytes ]
63+
64+ } ) ;
65+
66+ console . log (
67+ `Is the signature valid according to the smart contract? ${ isPrecompileValid } `
68+ ) ;
69+ assert . equal ( isPrecompileValid , true )
70+
71+ //////////////////////////////////////////////////////////////////////
72+ // Verify the signature for bad data using the precompile contract
73+
74+ let brokenHashedMessageBytes = hashedMessageBytes ;
75+ brokenHashedMessageBytes [ 0 ] = ( brokenHashedMessageBytes [ 0 ] + 1 ) % 0xff ;
76+ const brokenMessageHash = toHex ( brokenHashedMessageBytes ) ;
77+ console . log ( `brokenMessageHash = ${ brokenMessageHash } ` ) ;
78+
79+ const isPrecompileValidBadData = await ethClient . readContract ( {
80+ address : ISr25519VERIFY_ADDRESS ,
81+ abi : ISr25519VerifyABI ,
82+ functionName : "verify" ,
83+ args : [ brokenMessageHash ,
84+ publicKeyBytes ,
85+ rBytes ,
86+ sBytes ]
87+
88+ } ) ;
89+
90+ console . log (
91+ `Is the signature valid according to the smart contract for broken data? ${ isPrecompileValidBadData } `
92+ ) ;
93+ assert . equal ( isPrecompileValidBadData , false )
94+
95+ //////////////////////////////////////////////////////////////////////
96+ // Verify the bad signature for good data using the precompile contract
97+
98+ let brokenR = r ;
99+ brokenR [ 0 ] = ( brokenR [ 0 ] + 1 ) % 0xff ;
100+ rBytes = toHex ( r ) ;
101+ const isPrecompileValidBadSignature = await ethClient . readContract ( {
102+ address : ISr25519VERIFY_ADDRESS ,
103+ abi : ISr25519VerifyABI ,
104+ functionName : "verify" ,
105+ args : [ messageHash ,
106+ publicKeyBytes ,
107+ rBytes ,
108+ sBytes ]
109+
110+ } ) ;
111+
112+ console . log (
113+ `Is the signature valid according to the smart contract for broken signature? ${ isPrecompileValidBadSignature } `
114+ ) ;
115+ assert . equal ( isPrecompileValidBadSignature , false )
116+
117+ } ) ;
118+ } ) ;
0 commit comments