diff --git a/.changeset/curly-lemons-act.md b/.changeset/curly-lemons-act.md new file mode 100644 index 0000000000000..6dd4cfefca8f5 --- /dev/null +++ b/.changeset/curly-lemons-act.md @@ -0,0 +1,5 @@ +--- +'@mysten/zklogin': patch +--- + +Remove BCS export and introduce new getZkSignature export. diff --git a/apps/wallet/src/background/accounts/zk/ZkAccount.ts b/apps/wallet/src/background/accounts/zk/ZkAccount.ts index f56bbf30904b2..f99dec4328c35 100644 --- a/apps/wallet/src/background/accounts/zk/ZkAccount.ts +++ b/apps/wallet/src/background/accounts/zk/ZkAccount.ts @@ -4,11 +4,9 @@ import { type SerializedSignature, type ExportedKeypair, - SIGNATURE_SCHEME_TO_FLAG, toSerializedSignature, } from '@mysten/sui.js/cryptography'; -import { fromB64, toB64 } from '@mysten/sui.js/utils'; -import { computeZkAddress, zkBcs } from '@mysten/zklogin'; +import { computeZkAddress, getZkSignature } from '@mysten/zklogin'; import { blake2b } from '@noble/hashes/blake2b'; import { decodeJwt } from 'jose'; import { getCurrentEpoch } from './current-epoch'; @@ -230,25 +228,13 @@ export class ZkAccount } const { ephemeralKeyPair, proofs, maxEpoch } = credentials; const keyPair = fromExportedKeypair(ephemeralKeyPair); + const userSignature = toSerializedSignature({ signature: await keyPair.sign(digest), signatureScheme: keyPair.getKeyScheme(), publicKey: keyPair.getPublicKey(), }); - const bytes = zkBcs - .ser( - 'ZkSignature', - { - inputs: proofs, - max_epoch: maxEpoch, - user_signature: fromB64(userSignature), - }, - { maxSize: 2048 }, - ) - .toBytes(); - const signatureBytes = new Uint8Array(bytes.length + 1); - signatureBytes.set([SIGNATURE_SCHEME_TO_FLAG['Zk']]); - signatureBytes.set(bytes, 1); - return toB64(signatureBytes); + + return getZkSignature({ inputs: proofs, maxEpoch, userSignature }); } } diff --git a/sdk/zklogin/src/address.ts b/sdk/zklogin/src/address.ts index fe1ca7e7b01ad..fce52fde906c5 100644 --- a/sdk/zklogin/src/address.ts +++ b/sdk/zklogin/src/address.ts @@ -11,13 +11,7 @@ import { genAddressSeed, toBufferBE } from './utils.js'; export function jwtToAddress(jwt: string, userSalt: bigint) { const decodedJWT = decodeJwt(jwt); - if ( - !decodedJWT.sub || - !decodedJWT.iss || - !decodedJWT.aud || - !decodedJWT.email || - typeof decodedJWT.email !== 'string' - ) { + if (!decodedJWT.sub || !decodedJWT.iss || !decodedJWT.aud) { throw new Error('Missing jwt data'); } diff --git a/sdk/zklogin/src/bcs.ts b/sdk/zklogin/src/bcs.ts index 897e3fbb18e24..c76e556e9a17b 100644 --- a/sdk/zklogin/src/bcs.ts +++ b/sdk/zklogin/src/bcs.ts @@ -1,7 +1,8 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -import { BCS } from '@mysten/bcs'; +import { BCS, fromB64, toB64 } from '@mysten/bcs'; +import { SIGNATURE_SCHEME_TO_FLAG } from '@mysten/sui.js/cryptography'; import { bcs } from '@mysten/sui.js/bcs'; export const zkBcs = new BCS(bcs); @@ -17,6 +18,31 @@ zkBcs.registerStructType('ZkClaim', { index_mod_4: BCS.U8, }); +type Claim = { + name: string; + value_base64: string; + index_mod_4: number; +}; + +export interface ProofPoints { + pi_a: string[]; + pi_b: string[][]; + pi_c: string[]; +} + +export interface ZkSignatureInputs { + proof_points: ProofPoints; + address_seed: string; + claims: Claim[]; + header_base64: string; +} + +export interface ZkSignature { + inputs: ZkSignatureInputs; + maxEpoch: number; + userSignature: string | Uint8Array; +} + zkBcs.registerStructType('ZkSignature', { inputs: { proof_points: { @@ -31,3 +57,25 @@ zkBcs.registerStructType('ZkSignature', { max_epoch: BCS.U64, user_signature: [BCS.VECTOR, BCS.U8], }); + +function getZkSignatureBytes({ inputs, maxEpoch, userSignature }: ZkSignature) { + return zkBcs + .ser( + 'ZkSignature', + { + inputs, + max_epoch: maxEpoch, + user_signature: typeof userSignature === 'string' ? fromB64(userSignature) : userSignature, + }, + { maxSize: 2048 }, + ) + .toBytes(); +} + +export function getZkSignature({ inputs, maxEpoch, userSignature }: ZkSignature) { + const bytes = getZkSignatureBytes({ inputs, maxEpoch, userSignature }); + const signatureBytes = new Uint8Array(bytes.length + 1); + signatureBytes.set([SIGNATURE_SCHEME_TO_FLAG['Zk']]); + signatureBytes.set(bytes, 1); + return toB64(signatureBytes); +} diff --git a/sdk/zklogin/src/index.ts b/sdk/zklogin/src/index.ts index 652bbcaf03ae0..bf699cc400aa5 100644 --- a/sdk/zklogin/src/index.ts +++ b/sdk/zklogin/src/index.ts @@ -4,7 +4,7 @@ export { computeZkAddress, jwtToAddress } from './address.js'; export type { ComputeZKAddressOptions } from './address.js'; -export { zkBcs } from './bcs.js'; +export { getZkSignature } from './bcs.js'; export { poseidonHash } from './poseidon.js';