RSA-FDH
RSA-FDH is a is provably secure blind-signing signature scheme that uses RSA and a full domain hash.
This project implements a regular signature scheme with Full Domain Hash (FDH) padding.
Installation
$ npm install --save rsa-fdh
Usage
const jsbn = ;const bigInt = ;const FDH_padding = ; { const jsbnBigR = r; const jsbbnN = N; const jsbbnE = e; const jsbbnPaddedMessage = ; const MaskedMessage = jsbnBigR; return ;} { const jsbnBigInt = ; const jsbbnN = N; const jsbbnE = ; const MaskedMessage = jsbnBigInt; return ;} { const jsbnBigInt = r; const jsbbnN = N; const jsbbnPaddedMessage = ; const Signature = jsbnBigInt; return ;} // generate keys (backend)// new NodeRSA({b}) b = 4096 const e = ; // e = 2^16 + 1const N = ;const d = '23282399963902961889366589919965466215946811753019679196383601963073026613191453899926300248029233489789243362399308165690329565322928753601420278584758482746912697550351491890798946688520158669011260144232825240982614667183120321718305593611734705036861391713347126358186079249371112760227728035846980336435959248769233027730854826083718879920059961540485293082710349884551492275840955531629049426978639467925660853331260534811560188069192393264392588205879104916672550333998326293812618592325389850228055445162246436779443043223397512656518358337126551325082322672215385762922599168240697965091009692530903264807556670680484470229478940107545540835920598906558947901960121419927639247610499138992421409375496421992685721347527087138118721640418340821275729213415264535690693191336998922672043238344531550557349777887236388199934255219772830845326726984447157525409703422748423362819148906352436420831107204592249115128561378232761920339551114561374215401554512094507506349978765112270709835665263857161861822299858997294269998270864303157575035732881330471362077341228729301476533130040454166720399856834620556187156874147234515644344433865712782166068604850278956241690201025638224559129150999995816907370365944270837354719532673';console;console; const InitialMessage = 'Hello!'; // paddedconst PaddedMessage = ;console; // blindconst r = bigInt;console;const MaskedMessage = ;console; // signconst MaskedSignature = ; // unblindconst Signature = ;console; // verifyconst verify = ;console;
Protocol Description
A full domain hash (FDH) is constructed as follows:
FDH(𝑀, 𝐼𝑉) = H(𝑀 ‖ 𝑁 ‖ 𝐼𝑉 + 0) ‖ H(𝑀 ‖ 𝑁 ‖ 𝐼𝑉 + 1) ‖ H(𝑀 ‖ 𝑁 ‖ 𝐼𝑉 + 2) ...
Where:
- 𝑀 is the message
- H is any hash function
- 𝑁 is the signing key's public modulus
- 𝐼𝑉 is a one-byte initialization vector
The message is hashed (along with 𝑁 and 𝐼𝑉 + incrementing suffix) in rounds until the length of the hash is greater than or equal to the length of 𝑁. The hash is truncated as needed to produce the digest 𝐷 with the same length as 𝑁.
𝐷 must also be smaller than 𝑁, so we increment 𝐼𝑉 until we find a 𝐷 that is smaller than 𝑁.
Pseudocode:
fn generate_digest(message, public_key):
fdh = create_fdh(algo=sha256, length=public_key.bitlen())
iv = 0
digest = fdh(message, iv)
while digest.as_int() > public_key.n():
iv++
digest = fdh(message, iv)
return digest
The while
loop finishes within a minimal number of iterations because 𝑁 generally occurs around (2^bitlen) / 2
.
Two signature schemes are supported:
-
In the regular signature scheme, the signer applies the FDH before signing the message.
-
In the blind-signature scheme, the sender applies the FDH to the message before blinding the resulting digest and sending it to the signer, who signs the blinded digest directly. The signer must not re-use their private keys for encryption outside of the RSA-FDH blind-signature protocol.
Blinding, unblinding, signing and verification are done in the usual way for RSA.
## Co-Authors
Maksim Zakharov (linkedin) (github) Oleg Taraskin (linkedin)