Skip to content

Commit

Permalink
Add method to get a ZK signature instead of relying on BCS (MystenLab…
Browse files Browse the repository at this point in the history
…s#13546)

## Description 

This will simplify a decent amount of the process.

## 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 Sep 6, 2023
1 parent b67dc3a commit 8384490
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 27 deletions.
5 changes: 5 additions & 0 deletions .changeset/curly-lemons-act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@mysten/zklogin': patch
---

Remove BCS export and introduce new getZkSignature export.
22 changes: 4 additions & 18 deletions apps/wallet/src/background/accounts/zk/ZkAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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 });
}
}
8 changes: 1 addition & 7 deletions sdk/zklogin/src/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}

Expand Down
50 changes: 49 additions & 1 deletion sdk/zklogin/src/bcs.ts
Original file line number Diff line number Diff line change
@@ -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);
Expand All @@ -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: {
Expand All @@ -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);
}
2 changes: 1 addition & 1 deletion sdk/zklogin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down

0 comments on commit 8384490

Please sign in to comment.