generateNonce function
Generates the zkLogin nonce that commits to the ephemeral publicKey, the
maxEpoch until which it is valid, and a randomness value.
randomness may be either a decimal String (as returned by
generateRandomness) or a BigInt; any other type throws an
ArgumentError. Throws an Exception if the derived nonce is not
NONCE_LENGTH characters long.
Implementation
String generateNonce(PublicKey publicKey, int maxEpoch, dynamic randomness) {
final publicKeyBytes = toBigIntBE(publicKey.toSuiBytes());
final ephPublicKey0 = publicKeyBytes ~/ BigInt.two.pow(128);
final ephPublicKey1 = publicKeyBytes % BigInt.two.pow(128);
BigInt bigNum;
if (randomness is String) {
bigNum = poseidonHash([
ephPublicKey0,
ephPublicKey1,
BigInt.from(maxEpoch),
BigInt.parse(randomness),
]);
} else if (randomness is BigInt) {
bigNum = poseidonHash([
ephPublicKey0,
ephPublicKey1,
BigInt.from(maxEpoch),
randomness,
]);
} else {
throw ArgumentError(
'Invalid type for randomness. It should be either BigInt or String.',
);
}
final z = toBigEndianBytes(bigNum, 20);
final nonce = base64UrlEncode(
z,
).replaceAll('=', '').replaceAll('+', '-').replaceAll('/', '_');
if (nonce.length != NONCE_LENGTH) {
throw Exception(
'Length of nonce $nonce (${nonce.length}) is not equal to $NONCE_LENGTH',
);
}
return nonce;
}