signWithWire static method
Future<({Uint8List sessionId, Uint8List signature, List<MlDsaSigningMessage> wireMessages})>
signWithWire({})
Threshold-sign and export Mithril wire round payloads (M3 beta).
Returns the combined signature plus canonical MlDsaSigningMessage values
for dir-transport under round1/, round2/, round3/.
Implementation
static Future<({
Uint8List signature,
Uint8List sessionId,
List<MlDsaSigningMessage> wireMessages,
})> signWithWire({
required List<MlDsaShare> shares,
required Uint8List message,
Uint8List? context,
String? mithrilBridgePath,
}) async {
assertMlDsaShareSetConsistent(shares);
final params = shares.first.params;
if (params.scheme != SchemeId.mlDsa44ThresholdV1) {
throw SchemeNotImplemented(
'M2 Mithril bridge supports mlDsa44ThresholdV1 only; got ${params.scheme}',
);
}
if (shares.length < params.t) {
throw InsufficientShares(
'Need at least ${params.t} shares, got ${shares.length}',
);
}
final publicKeyBytes = await _derivePublicKey(
params: params,
ceremonySeed: shares.first.ceremonySeedBytes(),
mithrilBridgePath: mithrilBridgePath,
);
final publicKey = MlDsaPublicKey.create(
params: params,
ceremonyId: shares.first.ceremonyId,
publicKeyBytes: publicKeyBytes,
);
final active = shares
.take(params.t)
.map((s) => s.mithrilPartyId)
.toList()
..sort();
final wire = await mithrilWireSign(
t: params.t,
n: params.n,
ceremonySeed: shares.first.ceremonySeedBytes(),
activePartyIdsZeroBased: active,
message: message,
executablePath: mithrilBridgePath,
);
if (!MlDsaThresholdVerifier.verify(
scheme: params.scheme,
publicKey: publicKey.bytes,
message: message,
signature: wire.signature,
context: context,
)) {
throw InvalidPartialSignature('Mithril wire_sign produced invalid signature');
}
final wireMessages = mlDsaMessagesFromWireSignJson(
params: params,
ceremonyId: shares.first.ceremonyId,
sessionId: wire.sessionId,
wireJson: wire.wireJson,
);
return (
signature: wire.signature,
sessionId: wire.sessionId,
wireMessages: wireMessages,
);
}