libdemos-ts
WASM version of the core C library for nodejs and the browser
Science Score: 44.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
✓CITATION.cff file
Found CITATION.cff file -
✓codemeta.json file
Found codemeta.json file -
✓.zenodo.json file
Found .zenodo.json file -
○DOI references
-
○Academic publication links
-
○Academic email domains
-
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (14.2%) to scientific vocabulary
Repository
WASM version of the core C library for nodejs and the browser
Basic Info
- Host: GitHub
- Owner: ondemos
- License: agpl-3.0
- Language: TypeScript
- Default Branch: master
- Size: 643 KB
Statistics
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
- Releases: 0
Metadata Files
README.md
@ondemos/core
This repository contains cryptographic functions that may be useful for digital democracy.
It does not have any native dependencies and can be used in both Nodejs and the browser.
The API is not completely stable and the code has not undergone external security audits. Use at your own risk.
Introduction
This library uses the WASM output from the core C library and wraps it in Typescript.
Files
The commitment directory contains the utility functions for private liquid votes.
The utils directory contains sha512 and argon2 hashing, mnemonic generation and validation and symmetric and asymmetric cryptography operations with Ed25519 and ChaCha20Poly1305.
The merkle directory contains a Merkle root getter function, a Merkle proof artifacts getter, a root from proof getter and a proof verification function.
The shamir directory contains a WASM implementation of a cryptographic technique called Shamir's secret sharing, which allows one to split a secret into random shares that can only recreate it if a threshold of them is combined. Under the hood it uses the libsodium randombytes js method to generate random coefficients for the polynomial.
Getting Started
To get started you have to install the package with
npm install @ondemos/core
You can include as ES module
typescript
import ondemos from "@ondemos/core";
as CommonJS module
javascript
const ondemos = require("@ondemos/core");
or as UMD in the browser with
html
<script src="https://cdn.jsdelivr.net/npm/@ondemos/core@latest/lib/index.min.js"></script>
Examples
You can visit the tests folder to find usage examples.
For Curve25519 public key cryptography we have the following methods
```typescript import ondemos from "@ondemos/core";
// Words from dictionary create random seed for Ed25519 private key.
// Default entropy is 128bits, which results in 12 words.
const mnemonic = await ondemos.generateMnemonic();
console.log(Mnemonic with 128 bits of entropy => 12 words: ${mnemonic});
// Max entropy is 256bit, where generateMnemonic(256) results in 24 words.
// Keypair is an object representing an Ed25519 keypair with { publicKey: Uint8Array(32), secretKey: Uint8Array(64) }
const keypair = await ondemos.keyPairFromMnemonic(mnemonic);
console.log(
Keypair from mnemonic: {\n\
secretKey: ${Buffer.from(keypair.secretKey).toString("hex")}\n\
publicKey: ${Buffer.from(keypair.publicKey).toString("hex")}\n}\
,
);
// Generates a Uint8Array(128) full of random bytes const message = await ondemos.randomBytes(128);
// EdDSA const signature = await ondemos.sign(message, keypair.secretKey);
const verify = await ondemos.verify(message, signature, keypair.publicKey); console.log(verify); // true
const hash = await ondemos.sha512(message);
const keypair2 = await ondemos.keyPair();
// Forward secrecy box. // Encryptor generates a random keypair. The public key is contained in the // "encrypted" box and the secret key is used for the key exchange with // "keypair2.publicKey" and then it is removed from memory. const encrypted = await ondemos.encryptAsymmetric( message, keypair2.publicKey, keypair.secretKey, hash, );
const decrypted = await ondemos.decryptAsymmetric( encrypted, keypair.publicKey, keypair2.secretKey, hash, );
// To test equality for two Uint8Arrays in js you need to check if each of their elements are equal // The === operator does not work for (let i = 0; i < message.length; i++) { if (message[i] !== decrypted[i]) console.error("Arrays unequal"); }
const symmetricKey = await ondemos.randomBytes( ondemos.interfaces.cryptokxSESSIONKEYBYTES, ); const encrypted1 = await ondemos.encryptSymmetric(message, symmetricKey, hash); const decrypted1 = await ondemos.decryptSymmetric(encrypted1, key, hash); ```
For Shamir secret sharing you can test the following
```typescript import ondemos from "@ondemos/core";
const keypair = await ondemos.keyPair();
// 100 splitted shares, you need 60 to recreate keypair.secretKey // Note that you can have max 255 shares and threshold <= shares const shares = await ondemos.splitSecret(keypair.secretKey, 100, 60);
// Should be equal to keypair.secretKey const sk1 = await ondemos.restoreSecret(shares);
console.log("sk1 and kaypair.secretKey are equal");
// Remove 40 shares to see if it will still work const lessShares = shares.slice(0, shares.length - 40);
// Should be equal to sk1 and keypair.secretKey const sk2 = await ondemos.restoreSecret(lessShares);
console.log("sk2 and kaypair.secretKey are equal");
const evenLessShares = lessShares.slice(0, lessShares.length - 1);
// Should not be equal to sk1 and sk2. const sk3 = await ondemos.restoreSecret(evenLessShares);
console.log("sk3 and kaypair.secretKey are NOT equal"); ```
In order to find the Merkle root, proof and to verify the proof you can do the following:
```typescript import ondemos from "@ondemos/core";
const randomArrays: Uint8Array[] = []; for (let i = 0; i < 50; i++) { randomArrays.push(await ondemos.randomBytes(32)); }
// ondemos.constants.cryptohashsha512_BYTES // Function also accepts any type of data but it then requires a serializer function. const randomArraysMerkleRoot = await ondemos.getMerkleRoot(randomArrays);
// Multiple of ondemos.constants.cryptohashsha512_BYTES const randomArrayMerkleProof = await ondemos.getMerkleProof( randomArrays, randomArrays[43], );
const elementHash = await ondemos.sha512(randomArrays[43]);
const verify = await ondemos.verifyMerkleProof( elementHash, randomArraysMerkleRoot, randomArrayMerkleProof, );
console.log(verify); // should be true ```
For more examples you can see the tests directory.
Development
If you want to bundle the library yourselves, you need to have Emscripten
installed on your machine in order to compile the C code into WebAssembly.
We have the -s SINGLE_FILE=1 option for the emcc compiler, which converts the wasm file to a base64 string
that will be compiled by the glue js code into a WebAssembly module. This was done for the purpose of interoperability
and modularity.
Once you have all the dependencies installed, you can clone the core library, compile it, copy the wasm output and build:
git clone https://github.com/ondemos/core
cd core
git submodule update --init --recursive
git clone https://github.com/emscripten-core/emsdk
cd emsdk
./emsdk install latest
./emsdk activate latest
cd ..
source ./build.sh
cd ..
git clone https://github.com/ondemos/core
cd core
npm i
npm run copy:wasm
npm run build
and Rollup will generate the UMD, ESM and CJS bundles.
Releases
Releases are available on Github and npmjs.com
License
The source code is licensed under the terms of the Affero General Public License version 3.0 (see LICENSE).
Copyright
Copyright (C) 2024 Deliberative Technologies P.C.
Owner
- Name: ONDemos
- Login: ondemos
- Kind: organization
- Email: info@ondemos.org
- Location: Greece
- Website: https://ondemos.org
- Repositories: 3
- Profile: https://github.com/ondemos
Cryptographic tools for digital democracy
Citation (CITATION.cff)
cff-version: 0.2.5
title: ondemos
message: >-
If you use this software, please cite it using the
metadata from this file.
type: software
authors:
- given-names: Dimitrios
family-names: Karoukis
orcid: 'https://orcid.org/0009-0008-4417-1713'
repository-code: 'https://github.com/ondemos/core-js'
url: 'https://www.ondemos.org'
abstract: 'A cryptographic commitment scheme that implies order of ownership.'
keywords:
- cryptography
- library
license: AGPL-3.0
GitHub Events
Total
Last Year
Dependencies
- actions/checkout master composite
- actions/setup-node v4 composite
- codecov/codecov-action v4 composite
- mymindstorm/setup-emsdk v14 composite
- actions/checkout master composite
- david-a-wheeler/flawfinder 2.0.19 composite
- github/codeql-action/analyze v2 composite
- github/codeql-action/autobuild v2 composite
- github/codeql-action/init v2 composite
- actions/checkout master composite
- codecov/codecov-action v4 composite
- mymindstorm/setup-emsdk v14 composite
- 591 dependencies
- @eslint/js ^9.4.0 development
- @rollup/plugin-alias ^5.1.0 development
- @rollup/plugin-commonjs ^25.0.2 development
- @rollup/plugin-json ^6.0.0 development
- @rollup/plugin-node-resolve ^15.0.0 development
- @rollup/plugin-replace ^5.0.0 development
- @rollup/plugin-typescript ^11.0.0 development
- @rollup/plugin-url ^8.0.0 development
- @types/emscripten ^1.39.6 development
- @types/eslint__js ^8.42.3 development
- @types/jest ^29.0.0 development
- cross-env ^7.0.3 development
- eslint ^9.4.0 development
- eslint-config-prettier ^9.0.0 development
- eslint-plugin-jest ^28.0.0-next.7 development
- eslint-plugin-jsdoc ^48.2.7 development
- eslint-plugin-prefer-arrow ^1.2.3 development
- eslint-plugin-prettier ^5.1.3 development
- globals ^15.3.0 development
- jest ^29.0.1 development
- jest-badges ^0.1.3 development
- jest-environment-jsdom ^29.0.0 development
- npm-run-all ^4.1.5 development
- prettier ^3.0.0 development
- rollup ^4.6.1 development
- rollup-plugin-analyzer ^4.0.0 development
- rollup-plugin-copy ^3.4.0 development
- terser ^5.15.1 development
- ts-jest ^29.0.0-next.1 development
- tslib ^2.3.1 development
- tweetnacl ^1.0.3 development
- typedoc ^0.25.0 development
- typescript ^5.2.2 development
- typescript-eslint ^8.0.0-alpha.25 development