index.js
function doSign(params, xKey, message, generateHash) {
    // Let H be the hashing function and m the message:
    // Generate a random per-message value k where 1<k<q
    // Calculate r = (g^k mod p) mod q
    // In the unlikely case that r=0, start again with a different random k
    // Calculate s = k^(-1) * ( H (m) + xr) mod q
    // In the unlikely case that s=0, start again with a different random k
    // The signature is (r,s)
    // The first two steps amount to creating a new per-message key. The modular exponentiation here is the most
    // computationally expensive part of the signing operation, and it may be computed before the message hash is known.
    // The modular inverse k^(-1) mod q is the second most expensive part, and it may also be computed before the
    // message hash is known. It may be computed using the extended Euclidean algorithm or using Fermat's little theorem
    // as k^(q-2) mod q .

    let hash = generateHash(message);

    return hash.map(h => {
        let done = false;
        let r = 0;
        let s = 0;
        do {
            let k = 0;
            let kInverse = 0;

            do {
                // Generate a random per-message value k where 1<k<q
                k = params.q - Math.round(Math.random() * params.q);

                // Calculate r = (g^k mod p) mod q
                r = myNumbers.modPow(params.g, k, params.p) % params.q;

                // Calculate s = (k^(-1) * ( H (m) + xKey * r)) mod q
                // (k^(-1) x) mod q -- if q is prime --> x^(q-2) mod q
                if (r) kInverse = myNumbers.mInverse(k, params.q);

            } while (r === 0 || kInverse === 0); // In the unlikely case that r=0, start again with a different random k

            // Calculate s = (k^(-1) * ( H (m) + xKey * r)) mod q
            s = ( h + 1 + xKey * r ) * kInverse % params.q;
            if (s) done = true;
        } while (!done);
        return {r: r, s: s}
    });
}
function doSign(params, xKey, message, generateHash) {
    // Let H be the hashing function and m the message:
    // Generate a random per-message value k where 1<k<q
    // Calculate r = (g^k mod p) mod q
    // In the unlikely case that r=0, start again with a different random k
    // Calculate s = k^(-1) * ( H (m) + xr) mod q
    // In the unlikely case that s=0, start again with a different random k
    // The signature is (r,s)
    // The first two steps amount to creating a new per-message key. The modular exponentiation here is the most
    // computationally expensive part of the signing operation, and it may be computed before the message hash is known.
    // The modular inverse k^(-1) mod q is the second most expensive part, and it may also be computed before the
    // message hash is known. It may be computed using the extended Euclidean algorithm or using Fermat's little theorem
    // as k^(q-2) mod q .

    let hash = generateHash(message);

    return hash.map(h => {
        let done = false;
        let r = 0;
        let s = 0;
        do {
            let k = 0;
            let kInverse = 0;

            do {
                // Generate a random per-message value k where 1<k<q
                k = params.q - Math.round(Math.random() * params.q);

                // Calculate r = (g^k mod p) mod q
                r = myNumbers.modPow(params.g, k, params.p) % params.q;

                // Calculate s = (k^(-1) * ( H (m) + xKey * r)) mod q
                // (k^(-1) x) mod q -- if q is prime --> x^(q-2) mod q
                if (r) kInverse = myNumbers.mInverse(k, params.q);

            } while (r === 0 || kInverse === 0); // In the unlikely case that r=0, start again with a different random k

            // Calculate s = (k^(-1) * ( H (m) + xKey * r)) mod q
            s = ( h + 1 + xKey * r ) * kInverse % params.q;
            if (s) done = true;
        } while (!done);
        return {r: r, s: s}
    });
}
function doSign ( params , xKey , message , generateHash ) { // Let H be the hashing function and m the message: // Generate a random per-message value k where 1<k<q // Calculate r = (g^k mod p) mod q // In the unlikely case that r=0, start again with a different random k // Calculate s = k^(-1) * ( H (m) + xr) mod q // In the unlikely case that s=0, start again with a different random k // The signature is (r,s) // The first two steps amount to creating a new per-message key. The modular exponentiation here is the most // computationally expensive part of the signing operation, and it may be computed before the message hash is known. // The modular inverse k^(-1) mod q is the second most expensive part, and it may also be computed before the // message hash is known. It may be computed using the extended Euclidean algorithm or using Fermat's little theorem // as k^(q-2) mod q . let hash = generateHash ( message ) ; return hash . map ( h => { let done = false ; let r = 0 ; let s = 0 ; do { let k = 0 ; let kInverse = 0 ; do { // Generate a random per-message value k where 1<k<q k = params . q - Math . round ( Math . random ( ) * params . q ) ; // Calculate r = (g^k mod p) mod q r = myNumbers . modPow ( params . g , k , params . p ) % params . q ; // Calculate s = (k^(-1) * ( H (m) + xKey * r)) mod q // (k^(-1) x) mod q -- if q is prime --> x^(q-2) mod q if ( r ) kInverse = myNumbers . mInverse ( k , params . q ) ; } while ( r === 0 || kInverse === 0 ) ; // In the unlikely case that r=0, start again with a different random k // Calculate s = (k^(-1) * ( H (m) + xKey * r)) mod q s = ( h + 1 + xKey * r ) * kInverse % params . q ; if ( s ) done = true ; } while ( ! done ) ; return { r : r , s : s } } ) ; }
generates digital signature for data and hash function using private key and shared DSA params
@param {{q: number, p: number, g: number}} params shared DSA params
@param {{number}} xKey - private key
@param {string} message - data to sign
@param {function} generateHash - hash function (should accept {string} and return [number])
@returns {[{r: number, s: number}]}
generates digital signature for data and hash function using private key and shared DSA params