dvWebPushSignEs256 function
ES256 over message with a P-256 privateKey, as JWS wants it.
A raw, fixed-width r||s pair of 64 bytes — not the DER encoding a general
ECDSA signer emits. DER trims leading zero bytes and wraps the pair in a
sequence, so a DER signature is both a different length and a different
shape, and every push service answers one with a 401.
k is derived from the key and the message per RFC 6979 rather than drawn from an entropy source. That is a security property first: a repeated or predictable k leaks the private key, and ECDSA has lost keys that way. It makes the output reproducible second, which is what lets the signature be pinned to RFC 6979's published vectors instead of only round-tripped through this library's own verifier.
Public because it is the security-critical primitive under VAPID and is worth asserting on directly.
Implementation
Uint8List dvWebPushSignEs256(List<int> message, Uint8List privateKey) {
final domain = ECDomainParameters('prime256v1');
final signer = ECDSASigner(SHA256Digest(), HMac(SHA256Digest(), 64))
..init(
true,
PrivateKeyParameter<ECPrivateKey>(
ECPrivateKey(_bigIntFromBytes(privateKey), domain),
),
);
final signature =
signer.generateSignature(Uint8List.fromList(message)) as ECSignature;
return Uint8List.fromList(<int>[
..._fixedWidthBytes(signature.r, 32),
..._fixedWidthBytes(signature.s, 32),
]);
}