Question

I'm coding a javascript version that can decode a RSA encryption I made in PHP. everything works fine except I don't have a javascript equivalent of bcpowmod.

I used the PHP JS library for the other functions but it doesn't have bcpowmod.

If I use default math operators like: (pow(block,q)) % r I get NAN.

Is there a way or js library that can work for me?

Was it helpful?

Solution

bcpowmod is very tuff tough in javascript. Here's the code to do it. I just posted an entire library for anyone to use to employ RSA RC4 encryption in their web sites, but was promptly shot down by a moderator, Brad Larson. He said, they don't want this kind of stuff at Stack Overflow. Anyway here's the code for you.

Java script is slow at this. So I do it in multiple steps so javascript has time to show a progress bar or something. I had to write my own bcmath package to do it. You can see the whole library of encryption functions ready to go at http://jerrywickey.com/test/testJerrysLibrary.php

You need arbitrary precision multiply, divide, subtract and compare. So they are all here. the actual bcpowmod is done in multiple steps because it just takes so long.

When the calculations are done, it calls the function named in the callback parameter with the result. Swap a and b back and forth to get it to work for you, just incase we are using different terms for the RSA public, private and modulo values. Use just the alphanumeric name for the callback function. Don't use the parenthesis.

bcpowmod( 'plain text', RSAp, RSAq, 'myCallBackForResult');

    function myCallBackForResult( result){
            alert ( result + ' of powmod');
    }

    function bcpowmod( str, a, b, callback){
        RSAencryptStep( (''+str), (''+a), (''+b), '1', callback, 0);
    }

    function RSAencryptStep( str, a, b, result, callback, count){   
        count++;
        if ( JL_bccomp( JL_bcmod( a, '2'), '1')==0) {
            result = JL_bcmod( JL_bcmul( result, str), b);
        }
        str= JL_bcmod( JL_bcmul( str, str), b);
        a= JL_bcdiv( a, '2');
        if ( JL_bccomp( a, '0')!=0){
            var e= "RSAencryptStep('" +str+"','" +a+"','" +b+"','" +result+"','" +callback +"'," +count+")";
            setTimeout( e, 10); 
            clearTimeout( JL_crytime);
            try{
                ge('cryptocount').innerHTML= ( 60 - count);
            }catch(e){}
        }else{
            eval( callback+'("'+ result+'")' );
        }
    }

    function JL_bccomp( a, b){
        if (a.length > b.length){ return 1; }   
        if (a.length < b.length){ return -1; }
        var i= 0; while ( a.charAt(i)==b.charAt(i) && ++i<a.length){ }
        if ( i==a.length){ return 0; }
        if ( parseInt( a.charAt(i)) > parseInt( b.charAt(i))){ return 1; }  
        return -1;      
    }

    function JL_bcadd( a, b){
        var zero= '00000000000000000000'; while ( zero.length < a.length + b.length){ zero+= ''+zero; } 
        if ( a.length < b.length){ a= ''+ zero.substring( 0, ( b.length - a.length )) + a; }
        if ( b.length < a.length){ b= ''+ zero.substring( 0, ( a.length - b.length )) + b; }
        var s= ('0'+a).split('');
        var t= 0;
        for (var i=0; i<a.length; i++){
            t= parseInt( s[s.length-i-1]) + parseInt( b.charAt( b.length-i-1));;
            if (t > 9){
                s[s.length-i-1]= t - 10;
                s[s.length-i-2]= parseInt( s[s.length-i-2]) + 1;
            }else{
                s[s.length-i-1]= t;
            }       
        }
        return trim( trim(( s.join('')+' '), '0'), '');
    }

    function JL_bcsub( a, b){
        var x= JL_bccomp( a, b);
        if ( x==0){
            return '0';
        }
        var minus= '';
        if ( x < 0){
            var x= a;
            a= b;
            b= x;
            minus= '-';
        }
        var s= a.split('');
        var t= 0;
        for (var i=0; i<s.length; i++){
            t= parseInt(s[s.length-i-1]);
            if ( i<b.length){ t= t - parseInt( b.charAt( b.length-i-1)); }
            if ( t<0){
                s[s.length-i-1]= t + 10;
                s[s.length-i-2]= s[s.length-i-2] - 1;
            }else{
                s[s.length-i-1]= parseInt( t);
            }       
        }
        return minus + trim( trim(( s.join('')+' '), '0'), '');
    }

    function JL_bcmul( a, b){
        var s= [];
        for (var i=0; i < a.length + b.length; i++){ s[i]= 0; }
        var t= 0;
        for (i=0; i<b.length; i++){ 
            for (var j=0; j<a.length; j++){
                t= s[i+j] + ( parseInt( a.charAt( a.length - j - 1)) * parseInt( b.charAt( b.length - i - 1))); 
                s[i+j]= t % 10;
                s[i+j+1]= s[i+j+1] + Math.floor( t / 10);
            }
        }
        s.reverse();
        return trim( trim(( s.join('')+' '), '0'), '');
    }

    function JL_bcdiv( a, b){
        var r= '0';
        var rr= '1';
        var e= b;
        var rrs= [];
        var es= [];
        var i= 0;
        while( JL_bccomp( a, b) >= 0){
            rr= '1';
            e= b;
            i= 0;
            while( JL_bccomp( a, e) >= 0){
                a= JL_bcsub( a, e);
                r= JL_bcadd( r, rr);
                if ( typeof es[i] == 'undefined'){
                    es[i]= JL_bcmul( e, '2');
                    rrs[i]= JL_bcmul( rr, '2');
                }
                e= es[i];
                rr= rrs[i];
                i++;
            }
        }
        // a is the remainder
        return r;
    }

    function JL_bcmod( a, m){
        var s= [];
        var e= m;
        var i= 0;
        while( JL_bccomp( a, m) >= 0){
            e= m;
            i= 0;
            while( JL_bccomp( a, e) >= 0){
                a= JL_bcsub( a, e);
                if ( typeof s[i] == 'undefined'){
                    s[i]= JL_bcmul( e, '2');
                } 
                e= s[i];
                i++;
            }
        }
        return a;
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top