Stage 5a: ECDSA on P-256, P-384 and P-521, and RSA
nist_curves.dart reads an uncompressed point as Go's
ecdsa.ParseUncompressedPublicKey does, and computes u1 G + u2 Q in
Jacobian coordinates with Shamir's trick, the infinity included.
ecdsa.dart is VerifyASN1: the encoding as cryptobyte reads it, r and s
in [1, n - 1] and never reduced, s above n/2 accepted, the hash cut to
the bits of the order. rsa.dart is VerifyPKCS1v15, which rebuilds the
encoding and compares it whole, and VerifyPSS with a salt of the length
of the hash, with the bytes before emLen that must be zero; and the
hashes of the table, SHA-256, SHA-384 and SHA-512 of package:crypto.
All on BigInt, exact on the VM and compiled to JavaScript, and not
constant-time: a verification sees public values only. The curve
constants are those that the vectors record from Go.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 days ago
|
|
|
// The differential of ECDSA and RSA against the Go reference on the VM,
|
|
|
|
|
// with every case of test/vectors/cms_ecdsa.json and cms_rsa.json. And the
|
|
|
|
|
// part of the files test/vectors/cms_*.json that cms_vectors.g.dart holds
|
|
|
|
|
// for the tests compiled to JavaScript: for each section, the cases whose
|
|
|
|
|
// index is a multiple of the step that "every" gives.
|
Stage 5a: the vectors of Go for the CMS reader, ECDSA and RSA
tool/cms_go_vectors_test.go records what internal/cms of datekeys-go at
c531e93 (the draft v0.12) and the ECDSA and RSA of Go give: the curves,
points and signatures of ecdsa.VerifyASN1; RSA keys of 2048 to 4096 bits
and signatures of rsa.VerifyPKCS1v15 and VerifyPSS, with encodings built
by hand, each with one defect of its padding; ParseCert, ParseSignature,
SignerInfo.Check, ParseToken and Token.Check on the cases of the tests of
internal/cms and others (identifiers whose arcs wrap around in 32 or 64
bits, SET OF with an element repeated, the limits of the accuracy and of
the imprint, the ends of the validity); signatures, tokens and
certificates edited node by node and bit by bit; and every signature and
token of security_cms.json and of the two CMS fixtures, signer by signer.
It runs as a test in an export of datekeys-go, so that it can import
internal/cms and make keys and signatures deterministic with
testing/cryptotest: every run writes the same bytes. Each file stays
under 560 KB; repeated certificates are written once per file.
cms_vectors.g.dart holds a part of each file for the tests compiled to
JavaScript, and a test on the VM checks that it is that part.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 days ago
|
|
|
@TestOn('vm')
|
|
|
|
|
library;
|
|
|
|
|
|
|
|
|
|
import 'dart:convert';
|
|
|
|
|
import 'dart:io';
|
|
|
|
|
|
|
|
|
|
import 'package:test/test.dart';
|
|
|
|
|
|
|
|
|
|
import 'cms_support.dart';
|
|
|
|
|
import 'vectors/cms_vectors.g.dart';
|
|
|
|
|
|
|
|
|
|
const _embedded = {
|
|
|
|
|
'ecdsa': cmsEcdsaJson,
|
|
|
|
|
'rsa': cmsRsaJson,
|
|
|
|
|
'certs': cmsCertsJson,
|
|
|
|
|
'signatures': cmsSignaturesJson,
|
|
|
|
|
'algorithms': cmsAlgorithmsJson,
|
|
|
|
|
'tokens': cmsTokensJson,
|
|
|
|
|
'mutations': cmsMutationsJson,
|
|
|
|
|
'corpus': cmsCorpusJson,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void main() {
|
|
|
|
|
final files = {
|
|
|
|
|
for (final n in cmsFiles)
|
|
|
|
|
n: jsonDecode(
|
|
|
|
|
File('test/vectors/cms_$n.json').readAsStringSync(),
|
|
|
|
|
) as Json,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
test('every file is of the draft v0.12 and of its generator', () {
|
|
|
|
|
for (final f in files.values) {
|
|
|
|
|
expect(f['spec'], '0.12 draft');
|
|
|
|
|
expect(f['generator'], startsWith('tool/cms_go_vectors_test.go, go'));
|
|
|
|
|
expect(f['source'], startsWith('datekeys-go c531e93'));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
group('cms_vectors.g.dart', () {
|
|
|
|
|
for (final n in cmsFiles) {
|
|
|
|
|
test('holds the part of cms_$n.json of its steps', () {
|
|
|
|
|
final full = files[n]!;
|
|
|
|
|
final part = jsonDecode(_embedded[n]!) as Json;
|
|
|
|
|
final every = part['every']! as Json;
|
|
|
|
|
expect(part.keys.toSet(), {...full.keys, 'every'});
|
|
|
|
|
for (final MapEntry(:key, :value) in full.entries) {
|
|
|
|
|
final step = every[key] as int?;
|
|
|
|
|
if (step == null) {
|
|
|
|
|
expect(part[key], value, reason: key);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
expect(part[key], [
|
|
|
|
|
for (final (i, c) in (value! as List).indexed)
|
|
|
|
|
if (step != 0 && i % step == 0) c,
|
|
|
|
|
], reason: key);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
Stage 5a: ECDSA on P-256, P-384 and P-521, and RSA
nist_curves.dart reads an uncompressed point as Go's
ecdsa.ParseUncompressedPublicKey does, and computes u1 G + u2 Q in
Jacobian coordinates with Shamir's trick, the infinity included.
ecdsa.dart is VerifyASN1: the encoding as cryptobyte reads it, r and s
in [1, n - 1] and never reduced, s above n/2 accepted, the hash cut to
the bits of the order. rsa.dart is VerifyPKCS1v15, which rebuilds the
encoding and compares it whole, and VerifyPSS with a salt of the length
of the hash, with the bytes before emLen that must be zero; and the
hashes of the table, SHA-256, SHA-384 and SHA-512 of package:crypto.
All on BigInt, exact on the VM and compiled to JavaScript, and not
constant-time: a verification sees public values only. The curve
constants are those that the vectors record from Go.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 days ago
|
|
|
|
|
|
|
|
group('ECDSA', () => ecdsaTests(files['ecdsa']!));
|
|
|
|
|
group('RSA', () => rsaTests(files['rsa']!));
|
Stage 5a: the vectors of Go for the CMS reader, ECDSA and RSA
tool/cms_go_vectors_test.go records what internal/cms of datekeys-go at
c531e93 (the draft v0.12) and the ECDSA and RSA of Go give: the curves,
points and signatures of ecdsa.VerifyASN1; RSA keys of 2048 to 4096 bits
and signatures of rsa.VerifyPKCS1v15 and VerifyPSS, with encodings built
by hand, each with one defect of its padding; ParseCert, ParseSignature,
SignerInfo.Check, ParseToken and Token.Check on the cases of the tests of
internal/cms and others (identifiers whose arcs wrap around in 32 or 64
bits, SET OF with an element repeated, the limits of the accuracy and of
the imprint, the ends of the validity); signatures, tokens and
certificates edited node by node and bit by bit; and every signature and
token of security_cms.json and of the two CMS fixtures, signer by signer.
It runs as a test in an export of datekeys-go, so that it can import
internal/cms and make keys and signatures deterministic with
testing/cryptotest: every run writes the same bytes. Each file stays
under 560 KB; repeated certificates are written once per file.
cms_vectors.g.dart holds a part of each file for the tests compiled to
JavaScript, and a test on the VM checks that it is that part.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 days ago
|
|
|
}
|