Skip to content

Commit

Permalink
refactor: no assert in is_valid_impl(...) (#8397)
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan authored Sep 5, 2024
1 parent cfea06e commit 1c1d35a
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 35 deletions.
2 changes: 1 addition & 1 deletion docs/docs/aztec/concepts/accounts/keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ Usually, an account contract will validate a signature of the incoming payload a

This is a snippet of our Schnorr Account contract implementation, which uses Schnorr signatures for authentication:

#include_code entrypoint /noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr rust
#include_code is_valid_impl /noir-projects/noir-contracts/contracts/schnorr_account_contract/src/main.nr rust

Still, different accounts may use different signing schemes, may require multi-factor authentication, or _may not even use signing keys_ and instead rely on other authentication mechanisms. Read [how to write an account contract](../../../tutorials/codealong/contract_tutorials/write_accounts_contract.md) for a full example of how to manage authentication.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ contract EcdsaKAccount {
let public_key = storage.public_key.get_note();

// Load auth witness
let witness: [Field; 64] = get_auth_witness(outer_hash);
let witness: [Field; 64] = unsafe {
get_auth_witness(outer_hash)
};
let mut signature: [u8; 64] = [0; 64];
for i in 0..64 {
signature[i] = witness[i] as u8;
Expand All @@ -65,9 +67,6 @@ contract EcdsaKAccount {
// Note that noir expects the hash of the message/challenge as input to the ECDSA verification.
let outer_hash_bytes: [u8; 32] = outer_hash.to_be_bytes();
let hashed_message: [u8; 32] = std::hash::sha256(outer_hash_bytes);
let verification = std::ecdsa_secp256k1::verify_signature(public_key.x, public_key.y, signature, hashed_message);
assert(verification == true);

true
std::ecdsa_secp256k1::verify_signature(public_key.x, public_key.y, signature, hashed_message)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ contract EcdsaRAccount {
let public_key = storage.public_key.get_note();

// Load auth witness
let witness: [Field; 64] = get_auth_witness(outer_hash);
let witness: [Field; 64] = unsafe {
get_auth_witness(outer_hash)
};
let mut signature: [u8; 64] = [0; 64];
for i in 0..64 {
signature[i] = witness[i] as u8;
Expand All @@ -64,9 +66,6 @@ contract EcdsaRAccount {
// Note that noir expects the hash of the message/challenge as input to the ECDSA verification.
let outer_hash_bytes: [u8; 32] = outer_hash.to_be_bytes();
let hashed_message: [u8; 32] = std::hash::sha256(outer_hash_bytes);
let verification = std::ecdsa_secp256r1::verify_signature(public_key.x, public_key.y, signature, hashed_message);
assert(verification == true);

true
std::ecdsa_secp256r1::verify_signature(public_key.x, public_key.y, signature, hashed_message)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ contract SchnorrAccount {

#[aztec(storage)]
struct Storage {
// docs:start:storage
signing_public_key: PrivateImmutable<PublicKeyNote>,
// docs:end:storage
}

// Constructs the contract
Expand All @@ -33,10 +31,8 @@ contract SchnorrAccount {
// deploy this (typically MultiCallEntrypoint). I think it's ok here as I feel the outgoing here is not that
// important.

// docs:start:initialize
let mut pub_key_note = PublicKeyNote::new(signing_pub_key_x, signing_pub_key_y, this_keys.npk_m.hash());
storage.signing_public_key.initialize(&mut pub_key_note).emit(encode_and_encrypt_note_with_keys(&mut context, this_keys.ovpk_m, this_keys.ivpk_m, this));
// docs:end:initialize
}

// Note: If you globally change the entrypoint signature don't forget to update account_entrypoint.ts file
Expand All @@ -57,29 +53,27 @@ contract SchnorrAccount {

#[contract_library_method]
fn is_valid_impl(context: &mut PrivateContext, outer_hash: Field) -> bool {
// docs:start:entrypoint
// docs:start:is_valid_impl
// Load public key from storage
let storage = Storage::init(context);
// docs:start:get_note
let public_key = storage.signing_public_key.get_note();
// docs:end:get_note
// Load auth witness
let witness: [Field; 64] = get_auth_witness(outer_hash);
let witness: [Field; 64] = unsafe {
get_auth_witness(outer_hash)
};
let mut signature: [u8; 64] = [0; 64];
for i in 0..64 {
signature[i] = witness[i] as u8;
}

// Verify signature of the payload bytes
let verification = std::schnorr::verify_signature(
std::schnorr::verify_signature(
public_key.x,
public_key.y,
signature,
outer_hash.to_be_bytes::<32>()
);
assert(verification == true);
// docs:end:entrypoint
true
)
// docs:end:is_valid_impl
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
// docs:start:contract
// Account contract that uses Schnorr signatures for authentication using a hardcoded public key.
contract SchnorrHardcodedAccount {
use dep::std;
use dep::aztec::prelude::PrivateContext;

use dep::authwit::{
entrypoint::{app::AppPayload, fee::FeePayload}, account::AccountActions,
auth_witness::get_auth_witness
Expand All @@ -30,21 +28,21 @@ contract SchnorrHardcodedAccount {
#[contract_library_method]
fn is_valid_impl(_context: &mut PrivateContext, outer_hash: Field) -> bool {
// Load auth witness and format as an u8 array
let witness: [Field; 64] = get_auth_witness(outer_hash);
let witness: [Field; 64] = unsafe {
get_auth_witness(outer_hash)
};
let mut signature: [u8; 64] = [0; 64];
for i in 0..64 {
signature[i] = witness[i] as u8;
}

// Verify signature using hardcoded public key
let verification = std::schnorr::verify_signature(
std::schnorr::verify_signature(
public_key_x,
public_key_y,
signature,
outer_hash.to_be_bytes::<32>()
);
assert(verification == true);
true
)
}
// docs:end:is-valid
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ mod util;
mod auth_oracle;

contract SchnorrSingleKeyAccount {
use dep::aztec::prelude::{AztecAddress, FunctionSelector, PrivateContext};
use dep::aztec::prelude::PrivateContext;

use dep::authwit::{entrypoint::{app::AppPayload, fee::FeePayload}, account::AccountActions};

Expand All @@ -24,8 +24,9 @@ contract SchnorrSingleKeyAccount {

#[contract_library_method]
fn is_valid_impl(context: &mut PrivateContext, outer_hash: Field) -> bool {
let witness = get_auth_witness(outer_hash);
assert(recover_address(outer_hash, witness).eq(context.this_address()));
true
let witness = unsafe {
get_auth_witness(outer_hash)
};
recover_address(outer_hash, witness).eq(context.this_address())
}
}

0 comments on commit 1c1d35a

Please sign in to comment.