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
2 changed files with 137 additions and 8 deletions
|
|
@ -51,3 +51,12 @@ Future<Uint8List> ed25519PublicKeyFromSeed(List<int> seed) async {
|
|||
final pair = await Ed25519().newKeyPairFromSeed(seed);
|
||||
return Uint8List.fromList((await pair.extractPublicKey()).bytes);
|
||||
}
|
||||
|
||||
/// An X25519 public key made from [seed] (32 bytes, clamped as a scalar): a
|
||||
/// decoy's, which is a point of the prime-order subgroup as an account's
|
||||
/// is; random bytes would be one only one time in sixteen, telling a decoy
|
||||
/// from an account.
|
||||
Future<Uint8List> x25519PublicKeyFromSeed(List<int> seed) async {
|
||||
final pair = await X25519().newKeyPairFromSeed(seed);
|
||||
return Uint8List.fromList((await pair.extractPublicKey()).bytes);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1086,8 +1086,9 @@ Uint8List _decoyBytes(
|
|||
);
|
||||
|
||||
/// An address nobody has's keys, as a key proof's first step shows them:
|
||||
/// an X25519 public key (its top bit clear, as a point's u is), an Ed25519
|
||||
/// one made from a seed, and wrapped keys of an account's length; and the
|
||||
/// X25519 and Ed25519 public keys made from seeds, so each is a point a
|
||||
/// device's key could be (random bytes mostly aren't, which told a decoy
|
||||
/// from an account), and wrapped keys of an account's length; and the
|
||||
/// phrase's proof key its second step checks against. Computed for every
|
||||
/// proof begun, an account's too.
|
||||
Future<
|
||||
|
|
@ -1100,12 +1101,9 @@ Future<
|
|||
})
|
||||
>
|
||||
_decoyKeys(String decoyKey, String hash) async => (
|
||||
encryptionPublicKey: _decoyBytes(
|
||||
decoyKey,
|
||||
'encryption key',
|
||||
hash,
|
||||
_publicKeyLength,
|
||||
)..[_publicKeyLength - 1] &= 0x7f,
|
||||
encryptionPublicKey: await x25519PublicKeyFromSeed(
|
||||
_decoyBytes(decoyKey, 'encryption seed', hash, 32),
|
||||
),
|
||||
signingPublicKey: await ed25519PublicKeyFromSeed(
|
||||
_decoyBytes(decoyKey, 'signing seed', hash, 32),
|
||||
),
|
||||
|
|
|
|||
Loading…
Reference in a new issue