# LifeHash

<p align="center">
  <a href="https://github.com/AndreasGassmann/lifehash/actions/workflows/build.yml"><img src="https://github.com/AndreasGassmann/lifehash/actions/workflows/build.yml/badge.svg?branch=main" alt="Build" /></a>
  <a href="https://github.com/prettier/prettier"><img src="https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square" alt="code style: prettier" /></a>
  <a href="https://www.npmjs.com/package/lifehash"><img src="https://img.shields.io/npm/v/lifehash.svg?colorB=brightgreen" alt="npm" /></a>
</p>

TypeScript/JavaScript implementation of [LifeHash](https://lifehash.info): A visual hash algorithm.

<p align="center">
  <code>"Hello, world!"</code>
</p>

<p align="center">
  <img src="test/fixtures/hello-version1.png" width="128" alt="version1" />
  <img src="test/fixtures/hello-version2.png" width="128" alt="version2" />
  <img src="test/fixtures/hello-detailed.png" width="128" alt="detailed" />
  <img src="test/fixtures/hello-fiducial.png" width="128" alt="fiducial" />
  <img src="test/fixtures/hello-grayscale_fiducial.png" width="128" alt="grayscale_fiducial" />
</p>

<p align="center">
  <sub>version1 &nbsp;&bull;&nbsp; version2 &nbsp;&bull;&nbsp; detailed &nbsp;&bull;&nbsp; fiducial &nbsp;&bull;&nbsp; grayscale</sub>
</p>

## Description

LifeHash is a method of hash visualization based on Conway's Game of Life that creates beautiful icons that are deterministic, yet distinct and unique given the input data.

The basic concept is to take a SHA-256 hash of the input data (which can be any data including another hash) and then use the 256-bit digest as a 16x16 pixel "seed" for running the cellular automata known as Conway's Game of Life.

After the pattern becomes stable (or begins repeating) the resulting history is used to compile a grayscale image of all the states from the first to last generation. Using Game of Life provides visual structure to the resulting image, even though it was seeded with entropy.

Some bits of the initial hash are then used to deterministically apply symmetry and color to the icon to add beauty and quick recognizability.

Source: [https://lifehash.info/](https://lifehash.info/)

## Versions

All five LifeHash versions are supported:

| Version | Grid | Output | Description |
|---------|------|--------|-------------|
| `version1` | 16x16 | 32x32 | Original version, HSB color gamut |
| `version2` | 16x16 | 32x32 | CMYK-safe colors (default, recommended) |
| `detailed` | 32x32 | 64x64 | Higher resolution |
| `fiducial` | 32x32 | 32x32 | No symmetry, for machine vision |
| `grayscale_fiducial` | 32x32 | 32x32 | Grayscale, no symmetry |

Output is verified pixel-for-pixel against the [reference C++ implementation](https://github.com/BlockchainCommons/bc-lifehash) test vectors.

## Installation

```
npm install lifehash
```

## Example

```typescript
import { LifeHash, LifeHashVersion } from 'lifehash';

const image = LifeHash.makeFrom('Hello, world!', LifeHashVersion.version2, 1, true);

image.toDataUrl(); // data:image/png;base64,...
```

For more examples, check the [examples](/examples/) folder or the [tests](/test/).

## Documentation

This library exports one class called `LifeHash`.

#### LifeHash

```typescript
class LifeHash {
  static makeFrom(
    data: string | Uint8Array,
    version = LifeHashVersion.version2,
    module_size = 1,
    has_alpha = false,
  ): Image { /* */ }

  static makeFromDigest(
    digest: Uint8Array,
    version = LifeHashVersion.version2,
    module_size = 1,
    has_alpha = false,
  ): Image { /* */ }
}
```

## Testing

```bash
npm install
npm test
```

Test vectors are sourced from the [reference implementation](https://github.com/BlockchainCommons/bc-lifehash/tree/master/test).

## Dependencies

There is only 1 (non-dev) dependency:

- [@noble/hashes](https://www.npmjs.com/package/@noble/hashes) — audited, minimal SHA-256 implementation

## Usages

Currently, the following wallets support LifeHash:

- [AirGap Vault](https://github.com/airgap-it/airgap-vault)

## Credits

The project setup has been inspired by multiple bitcoinjs libraries, such as [bip39](https://www.npmjs.com/package/bip39) and [bip85](https://www.npmjs.com/package/bip85).

Original C++ implementation: https://github.com/BlockchainCommons/bc-lifehash

This implementation is heavily inspired by https://github.com/BlockchainCommons/bc-lifehash-python

## LICENSE

MIT
