Skip to content

Commit

Permalink
chore: comments cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
LHerskind committed Sep 4, 2023
1 parent 75ad842 commit c53ab46
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ 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.
* Extended to pull verification data from the oracle instead of passed as arguments.
*/
export class Eip1271AccountContract implements AccountContract {
constructor(private encryptionPrivateKey: PrivateKey) {}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
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 { ContractAbi, FunctionAbi, encodeArguments } from '@aztec/foundation/abi';
import { FunctionCall, PackedArguments, TxExecutionRequest } from '@aztec/types';

import SchnorrEip1271AccountContractAbi from '../../abis/schnorr_eip_1271_account_contract.json' assert { type: 'json' };
Expand All @@ -13,6 +13,7 @@ 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.
* The entrypoint is extended to support signing and creating eip1271-like witnesses.
*/
export class Eip1271AccountEntrypoint implements Entrypoint {
constructor(
Expand All @@ -24,19 +25,27 @@ export class Eip1271AccountEntrypoint implements Entrypoint {
private version: number = DEFAULT_VERSION,
) {}

public sign(message: Buffer) {
/**
* Sign a message hash with the private key.
* @param message - The message hash to sign.
* @returns The signature as a Buffer.
*/
public sign(message: Buffer): Buffer {
return this.signer.constructSignature(message, this.privateKey).toBuffer();
}

async createEip1271Witness(message: Buffer) {
/**
* Creates an eip1271 witness for the given message. In this case, witness is the public key, the signature
* and the partial address, to be used for verification.
* @param message - The message hash to sign.
* @returns [publicKey, signature, partialAddress] as Fr[].
*/
async createEip1271Witness(message: Buffer): Promise<Fr[]> {
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]));
}

Expand All @@ -48,7 +57,7 @@ export class Eip1271AccountEntrypoint implements Entrypoint {
* Returning the witness here as a nonce is generated in the buildPayload action.
* @param executions - The function calls to execute
* @param opts - The options
* @returns
* @returns The TxRequest, the eip1271 witness to insert in db and the message signed
*/
async createTxExecutionRequestWithWitness(
executions: FunctionCall[],
Expand Down Expand Up @@ -84,13 +93,10 @@ export class Eip1271AccountEntrypoint implements Entrypoint {
}

createTxExecutionRequest(executions: FunctionCall[], _opts: CreateTxRequestOpts = {}): Promise<TxExecutionRequest> {
throw new Error(`Not implemented`);
throw new Error(`Not implemented, use createTxExecutionRequestWithWitness instead`);
}

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.
private getEntrypointAbi(): FunctionAbi {
const abi = (SchnorrEip1271AccountContractAbi as any as ContractAbi).functions.find(f => f.name === 'entrypoint');
if (!abi) throw new Error(`Entrypoint abi for account contract not found`);
return abi;
Expand Down
19 changes: 14 additions & 5 deletions yarn-project/aztec.js/src/aztec_rpc_client/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,19 +113,29 @@ export class EntrypointWallet extends BaseWallet {

/**
* A wallet implementation supporting EIP1271.
* This wallet inserts eip1271-like witnesses into the RPC, which are then fetched using an oracle
* to provide authentication data to the contract during execution.
*/
export class EipEntrypointWallet extends BaseWallet {
constructor(rpc: AztecRPC, protected accountImpl: Eip1271AccountEntrypoint) {
super(rpc);
}

/**
* Create a transaction request and add the eip1271 witness to the RPC.
* Note: When used in simulations, the witness that is inserted could be used later by attacker with
* access to the RPC.
* Meaning that if you were to use someone elses rpc with db you could send these transactions.
* For simulations it would be desirable to bypass such that no data is generated.
*
* @param executions - The function calls to execute.
* @param opts - The options.
* @returns - The TxRequest
*/
async createTxExecutionRequest(
executions: FunctionCall[],
opts: CreateTxRequestOpts = {},
): Promise<TxExecutionRequest> {
// Note that as we are inserting into the DB when creating this, it can be used after a simulation
// Meaning that if you were to use someone elses rpc with db you could send these transactions.
// For simulations these should be bypassed such that no data is generated.
const { txRequest, message, witness } = await this.accountImpl.createTxExecutionRequestWithWitness(
executions,
opts,
Expand All @@ -141,9 +151,8 @@ export class EipEntrypointWallet extends BaseWallet {
/**
* Signs the `messageHash` and adds the witness to the RPC.
* This is useful for signing messages that are not directly part of the transaction payload, such as
* approvals.
* approvals .
* @param messageHash - The message hash to sign
* @returns
*/
async signAndAddEip1271Witness(messageHash: Buffer): Promise<void> {
const witness = await this.accountImpl.createEip1271Witness(messageHash);
Expand Down
7 changes: 1 addition & 6 deletions yarn-project/end-to-end/src/e2e_lending_contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,10 @@ describe('e2e_lending_contract', () => {
beforeEach(async () => {
({ aztecNode, aztecRpcServer, logger, cheatCodes: cc } = await setup());

// Somewhere up here it gets nasty with the wallet addresses.

// We want to replace that wallet. And want to create one that has the Eip 1271
const privateKey = PrivateKey.random();
const account = new Account(aztecRpcServer, privateKey, new Eip1271AccountContract(privateKey));
// IS this too early or what is going on?
const entryPoint = (await account.getEntrypoint()) as unknown as Eip1271AccountEntrypoint;

// await account.getDeployMethod().then(d => d.simulate({ contractAddressSalt: account.salt }));
const deployTx = await account.deploy();
await deployTx.wait({ interval: 0.1 });

Expand Down Expand Up @@ -290,7 +285,7 @@ describe('e2e_lending_contract', () => {
}

it('Full lending run-through', async () => {
// Gotta use the actual eip1271 account here.
// Gotta use the actual eip1271 account here and not the standard wallet.
const recipientFull = accounts[1];
const recipient = recipientFull.address;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ contract NativeToken {
// @todo @lherskind, probably need a separate generator index and address of the
// @todo @lherskind Currently this can be used multiple times since it is not nullified.
// We can do a simple nullifier to handle that in here. Spends only 32 bytes onchain.
// @todo @LHerskind Is to be solved as part of https://github.com/AztecProtocol/aztec-packages/issues/1743
let message_field: Field = std::hash::pedersen_with_separator([
0x90785014,
from,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ impl Eip1271Witness {
}
}

// Need to figure something out for number of fields returned
unconstrained fn get_eip_1271_witness(message_hash: Field) -> Eip1271Witness {
Eip1271Witness::deserialize(get_eip_1271_witness_oracle(message_hash))
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,9 @@ fn recover_address(
message_bytes[i] = message_bytes_slice[i];
}

// Verify signature of the payload hash
let verification = verify_signature(witness.owner.x, witness.owner.y, witness.signature, message_bytes);
assert(verification == true);

// Verify public key against address
let reproduced_address = pedersen_with_separator([witness.owner.x, witness.owner.y, witness.partial_address], GENERATOR_INDEX__CONTRACT_ADDRESS)[0];
reproduced_address
}

0 comments on commit c53ab46

Please sign in to comment.