JSPM

eff-pre

0.0.2
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 2
  • Score
    100M100P100Q31724F
  • License BSD-3-Clause

An efficient Proxy Re-encryption library in JavaScript without pairing.

Package Exports

  • eff-pre

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (eff-pre) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

eff-pre

An efficient Proxy Re-encryption library in JavaScript without pairing.

It's an implement of paper Efficient Unidirectional Proxy Re-encryption

Currently using curve BLS12-381 curve (G1) in mcl-wasm for speed.

Usage

This library is static utility library, which can be used in the following class PREClient and PREProxy

const PRE = require("eff-pre");
const crypto = require("crypto");

class PREClient {
    constructor(g, {sk = undefined} = {}) {
        this.g = g;
        this.pk = undefined;
        this.sk = undefined;
    }

    keyGen() {
        [this.sk, this.pk] = PRE.keyGen(this.g);
        return [this.sk, this.pk]
    }

    loadKey(sk) {
        this.sk = PRE.parseSk(sk);
        this.pk = PRE.pkFromSk(this.g, this.sk);

    }

    getSk() {
        return PRE.keyToBuf(this.sk)
    }

    getPk() {
        return PRE.keyToBuf(this.pk)
    }

    reKeyGen(to) {
        to = PRE.parsePk(to);
        return PRE.reKeyGen(this.g, this.sk, this.pk, to)

    }

    enc(M, {to = this.pk, transformable = true} = {}) {
        to = PRE.parsePk(to);
        if (transformable)
            return PRE.enc1(this.g, M, to);
        else
            return PRE.enc2(this.g, M, to);
    }

    dec(C) {
        return C.length === PRE.C1LEN ?
            PRE.dec1(this.g, C, this.sk, this.pk) :
            PRE.dec2(this.g, C, this.sk, this.pk)

    }


}

class PREProxy {
    constructor(g) {
        this.g = g;
    }

    reEnc(C1, reKey, owner) {
        owner = PRE.parsePk(owner);
        return PRE.reEnc(this.g, reKey, C1, owner)
    }
}

PRE.init().then(g => {
    const A = new PREClient(g);
    const B = new PREClient(g);
    const P = new PREProxy(g);

    A.keyGen();
    B.keyGen();

    const pkA = A.getPk();
    const pkB = B.getPk();
    console.log(pkA.toString('hex'));
    console.log(pkB.toString('hex'));

    //generate random message, recommend it to be symmetric(e.g AES) key.
    const m = crypto.randomBytes(PRE.L0);
    console.log(m.toString('hex'));
    //A encrypt and decrypt on his own
    const encrypted = A.enc(m);
    const [decStatus, decrypted] = A.dec(encrypted);
    console.log(decrypted.toString('hex'), decStatus);

    //A generate reKey(A->B) with B's public key
    const rkey = A.reKeyGen(pkB);
    //P re-encrypt with rkey and encrypted, (use pkA to verify owner of encrypted)
    const [reEncStatus, reEncrypted] = P.reEnc(encrypted, rkey, pkA);
    //now B can decrypt it
    const [reDecStatus, reDecrypted] = B.dec(reEncrypted);
    console.log(reDecrypted.toString('hex'), reDecStatus);

    //anyone can create non-transformable ciphertext using receiver's public key
    const ntEncrypted = B.enc(m, {to: pkA, transformable: false});
    const [ntDecStatus, ntDecrypted] = A.dec(ntEncrypted);
    console.log(ntDecrypted.toString('hex'), ntDecStatus);
    //others cannot decrypt above ciphertext
    const C = new PREClient(g);
    C.keyGen();
    console.log(C.dec(encrypted)[0]);
    console.log(C.dec(reEncrypted)[0]);
    console.log(C.dec(ntEncrypted)[0]);

}).catch(r => {
    console.log(r)
})

Reference

Chow, Sherman SM, et al. "Efficient unidirectional proxy re-encryption." International Conference on Cryptology in Africa. Springer, Berlin, Heidelberg, 2010.