Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions noir-projects/aztec-nr/aztec/src/oracle/auth_witness.nr
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,37 @@ unconstrained fn get_auth_witness_oracle<let N: u32>(_message_hash: Field) -> [F
pub unconstrained fn get_auth_witness<let N: u32>(message_hash: Field) -> [Field; N] {
get_auth_witness_oracle(message_hash)
}

/// Fetches an auth witness and casts each field to a byte.
///
/// Each field is range-checked to `[0, 256)` before casting to prevent silent truncation (e.g. a field value of
/// `b + 256` would truncate to the same byte as `b`).
Comment thread
nchamo marked this conversation as resolved.
pub unconstrained fn get_auth_witness_as_bytes<let N: u32>(message_hash: Field) -> [u8; N] {
let witness = get_auth_witness::<N>(message_hash);
let mut result: [u8; N] = [0; N];
for i in 0..N {
assert(witness[i].lt(256), "auth witness field is not a single byte");
result[i] = witness[i] as u8;
}
result
}

mod test {
use super::get_auth_witness_as_bytes;
use std::test::OracleMock;

#[test]
unconstrained fn get_auth_witness_as_bytes_casts_valid_witness() {
let witness: [Field; 3] = [0, 127, 255];
let _ = OracleMock::mock("aztec_utl_getAuthWitness").returns(witness);
let bytes: [u8; 3] = get_auth_witness_as_bytes(0);
assert_eq(bytes, [0, 127, 255]);
}

#[test(should_fail_with = "auth witness field is not a single byte")]
unconstrained fn get_auth_witness_as_bytes_rejects_field_above_byte_range() {
let witness: [Field; 1] = [256];
let _ = OracleMock::mock("aztec_utl_getAuthWitness").returns(witness);
let _: [u8; 1] = get_auth_witness_as_bytes(0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ pub contract EcdsaKAccount {
storage::storage,
},
messages::message_delivery::MessageDelivery,
oracle::{auth_witness::get_auth_witness, notes::{get_sender_for_tags, set_sender_for_tags}},
oracle::{
auth_witness::get_auth_witness_as_bytes,
notes::{get_sender_for_tags, set_sender_for_tags},
},
state_vars::SinglePrivateImmutable,
};

Expand Down Expand Up @@ -81,14 +84,9 @@ pub contract EcdsaKAccount {
let storage = Storage::init(context);
let public_key = storage.signing_public_key.get_note();

// Load auth witness
// Safety: The witness is only used as a "magical value" that makes the signature verification below pass.
// Hence it's safe.
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;
}
let signature: [u8; 64] = unsafe { get_auth_witness_as_bytes(outer_hash) };

// Verify payload signature using Ethereum's signing scheme
// Note that noir expects the hash of the message/challenge as input to the ECDSA verification.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ pub contract EcdsaRAccount {
storage::storage,
},
messages::message_delivery::MessageDelivery,
oracle::{auth_witness::get_auth_witness, notes::{get_sender_for_tags, set_sender_for_tags}},
oracle::{
auth_witness::get_auth_witness_as_bytes,
notes::{get_sender_for_tags, set_sender_for_tags},
},
state_vars::SinglePrivateImmutable,
};

Expand Down Expand Up @@ -79,14 +82,9 @@ pub contract EcdsaRAccount {
let storage = Storage::init(context);
let public_key = storage.signing_public_key.get_note();

// Load auth witness
// Safety: The witness is only used as a "magical value" that makes the signature verification below pass.
// Hence it's safe.
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;
}
let signature: [u8; 64] = unsafe { get_auth_witness_as_bytes(outer_hash) };

// Verify payload signature using Ethereum's signing scheme
// Note that noir expects the hash of the message/challenge as input to the ECDSA verification.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub contract SchnorrAccount {
},
messages::message_delivery::MessageDelivery,
oracle::{
auth_witness::get_auth_witness,
auth_witness::get_auth_witness_as_bytes,
get_nullifier_membership_witness::get_low_nullifier_membership_witness,
notes::{get_sender_for_tags, set_sender_for_tags},
},
Expand Down Expand Up @@ -95,14 +95,9 @@ pub contract SchnorrAccount {
let storage = Storage::init(context);
let public_key = storage.signing_public_key.get_note();

// Load auth witness
// Safety: The witness is only used as a "magical value" that makes the signature verification below pass.
// Hence it's safe.
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;
}
let signature: [u8; 64] = unsafe { get_auth_witness_as_bytes(outer_hash) };

let pub_key =
std::embedded_curve_ops::EmbeddedCurvePoint { x: public_key.x, y: public_key.y };
Expand All @@ -128,11 +123,7 @@ pub contract SchnorrAccount {
inner_hash,
);

let witness: [Field; 64] = get_auth_witness(message_hash);
let mut signature: [u8; 64] = [0; 64];
for i in 0..64 {
signature[i] = witness[i] as u8;
}
let signature: [u8; 64] = get_auth_witness_as_bytes(message_hash);
let pub_key =
std::embedded_curve_ops::EmbeddedCurvePoint { x: public_key.x, y: public_key.y };
let valid_in_private =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub contract SchnorrHardcodedAccount {
authwit::{account::AccountActions, entrypoint::app::AppPayload},
context::PrivateContext,
macros::functions::{allow_phase_change, external, view},
oracle::{auth_witness::get_auth_witness, notes::set_sender_for_tags},
oracle::{auth_witness::get_auth_witness_as_bytes, notes::set_sender_for_tags},
};
use std::embedded_curve_ops::EmbeddedCurvePoint;

Expand Down Expand Up @@ -38,15 +38,9 @@ pub 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

// Safety: The witness is only used as a "magical value" that makes the signature verification below pass.
// Hence it's safe.
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;
}
let signature: [u8; 64] = unsafe { get_auth_witness_as_bytes(outer_hash) };

// Verify signature using hardcoded public key
schnorr::verify_signature(
Expand Down
Loading