-
Notifications
You must be signed in to change notification settings - Fork 259
fix: Ensure passkey-derived keys are always treated as ed25519
#1625
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Ensure passkey-derived keys are always treated as ed25519
#1625
Conversation
- Introduce `makeEd25519KeyString` helper to prepend the required prefix - Update all call sites to use the helper when creating or retrieving KeyPair from passkey data - Add regression test to ensure KeyPair.fromString parses correctly - Test verifies that bare keys fail and prefixed keys succeed
🦋 Changeset detectedLatest commit: c0e8c19 The changes in this PR will be included in the next version bump. This PR includes changesets to release 15 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
hey, @SmolinPavel thanks for contributing and highlighting the issue! the idea looks good to me, though I'd like to tweak the implementation slightly, since we know the output key will always be as for the tests, we don't really have proper tests for this functionality yet, so if you have time/ability, it'd really valuable to add some that cover |
@@ -87,7 +87,7 @@ export const createKey = async (username: string): Promise<KeyPair> => { | |||
const publicKeyBytes = get64BytePublicKeyFromPEM(publicKey); | |||
const secretKey = sha256.create().update(Buffer.from(publicKeyBytes)).digest(); | |||
const pubKey = ed25519.getPublicKey(secretKey); | |||
return KeyPair.fromString(baseEncode(new Uint8Array(Buffer.concat([Buffer.from(secretKey), Buffer.from(pubKey)]))) as KeyPairString); | |||
return KeyPair.fromString(makeEd25519KeyString(secretKey, pubKey)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's change that to new KeyPairEd25519
const firstKeyPair = KeyPair.fromString(baseEncode(new Uint8Array(Buffer.concat([Buffer.from(firstEDSecret), Buffer.from(firstEDPublic)]))) as KeyPairString); | ||
const secondKeyPair = KeyPair.fromString(baseEncode(new Uint8Array(Buffer.concat([Buffer.from(secondEDSecret), Buffer.from(secondEDPublic)]))) as KeyPairString); | ||
const firstKeyPair = KeyPair.fromString(makeEd25519KeyString(firstEDSecret, firstEDPublic)); | ||
const secondKeyPair = KeyPair.fromString(makeEd25519KeyString(secondEDSecret, secondEDPublic)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the same as above
ed25519
This PR addresses a bug in
@near-js/biometric-ed25519
where passkey-derived key strings were not prefixed withed25519:
, causingKeyPair.fromString
to throw errors:The change ensures that all passkey-derived keys are properly prefixed, and adds a regression test to prevent future regressions.
Pre-flight checklist
pnpm changeset
to create achangeset
JSON document appropriate for this change.Motivation
The bug was caused by legacy behavior in
@near-js/biometric-ed25519
where KeyPair.fromString was sometimes called with a raw base-encoded secret+public key string.Legacy behavior (pre-fix) allowed KeyPairEd25519 to be constructed from a single-part string:
See pre-fix state for reference.
The update introduced in #1355 made param to be
KeyPairString
, assuming there is always a prefix.The update introduced in this PR enforces the prefix explicitly, ensuring compatibility with
KeyPair.fromString
and making the behavior consistent and predictable.Test Plan
The regression tests were added, making sure that the call to
KeyPair.fromString
will fail without the ed25519 prefix, while the one with the prefix will work.Related issues/PRs
#1355