0.4.2 • Published 1 month ago

@cloudflare/blindrsa-ts v0.4.2

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
1 month ago

NPM NPM

NPM

blindrsa-ts: A TypeScript Library for Blind and Partially-Blind RSA Signature Protocols

Specification: Library is compliant with the RFC-9474 document by IETF/IRTF, with Partially Blind RSA Signatures Draft 02, and matches the provided tests vectors, resp.

Blind RSA Signature Protocol

The RSA Blind Signature Protocol is a two-party protocol between a Client and Server where they interact to compute

sig = Sign(sk, input_msg)

where input_msg = Prepare(msg) is a prepared version of the private message msg provided by the Client, and sk is the private signing key provided by the Server.

 Client(pk, msg)                      Server(sk, pk)
-----------------------------------------------------
input_msg = Prepare(msg)
blinded_msg, inv = Blind(pk, input_msg)
                      blinded_msg
                      ---------->
               blind_sig = BlindSign(sk, blinded_msg)
                       blind_sig
                      <----------
sig = Finalize(pk, input_msg, blind_sig, inv)

Partially-Blind RSA Signature Protocol

One possible generalization of the protocol above is Partially-Blind Signatures, in which an additional info string can be provided, allowing public metadata to be shared.

 Client(pk, msg, info)          Server(sk, pk, info)
-------------------------------------------------------
input_msg = Prepare(msg)
blind_msg, inv = Blind(pk, input_msg, info)
                      blind_msg
                      ---------->
          blind_sig = BlindSign(sk, blind_msg, info)
                       blind_sig
                      <----------
sig = Finalize(pk, input_msg, info, blind_sig, inv)

Usage

Variants Supported

This package supports the four variants specified in RFC9474. Consult Section 5 of the document for the proper usage of each variant in an application.

import { RSABSSA } from '@cloudflare/blindrsa-ts';
const variants = [
    RSABSSA.SHA384.PSS.Randomized,
    RSABSSA.SHA384.PSSZero.Randomized,
    RSABSSA.SHA384.PSS.Deterministic,
    RSABSSA.SHA384.PSSZero.Deterministic,
];

In addition, it supports the four variants specified in Partially Blind RSA Signatures Draft 02. Consult Section 6 of the document for the proper usage of each variant in an application.

import { RSAPBSSA } from '@cloudflare/blindrsa-ts';
const variants = [
    RSAPBSSA.SHA384.PSS.Randomized,
    RSAPBSSA.SHA384.PSSZero.Randomized,
    RSAPBSSA.SHA384.PSS.Deterministic,
    RSAPBSSA.SHA384.PSSZero.Deterministic,
];

Platform specific configuration

By default, this library uses the WebCrypto API. Certain platforms, such as Cloudflare Workers, have implemented native operation. These can be enabled by passing { supportRSARAW: true } when retrieving a suite. At the time of writing, this dedicated optimization is done only for the BlindSign operation. Key type does not have to be modified, and will be set to RSA-RAW by the library for the time of the operation.

Setup

Once a Blind-RSA variant was chosen, start by generating the server's key pair. Both the key length and the public exponent can be specified.

const suite = RSABSSA.SHA384.PSS.Randomized();
const { privateKey, publicKey } = await suite.generateKey({
    publicExponent: Uint8Array.from([1, 0, 1]),
    modulusLength: 2048,
});

Server distributes its public key to clients.

Partially Blind RSA Signatures consideration

Partially Blind RSA Signatures requires Client and Server to have a public byte array info shared out-of-band. Where applicable, this byte array has to be provided as a parameter. Please refer to the example provided in examples/partially_blindrsa.ts to see usage.

Step 1

The client prepares arbitrary input to be blindly-signed by the server. The blind method generates a blinded message and an inverse object that later will be used during the finalization step.

const msgString = 'Alice and Bob';
const message = new TextEncoder().encode(msgString);
const preparedMsg = suite.prepare(message);
const { blindedMsg, inv } = await suite.blind(publicKey, preparedMsg);

The client sends only the blinded message to the server.

Step 2

Once the server received the blinded message, it responds to the client with a blind signature.

const blindSignature = await suite.blindSign(privateKey, blindedMsg);

The server sends the blinded signature to the client.

Step 3

The client produces the final signature using blinded signature received from the server together with the inverse object generated at the first step.

const signature = await suite.finalize(publicKey, preparedMsg, blindSignature, inv);

Thus, the client obtains a pair (preparedMsg, signature) which can be verified for validity.

Step 4

Anyone with access to the server's public key can verify the signature on top of the preparedMsg.

const isValid = await suite.verify(publicKey, signature, preparedMsg); // true

Development

TaskNPM scripts
Installing$ npm ci
Building$ npm run build
Unit Tests$ npm run test
Examples$ npm run examples
Code Linting$ npm run lint
Code Formatting$ npm run format

Dependencies

This project uses the Stanford JavaScript Crypto Library sjcl. Use the following command to configure the library.

make -f sjcl.Makefile

License

The project is licensed under the Apache-2.0 License.

0.4.2

1 month ago

0.4.1

2 months ago

0.4.0

2 months ago

0.3.2

3 months ago

0.3.1

3 months ago

0.2.0

7 months ago

0.1.2

9 months ago

0.1.0

9 months ago