Skip to content

Commit

Permalink
Fix string values in zk (MystenLabs#14265)
Browse files Browse the repository at this point in the history
## Description 

Describe the changes or additions included in this PR.

## Test Plan 

How did you test the new or updated feature?

---
If your changes are not user-facing and not a breaking change, you can
skip the following section. Otherwise, please indicate what changed, and
then add to the Release Notes section as highlighted during the release
process.

### Type of Change (Check all that apply)

- [ ] protocol change
- [ ] user-visible impact
- [ ] breaking change for a client SDKs
- [ ] breaking change for FNs (FN binary must upgrade)
- [ ] breaking change for validators or node operators (must upgrade
binaries)
- [ ] breaking change for on-chain data layout
- [ ] necessitate either a data wipe or data migration

### Release notes
  • Loading branch information
Jordan-Mysten authored Oct 13, 2023
1 parent 01a9727 commit 9a1c810
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 14 deletions.
5 changes: 5 additions & 0 deletions .changeset/tall-doors-guess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@mysten/zklogin': patch
---

Fix usage of string values in the SDK
14 changes: 3 additions & 11 deletions sdk/zklogin/src/nonce.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,26 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

import { toB64, toHEX } from '@mysten/bcs';
import { PublicKey } from '@mysten/sui.js/cryptography';
import { toBigEndianBytes } from '@mysten/sui.js/zklogin';
import { randomBytes } from '@noble/hashes/utils';
import { base64url } from 'jose';

import { poseidonHash } from './poseidon.js';
import { toBigIntBE } from './utils.js';

const NONCE_LENGTH = 27;

function toBigIntBE(bytes: Uint8Array) {
const hex = toHEX(bytes);
if (hex.length === 0) {
return BigInt(0);
}
return BigInt(`0x${hex}`);
}

export function generateRandomness() {
// Once Node 20 enters LTS, we can just use crypto.getRandomValues(new Uint8Array(16)), but until then this improves compatibility:
return toB64(randomBytes(16));
return String(toBigIntBE(randomBytes(16)));
}

export function generateNonce(publicKey: PublicKey, maxEpoch: number, randomness: bigint | string) {
const publicKeyBytes = toBigIntBE(publicKey.toSuiBytes());
const eph_public_key_0 = publicKeyBytes / 2n ** 128n;
const eph_public_key_1 = publicKeyBytes % 2n ** 128n;
const bigNum = poseidonHash([eph_public_key_0, eph_public_key_1, maxEpoch, randomness]);
const bigNum = poseidonHash([eph_public_key_0, eph_public_key_1, maxEpoch, BigInt(randomness)]);
const Z = toBigEndianBytes(bigNum, 20);
const nonce = base64url.encode(Z);
if (nonce.length !== NONCE_LENGTH) {
Expand Down
14 changes: 11 additions & 3 deletions sdk/zklogin/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

import { toB64 } from '@mysten/bcs';
import { toHEX } from '@mysten/bcs';
import { PublicKey } from '@mysten/sui.js/cryptography';

import { poseidonHash } from './poseidon.js';
Expand All @@ -12,7 +12,15 @@ export const MAX_AUD_VALUE_LENGTH = 145;
const PACK_WIDTH = 248;

export function getExtendedEphemeralPublicKey(publicKey: PublicKey) {
return toB64(publicKey.toSuiBytes());
return String(toBigIntBE(publicKey.toSuiBytes()));
}

export function toBigIntBE(bytes: Uint8Array) {
const hex = toHEX(bytes);
if (hex.length === 0) {
return BigInt(0);
}
return BigInt(`0x${hex}`);
}

/**
Expand Down Expand Up @@ -71,6 +79,6 @@ export function genAddressSeed(
hashASCIIStrToField(name, max_name_length),
hashASCIIStrToField(value, max_value_length),
hashASCIIStrToField(aud, max_aud_length),
poseidonHash([salt]),
poseidonHash([BigInt(salt)]),
]);
}
19 changes: 19 additions & 0 deletions sdk/zklogin/test/nonce.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

import { expect, test } from 'vitest';

import { Ed25519Keypair } from '../../typescript/src/keypairs/ed25519';
import { generateNonce, generateRandomness } from '../src';

test('can generate using `generateRandomness`', () => {
const kp = Ed25519Keypair.fromSecretKey(new Uint8Array(32));
const randomness = generateRandomness();
expect(generateNonce(kp.getPublicKey(), 0, randomness)).toBeTypeOf('string');
});

test('can generate using a bigint', () => {
const kp = Ed25519Keypair.fromSecretKey(new Uint8Array(32));
const randomness = 0n;
expect(generateNonce(kp.getPublicKey(), 0, randomness)).toBeTypeOf('string');
});

0 comments on commit 9a1c810

Please sign in to comment.