# eth-crypto

> Cryptographic functions for ethereum and how to use them with web3 and solidity

Latest version **4.1.0** (published 2026-04-27) · MIT license · 0 weekly downloads

## Install

```sh
npm install eth-crypto
pnpm add eth-crypto
yarn add eth-crypto
bun add eth-crypto
```

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; has provenance; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 4.1.0 |
| Published | 2026-04-27 |
| First published | 2018-02-23 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 7 |
| Unpacked size | 95.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 921 |
| Author | pubkey |
| Maintainers | pubkey |
| Keywords | ethereum, eth, web3, solidity, encryption, secp256k1, dapp, blockchain, ecies, smart-contract, identity, signature |

## Links

- npm: https://www.npmjs.com/package/eth-crypto
- Repository: https://github.com/pubkey/eth-crypto
- Homepage: https://github.com/pubkey/eth-crypto#readme
- Issues: https://github.com/pubkey/eth-crypto/issues
- Funding: https://github.com/sponsors/pubkey
- npm.io page: https://npm.io/package/eth-crypto

## Dependencies (7)

- [ethers](https://npm.io/package/ethers.md) 6.16.0
- [@types/bn.js](https://npm.io/package/@types/bn.js.md) 5.2.0
- [@noble/hashes](https://npm.io/package/@noble/hashes.md) 2.2.0
- [@babel/runtime](https://npm.io/package/@babel/runtime.md) 7.29.2
- [@ethereumjs/tx](https://npm.io/package/@ethereumjs/tx.md) 10.1.1
- [@ethereumjs/util](https://npm.io/package/@ethereumjs/util.md) 10.1.1
- [ethereum-cryptography](https://npm.io/package/ethereum-cryptography.md) 3.2.0

## Alternatives

- [@sindresorhus/slugify](https://npm.io/package/@sindresorhus/slugify.md) — 3.7M weekly downloads
- [solid-js](https://npm.io/package/solid-js.md) — 2.7M weekly downloads
- [expo-glass-effect](https://npm.io/package/expo-glass-effect.md) — 2.5M weekly downloads
- [nanoassert](https://npm.io/package/nanoassert.md) — 780.8K weekly downloads
- [@ffmpeg/ffmpeg](https://npm.io/package/@ffmpeg/ffmpeg.md) — 529.5K weekly downloads

## Recent versions

- 4.1.0 (latest) — 2026-04-27
- 4.0.0 — 2026-02-24
- 3.1.0 — 2025-07-01
- 3.0.0 — 2025-06-26
- 2.8.0 — 2025-04-23
- 2.7.0 — 2024-11-03
- 2.6.0 — 2023-02-20
- 2.5.0 — 2022-12-03
- 2.4.0 — 2022-10-27
- 2.3.0 — 2022-04-20
- 2.2.0 — 2022-02-01
- 2.1.0 — 2021-09-26
- 2.0.0 — 2021-07-05
- 1.9.0 — 2021-03-20
- 1.8.0 — 2020-09-15
- … 29 more at https://npm.io/package/eth-crypto/versions

## README

<p align="center">
    <a href="https://twitter.com/pubkeypubkey">
        <img src="https://img.shields.io/twitter/follow/pubkeypubkey.svg?style=social&logo=twitter"
            alt="follow on Twitter">
    </a>
</p>

# eth-crypto

Cryptographic javascript-functions for ethereum and tutorials on how to use them together with web3js and solidity.

## Tutorials

- **[Creating keys and use them for ethereum transactions](./tutorials/creating-transactions.md)**

  In this tutorial we will create an ethereum-identity and use it to send transactions to the blockchain.

- **[Sign and validate data with solidity](./tutorials/signed-data.md)**

  In this tutorial we will sign data in javascript and validate the signature inside of a smart-contract.

- **[Sending encrypted and signed data to other identities](./tutorials/encrypted-message.md)**  

  In this tutorial we will use the ethereum-identities and asymmetric cryptography to send an encrypted and signed message from Alice to Bob.

## Sponsored by

<p align="center">
    <a href="https://rxdb.info/?utm_source=github&utm_medium=repo&utm_campaign=github-eth-crypto-readme">
        <img
            src="https://rxdb.info/files/logo/logo_text.svg"
            alt="JavaScript Database"
            width="300"
         />
         <br />
         <br />
         <span>The <b>JavaScript Database</b></span>
    </a>
</p>

## Using eth-crypto

### Install

```bash
  npm install eth-crypto --save
```

```javascript
// es6
import EthCrypto from 'eth-crypto';

// node
const EthCrypto = require('eth-crypto');
```

## API

- [createIdentity()](#createidentity)
- [publicKeyByPrivateKey()](#publickeybyprivatekey)
- [publicKey.toAddress()](#publickeytoaddress)
- [publicKey.compress()](#publickeycompress)
- [publicKey.decompress()](#publickeydecompress)
- [sign()](#sign)
- [recover()](#recover)
- [recoverPublicKey()](#recoverpublickey)
- [encryptWithPublicKey()](#encryptwithpublickey)
- [decryptWithPrivateKey()](#decryptwithprivatekey)
- [cipher.stringify()](#cipherstringify)
- [cipher.parse()](#cipherparse)
- [signTransaction()](#signtransaction)
- [txDataByCompiled()](#txdatabycompiled)
- [calculateContractAddress()](#calculatecontractaddress)
- [hex compress/decompress](#hex-compressdecompress)

### createIdentity()

Creates a new ethereum-identity with privateKey, publicKey and address as hex-string.

```javascript
  const identity = EthCrypto.createIdentity();
  /* > {
      address: '0x3f243FdacE01Cfd9719f7359c94BA11361f32471',
      privateKey: '0x107be946709e41b7895eea9f2dacf998a0a9124acbb786f0fd1a826101581a07',
      publicKey: 'bf1cc3154424dc22191941d9f4f50b063a2b663a2337e5548abea633c1d06ece...'
  } */
```

You can also create an identity by providing your own entropy-buffer. Use this with caution, a bad entropy can result in an unsecure private key.

```javascript
  const entropy = Buffer.from('f2dacf...', 'utf-8'); // must contain at least 128 chars
  const identity = EthCrypto.createIdentity(entropy);
  /* > {
      address: '0x59c8d4d645B0a3b230DE368d815ebDE372d37Ea8',
      privateKey: '0x18cea40e44624867ddfd775b2898cdb2da29b4be92ee072b9eb02d43b6f2473a',
      publicKey: '991ce4643653ef452327ee3d1a56af19c84599d340ffd427e784...'
  } */
```

### publicKeyByPrivateKey()

Derives the publicKey from a privateKey and returns it as hex-string.

```javascript
  const publicKey = EthCrypto.publicKeyByPrivateKey(
      '0x107be946709e41b7895eea9f2dacf998a0a9124acbb786f0fd1a826101581a07'
  );
  // > 'bf1cc3154424dc22191941d9f4f50b063a2b663a2337e5548abea633c1d06ece...'
```

### publicKey.toAddress()

Derives the ethereum-address from the publicKey.

```javascript
  const address = EthCrypto.publicKey.toAddress(
      'bf1cc3154424dc22191941d9f4f50b063a2b663a2337e5548abea633c1d06ece...'
  );
  // > '0x3f243FdacE01Cfd9719f7359c94BA11361f32471'
```

### publicKey.compress()

Compresses an uncompressed publicKey.

```javascript
  const address = EthCrypto.publicKey.compress(
      '04a34d6aef3eb42335fb3cacb59...'
  );
  // > '03a34d6aef3eb42335fb3cacb59478c0b44c0bbeb8bb4ca427dbc7044157a5d24b' // compressed keys start with '02' or '03'
```

### publicKey.decompress()

Decompresses a compressed publicKey.

```javascript
  const address = EthCrypto.publicKey.decompress(
      '03a34d6aef3eb42335fb3c...'
  );
  // > 'a34d6aef3eb42335fb3cacb5947' // non-compressed keys start with '04' or no prefix
```

### sign()

Signs the hash with the privateKey. Returns the signature as hex-string.

```javascript
  const message = 'foobar';
  const messageHash = EthCrypto.hash.keccak256(message);
  const signature = EthCrypto.sign(
      '0x107be946709e41b7895eea9f2dacf998a0a9124acbb786f0fd1a826101581a07', // privateKey
      messageHash // hash of message
  );
  // > '0xc04b809d8f33c46ff80c44ba58e866ff0d5..'
```

### recover()

Recovers the signers address from the signature.

```javascript
    const signer = EthCrypto.recover(
      '0xc04b809d8f33c46ff80c44ba58e866ff0d5..',
      EthCrypto.hash.keccak256('foobar') // signed message hash
  );
  // > '0x3f243FdacE01Cfd9719f7359c94BA11361f32471'
```

### recoverPublicKey()

Recovers the signers `publicKey` from the signature.
```javascript
    const signer = EthCrypto.recoverPublicKey(
      '0xc04b809d8f33c46ff80c44ba58e866ff0d5..', // signature
      EthCrypto.hash.keccak256('foobar') // message hash
  );
  // > 'bf1cc3154424dc22191941d9f4f50b063a2b663a2337e5548abea633c1d06ece..'
```


### encryptWithPublicKey()

Encrypts the message with the publicKey so that only the corresponding privateKey can decrypt it. Returns (async) the encrypted data as object with hex-strings.

```javascript
    const encrypted = await EthCrypto.encryptWithPublicKey(
        'bf1cc3154424dc22191941d9f4f50b063a2b663a2337e5548abea633c1d06ece...', // publicKey
        'foobar' // message
    );
    /* >  {
            iv: '02aeac54cb45283b427bd1a5028552c1',
            ephemPublicKey: '044acf39ed83c304f19f41ea66615d7a6c0068d5fc48ee181f2fb1091...',
            ciphertext: '5fbbcc1a44ee19f7499dbc39cfc4ce96',
            mac: '96490b293763f49a371d3a2040a2d2cb57f246ee88958009fe3c7ef2a38264a1'
        } */
```

### decryptWithPrivateKey()

Decrypts the encrypted data with the privateKey. Returns (async) the message as string.

```javascript
    const message = await EthCrypto.decryptWithPrivateKey(
        '0x107be946709e41b7895eea9f2dacf998a0a9124acbb786f0fd1a826101581a07', // privateKey
        {
            iv: '02aeac54cb45283b427bd1a5028552c1',
            ephemPublicKey: '044acf39ed83c304f19f41ea66615d7a6c0068d5fc48ee181f2fb1091...',
            ciphertext: '5fbbcc1a44ee19f7499dbc39cfc4ce96',
            mac: '96490b293763f49a371d3a2040a2d2cb57f246ee88958009fe3c7ef2a38264a1'
        } // encrypted-data
    );
    // 'foobar'
```

### cipher.stringify()

Transforms the object with the encrypted data into a smaller string-representation.

```javascript
const str = EthCrypto.cipher.stringify({
    iv: '02aeac54cb45283b427bd1a5028552c1',
    ephemPublicKey: '044acf39ed83c304f19f41ea66615d7a6c0068d5fc48ee181f2fb1091...',
    ciphertext: '5fbbcc1a44ee19f7499dbc39cfc4ce96',
    mac: '96490b293763f49a371d3a2040a2d2cb57f246ee88958009fe3c7ef2a38264a1'
});
// > '59ab06532fc965b0107977f43e69e5a4038db32099dab281c8f5aece2852...'
```

### cipher.parse()

Parses the string-representation back into the encrypted object.

```javascript
const str = EthCrypto.cipher.parse('59ab06532fc965b0107977f43e69e5a4038db32099dab281c8f5aece2852...');
/* >  {
        iv: '02aeac54cb45283b427bd1a5028552c1',
        ephemPublicKey: '044acf39ed83c304f19f41ea66615d7a6c0068d5fc48ee181f2fb1091...',
        ciphertext: '5fbbcc1a44ee19f7499dbc39cfc4ce96',
        mac: '96490b293763f49a371d3a2040a2d2cb57f246ee88958009fe3c7ef2a38264a1'
    } */
```

### signTransaction()

Signs a raw transaction with the privateKey. Returns a `Promise` that resolves a serialized tx-string which can be submitted to the node.

```javascript
const identity = EthCrypto.createIdentity();
const rawTx = {
    from: identity.address,
    to: '0x86Fa049857E0209aa7D9e616F7eb3b3B78ECfdb0',
    value: new BN('1000000000000000000'),
    gasPrice: 5000000000,
    nonce: 0,
    gasLimit: 21000
};
const signedTx = await EthCrypto.signTransaction(
    rawTx,
    identity.privateKey
);
console.log(signedTx);
// > '071d3a2040a2d2cb...'

// you can now send the tx to the node
const receipt = await web3.eth.sendSignedTransaction(signedTx);
```

### txDataByCompiled()

Creates the data-string which must be submitted with an transaction to create a contract-instance.

```javascript
const SolidityCli = require('solidity-cli');

// create compiled solidity-code
const compiled = await SolidityCli.compileCode(
    'contract ExampleContract {...'
)[':ExampleContract'];

const createCode = EthCrypto.txDataByCompiled(
    compiled.interface, // abi
    compiled.bytecode, // bytecode
    [identity.address] // constructor-arguments
);

// now you can submit this to the blockchain
const serializedTx = await EthCrypto.signTransaction(
    {
        from: identity.address,
        nonce: 0,
        gasLimit: 5000000,
        gasPrice: 5000000000,
        data: createCode
    },
    identity.privateKey
);
const receipt = await web3.eth.sendSignedTransaction(serializedTx);
```

### calculateContractAddress()
Calculates the address for the contract from the senders address and the nonce, without deploying it to the blockchain.

```javascript
// pre-calculate address
const calculatedAddress = EthCrypto.calculateContractAddress(
    account.address, // address of the sender
    3 // nonce with which the contract will be deployed
);

const rawTx = {
    from: account.address,
    gasPrice: parseInt(gasPrice),
    nonce: 3,
    data: compiled.code
};
const receipt = await state.web3.eth.sendTransaction(rawTx);

console.log(receipt.contractAddress === calculatedAddress);
// > true
```

### hex compress/decompress

"Compress" or "decompress" a hex-string to make it smaller. You can either compress to utf16 which reduces the size to about 1/4, or to base64 which reduces the size to about 4/5. This is not a real compression, it just make your string smaller when you have to store it in utf-16 anyways.

```javascript
const hexString = '0x107be946709e41b7895eea9f2dacf998a0a9124acbb786f0fd1a826101581a07'; // 66 chars

const utf16 = EthCrypto.hex.compress(hexString); // compress to utf16
// > 'ၻ炞䆷襞ⶬ輦ꂩቊ쮷蛰ﴚ艡Řᨇ' // 16 chars

const base64 = EthCrypto.hex.compress(hexString, true); // compress to base64
// > 'EHvpRnCeQbeJXuqfLaz5mKCpEkrLt4bw/RqCYQFYGgc=' // 44 chars

EthCrypto.hex.decompress(utf16); // decompress from utf16
// > '0x107be946709e41b7895eea9f2d...'

EthCrypto.hex.decompress(base64, true); // decompress from base64
// > '0x107be946709e41b7895eea9f2d...'

```

---
_Source: https://npm.io/package/eth-crypto · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
