@typedstandards/verify-core 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -190,7 +190,13 @@ export function verifyCheckpointSignature(checkpoint, anchors) {
190
190
  continue;
191
191
  try {
192
192
  const point = extractP256Point(anchor.publicKeyDer);
193
- if (p256.verify(sig.sig, checkpoint.signedBody, point, { format: 'der' })) {
193
+ // `lowS: false`: the log signer may emit a high-S checkpoint signature; low-S
194
+ // is a signing-side malleability convention, not a verification rule, so a
195
+ // verifier must accept both S and n−S (see the rfc3161.ts note — a real high-S
196
+ // TSA token exposed this default). We only ask "did this log key sign this
197
+ // checkpoint". (`@noble` prehashes with the curve hash by default, so the note
198
+ // body is passed as the message.)
199
+ if (p256.verify(sig.sig, checkpoint.signedBody, point, { format: 'der', lowS: false })) {
194
200
  return { verified: true, origin: anchor.origin, keyHint: hint };
195
201
  }
196
202
  }
package/dist/rfc3161.js CHANGED
@@ -213,7 +213,13 @@ export function verifyRfc3161Timestamp(tokenB64, expectedHashHex, anchors = FREE
213
213
  for (const anchor of anchors) {
214
214
  try {
215
215
  const point = extractP384Point(anchor.signingKeyDer);
216
- if (p384.verify(token.signature, digest, point, { format: 'der', prehash: false })) {
216
+ // `lowS: false` is REQUIRED here: low-S is a signature-malleability convention
217
+ // for SIGNING, not a validity rule. A TSA (like FreeTSA) legitimately emits
218
+ // high-S ECDSA signatures (~half of them); `@noble`'s default `lowS: true`
219
+ // would false-negative those (it rejected the real high-S da9246 token —
220
+ // regression-tested). Accepting high-S is correct: both S and n−S are valid
221
+ // signatures by the same key, and we only ask "did this TSA sign this hash".
222
+ if (p384.verify(token.signature, digest, point, { format: 'der', prehash: false, lowS: false })) {
217
223
  matched = anchor;
218
224
  break;
219
225
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typedstandards/verify-core",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Portable, browser-safe verification core for Typed Standards evidence packages — the §9.2 check suite, single-sourced so it verifies identically on a server and in the browser.",
5
5
  "license": "MIT",
6
6
  "author": "Nathan Storey",