@@ -5,15 +5,15 @@ import { ECDSASigValue } from "@peculiar/asn1-ecc";
55import { AsnParser } from "@peculiar/asn1-schema" ;
66import { bigintToBuf , bufToBigint } from "bigint-conversion" ;
77import { assert , expect } from "chai" ;
8+ import { randomBytes } from "crypto" ;
9+ import { parseEther , ZeroAddress } from "ethers" ;
810import * as hre from "hardhat" ;
11+ import { encodeAbiParameters , Hex , hexToBytes , toHex } from "viem" ;
912import { SmartAccount , Wallet } from "zksync-ethers" ;
13+ import { base64UrlToUint8Array } from "zksync-sso/utils" ;
1014
11- import { SsoAccount__factory , WebAuthValidator , WebAuthValidator__factory } from "../typechain-types" ;
15+ import { SsoAccount__factory , WebAuthValidator , WebAuthValidator__factory , WebAuthValidatorTest , WebAuthValidatorTest__factory } from "../typechain-types" ;
1216import { ContractFixtures , getProvider , getWallet , LOCAL_RICH_WALLETS , logInfo , RecordedResponse } from "./utils" ;
13- import { base64UrlToUint8Array } from "zksync-sso/utils" ;
14- import { encodeAbiParameters , Hex , hexToBytes , toHex } from "viem" ;
15- import { randomBytes } from "crypto" ;
16- import { parseEther , ZeroAddress } from "ethers" ;
1717
1818/**
1919 * Decode from a Base64URL-encoded string to an ArrayBuffer. Best used when converting a
@@ -36,6 +36,14 @@ async function deployValidator(wallet: Wallet): Promise<WebAuthValidator> {
3636 return WebAuthValidator__factory . connect ( await validator . getAddress ( ) , wallet ) ;
3737}
3838
39+ async function deployP256Tester ( wallet : Wallet ) : Promise < WebAuthValidatorTest > {
40+ const deployer : Deployer = new Deployer ( hre , wallet ) ;
41+ const passkeyValidatorArtifact = await deployer . loadArtifact ( "WebAuthValidatorTest" ) ;
42+
43+ const validator = await deployer . deploy ( passkeyValidatorArtifact , [ ] ) ;
44+ return WebAuthValidatorTest__factory . connect ( await validator . getAddress ( ) , wallet ) ;
45+ }
46+
3947/**
4048 * COSE Keys
4149 *
@@ -338,9 +346,6 @@ function encodeFatSignature(
338346 clientDataJSON : string ;
339347 signature : string ;
340348 } ,
341- contracts : {
342- passkey : string ;
343- } ,
344349) {
345350 const signature = unwrapEC2Signature ( base64UrlToUint8Array ( passkeyResponse . signature ) ) ;
346351 return encodeAbiParameters (
@@ -358,7 +363,7 @@ function encodeFatSignature(
358363}
359364
360365async function rawVerify (
361- passkeyValidator : WebAuthValidator ,
366+ passkeyValidator : WebAuthValidatorTest ,
362367 authenticatorData : string ,
363368 clientData : string ,
364369 b64SignedChallange : string ,
@@ -370,7 +375,7 @@ async function rawVerify(
370375 const rs = unwrapEC2Signature ( toBuffer ( b64SignedChallange ) ) ;
371376 const publicKeys = await getPublicKey ( publicKeyEs256Bytes ) ;
372377
373- return await passkeyValidator . rawVerify ( hashedData , rs , publicKeys ) ;
378+ return await passkeyValidator . p256Verify ( hashedData , rs , publicKeys ) ;
374379}
375380
376381async function verifyKeyStorage (
@@ -390,11 +395,11 @@ function encodeKeyFromHex(hexStrings: [Hex, Hex], domain: string) {
390395 // the same as the ethers: new AbiCoder().encode(["bytes32[2]", "string"], [bytes, domain]);
391396 return encodeAbiParameters (
392397 [
393- { name : ' publicKeys' , type : ' bytes32[2]' } ,
394- { name : ' domain' , type : ' string' } ,
398+ { name : " publicKeys" , type : " bytes32[2]" } ,
399+ { name : " domain" , type : " string" } ,
395400 ] ,
396- [ hexStrings , domain ]
397- )
401+ [ hexStrings , domain ] ,
402+ ) ;
398403}
399404
400405function encodeKeyFromBytes ( bytes : [ Uint8Array , Uint8Array ] , domain : string ) {
@@ -428,8 +433,8 @@ async function validateSignatureTest(
428433 { name : "clientDataJson" , type : "string" } ,
429434 { name : "rs" , type : "bytes32[2]" } ,
430435 ] ,
431- [ toHex ( authData ) , sampleClientString , [ toHex ( rNormalization ( generatedSignature . r ) ) , toHex ( sNormalization ( generatedSignature . s ) ) ] ]
432- )
436+ [ toHex ( authData ) , sampleClientString , [ toHex ( rNormalization ( generatedSignature . r ) ) , toHex ( sNormalization ( generatedSignature . s ) ) ] ] ,
437+ ) ;
433438 return await passkeyValidator . validateSignature ( transactionHash , fatSignature ) ;
434439}
435440
@@ -480,7 +485,7 @@ describe("Passkey validation", function () {
480485 const receipt = await fundTx . wait ( ) ;
481486 expect ( receipt . status ) . to . eq ( 1 , "send funds to proxy account" ) ;
482487
483- return { passKeyModuleContract, sampleDomain, proxyAccountAddress, generatedR1Key, passKeyModuleAddress }
488+ return { passKeyModuleContract, sampleDomain, proxyAccountAddress, generatedR1Key, passKeyModuleAddress } ;
484489 }
485490
486491 it ( "should deploy proxy account via factory" , async ( ) => {
@@ -523,16 +528,16 @@ describe("Passkey validation", function () {
523528 ] , [
524529 toHex ( authData ) ,
525530 sampleClientString ,
526- [ toHex ( normalizeR ( generatedSignature . r ) ) , toHex ( normalizeS ( generatedSignature . s ) ) ]
527- ] )
531+ [ toHex ( normalizeR ( generatedSignature . r ) ) , toHex ( normalizeS ( generatedSignature . s ) ) ] ,
532+ ] ) ;
528533
529534 const moduleSignature = encodeAbiParameters (
530535 [ { name : "signature" , type : "bytes" } , { name : "moduleAddress" , type : "address" } , { name : "validatorData" , type : "bytes" } ] ,
531536 [ fatSignature , passKeyModuleAddress , "0x" ] ) ;
532537 return moduleSignature ;
533538 } ,
534539 address : proxyAccountAddress ,
535- secret : wallet . privateKey , //generatedR1Key.privateKey,
540+ secret : wallet . privateKey , // generatedR1Key.privateKey,
536541 } , provider ) ;
537542
538543 const aaTransaction = {
@@ -653,7 +658,6 @@ describe("Passkey validation", function () {
653658 clientDataJSON : ethersResponse . clientData ,
654659 signature : ethersResponse . b64SignedChallenge ,
655660 } ,
656- { passkey : publicKeys [ 0 ] } ,
657661 ) ;
658662
659663 const initData = encodeKeyFromHex ( publicKeys , "http://localhost:5173" ) ;
@@ -671,14 +675,14 @@ describe("Passkey validation", function () {
671675 // fully expand the raw validation to compare step by step
672676 describe ( "P256 precompile comparison" , ( ) => {
673677 it ( "should verify passkey" , async function ( ) {
674- const passkeyValidator = await deployValidator ( wallet ) ;
678+ const passkeyValidator = await deployP256Tester ( wallet ) ;
675679
676680 // 37 bytes
677681 const authenticatorData = "SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2MFAAAABQ" ;
678- const clientData =
679- "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiZFhPM3ctdWdycS00SkdkZUJLNDFsZFk1V2lNd0ZORDkiLCJvcmlnaW4iOiJodHRwOi8vbG9jYWxob3N0OjUxNzMiLCJjcm9zc09yaWdpbiI6ZmFsc2UsIm90aGVyX2tleXNfY2FuX2JlX2FkZGVkX2hlcmUiOiJkbyBub3QgY29tcGFyZSBjbGllbnREYXRhSlNPTiBhZ2FpbnN0IGEgdGVtcGxhdGUuIFNlZSBodHRwczovL2dvby5nbC95YWJQZXgifQ" ;
680- const b64SignedChallenge =
681- "MEUCIQCYrSUCR_QUPAhvRNUVfYiJC2JlOKuqf4gx7i129n9QxgIgaY19A9vAAObuTQNs5_V9kZFizwRpUFpiRVW_dglpR2A" ;
682+ const clientData
683+ = "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiZFhPM3ctdWdycS00SkdkZUJLNDFsZFk1V2lNd0ZORDkiLCJvcmlnaW4iOiJodHRwOi8vbG9jYWxob3N0OjUxNzMiLCJjcm9zc09yaWdpbiI6ZmFsc2UsIm90aGVyX2tleXNfY2FuX2JlX2FkZGVkX2hlcmUiOiJkbyBub3QgY29tcGFyZSBjbGllbnREYXRhSlNPTiBhZ2FpbnN0IGEgdGVtcGxhdGUuIFNlZSBodHRwczovL2dvby5nbC95YWJQZXgifQ" ;
684+ const b64SignedChallenge
685+ = "MEUCIQCYrSUCR_QUPAhvRNUVfYiJC2JlOKuqf4gx7i129n9QxgIgaY19A9vAAObuTQNs5_V9kZFizwRpUFpiRVW_dglpR2A" ;
682686
683687 const verifyMessage = await rawVerify (
684688 passkeyValidator ,
@@ -691,7 +695,7 @@ describe("Passkey validation", function () {
691695 assert ( verifyMessage == true , "valid sig" ) ;
692696 } ) ;
693697 it ( "should sign with new data" , async function ( ) {
694- const passkeyValidator = await deployValidator ( wallet ) ;
698+ const passkeyValidator = await deployP256Tester ( wallet ) ;
695699 // The precompile expects the fully hashed data
696700 const preHashedData = await toHash (
697701 concat ( [ toBuffer ( ethersResponse . authenticatorData ) , await toHash ( toBuffer ( ethersResponse . clientData ) ) ] ) ,
@@ -718,7 +722,7 @@ describe("Passkey validation", function () {
718722 [ generatedSignature . r , generatedSignature . s ] ,
719723 [ generatedX , generatedY ] ,
720724 ) ;
721- const onChainGeneratedVerified = await passkeyValidator . rawVerify (
725+ const onChainGeneratedVerified = await passkeyValidator . p256Verify (
722726 preHashedData ,
723727 [ generatedSignature . r , generatedSignature . s ] ,
724728 [ generatedX , generatedY ] ,
@@ -728,7 +732,7 @@ describe("Passkey validation", function () {
728732 [ recordedR , recordedS ] ,
729733 [ recordedX , recordedY ] ,
730734 ) ;
731- const onChainRecordedVerified = await passkeyValidator . rawVerify (
735+ const onChainRecordedVerified = await passkeyValidator . p256Verify (
732736 preHashedData ,
733737 [ recordedR , recordedS ] ,
734738 [ recordedX , recordedY ] ,
@@ -741,7 +745,7 @@ describe("Passkey validation", function () {
741745 } ) ;
742746
743747 it ( "should verify other test passkey data" , async function ( ) {
744- const passkeyValidator = await deployValidator ( wallet ) ;
748+ const passkeyValidator = await deployP256Tester ( wallet ) ;
745749
746750 const verifyMessage = await rawVerify (
747751 passkeyValidator ,
@@ -755,10 +759,10 @@ describe("Passkey validation", function () {
755759 } ) ;
756760
757761 it ( "should fail when signature is bad" , async function ( ) {
758- const passkeyValidator = await deployValidator ( wallet ) ;
762+ const passkeyValidator = await deployP256Tester ( wallet ) ;
759763
760- const b64SignedChallenge =
761- "MEUCIQCYrSUCR_QUPAhvRNUVfYiJC2JlOKuqf4gx7i129n9QxgIgaY19A9vAAObuTQNs5_V9kZFizwRpUFpiRVW_dglpR2A" ;
764+ const b64SignedChallenge
765+ = "MEUCIQCYrSUCR_QUPAhvRNUVfYiJC2JlOKuqf4gx7i129n9QxgIgaY19A9vAAObuTQNs5_V9kZFizwRpUFpiRVW_dglpR2A" ;
762766 const verifyMessage = await rawVerify (
763767 passkeyValidator ,
764768 ethersResponse . authenticatorData ,
@@ -899,10 +903,10 @@ describe("Passkey validation", function () {
899903 const partialClientObject = {
900904 challenge : "jBBiiOGt1aSBy1WAuRGxqU7YzRM5oWpMA9g8MKydjPI" ,
901905 } ;
902- const duplicatedClientString =
903- JSON . stringify ( sampleClientObject ) . slice ( 0 , - 1 ) +
904- "," +
905- JSON . stringify ( partialClientObject ) . slice ( 1 ) ;
906+ const duplicatedClientString
907+ = JSON . stringify ( sampleClientObject ) . slice ( 0 , - 1 )
908+ + ","
909+ + JSON . stringify ( partialClientObject ) . slice ( 1 ) ;
906910 const authData = toBuffer ( ethersResponse . authenticatorData ) ;
907911 const transactionHash = Buffer . from ( sampleClientObject . challenge , "base64url" ) ;
908912 const isValidSignature = await validateSignatureTest (
0 commit comments