-
Notifications
You must be signed in to change notification settings - Fork 266
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: initial
is_valid
eip1271 style wallet + minimal test changes
- Loading branch information
Showing
23 changed files
with
629 additions
and
67 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
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
120 changes: 120 additions & 0 deletions
120
yarn-project/aztec.js/src/abis/schnorr_eip_1271_account_contract.json
Large diffs are not rendered by default.
Oops, something went wrong.
34 changes: 34 additions & 0 deletions
34
yarn-project/aztec.js/src/account/contract/eip_1271_account_contract.ts
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,34 @@ | ||
import { Schnorr } from '@aztec/circuits.js/barretenberg'; | ||
import { ContractAbi } from '@aztec/foundation/abi'; | ||
import { CompleteAddress, NodeInfo, PrivateKey } from '@aztec/types'; | ||
|
||
import Eip1271AccountContractAbi from '../../abis/schnorr_eip_1271_account_contract.json' assert { type: 'json' }; | ||
import { Eip1271AccountEntrypoint } from '../entrypoint/eip_1271_account_entrypoint.js'; | ||
import { AccountContract } from './index.js'; | ||
|
||
/** | ||
* Account contract that authenticates transactions using Schnorr signatures verified against | ||
* the note encryption key, relying on a single private key for both encryption and authentication. | ||
*/ | ||
export class Eip1271AccountContract implements AccountContract { | ||
constructor(private encryptionPrivateKey: PrivateKey) {} | ||
|
||
public getDeploymentArgs() { | ||
return Promise.resolve([]); | ||
} | ||
|
||
public async getEntrypoint({ address, partialAddress }: CompleteAddress, { chainId, version }: NodeInfo) { | ||
return new Eip1271AccountEntrypoint( | ||
address, | ||
partialAddress, | ||
this.encryptionPrivateKey, | ||
await Schnorr.new(), | ||
chainId, | ||
version, | ||
); | ||
} | ||
|
||
public getContractAbi(): ContractAbi { | ||
return Eip1271AccountContractAbi as unknown as ContractAbi; | ||
} | ||
} |
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
82 changes: 82 additions & 0 deletions
82
yarn-project/aztec.js/src/account/entrypoint/eip_1271_account_entrypoint.ts
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,82 @@ | ||
import { AztecAddress, Fr, FunctionData, PartialAddress, PrivateKey, TxContext } from '@aztec/circuits.js'; | ||
import { Signer } from '@aztec/circuits.js/barretenberg'; | ||
import { ContractAbi, encodeArguments } from '@aztec/foundation/abi'; | ||
import { FunctionCall, PackedArguments, TxExecutionRequest } from '@aztec/types'; | ||
|
||
import SchnorrSingleKeyAccountContractAbi from '../../abis/schnorr_single_key_account_contract.json' assert { type: 'json' }; | ||
import { generatePublicKey } from '../../index.js'; | ||
import { DEFAULT_CHAIN_ID, DEFAULT_VERSION } from '../../utils/defaults.js'; | ||
import { buildPayload, hashPayload } from './entrypoint_payload.js'; | ||
import { CreateTxRequestOpts, Entrypoint } from './index.js'; | ||
|
||
/** | ||
* Account contract implementation that uses a single key for signing and encryption. This public key is not | ||
* stored in the contract, but rather verified against the contract address. Note that this approach is not | ||
* secure and should not be used in real use cases. | ||
*/ | ||
export class Eip1271AccountEntrypoint implements Entrypoint { | ||
constructor( | ||
private address: AztecAddress, | ||
private partialAddress: PartialAddress, | ||
private privateKey: PrivateKey, | ||
private signer: Signer, | ||
private chainId: number = DEFAULT_CHAIN_ID, | ||
private version: number = DEFAULT_VERSION, | ||
) {} | ||
|
||
public sign(message: Buffer) { | ||
return this.signer.constructSignature(message, this.privateKey).toBuffer(); | ||
} | ||
|
||
async generateEip1271Witness(message: Buffer) { | ||
const signature = this.sign(message); | ||
const publicKey = await generatePublicKey(this.privateKey); | ||
|
||
const publicKeyBytes = publicKey.toBuffer(); | ||
const sigFr: Fr[] = []; | ||
const pubKeyFr: Fr[] = []; | ||
for (let i = 0; i < 64; i++) { | ||
pubKeyFr.push(new Fr(publicKeyBytes[i])); | ||
sigFr.push(new Fr(signature[i])); | ||
} | ||
|
||
return [...pubKeyFr, ...sigFr, this.partialAddress]; | ||
} | ||
|
||
async createTxExecutionRequest( | ||
executions: FunctionCall[], | ||
opts: CreateTxRequestOpts = {}, | ||
): Promise<TxExecutionRequest> { | ||
if (opts.origin && !opts.origin.equals(this.address)) { | ||
throw new Error(`Sender ${opts.origin.toString()} does not match account address ${this.address.toString()}`); | ||
} | ||
|
||
const { payload, packedArguments: callsPackedArguments } = await buildPayload(executions); | ||
const message = await hashPayload(payload); | ||
|
||
const signature = this.sign(message); | ||
|
||
const publicKey = await generatePublicKey(this.privateKey); | ||
const args = [payload, publicKey.toBuffer(), signature, this.partialAddress]; | ||
const abi = this.getEntrypointAbi(); | ||
const packedArgs = await PackedArguments.fromArgs(encodeArguments(abi, args)); | ||
const txRequest = TxExecutionRequest.from({ | ||
argsHash: packedArgs.hash, | ||
origin: this.address, | ||
functionData: FunctionData.fromAbi(abi), | ||
txContext: TxContext.empty(this.chainId, this.version), | ||
packedArguments: [...callsPackedArguments, packedArgs], | ||
}); | ||
|
||
return txRequest; | ||
} | ||
|
||
private getEntrypointAbi() { | ||
// We use the SchnorrSingleKeyAccountContract because it implements the interface we need, but ideally | ||
// we should have an interface that defines the entrypoint for SingleKeyAccountContracts and | ||
// load the abi from it. | ||
const abi = (SchnorrSingleKeyAccountContractAbi as any as ContractAbi).functions.find(f => f.name === 'entrypoint'); | ||
if (!abi) throw new Error(`Entrypoint abi for account contract not found`); | ||
return abi; | ||
} | ||
} |
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
Oops, something went wrong.