Skip to content

Commit

Permalink
addressing comments
Browse files Browse the repository at this point in the history
  • Loading branch information
sklppy88 committed Oct 24, 2024
1 parent 9de53fd commit 300de7f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 17 deletions.
17 changes: 15 additions & 2 deletions yarn-project/circuits.js/src/keys/derivation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,31 @@ export function computeAddressFromPreaddressAndIvpkM(preaddress: Fr, ivpkM: Poin
}

export function computeAddressPointFromPreaddressAndIvpkM(preaddress: Fr, ivpkM: Point) {
// Given h, our preaddress, and our ivpk_m, we can derive our address point.
// All we need to do is:
// First, take our preaddress, and multiply it by the generator G
const preaddressPoint = derivePublicKeyFromSecretKey(new Fq(preaddress.toBigInt()));
// Then we add our ivpk_m to it. Tada !
const addressPoint = new Grumpkin().add(preaddressPoint, ivpkM);

return addressPoint;
}

export function computeAddressSecret(preaddress: Fr, ivsk: Fq) {
// TLDR; (h + ivsk) * G = P1
// if P1.y is pos
// S = (h + ivsk)
// else
// S = Fq.MODULUS - (h + ivsk)
//
// Given h, our preaddress, and our ivsk, we have two different addressSecret candidates. One encodes to a point with a positive y-coordinate
// and the other encodes to a point with a negative y-coordinate. We take the addressSecret candidate that is a simple addition of the two Scalars.
const addressSecretCandidate = ivsk.add(new Fq(preaddress.toBigInt()));
// We then multiply this secretCandidate by the generator G to create an addressPoint candidate.
const addressPointCandidate = derivePublicKeyFromSecretKey(addressSecretCandidate);

// If our secret computes a point with a negative y-coordinate, we then negate the secret to produce the secret
// that can decrypt payloads encrypted with the point having a positive y-coordinate.
// Because all encryption to addresses is done using a point with the positive y-coordinate, if our addressSecret candidate derives a point with a
// negative y-coordinate, we use the other candidate by negating the secret. This transformation of the secret simply flips the y-coordinate of the derived point while keeping the x-coordinate the same.
if (!(addressPointCandidate.y.toBigInt() <= (Fr.MODULUS - 1n) / 2n)) {
return new Fq(Fq.MODULUS - addressSecretCandidate.toBigInt());
}
Expand Down
22 changes: 7 additions & 15 deletions yarn-project/circuits.js/src/structs/complete_address.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { Fq, Fr } from '@aztec/foundation/fields';
import { Fr } from '@aztec/foundation/fields';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';

import { Grumpkin } from '../barretenberg/index.js';
import { computePartialAddress } from '../contract/contract_address.js';
import { computePreaddress, deriveKeys, derivePublicKeyFromSecretKey } from '../keys/index.js';
import { computeAddress, computePreaddress, deriveKeys } from '../keys/index.js';
import { type PartialAddress } from '../types/partial_address.js';
import { PublicKeys } from '../types/public_keys.js';

Expand Down Expand Up @@ -36,14 +35,10 @@ export class CompleteAddress {
}

static fromSecretKeyAndPartialAddress(secretKey: Fr, partialAddress: Fr): CompleteAddress {
const { publicKeys, masterIncomingViewingSecretKey } = deriveKeys(secretKey);
const preaddress = computePreaddress(publicKeys.hash(), partialAddress);
const { publicKeys } = deriveKeys(secretKey);
const address = computeAddress(publicKeys, partialAddress);

const addressSecret = masterIncomingViewingSecretKey.add(new Fq(preaddress.toBigInt()));

const addressPoint = derivePublicKeyFromSecretKey(addressSecret);

return new CompleteAddress(AztecAddress.fromField(addressPoint.x), publicKeys, partialAddress);
return new CompleteAddress(address, publicKeys, partialAddress);
}

getPreaddress() {
Expand All @@ -60,12 +55,9 @@ export class CompleteAddress {

/** Throws if the address is not correctly derived from the public key and partial address.*/
public validate() {
const expectedPreAddress = computePreaddress(this.publicKeys.hash(), this.partialAddress);
const expectedPreAddressPoint = derivePublicKeyFromSecretKey(new Fq(expectedPreAddress.toBigInt()));

const expectedAddress = new Grumpkin().add(expectedPreAddressPoint, this.publicKeys.masterIncomingViewingPublicKey);
const expectedAddress = computeAddress(this.publicKeys, this.partialAddress);

if (!AztecAddress.fromField(expectedAddress.x).equals(this.address)) {
if (!AztecAddress.fromField(expectedAddress).equals(this.address)) {
throw new Error(
`Address cannot be derived from public keys and partial address (received ${this.address.toString()}, derived ${expectedAddress.toString()})`,
);
Expand Down

0 comments on commit 300de7f

Please sign in to comment.