Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: deriveAddressSeed and deriveAddress utilities #1265

Merged
merged 1 commit into from
Oct 1, 2024

Conversation

vadorovsky
Copy link
Contributor

@vadorovsky vadorovsky commented Sep 27, 2024

Problems

  • The distinction between derive_address_seed and derive_address was
    unclear and we were inconsistent in it:
    • We ended up applying address Merkle tree public key in both
      functions, which is confusing.
  • Before this change, there was no TypeScript function for deriving
    address seed. There was only deriveAddress, but deriving the
    unified seed was a mystery for developers.
  • We have two utilities for hashing and truncating to BN254:
    • hash_to_bn254_field_size_be - the older one, which:
      • Searches for a bump in a loop, adds it to the hash inputs and then
        truncates the hash. That doesn't make sense, because truncating
        the hash should be sufficient, adding a bump is unnecessary.
      • Another limitation is that it takes only one sequence of bytes,
        making it difficult to provide multiple inputs without
        concatenating them.
    • hashv_to_bn254_field_size - the newer one, which:
      • Just truncates the hash result, without the bump mechanism.
      • Takes 2D byte slice as input, making it possible to pass multiple
        inputs.

Changes

  • Don't add MT pubkey in derive_address_seed. It's not a correct place
    for it to be applied. The distinction between derive_address_seed
    and derive_address should be:
    • derive_address_seed takes provided seeds (defined by the
      developer) and hashes them together with the program ID. This
      operation is done only in the third-party program.
    • derive_address takes the address seed (result of
      address_address_seed) and hashes it together with the address
      Merkle tree public key. This is done both in the third-party program
      and in light-system-program. light-system-program does that as a
      check whether the correct Merkle tree is used.
  • Adjust the stateless.js API:
    • Provide deriveAddressSeed function.
    • Add unit tests, make sure that deriveAddressSeed and
      deriveAddress provide the same results as the equivalent functions
      in Rust SDK.

Copy link
Contributor

@SwenSchaeferjohann SwenSchaeferjohann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, just needs the name_service program adjusted

@@ -66,19 +66,12 @@ pub fn pack_new_address_params(
/// &address_merkle_context,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment is not adapted

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, done

@vadorovsky vadorovsky marked this pull request as draft September 30, 2024 08:58
@vadorovsky vadorovsky changed the title fix: Don't add MT pubkey in derive_address_seed refactor: deriveAddressSeed and deriveAddress utilities Sep 30, 2024
@vadorovsky vadorovsky force-pushed the derive-address branch 3 times, most recently from 74b20a2 to ca4a6aa Compare September 30, 2024 10:56
@vadorovsky vadorovsky marked this pull request as ready for review September 30, 2024 11:49
@vadorovsky vadorovsky force-pushed the derive-address branch 5 times, most recently from 1d4c8b8 to 862b455 Compare September 30, 2024 15:14
@@ -12,13 +21,13 @@ import { getIndexOrAdd } from '../instruction';
* defaultTestStateTreeAccounts().merkleTree
* @returns Derived address
*/
export async function deriveAddress(
export function deriveAddress(
seed: Uint8Array,
merkleTreePubkey: PublicKey = defaultTestStateTreeAccounts().merkleTree,
Copy link

@me-imfhd me-imfhd Sep 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: shouldn't the default be addressTree ('amt...') instead of merkleTree sorry

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it should, good catch.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, btw the comment is not consistent in the next commit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. I also updated the variable name now to make it crystal clear it's address Merkle tree.

@vadorovsky vadorovsky force-pushed the derive-address branch 4 times, most recently from c16ca85 to 078508a Compare October 1, 2024 06:45
**Problems**

- The distinction between `derive_address_seed` and `derive_address` was
  unclear and we were inconsistent in it:
  - We ended up applying address Merkle tree public key in both
    functions, which is confusing.
- Before this change, there was no TypeScript function for deriving
  **address seed**. There was only `deriveAddress`, but deriving the
  unified seed was a mystery for developers.
- We have two utilities for hashing and truncating to BN254:
  - `hash_to_bn254_field_size_be` - the older one, which:
    - Searches for a bump in a loop, adds it to the hash inputs and then
      truncates the hash. That doesn't make sense, because truncating
      the hash should be sufficient, adding a bump is unnecessary.
    - Another limitation is that it takes only one sequence of bytes,
      making it difficult to provide multiple inputs without
      concatenating them.
  - `hashv_to_bn254_field_size` - the newer one, which:
    - Just truncates the hash result, without the bump mechanism.
    - Takes 2D byte slice as input, making it possible to pass multiple
      inputs.

**Changes**

- Don't add MT pubkey in `derive_address_seed`. It's not a correct place
  for it to be applied. The distinction between `derive_address_seed`
  and `derive_address` should be:
  - `derive_address_seed` takes provided seeds (defined by the
    developer) and hashes them together with the program ID. This
    operation is done only in the third-party program.
  - `derive_address` takes the address seed (result of
    `address_address_seed`) and hashes it together with the address
    Merkle tree public key. This is done both in the third-party program
    and in light-system-program. light-system-program does that as a
    check whether the correct Merkle tree is used.
- Adjust the stateless.js API:
  - Provide `deriveAddressSeed` function.
  - Add unit tests, make sure that `deriveAddressSeed` and
    `deriveAddress` provide the same results as the equivalent functions
    in Rust SDK.
@SwenSchaeferjohann SwenSchaeferjohann merged commit 49ca247 into main Oct 1, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants