Skip to content

Commit a401416

Browse files
committed
test: EIP1271 SHA256 AuthSig suite
1 parent 253f386 commit a401416

File tree

3 files changed

+172
-7
lines changed

3 files changed

+172
-7
lines changed

local-tests/test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ import { testUseInvalidLitActionIpfsCodeToGenerateSessionSigs } from './tests/te
4444
import { testSolAuthSigToEncryptDecryptString } from './tests/testSolAuthSigToEncryptDecryptString';
4545
import { testEthAuthSigToEncryptDecryptString } from './tests/testEthAuthSigToEncryptDecryptString';
4646
import { testCosmosAuthSigToEncryptDecryptString } from './tests/testCosmosAuthSigToEncryptDecryptString';
47-
import { testEip1271AuthSigToEncryptDecryptString } from './tests/testEip1271AuthSigToEncryptDecryptString';
47+
import { testKeccakEip1271AuthSigToEncryptDecryptString } from './tests/testKeccakEip1271AuthSigToEncryptDecryptString';
48+
import { testShaEip1271AuthSigToEncryptDecryptString } from './tests/testShaEip1271AuthSigToEncryptDecryptString';
4849
import { testPkpEthersWithEoaSessionSigsToSignMessage } from './tests/testPkpEthersWithEoaSessionSigsToSignMessage';
4950
import { testPkpEthersWithEoaSessionSigsToSignWithAuthContext } from './tests/testPkpEthersWithEoaSessionSigsToSignWithAuthContext';
5051
import { testPkpEthersWithEoaSessionSigsToEthSign } from './tests/testPkpEthersWithEoaSessionSigsToEthSign';
@@ -234,7 +235,8 @@ setLitActionsCodeToLocal();
234235
};
235236

236237
const eip1271AuthSigTests = {
237-
testEip1271AuthSigToEncryptDecryptString,
238+
testKeccakEip1271AuthSigToEncryptDecryptString,
239+
testShaEip1271AuthSigToEncryptDecryptString,
238240
};
239241

