Javacard implementation of Curve25519 (prototype, work-in-progress)
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Javacard implementation of Curve25519 (prototype, work-in-progress).

This code is in the public domain.


  • Javacard 3.0.1 or higher (currently developed on J2D081)
  • JCDK 3.0.3 or higher (see below)
  • Working Java SDK / ant installation
  • For testing: Python with smartcard packages


This code uses the excellent JC Ant task and the GP tool for building and installation. Compile using:

ant curve

This assumes you have a Javacard 3.0.3 SDK (JCDK) in the folder pointed to by build.xml:

<property name="JC303" value="../jc303" />

Here, we assume the JCDK is one folder up. Change as needed. JCDK packages can e.g. be found at

JC Ant and the GP tool are written by Martin Paljak ( and are available under the MIT / LGPL license (see the respective repositories for details).


Upload .cap file after compilation to card using gp:

gp --install curve25519_jc303.cap

If the applet was installed before, remove it first:

gp --uninstall curve25519_jc303.cap	


Using Python, execute Requires pyScard to communicate with card. A convenient way under Windows is using Anaconda ( An example output could be:

== Testing against test vector == 
pkRef  = 0x6a4e9baa8ea9a4ebf41a38260d3abf0d5af73eb4dc7d8b7454a7308909f02085L
pkTest = 0x6a4e9baa8ea9a4ebf41a38260d3abf0d5af73eb4dc7d8b7454a7308909f02085L
diff = 0x0L

== Available readers:
0) SCM Microsystems Inc. SCR35xx USB Smart Card Reader 0
 Connecting to first reader ... 
 ATR: 3B F9 18 00 00 81 31 FE 45 4A 32 44 30 38 31 5F 50 56 B6
 App selected

== Testing on-card key generation
pkRef  = 0x336f019040df969295182ef7cc4873f2d406a3e878cea1c035d740bdbab673aeL
pkTest = 0x336f019040df969295182ef7cc4873f2d406a3e878cea1c035d740bdbab673aeL
diff = 0x0L

== Testing setting the private key
pkRef  = 0x6a4e9baa8ea9a4ebf41a38260d3abf0d5af73eb4dc7d8b7454a7308909f02085L
pkTest = 0x6a4e9baa8ea9a4ebf41a38260d3abf0d5af73eb4dc7d8b7454a7308909f02085L
diff = 0x0L

== Testing generating shared secret
secretRef  = 0x4217161e3c9bf076339ed147c9217ee0250f3580f43b8e72e12dcea45b9d5d4aL
secretTest = 0x4217161e3c9bf076339ed147c9217ee0250f3580f43b8e72e12dcea45b9d5d4aL
diff = 0x0L

Execution times

I measured the following execution times on a J2D081 smartcard using timeit.default_timer. These timings include the communication overhead for sending and receiving data, but not the post-processing in Python:

On-card key generation (generate 32 random bytes, perform one ECC operation): 624 ms
Set private key (perform one ECC operation): 618 ms
Generate shared secret (perform one ECC operation with pre-set private key): 122 ms

The timings are very consistent over multiple executions.


Thanks to Peter Schwabe for his helpful comments and suggestions and to Shaima Al Amri, who worked on this topic for an MSc project.


Public domain, see LICENSE

Useful links