Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
sklppy88 committed Oct 21, 2024
1 parent 62b4c08 commit e1846a5
Show file tree
Hide file tree
Showing 24 changed files with 247 additions and 76 deletions.
12 changes: 9 additions & 3 deletions noir-projects/aztec-nr/aztec/src/encrypted_logs/payload.nr
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,16 @@ pub fn compute_encrypted_log<let P: u32, let M: u32>(

let header = EncryptedLogHeader::new(contract_address);

let incoming_header_ciphertext: [u8; 48] = header.compute_ciphertext(eph_sk, ivpk);
let incoming_header_ciphertext: [u8; 48] = header.compute_ciphertext(eph_sk, recipient);
let outgoing_header_ciphertext: [u8; 48] = header.compute_ciphertext(eph_sk, ovpk);
let incoming_body_ciphertext = compute_incoming_body_ciphertext(plaintext, eph_sk, ivpk);
let outgoing_body_ciphertext: [u8; 144] = compute_outgoing_body_ciphertext(recipient, ivpk, fr_to_fq(ovsk_app), eph_sk, eph_pk);
let incoming_body_ciphertext = compute_incoming_body_ciphertext(plaintext, eph_sk, IvpkM { inner: recipient.to_point() });
let outgoing_body_ciphertext: [u8; 144] = compute_outgoing_body_ciphertext(
recipient,
IvpkM { inner: recipient.to_point() },
fr_to_fq(ovsk_app),
eph_sk,
eph_pk
);

let mut encrypted_bytes: [u8; M] = [0; M];
// @todo We ignore the tags for now
Expand Down
2 changes: 1 addition & 1 deletion noir-projects/aztec-nr/aztec/src/keys/getters/mod.nr
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub fn get_public_keys(account: AztecAddress) -> PublicKeys {
get_public_keys_and_partial_address(account)
};
assert_eq(
account, AztecAddress::compute(hinted_canonical_public_keys.hash(), partial_address), "Invalid public keys hint for address"
account, AztecAddress::compute_from_public_keys(hinted_canonical_public_keys, partial_address), "Invalid public keys hint for address"
);

hinted_canonical_public_keys
Expand Down
2 changes: 1 addition & 1 deletion noir-projects/aztec-nr/aztec/src/utils/point.nr
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use dep::protocol_types::point::Point;

// I am storing the modulus divided by 2 plus 1 here because full modulus would throw "String literal too large" error
// I am storing the modulus minus 1 divided by 2 here because full modulus would throw "String literal too large" error
// Full modulus is 21888242871839275222246405745257275088548364400416034343698204186575808495617
global BN254_FR_MODULUS_DIV_2: Field = 10944121435919637611123202872628637544274182200208017171849102093287904247808;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ contract ContractInstanceDeployer {

let partial_address = PartialAddress::compute(contract_class_id, salt, initialization_hash, deployer);

let address = AztecAddress::compute(public_keys.hash(), partial_address);
let address = AztecAddress::compute_from_public_keys(public_keys, partial_address);

// Emit the address as a nullifier to be able to prove that this instance has been (not) deployed
context.push_nullifier(address.to_field());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ pub fn recover_address(message_hash: Field, witness: AuthWitness) -> AztecAddres
);
assert(verification == true);

AztecAddress::compute(witness.keys.hash(), witness.partial_address)
AztecAddress::compute_from_public_keys(witness.keys, witness.partial_address)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub fn validate_contract_address(private_call_data: PrivateCallData, protocol_co
private_call_data.contract_class_artifact_hash,
private_call_data.contract_class_public_bytecode_commitment,
private_call_data.salted_initialization_hash,
private_call_data.public_keys.hash()
private_call_data.public_keys
);

let protocol_contract_index = contract_address.to_field();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
use crate::{
abis::function_selector::FunctionSelector,
abis::function_selector::FunctionSelector, public_keys::{ToPoint, PublicKeys},
address::{
partial_address::PartialAddress, public_keys_hash::PublicKeysHash,
salted_initialization_hash::SaltedInitializationHash
},
constants::{AZTEC_ADDRESS_LENGTH, FUNCTION_TREE_HEIGHT, GENERATOR_INDEX__CONTRACT_ADDRESS_V1},
constants::{
AZTEC_ADDRESS_LENGTH, FUNCTION_TREE_HEIGHT, GENERATOR_INDEX__PUBLIC_KEYS_HASH,
GENERATOR_INDEX__CONTRACT_ADDRESS_V1
},
contract_class_id::ContractClassId,
hash::{poseidon2_hash_with_separator, private_functions_root_from_siblings},
merkle_tree::membership::MembershipWitness,
traits::{Empty, FromField, ToField, Serialize, Deserialize}, utils
};

global BN254_FR_MODULUS_DIV_2: Field = 10944121435919637611123202872628637544274182200208017171849102093287904247808;

// We do below because `use crate::point::Point;` does not work
use dep::std::embedded_curve_ops::EmbeddedCurvePoint as Point;

use std::{
ec::{sqrt, pow},
embedded_curve_ops::{fixed_base_scalar_mul as derive_public_key, EmbeddedCurveScalar}
};

// Aztec address
pub struct AztecAddress {
inner : Field
Expand Down Expand Up @@ -52,6 +65,31 @@ impl Deserialize<AZTEC_ADDRESS_LENGTH> for AztecAddress {
}
}

impl ToPoint for AztecAddress {
fn to_point(self) -> Point {
// Calculate y^2 = x^3 - 17
let y_squared = pow(self.inner, 3) - 17;

// We can see if y is square first, or we can soft fail with just sqrt(y_squared);
// If y is not square, the x-coordinate is not on the curve
// Do we throw here or soft continue ?
// let y_is_square = is_square(y_squared);
// assert(y_is_square);

let mut y = sqrt(y_squared);

// We can NOT do a check like the below. We do not have access to the sign, and this derivation produces "both" points
// assert(y.lt(BN254_FR_MODULUS_DIV_2) | y.eq(BN254_FR_MODULUS_DIV_2));

// If we get a negative y coordinate, we pin it to the positive one by subtracting it from the Field modulus
if (!(y.lt(BN254_FR_MODULUS_DIV_2) | y.eq(BN254_FR_MODULUS_DIV_2))) {
y = (BN254_FR_MODULUS_DIV_2 + BN254_FR_MODULUS_DIV_2 + 1) - y;
}

Point { x: self.inner, y, is_infinite: false }
}
}

impl AztecAddress {
pub fn zero() -> Self {
Self { inner: 0 }
Expand All @@ -66,14 +104,26 @@ impl AztecAddress {
)
}

pub fn compute_from_public_keys(public_keys: PublicKeys, partial_address: PartialAddress) -> AztecAddress {
let public_keys_hash = public_keys.hash();

let pre_address = poseidon2_hash_with_separator(
[public_keys_hash.to_field(), partial_address.to_field()],
GENERATOR_INDEX__CONTRACT_ADDRESS_V1
);

let address_point = derive_public_key(EmbeddedCurveScalar::from_field(pre_address)).add(public_keys.ivpk_m.to_point());
AztecAddress::from_field(address_point.x)
}

pub fn compute_from_private_function(
function_selector: FunctionSelector,
functino_vk_hash: Field,
function_leaf_membership_witness: MembershipWitness<FUNCTION_TREE_HEIGHT>,
contract_class_artifact_hash: Field,
contract_class_public_bytecode_commitment: Field,
salted_initialization_hash: SaltedInitializationHash,
public_keys_hash: PublicKeysHash
public_keys: PublicKeys
) -> Self {
let private_functions_root = private_functions_root_from_siblings(
function_selector,
Expand All @@ -91,7 +141,7 @@ impl AztecAddress {
// Compute contract address using the preimage which includes the class_id.
let partial_address = PartialAddress::compute_from_salted_initialization_hash(contract_class_id, salted_initialization_hash);

AztecAddress::compute(public_keys_hash, partial_address)
AztecAddress::compute_from_public_keys(public_keys, partial_address)
}

pub fn is_zero(self) -> bool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ impl Hash for ContractInstance {

impl ContractInstance {
fn to_address(self) -> AztecAddress {
AztecAddress::compute(
self.public_keys.hash(),
AztecAddress::compute_from_public_keys(
self.public_keys,
PartialAddress::compute(
self.contract_class_id,
self.salt,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub fn get_protocol_contract(index: u32) -> ContractData {

let partial_address = PartialAddress::compute_from_salted_initialization_hash(contract_class_id, salted_initialization_hash);

let address = AztecAddress::compute(public_keys.hash(), partial_address);
let address = AztecAddress::compute_from_public_keys(public_keys, partial_address);

ContractData {
contract_address_salt: 1,
Expand Down
40 changes: 16 additions & 24 deletions yarn-project/aztec.js/src/account_manager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,29 @@ export class AccountManager {
public readonly salt: Fr;

// TODO(@spalladino): Does it make sense to have both completeAddress and instance?
private completeAddress?: CompleteAddress;
private instance?: ContractInstanceWithAddress;
private publicKeys?: PublicKeys;
private completeAddress: CompleteAddress;
private instance: ContractInstanceWithAddress;

constructor(private pxe: PXE, private secretKey: Fr, private accountContract: AccountContract, salt?: Salt) {
this.salt = salt !== undefined ? new Fr(salt) : Fr.random();
}

protected getPublicKeysHash() {
if (!this.publicKeys) {
this.publicKeys = deriveKeys(this.secretKey).publicKeys;
}
return this.publicKeys.hash();
const { publicKeys } = deriveKeys(secretKey);

this.instance = getContractInstanceFromDeployParams(this.accountContract.getContractArtifact(), {
constructorArgs: this.accountContract.getDeploymentArgs(),
salt: this.salt,
publicKeys,
});

this.completeAddress = CompleteAddress.fromSecretKeyAndInstance(this.secretKey, this.instance);
}

protected getPublicKeys() {
if (!this.publicKeys) {
this.publicKeys = deriveKeys(this.secretKey).publicKeys;
}
return this.publicKeys;
return this.instance.publicKeys;
}

protected getPublicKeysHash() {
return this.getPublicKeys().hash();
}

/**
Expand All @@ -73,10 +76,6 @@ export class AccountManager {
* @returns The address, partial address, and encryption public key.
*/
public getCompleteAddress(): CompleteAddress {
if (!this.completeAddress) {
const instance = this.getInstance();
this.completeAddress = CompleteAddress.fromSecretKeyAndInstance(this.secretKey, instance);
}
return this.completeAddress;
}

Expand All @@ -95,13 +94,6 @@ export class AccountManager {
* @returns ContractInstance instance.
*/
public getInstance(): ContractInstanceWithAddress {
if (!this.instance) {
this.instance = getContractInstanceFromDeployParams(this.accountContract.getContractArtifact(), {
constructorArgs: this.accountContract.getDeploymentArgs(),
salt: this.salt,
publicKeys: this.getPublicKeys(),
});
}
return this.instance;
}

Expand Down
3 changes: 2 additions & 1 deletion yarn-project/circuit-types/src/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
ScopedLogHash,
SerializableContractInstance,
computeContractAddressFromInstance,
computeContractAddressFromInstanceNew,
computeContractClassId,
getContractClassFromArtifact,
} from '@aztec/circuits.js';
Expand Down Expand Up @@ -329,7 +330,7 @@ export const randomContractInstanceWithAddress = (
address?: AztecAddress,
): ContractInstanceWithAddress => {
const instance = SerializableContractInstance.random(opts);
return instance.withAddress(address ?? computeContractAddressFromInstance(instance));
return instance.withAddress(address ?? computeContractAddressFromInstanceNew(instance));
};

export const randomDeployedContract = () => {
Expand Down
11 changes: 10 additions & 1 deletion yarn-project/circuits.js/src/contract/contract_address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Fr } from '@aztec/foundation/fields';

import { GeneratorIndex } from '../constants.gen.js';
import { computeVarArgsHash } from '../hash/hash.js';
import { computeAddress } from '../keys/index.js';
import { computeAddress, computeNewAddress } from '../keys/index.js';
import { type ContractInstance } from './interfaces/contract_instance.js';

// TODO(@spalladino): Review all generator indices in this file
Expand All @@ -29,6 +29,15 @@ export function computeContractAddressFromInstance(
return computeAddress(publicKeysHash, partialAddress);
}

export function computeContractAddressFromInstanceNew(
instance:
| ContractInstance
| ({ contractClassId: Fr; saltedInitializationHash: Fr } & Pick<ContractInstance, 'publicKeys'>),
): AztecAddress {
const partialAddress = computePartialAddress(instance);
return computeNewAddress(instance.publicKeys, partialAddress);
}

/**
* Computes the partial address defined as the hash of the contract class id and salted initialization hash.
* @param instance - Contract instance for which to calculate the partial address.
Expand Down
3 changes: 2 additions & 1 deletion yarn-project/circuits.js/src/contract/contract_instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { computeContractClassId } from '../contract/contract_class_id.js';
import { PublicKeys } from '../types/public_keys.js';
import {
computeContractAddressFromInstance,
computeContractAddressFromInstanceNew,
computeInitializationHash,
computeInitializationHashFromEncodedArgs,
} from './contract_address.js';
Expand Down Expand Up @@ -133,7 +134,7 @@ export function getContractInstanceFromDeployParams(
version: 1,
};

return { ...instance, address: computeContractAddressFromInstance(instance) };
return { ...instance, address: computeContractAddressFromInstanceNew(instance) };
}

function getConstructorArtifact(
Expand Down
36 changes: 35 additions & 1 deletion yarn-project/circuits.js/src/keys/derivation.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { poseidon2HashWithSeparator, sha512ToGrumpkinScalar } from '@aztec/foundation/crypto';
import { type Fq, type Fr, GrumpkinScalar } from '@aztec/foundation/fields';
import { Fq, Fr, GrumpkinScalar, type Point } from '@aztec/foundation/fields';

import { Grumpkin } from '../barretenberg/crypto/grumpkin/index.js';
import { GeneratorIndex } from '../constants.gen.js';
Expand Down Expand Up @@ -46,6 +46,40 @@ export function computeAddress(publicKeysHash: Fr, partialAddress: Fr) {
return AztecAddress.fromField(addressFr);
}

export function computeNewAddress(publicKeys: PublicKeys, partialAddress: Fr) {
const preaddress = poseidon2HashWithSeparator(
[publicKeys.hash(), partialAddress],
GeneratorIndex.CONTRACT_ADDRESS_V1,
);
const address = computeAddressFromPreaddressAndIvpkM(preaddress, publicKeys.masterIncomingViewingPublicKey);

return address;
}

export function computeAddressFromPreaddressAndIvpkM(preaddress: Fr, ivpkM: Point) {
const addressPoint = computeAddressPointFromPreaddressAndIvpkM(preaddress, ivpkM);

return AztecAddress.fromField(addressPoint.x);
}

export function computeAddressPointFromPreaddressAndIvpkM(preaddress: Fr, ivpkM: Point) {
const preaddressPoint = derivePublicKeyFromSecretKey(new Fq(preaddress.toBigInt()));
const addressPoint = new Grumpkin().add(preaddressPoint, ivpkM);

return addressPoint;
}

export function computeAddressSecret(preaddress: Fr, ivsk: Fq) {
const addressSecretCandidate = ivsk.add(new Fq(preaddress.toBigInt()));
const addressPointCandidate = derivePublicKeyFromSecretKey(addressSecretCandidate);

if (!addressPointCandidate.y.lt(new Fr((Fr.MODULUS - 1n) / 2n))) {
return new Fq(Fq.MODULUS - addressSecretCandidate.toBigInt());
}

return addressSecretCandidate;
}

export function derivePublicKeyFromSecretKey(secretKey: Fq) {
const curve = new Grumpkin();
return curve.mul(curve.generator(), secretKey);
Expand Down
Loading

0 comments on commit e1846a5

Please sign in to comment.