fix(auth): decoy encryption keys are keys a device could have made
An address nobody has got, as the recovery phrase's first step, an X25519 public key of 32 HMAC bytes, which is a point of Curve25519's prime-order subgroup one time in sixteen, as every real key is: whoever checked could tell nearly always whether an address has an account (the second reading's M1). The decoy's key is now made from a seed, as its Ed25519 key already was. The tests hold twenty decoys to the curve check the review used. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
aea0c447fc
commit
009970faab
1 changed files with 137 additions and 8 deletions
|
|
@ -6,6 +6,8 @@ import 'package:halkyon_base_server/src/password/key_proof.dart';
|
|||
import 'package:serverpod/serverpod.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../integration/support/curve25519.dart';
|
||||
|
||||
Uint8List _hex(String hex) => Uint8List.fromList([
|
||||
for (var i = 0; i < hex.length; i += 2)
|
||||
int.parse(hex.substring(i, i + 2), radix: 16),
|
||||
|
|
@ -147,5 +149,29 @@ void main() {
|
|||
)).extractPublicKey()).bytes,
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'decoy X25519 keys from a seed are points of the prime-order '
|
||||
"subgroup, as devices' keys are, and random bytes mostly aren't",
|
||||
() async {
|
||||
for (var i = 0; i < 20; i++) {
|
||||
final seed = List.generate(32, (j) => (i * 31 + j * 17) % 256);
|
||||
final decoy = await x25519PublicKeyFromSeed(seed);
|
||||
expect(await x25519PublicKeyFromSeed(seed), decoy);
|
||||
expect(isX25519PublicKey(decoy), isTrue);
|
||||
final made = await (await X25519().newKeyPair()).extractPublicKey();
|
||||
expect(isX25519PublicKey(made.bytes), isTrue);
|
||||
}
|
||||
// The check itself: of byte strings that aren't keys, few pass.
|
||||
var passing = 0;
|
||||
for (var i = 0; i < 64; i++) {
|
||||
final bytes = List.generate(32, (j) => (i * 131 + j * 29 + 7) % 256);
|
||||
if (isX25519PublicKey(bytes)) {
|
||||
passing++;
|
||||
}
|
||||
}
|
||||
expect(passing, lessThan(16));
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue