From 7c2abc525881508953c6bf5999590a1fa8414ae7 Mon Sep 17 00:00:00 2001 From: benesjan Date: Fri, 10 May 2024 09:07:03 +0000 Subject: [PATCH] feat: re-enabling authwit constraint --- .../src/auth_oracle.nr | 15 ++++++---- .../src/main.nr | 7 ++--- .../src/util.nr | 30 +++++++++---------- .../src/single_key/account_contract.ts | 11 +++---- .../src/structs/complete_address.ts | 12 ++++++-- 5 files changed, 39 insertions(+), 36 deletions(-) diff --git a/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/auth_oracle.nr b/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/auth_oracle.nr index 67791c752106..2874026cc16d 100644 --- a/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/auth_oracle.nr +++ b/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/auth_oracle.nr @@ -2,26 +2,29 @@ use dep::authwit::auth_witness; use dep::aztec::protocol_types::{address::PartialAddress, grumpkin_point::GrumpkinPoint}; struct AuthWitness { - owner: GrumpkinPoint, + npk_m: GrumpkinPoint, ivpk_m: GrumpkinPoint, ovpk_m: GrumpkinPoint, tpk_m: GrumpkinPoint, signature: [u8; 64], partial_address: PartialAddress, } impl AuthWitness { - fn deserialize(values: [Field; 67]) -> Self { + fn deserialize(values: [Field; 73]) -> Self { let mut signature = [0; 64]; for i in 0..64 { - signature[i] = values[i + 2] as u8; + signature[i] = values[i + 8] as u8; } Self { - owner: GrumpkinPoint::new(values[0], values[1]), + npk_m: GrumpkinPoint::new(values[0], values[1]), + ivpk_m: GrumpkinPoint::new(values[2], values[3]), + ovpk_m: GrumpkinPoint::new(values[4], values[5]), + tpk_m: GrumpkinPoint::new(values[6], values[7]), signature, - partial_address: PartialAddress::from_field(values[66]) + partial_address: PartialAddress::from_field(values[72]) } } } unconstrained pub fn get_auth_witness(message_hash: Field) -> AuthWitness { - let witness: [Field; 67] = auth_witness::get_auth_witness(message_hash); + let witness: [Field; 73] = auth_witness::get_auth_witness(message_hash); AuthWitness::deserialize(witness) } diff --git a/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/main.nr index 5c75c095d2fb..9803ed4f15e5 100644 --- a/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/main.nr @@ -6,8 +6,7 @@ contract SchnorrSingleKeyAccount { use dep::authwit::{entrypoint::{app::AppPayload, fee::FeePayload}, account::AccountActions}; - // use crate::{util::recover_address, auth_oracle::get_auth_witness}; - use crate::auth_oracle::get_auth_witness; + use crate::{util::recover_address, auth_oracle::get_auth_witness}; global ACCOUNT_ACTIONS_STORAGE_SLOT = 1; @@ -46,9 +45,7 @@ contract SchnorrSingleKeyAccount { #[contract_library_method] fn is_valid_impl(context: &mut PrivateContext, outer_hash: Field) -> bool { let witness = get_auth_witness(outer_hash); - // TODO(#5830): the following is currently broken because we are no longer able to compute public keys hash - // in recover_address(...) just from user public key. - // assert(recover_address(outer_hash, witness).eq(context.this_address())); + assert(recover_address(outer_hash, witness).eq(context.this_address())); true } } diff --git a/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/util.nr b/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/util.nr index 89f7e2e9b4d5..dd1fded44ad7 100644 --- a/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/util.nr +++ b/noir-projects/noir-contracts/contracts/schnorr_single_key_account_contract/src/util.nr @@ -3,19 +3,19 @@ use dep::aztec::protocol_types::address::PublicKeysHash; use dep::std::{schnorr::verify_signature_slice}; use crate::auth_oracle::AuthWitness; -// TODO(#5830): the following is currently broken because we are no longer able to compute public keys hash -// pub fn recover_address(message_hash: Field, witness: AuthWitness) -> AztecAddress { -// let message_bytes = message_hash.to_be_bytes(32); -// let verification = verify_signature_slice( -// witness.owner.x, -// witness.owner.y, -// witness.signature, -// message_bytes -// ); -// assert(verification == true); +pub fn recover_address(message_hash: Field, witness: AuthWitness) -> AztecAddress { + let message_bytes = message_hash.to_be_bytes(32); + // In a single key account contract we re-used ivpk_m as signing key + let verification = verify_signature_slice( + witness.ivpk_m.x, + witness.ivpk_m.y, + witness.signature, + message_bytes + ); + assert(verification == true); -// AztecAddress::compute( -// PublicKeysHash::compute(witness.owner), -// witness.partial_address -// ) -// } + AztecAddress::compute( + PublicKeysHash::compute(witness.npk_m, witness.ivpk_m, witness.ovpk_m, witness.tpk_m), + witness.partial_address + ) +} diff --git a/yarn-project/accounts/src/single_key/account_contract.ts b/yarn-project/accounts/src/single_key/account_contract.ts index 393bbab82d81..b0e567cebcba 100644 --- a/yarn-project/accounts/src/single_key/account_contract.ts +++ b/yarn-project/accounts/src/single_key/account_contract.ts @@ -1,7 +1,5 @@ -import { generatePublicKey } from '@aztec/aztec.js'; import { type AuthWitnessProvider } from '@aztec/aztec.js/account'; import { AuthWitness, type CompleteAddress, type GrumpkinPrivateKey } from '@aztec/circuit-types'; -import { type PartialAddress } from '@aztec/circuits.js'; import { Schnorr } from '@aztec/circuits.js/barretenberg'; import { type ContractArtifact } from '@aztec/foundation/abi'; import { type Fr } from '@aztec/foundation/fields'; @@ -22,8 +20,8 @@ export class SingleKeyAccountContract extends DefaultAccountContract { return undefined; } - getAuthWitnessProvider({ partialAddress }: CompleteAddress): AuthWitnessProvider { - return new SingleKeyAuthWitnessProvider(this.encryptionPrivateKey, partialAddress); + getAuthWitnessProvider(account: CompleteAddress): AuthWitnessProvider { + return new SingleKeyAuthWitnessProvider(this.encryptionPrivateKey, account); } } @@ -33,13 +31,12 @@ export class SingleKeyAccountContract extends DefaultAccountContract { * by reconstructing the current address. */ class SingleKeyAuthWitnessProvider implements AuthWitnessProvider { - constructor(private privateKey: GrumpkinPrivateKey, private partialAddress: PartialAddress) {} + constructor(private privateKey: GrumpkinPrivateKey, private account: CompleteAddress) {} createAuthWit(messageHash: Fr): Promise { const schnorr = new Schnorr(); const signature = schnorr.constructSignature(messageHash.toBuffer(), this.privateKey); - const publicKey = generatePublicKey(this.privateKey); - const witness = [...publicKey.toFields(), ...signature.toBuffer(), this.partialAddress]; + const witness = [...this.account.publicKeys.flatMap(pk => pk.toFields()), ...signature.toBuffer(), this.account.partialAddress]; return Promise.resolve(new AuthWitness(messageHash, witness)); } } diff --git a/yarn-project/circuits.js/src/structs/complete_address.ts b/yarn-project/circuits.js/src/structs/complete_address.ts index 2e57265516a3..a067704f46c5 100644 --- a/yarn-project/circuits.js/src/structs/complete_address.ts +++ b/yarn-project/circuits.js/src/structs/complete_address.ts @@ -1,6 +1,6 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr, Point } from '@aztec/foundation/fields'; -import { BufferReader } from '@aztec/foundation/serialize'; +import { BufferReader, Tuple } from '@aztec/foundation/serialize'; import { computePartialAddress } from '../contract/contract_address.js'; import { computeAddress, computePublicKeysHash, deriveKeys } from '../keys/index.js'; @@ -195,12 +195,18 @@ export class CompleteAddress { return `0x${this.toBuffer().toString('hex')}`; } - get publicKeysHash(): Fr { - return computePublicKeysHash( + get publicKeys(): Tuple { + return [ this.masterNullifierPublicKey, this.masterIncomingViewingPublicKey, this.masterOutgoingViewingPublicKey, this.masterTaggingPublicKey, + ]; + } + + get publicKeysHash(): Fr { + return computePublicKeysHash( + ...this.publicKeys ); } }