240242
const pkpEthersTest = {

local-tests/tests/testEip1271AuthSigToEncryptDecryptString.ts renamed to local-tests/tests/testKeccakEip1271AuthSigToEncryptDecryptString.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
44
import { log } from '@lit-protocol/misc';
55
import { encryptString, decryptToString } from '@lit-protocol/encryption';
66
import { CENTRALISATION_BY_NETWORK } from '@lit-protocol/constants';
7-
import { createSiweMessage, generateAuthSig } from '@lit-protocol/auth-helpers';
7+
import { createSiweMessage } from '@lit-protocol/auth-helpers';
88
import { hashMessage } from 'ethers/lib/utils';
99
import { ethers } from 'ethers';
10+
import { createHash } from 'crypto';
1011

1112
/**
1213
* Test Commands:
13-
* ✅ NETWORK=datil-dev yarn test:local --filter=testEip1271AuthSigToEncryptDecryptString
14-
* ✅ NETWORK=datil-test yarn test:local --filter=testEip1271AuthSigToEncryptDecryptString
15-
* ✅ NETWORK=custom yarn test:local --filter=testEip1271AuthSigToEncryptDecryptString
14+
* ✅ NETWORK=datil-dev yarn test:local --filter=testKeccakEip1271AuthSigToEncryptDecryptString
15+
* ✅ NETWORK=datil-test yarn test:local --filter=testKeccakEip1271AuthSigToEncryptDecryptString
16+
* ✅ NETWORK=custom yarn test:local --filter=testKeccakEip1271AuthSigToEncryptDecryptString
1617
*/
17-
export const testEip1271AuthSigToEncryptDecryptString = async (
18+
export const testKeccakEip1271AuthSigToEncryptDecryptString = async (
1819
devEnv: TinnyEnvironment
1920
) => {
2021
const dataToEncrypt = 'Decrypted from EIP1271 AuthSig';
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
import { AuthSig, BaseSiweMessage, ILitNodeClient } from '@lit-protocol/types';
2+
import { AccessControlConditions } from 'local-tests/setup/accs/accs';
3+
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
4+
import { log } from '@lit-protocol/misc';
5+
import { encryptString, decryptToString } from '@lit-protocol/encryption';
6+
import { CENTRALISATION_BY_NETWORK } from '@lit-protocol/constants';
7+
import { createSiweMessage } from '@lit-protocol/auth-helpers';
8+
import { joinSignature } from 'ethers/lib/utils';
9+
import { ethers } from 'ethers';
10+
import { createHash } from 'crypto';
11+
12+
/**
13+
* Test Commands:
14+
* ✅ NETWORK=datil-dev yarn test:local --filter=testShaEip1271AuthSigToEncryptDecryptString
15+
* ✅ NETWORK=datil-test yarn test:local --filter=testShaEip1271AuthSigToEncryptDecryptString
16+
* ✅ NETWORK=custom yarn test:local --filter=testShaEip1271AuthSigToEncryptDecryptString
17+
*/
18+
export const testShaEip1271AuthSigToEncryptDecryptString = async (
19+
devEnv: TinnyEnvironment
20+
) => {
21+
const dataToEncrypt = 'Decrypted from EIP1271 AuthSig';
22+
const contractAddress = '0x88105De2349f59767278Fd15c0858f806c08d615';
23+
const deployerAddress = '0x0b1C5E9E82393AD5d1d1e9a498BF7bAAC13b31Ee'; // No purpose other than to be a random address
24+
const abi = [
25+
"function setTempOwner(address _tempOwner) external",
26+
"function getTempOwner() external view returns (address)",
27+
"function isValidSignature(bytes32 _hash, bytes calldata _signature) external view returns (bytes4)"
28+
];
29+
30+
const alice = await devEnv.createRandomPerson();
31+
if (CENTRALISATION_BY_NETWORK[devEnv.network] === 'decentralised') {
32+
// The capacity credits NFT owner automatically uses the capacity credits
33+
// to pay for the encryption
34+
await alice.mintCapacityCreditsNFT();
35+
}
36+
37+
let accs = AccessControlConditions.getEmvBasicAccessControlConditions({
38+
userAddress: contractAddress,
39+
});
40+
accs[0].chain = 'yellowstone'; // Contract deployed on Yellowstone
41+
42+
const encryptRes = await encryptString(
43+
{
44+
accessControlConditions: accs,
45+
dataToEncrypt,
46+
},
47+
devEnv.litNodeClient as unknown as ILitNodeClient
48+
);
49+
50+
// log('encryptRes:', encryptRes);
51+
52+
if (!encryptRes.ciphertext) {
53+
throw new Error(`Expected "ciphertext" in encryptRes`);
54+
}
55+
56+
if (!encryptRes.dataToEncryptHash) {
57+
throw new Error(`Expected "dataToEncryptHash" to in encryptRes`);
58+
}
59+
60+
// Craft the SiweMessage to be hashed & signed
61+
const siweMessage = await createSiweMessage<BaseSiweMessage>({
62+
nonce: await devEnv.litNodeClient.getLatestBlockhash(),
63+
walletAddress: alice.wallet.address,
64+
});
65+
66+
// Explicitly SHA256 hash the SIWE message
67+
const hash = createHash('sha256').update(siweMessage).digest();
68+
const hashHex = '0x' + hash.toString('hex');
69+
const hashUint8Array = ethers.utils.arrayify(hashHex);
70+
log('hash:', hashHex);
71+
log('hashUint8Array: ', hashUint8Array); // Match it against the hash done on the nodes before calling verifySignature()
72+
73+
const siweSignature = joinSignature(alice.wallet._signingKey().signDigest(hashHex));
74+
log('siweSignature: ', siweSignature);
75+
76+
const eip1271AuthSig: AuthSig = {
77+
address: contractAddress,
78+
sig: siweSignature,
79+
derivedVia: "EIP1271_SHA256",
80+
signedMessage: siweMessage,
81+
};
82+
83+
// log(eip1271AuthSig);
84+
85+
// Test from the contract
86+
const contract = new ethers.Contract(contractAddress, abi, alice.wallet);
87+
const setDeployerAsTempOwnerTx = await contract.setTempOwner(deployerAddress);
88+
await setDeployerAsTempOwnerTx.wait();
89+
90+
log("0. isValidSignature should FAIL since Alice (AuthSig.sig) is not the tempOwner yet");
91+
try {
92+
const isValid = await contract.isValidSignature(hash, siweSignature);
93+
if (isValid === "0x1626ba7e") {
94+
throw new Error(`Expected isValidSignature to be 0xffffffff but got ${isValid}`);
95+
}
96+
} catch (error) {
97+
log("Error calling isValidSignature:", error);
98+
throw error;
99+
}
100+
101+
try {
102+
const _decryptRes = await decryptToString(
103+
{
104+
accessControlConditions: accs,
105+
ciphertext: encryptRes.ciphertext,
106+
dataToEncryptHash: encryptRes.dataToEncryptHash,
107+
authSig: eip1271AuthSig,
108+
chain: 'yellowstone', // Deployed chain
109+
},
110+
devEnv.litNodeClient as unknown as ILitNodeClient
111+
);
112+
} catch (error) {
113+
if (!error.message.includes('NodeContractAuthsigUnauthorized') ||
114+
!error.message.includes('Access control failed for Smart contract') ||
115+
!error.message.includes('validation error: Authsig failed for contract 0x88105De2349f59767278Fd15c0858f806c08d615. Return value was ffffffff.')
116+
) {
117+
throw new Error(`Expected error message to contain specific EIP1271 validation failure, but got: ${error}`);
118+
}
119+
}
120+
121+
// Should PASS now
122+
log("1. Setting temp owner...");
123+
const setTempOwnerTx = await contract.setTempOwner(alice.wallet.address);
124+
await setTempOwnerTx.wait();
125+
log("Set tempOwner transaction hash: ", setTempOwnerTx.hash);
126+
127+
const tempOwner = await contract.getTempOwner();
128+
if (tempOwner.toLowerCase() !== alice.wallet.address.toLowerCase()) {
129+
throw new Error(`Expected temp owner to be ${alice.wallet.address} but got ${tempOwner}`);
130+
}
131+
132+
log("2. Checking isValidSignature...");
133+
try {
134+
const isValid = await contract.isValidSignature(hash, siweSignature);
135+
if (isValid !== "0x1626ba7e") {
136+
throw new Error(`Expected isValidSignature to be 0x1626ba7e but got ${isValid}`);
137+
}
138+
} catch (error) {
139+
log("Error calling isValidSignature:", error);
140+
throw error;
141+
}
142+
143+
// -- Decrypt the encrypted string
144+
const decryptRes = await decryptToString(
145+
{
146+
accessControlConditions: accs,
147+
ciphertext: encryptRes.ciphertext,
148+
dataToEncryptHash: encryptRes.dataToEncryptHash,
149+
authSig: eip1271AuthSig,
150+
chain: 'yellowstone', // Deployed chain
151+
},
152+
devEnv.litNodeClient as unknown as ILitNodeClient
153+
);
154+
155+
if (decryptRes !== dataToEncrypt) {
156+
throw new Error(
157+
`Expected decryptRes to be ${dataToEncrypt} but got ${decryptRes}`
158+
);
159+
}
160+
161+
log('✅ decryptRes:', decryptRes);
162+
};

0 commit comments

Comments
 (0)