Skip to main content
ABDM’s HIE-CM specification requires a specific ECDH-based encryption scheme for exchanging health records between parties. Use the open-source eka-care/abdm-ecdh library to perform all cryptographic operations.
The library implements ECDH key agreement on Curve25519 (Weierstrass form) — matching Java/BouncyCastle — with HKDF-SHA256 key derivation and AES-256-GCM encryption. This is the same algorithm required by ABDM.

Installation

go get github.com/eka-care/abdm-ecdh/go@v1.0.0
pip install abdm-ecdh
<repositories>
  <repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
  </repository>
</repositories>

<dependency>
  <groupId>com.github.eka-care</groupId>
  <artifactId>abdm-ecdh</artifactId>
  <version>java/v1.0.0</version>
</dependency>

Usage

package main

import (
    abdmecdh "github.com/eka-care/abdm-ecdh/go"
    "fmt"
)

func main() {
    e := abdmecdh.New()

    // Each party generates their own key material
    sender, err := e.GenerateKeyMaterial()
    if err != nil {
        panic(err)
    }
    requester, err := e.GenerateKeyMaterial()
    if err != nil {
        panic(err)
    }

    // Sender encrypts
    enc, err := e.Encrypt(abdmecdh.EncryptionRequest{
        StringToEncrypt:    "sensitive health data",
        SenderNonce:        sender.Nonce,
        RequesterNonce:     requester.Nonce,
        SenderPrivateKey:   sender.PrivateKey,
        RequesterPublicKey: requester.X509PublicKey,
    })
    if err != nil {
        panic(err)
    }

    // Requester decrypts
    dec, err := e.Decrypt(abdmecdh.DecryptionRequest{
        EncryptedData:       enc.EncryptedData,
        SenderNonce:         sender.Nonce,
        RequesterNonce:      requester.Nonce,
        RequesterPrivateKey: requester.PrivateKey,
        SenderPublicKey:     sender.X509PublicKey,
    })
    if err != nil {
        panic(err)
    }

    fmt.Println(dec.DecryptedData) // "sensitive health data"
}
from abdm_ecdh import generate_key_material, encrypt, decrypt

# Each party generates their own key material
sender    = generate_key_material()
requester = generate_key_material()

# Sender encrypts
enc = encrypt(
    string_to_encrypt="sensitive health data",
    sender_nonce=sender.nonce,
    requester_nonce=requester.nonce,
    sender_private_key=sender.private_key,
    requester_public_key=requester.x509_public_key,
)

# Requester decrypts
dec = decrypt(
    encrypted_data=enc.encrypted_data,
    sender_nonce=sender.nonce,
    requester_nonce=requester.nonce,
    requester_private_key=requester.private_key,
    sender_public_key=sender.x509_public_key,
)

print(dec.decrypted_data)  # "sensitive health data"
import care.eka.abdmecdh.AbdmEcdh;
import care.eka.abdmecdh.KeyMaterial;
import care.eka.abdmecdh.EncryptionResponse;
import care.eka.abdmecdh.DecryptionResponse;

// Each party generates their own key material
KeyMaterial sender = AbdmEcdh.generateKeyMaterial();
KeyMaterial requester = AbdmEcdh.generateKeyMaterial();

// Sender encrypts
EncryptionResponse enc = AbdmEcdh.encrypt(
    "sensitive health data",
    sender.nonce(),
    requester.nonce(),
    sender.privateKey(),
    requester.x509PublicKey()
);

// Requester decrypts
DecryptionResponse dec = AbdmEcdh.decrypt(
    enc.encryptedData(),
    sender.nonce(),
    requester.nonce(),
    requester.privateKey(),
    sender.x509PublicKey()
);

System.out.println(dec.decryptedData()); // "sensitive health data"

Key Material

GenerateKeyMaterial / generate_key_material returns:
FieldDescription
privateKey / private_keyBase64-encoded private scalar
publicKey / public_keyBase64-encoded uncompressed EC point (65 bytes)
x509PublicKey / x509_public_keyBase64-encoded X.509 SubjectPublicKeyInfo DER — share with the counterparty
nonce / nonceBase64-encoded 32-byte random nonce — share with the counterparty

Cryptographic Details

StepAlgorithm
Key agreementECDH on Curve25519 (Weierstrass form)
Key derivationHKDF-SHA256 (salt = first 20 bytes of XOR’d nonces)
EncryptionAES-256-GCM (IV = last 12 bytes of XOR’d nonces)
Key encodingX.509 SubjectPublicKeyInfo DER (BouncyCastle explicit params)
For more details, see the ABDM Encryption and Decryption Guide and the abdm-ecdh source.