Skip to content
This repository was archived by the owner on May 2, 2026. It is now read-only.

Replace JCE-based Ed25519 key generation with Tink#6

Merged
filinvadim merged 1 commit intomainfrom
claude/fix-warpdroid-crash-1t7ny
Apr 26, 2026
Merged

Replace JCE-based Ed25519 key generation with Tink#6
filinvadim merged 1 commit intomainfrom
claude/fix-warpdroid-crash-1t7ny

Conversation

@filinvadim
Copy link
Copy Markdown
Member

Summary

Replaces the JCE-based Ed25519 key pair generation in Ed25519IdentityStore with Google's Tink library to work around platform limitations on Android.

Key Changes

  • Switched key generation approach: Replaced KeyPairGenerator.getInstance("Ed25519") with Ed25519Sign.KeyPair.newKeyPair() from Tink
  • Simplified key extraction: Removed PKCS#8/X.509 encoding parsing logic since Tink directly returns raw 32-byte seed and public key formats
  • Added Tink dependency: Added tink-android v1.8.0 to module dependencies

Implementation Details

The previous implementation relied on JCE's Ed25519 support, which has compatibility issues:

  • Conscrypt 2.5.x ships a KeyFactory but no KeyPairGenerator
  • AndroidOpenSSL provider doesn't register Ed25519 on min SDK 24
  • This caused NoSuchAlgorithmException on real devices

Tink's standalone Ed25519 implementation:

  • Doesn't require a JCE provider
  • Directly yields the raw 32-byte seed and public key that go-libp2p expects
  • Eliminates the need to extract keys from PKCS#8/X.509 encoded formats
  • Is already available transitively via androidx.security-crypto

https://claude.ai/code/session_01U4YqA23uAfzZM9oWAEfEBZ

Conscrypt 2.5.x ships an Ed25519 KeyFactory but no Ed25519
KeyPairGenerator, and the platform AndroidOpenSSL provider does
not register Ed25519 at all on min SDK 24. The previous code's
KeyPairGenerator.getInstance("Ed25519") therefore crashed the
pairing flow with NoSuchAlgorithmException on every supported
device. Switch the identity-store generator to Tink's standalone
Ed25519Sign.KeyPair, which is already on the runtime classpath
via androidx.security-crypto and does not depend on JCE provider
registration.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Warpnet’s Android transport identity generation to avoid Android/Conscrypt JCE Ed25519 gaps by generating Ed25519 key material via Google Tink, while keeping the persisted libp2p key format unchanged (seed(32) || publicKey(32)).

Changes:

  • Replaced JCE KeyPairGenerator.getInstance("Ed25519") generation with Tink Ed25519Sign.KeyPair.newKeyPair().
  • Removed PKCS#8/X.509 parsing and switched to using Tink’s raw 32-byte seed + 32-byte public key.
  • Added an explicit tink-android dependency via the version catalog.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
warpnet-transport/src/main/kotlin/site/warpnet/transport/Ed25519IdentityStore.kt Switches Ed25519 keypair generation from JCE to Tink and returns raw seed+pub bytes directly.
warpnet-transport/build.gradle Declares the module-level tink-android dependency needed for compilation.
gradle/libs.versions.toml Adds the tink version and the tink-android library alias to the version catalog.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +72 to +74
val kp = Ed25519Sign.KeyPair.newKeyPair()
val seed = kp.privateKey
val pub = kp.publicKey
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

com.google.crypto.tink.subtle.Ed25519Sign is part of Tink’s low-level subtle package (not the higher-level/public Tink APIs). This increases upgrade risk because subtle classes are more likely to change or be relocated between Tink versions. Consider either (a) switching to the public signature APIs if they can provide the raw seed/public key you need, or (b) isolating this behind a small internal adapter (and adding a short comment) so future Tink upgrades only touch one place.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tink's public sign/verify APIs (PublicKeySign via KeysetHandle) wrap key material in opaque keysets with extra format/algorithm metadata — they intentionally don't expose the raw 32-byte seed and public key. go-libp2p's crypto.UnmarshalEd25519PrivateKey requires exactly the raw seed(32) || publicKey(32) layout the AAR consumes, so option (a) isn't viable without changing the on-disk and on-wire key format.

Option (b) is already in place: the Tink call is confined to a single private generate() method in Ed25519IdentityStore. If a future Tink version relocates subtle.Ed25519Sign, the fix is one import in one file. Pinning Tink to 1.8.0 (matched to what androidx.security-crypto already pulls in) keeps the upgrade window under our control.


Generated by Claude Code

@filinvadim filinvadim merged commit 4928d94 into main Apr 26, 2026
5 checks passed
@filinvadim filinvadim deleted the claude/fix-warpdroid-crash-1t7ny branch April 27, 2026 08:46
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants