Novelty Plastic Moustache

    This package has been deprecated

    Author message:

    No longer maintained. Replaced by @privacyresearch/curve25519-typescript

    TypeScript icon, indicating that this package has built-in type declarations

    0.0.6 • Public • Published

    Typescript Library for Curve 25519

    This library isolates the implementation of the X25519 curves used in libsignal-protocol-javascript and exposes the basic functions in an easy to use TypeScript package.


    Use yarn to install:

    yarn add @rolfe/curve25519-typescript

    Then in your code simply import the class you want:

    import { Curve25519Wrapper } from '@rolfe/curve25519-typescript'
    // OR...
    import { AsyncCurve25519Wrapper } from '@rolfe/curve25519-typescript'

    We'll say more about the differences between the two curve wrappers below.


    Before getting into the details, here's a quick example of a Diffie-Hellman key exchange (not that you would ever do both key computations in one place!):

    const curve = await Curve25519Wrapper.create()
    const alicePair = curve.keyPair(alice_bytes)
    const bobPair = curve.keyPair(bob_bytes)
    const aliceSecret = curve.sharedSecret(bobPair.pubKey, alicePair.privKey)
    const bobSecret = curve.sharedSecret(alicePair.pubKey, bobPair.privKey)

    Note the await! The curve wrapper is created asynchronously.

    We can sign and verify too:

    // pub, priv, msg are all ArrayBuffers
    const curve = await Curve25519Wrapper.create()
    const sig = curve.sign(priv, msg)
    const verified = curve.verify(pub, msg, sig)
    if (verified) {
      // Yes, this is correct.  `verify` returns `true` for invalid signatures
      throw new Error('INVALID SIGNATURE!')

    Note the return value of verify! This is for compatibility with usage in libsignal-protocol-javascript. To avoid confusion, we offer an alternative:

    const signatureIsValid = curve.signatureIsValid(pub, msg, sig)
    if (!signatureIsValid) {
      throw new Error('INVALID SIGNATURE!')

    That pretty much covers it, but look at the tests for details about creating ArrayBuffers for input and getting some sample data to get started.

    Async or not Async?

    In the installation instructions we noted that the package exports two classes: Curve25519Wrapper and AsyncCurve25519Wrapper. The examples above all use Curve25519Wrapper. Here are the differences between the two:

    Wrapper creation

    As seen in the examples above Curve25519Wrapper must be created asynchronously, but all of its methods are synchronous.

    On the other hand AsyncCurve25519Wrapper can be instantiated synchronously, but all of its methods are async. For example, here his how message signing looks with this wrapper:

    // Just create the wrapper, no need to await it
    const curve = new AsyncCurve25519Wrapper()
    // but now curve.sign returns a Promise<ArrayBuffer>!
    const sigCalc = await curve.sign(priv, msg)


    The core curve implementation is written in C and can be found in the native/ directory. It is compiled to Javascript with Emscripten and the compilation command can be seen in

    If you want to make modifications to the C code or change compilation arguments (e.g. to optimize more aggressively), you will need to install Emscripten.


    This is really just a direct lift of work done by the folks at Signal so that we can use it easily in our TypeScript projects. Thanks to them for putting the core of this together!


    Copyright 2020 Privacy Research, LLC

    Licensed under the GPLv3:




    npm i @rolfe/curve25519-typescript

    DownloadsWeekly Downloads






    Unpacked Size

    885 kB

    Total Files


    Last publish


    • rolfe