blsCreateProofFFI method
Future<Uint8List>
blsCreateProofFFI({
- required Uint8List publicKey,
- required Uint8List nonce,
- required Uint8List signature,
- required List<
ProofMessage> messages,
Creates a BBS+ proof using the BLS public key, nonce, signature, and messages.
This method leverages FFI calls to interact with the native BBS+ library for proof generation.
- Converts the provided BLS public key to a BBS public key before proceeding with the proof creation.
- Handles the allocation and deallocation of required memory during the FFI calls.
Implementation
Future<Uint8List> blsCreateProofFFI({
required Uint8List publicKey,
required Uint8List nonce,
required Uint8List signature,
required List<ProofMessage> messages,
}) {
// Convert publickey bls to bbs
final bbsPublicKey = blsPublicToBbsPublicKey(publicKey, messages.length);
Tools.logDebug('bbsPublicKey length = ${bbsPublicKey.length}');
Tools.logDebug('BBS public key (base64): ${base64.encode(bbsPublicKey)}');
final err1 = calloc<ExternError>();
final handle = bbs.bbsCreateProofContextInit(err1);
Tools.logDebug('handle init: $handle');
if (handle == 0) {
throw Exception('Unable to create proof context');
}
calloc.free(err1);
final publicKeyPtr = ByteArrayHelper.allocate(bbsPublicKey);
final err2 = calloc<ExternError>();
final result = bbs.bbsCreateProofContextSetPublicKey(
handle,
publicKeyPtr.ref,
err2,
);
Tools.logDebug('result bbsCreateProofContextSetPublicKey: $result');
calloc.free(publicKeyPtr.ref.data);
calloc.free(publicKeyPtr);
if (result != 0) {
throwIfError(result, err2, 'Unable to set public key');
}
calloc.free(err2);
final noncePtr = ByteArrayHelper.allocate(nonce); // nonce is Uint8List
final err3 = calloc<ExternError>();
final result1 = bbs.bbsCreateProofContextSetNonceBytes(
handle,
noncePtr.ref,
err3,
);
Tools.logDebug('result bbsCreateProofContextSetNonceBytes: $result1');
calloc.free(noncePtr.ref.data);
calloc.free(noncePtr);
if (result1 != 0) {
throwIfError(result1, err3, 'Unable to set nonce');
}
calloc.free(err3);
final sigPtr = ByteArrayHelper.allocate(signature); // signature: Uint8List
final err4 = calloc<ExternError>();
final result2 = bbs.bbsCreateProofContextSetSignature(
handle,
sigPtr.ref,
err4,
);
Tools.logDebug('result bbsCreateProofContextSetSignature: $result2');
calloc.free(sigPtr.ref.data);
calloc.free(sigPtr);
if (result2 != 0) {
throwIfError(result2, err4, 'Unable to set signature');
}
calloc.free(err4);
final err5 = calloc<ExternError>();
for (final msg in messages) {
final msgPtr = ByteArrayHelper.allocate(msg.message);
final blindPtr = ByteArrayHelper.allocate(msg.blindingFactor);
final result3 = bbs.bbsCreateProofContextAddProofMessageBytes(
handle,
msgPtr.ref,
msg.type,
blindPtr.ref,
err5,
);
calloc.free(msgPtr.ref.data);
calloc.free(msgPtr);
calloc.free(blindPtr.ref.data);
calloc.free(blindPtr);
if (result3 != 0) {
throwIfError(result3, err5, 'Unable to add proof message');
}
}
calloc.free(err5);
final proofSize = bbs.bbsCreateProofContextSize(handle);
Tools.logDebug('proofSize: $proofSize');
if (proofSize <= 0) {
throw Exception('Invalid proof size from bbs_create_proof_size()');
}
final proofPtr = calloc<ByteBuffer>();
final err6 = calloc<ExternError>();
final result4 = bbs.bbsCreateProofContextFinish(handle, proofPtr, err6);
Tools.logDebug('result bbsCreateProofContextFinish: $result4');
if (result4 != 0) {
calloc.free(proofPtr);
throwIfError(result4, err6, 'Unable to create proof');
}
calloc.free(err6);
final proofBytes = proofPtr.ref.data.asTypedList(proofPtr.ref.len);
calloc.free(proofPtr);
return Future.value(Uint8List.fromList(proofBytes));
}