javascript中的elgamal解密

javascript中的elgamal解密,javascript,encryption,elgamal,Javascript,Encryption,Elgamal,我需要一种计算方法: m = a. b ^(p-1-x) mod p 在javascript中。 我找到了计算基^exp%mod的算法: function expmod(base, exp, mod){ if (exp == 0) return 1; if (exp % 2 == 0){ return Math.pow((this.expmod(base, (exp / 2), mod)), 2) % mod; } else { return (base * (this.exp

我需要一种计算方法:

m = a. b ^(p-1-x) mod p
在javascript中。 我找到了计算基^exp%mod的算法:

function expmod(base, exp, mod){
if (exp == 0) return 1;
if (exp % 2 == 0){
    return Math.pow((this.expmod(base, (exp / 2), mod)), 2) % mod;
}
else {
    return (base * (this.expmod(base, (exp - 1), mod))) % mod;
}          
}

而且效果很好。但我似乎找不到一个方法来为你做这件事

m         = a. b ^(p-1-x) mod p

如果这个问题不完美,我很抱歉。这是我的第一个问题。谢谢。

我没有密码方面的经验,但是,既然没有其他人回答,我就试试看

你的问题在我看来没有什么意义,所以我决定用JavaScript实现一个完整的Elgamal,这样我就可以在上下文中理解你的问题。以下是我的想法:

// Abstract:

var Alphabet = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ \n𮃩∆";

Alphabet = Alphabet.split("");

var Crypto = function (alpha, gen, C) {
    var p, B, encrypt, decrypt, f, g, modInv, modPow, toAlpha, to10;
    toAlpha = function (x) {
        var y, p, l, n;
        if (x === 0) {
            return "!!!!";
        }
        y = [];
        n = 4;
        n = Math.ceil(n);
        while (n--) {
            p = Math.pow(alpha.length, n);
            l = Math.floor(x / p);
            y.push(alpha[l]);
            x -= l * p;
        }
        y = y.join("");
        return y;
    };
    to10 = function (x) {
        var y, p, n;
        y = 0;
        p = 1;
        x = x.split("");
        n = x.length;
        while (n--) {
            y += alpha.indexOf(x[n]) * p;
            p *= alpha.length;
        }
        return y;
    };
    modInv = function (gen, mod) {
        var v, d, u, t, c, q;
        v = 1;
        d = gen;
        t = 1;
        c = mod % gen;
        u = Math.floor(mod / gen);
        while (d > 1) {
            q = Math.floor(d / c);
            d = d % c;
            v = v + q * u;
            if (d) {
                q = Math.floor(c / d);
                c = c % d;
                u = u + q * v;
            }
        }
        return d ? v : mod - u;
    };
    modPow = function (base, exp, mod) {
        var c, x;
        if (exp === 0) {
            return 1;
        } else if (exp < 0) {
            exp = -exp;
            base = modInv(base, mod);
        }
        c = 1;
        while (exp > 0) {
            if (exp % 2 === 0) {
                base = (base * base) % mod;
                exp /= 2;
            } else {
                c = (c * base) % mod;
                exp--;
            }
        }
        return c;
    };
    p = 91744613;
    C = parseInt(C, 10);
    if (isNaN(C)) {
        C = Math.round(Math.sqrt(Math.random() * Math.random()) * (p - 2) + 2);
    }
    B = modPow(gen, C, p);
    decrypt = function (a) {
        var d, x, y;
        x = a[1];
        y = modPow(a[0], -C, p);
        d = (x * y) % p;
        d = Math.round(d) % p;
        return alpha[d - 2];
    };
    encrypt = function (key, d) {
        var k, a;
        k = Math.ceil(Math.sqrt(Math.random() * Math.random()) * 1E10);
        d = alpha.indexOf(d) + 2;
        a = [];
        a[0] = modPow(key[1], k, key[0]);
        a[1] = (d * modPow(key[2], k, key[0])) % key[0];
        return a;
    };
    f = function (message, key) {
        var n, x, y, w;
        y = [];
        message = message.split("");
        n = message.length;
        while (n--) {
            x = encrypt(key, message[n]);
            y.push(toAlpha(x[0]));
            y.push(toAlpha(x[1]));
        }
        y = y.join("");
        return y;
    };
    g = function (message) {
        var n, m, d, x;
        m = [];
        n = message.length / 8;
        while (n--) {
            x = message[8 * n + 4];
            x += message[8 * n + 5];
            x += message[8 * n + 6];
            x += message[8 * n + 7];
            m.unshift(x);
            x = message[8 * n];
            x += message[8 * n + 1];
            x += message[8 * n + 2];
            x += message[8 * n + 3];
            m.unshift(x);
        }
        x = [];
        d = [];
        n = m.length / 2;
        while (n--) {
            x[0] = m[2 * n];
            x[1] = m[2 * n + 1];
            x[0] = to10(x[0]);
            x[1] = to10(x[1]);
            d.push(decrypt(x));
        }
        message = d.join("");
        return message;
    };
    return {
        pubKey: [p, gen, B],
        priKey: C,
        decrypt: g,
        encrypt: f
    };
};

// Usage:

var Alice = Crypto(Alphabet, 69);

var Bob = Crypto(Alphabet, 69);

var message = "Hello!";
console.log(message);
// "Hello!"

message = Alice.encrypt(message, Bob.pubKey);
print(message);
// "Pl)7t&rfGueuL@|)H'P,*<K\.hxw+∆d*`?Io)lg~Adz-6xrR" or something like it.

message = Bob.decrypt(message);
console.log(message);
// "Hello!"
这里,
Alice
只是一个变量,
Alphabet
是我在代码顶部定义的29个符号的字母表,
69
是一个

然后,创建另一个加密对象来解密文本,然后保存它:

var Alice=Crypto(Alphabet, 69);
var Bob=Crypto(Alphabet, 69);
虽然
Bob
的创建方式与
Alice
相同,但它们是不同的对象。Bob无法解密针对Alice的文本,Alice也无法解密针对Bob的文本

现在,使用Alice的encrypt方法对一些文本进行加密,并保存结果:

var codedMessage=Alice.encrypt("HELLO, WORLD.", Bob.pubKey);

这里,
message
是一个空变量,
“你好,世界。”
是要加密的文本(或文本文件的内容)。key是Bob的公钥。我们必须在加密中使用Bob的密钥,这样Bob(并且只有Bob)才能解密文本。生成的加密文本看起来是这样的:
“Pl)7t&rfGueuL@|)H'P,*

我没有加密方面的经验,但是,既然没有其他人回答,我就试试看

你的问题在我看来没有什么意义,所以我决定用JavaScript实现一个完整的Elgamal,这样我就可以在上下文中理解你的问题。下面是我的想法:

// Abstract:

var Alphabet = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ \n𮃩∆";

Alphabet = Alphabet.split("");

var Crypto = function (alpha, gen, C) {
    var p, B, encrypt, decrypt, f, g, modInv, modPow, toAlpha, to10;
    toAlpha = function (x) {
        var y, p, l, n;
        if (x === 0) {
            return "!!!!";
        }
        y = [];
        n = 4;
        n = Math.ceil(n);
        while (n--) {
            p = Math.pow(alpha.length, n);
            l = Math.floor(x / p);
            y.push(alpha[l]);
            x -= l * p;
        }
        y = y.join("");
        return y;
    };
    to10 = function (x) {
        var y, p, n;
        y = 0;
        p = 1;
        x = x.split("");
        n = x.length;
        while (n--) {
            y += alpha.indexOf(x[n]) * p;
            p *= alpha.length;
        }
        return y;
    };
    modInv = function (gen, mod) {
        var v, d, u, t, c, q;
        v = 1;
        d = gen;
        t = 1;
        c = mod % gen;
        u = Math.floor(mod / gen);
        while (d > 1) {
            q = Math.floor(d / c);
            d = d % c;
            v = v + q * u;
            if (d) {
                q = Math.floor(c / d);
                c = c % d;
                u = u + q * v;
            }
        }
        return d ? v : mod - u;
    };
    modPow = function (base, exp, mod) {
        var c, x;
        if (exp === 0) {
            return 1;
        } else if (exp < 0) {
            exp = -exp;
            base = modInv(base, mod);
        }
        c = 1;
        while (exp > 0) {
            if (exp % 2 === 0) {
                base = (base * base) % mod;
                exp /= 2;
            } else {
                c = (c * base) % mod;
                exp--;
            }
        }
        return c;
    };
    p = 91744613;
    C = parseInt(C, 10);
    if (isNaN(C)) {
        C = Math.round(Math.sqrt(Math.random() * Math.random()) * (p - 2) + 2);
    }
    B = modPow(gen, C, p);
    decrypt = function (a) {
        var d, x, y;
        x = a[1];
        y = modPow(a[0], -C, p);
        d = (x * y) % p;
        d = Math.round(d) % p;
        return alpha[d - 2];
    };
    encrypt = function (key, d) {
        var k, a;
        k = Math.ceil(Math.sqrt(Math.random() * Math.random()) * 1E10);
        d = alpha.indexOf(d) + 2;
        a = [];
        a[0] = modPow(key[1], k, key[0]);
        a[1] = (d * modPow(key[2], k, key[0])) % key[0];
        return a;
    };
    f = function (message, key) {
        var n, x, y, w;
        y = [];
        message = message.split("");
        n = message.length;
        while (n--) {
            x = encrypt(key, message[n]);
            y.push(toAlpha(x[0]));
            y.push(toAlpha(x[1]));
        }
        y = y.join("");
        return y;
    };
    g = function (message) {
        var n, m, d, x;
        m = [];
        n = message.length / 8;
        while (n--) {
            x = message[8 * n + 4];
            x += message[8 * n + 5];
            x += message[8 * n + 6];
            x += message[8 * n + 7];
            m.unshift(x);
            x = message[8 * n];
            x += message[8 * n + 1];
            x += message[8 * n + 2];
            x += message[8 * n + 3];
            m.unshift(x);
        }
        x = [];
        d = [];
        n = m.length / 2;
        while (n--) {
            x[0] = m[2 * n];
            x[1] = m[2 * n + 1];
            x[0] = to10(x[0]);
            x[1] = to10(x[1]);
            d.push(decrypt(x));
        }
        message = d.join("");
        return message;
    };
    return {
        pubKey: [p, gen, B],
        priKey: C,
        decrypt: g,
        encrypt: f
    };
};

// Usage:

var Alice = Crypto(Alphabet, 69);

var Bob = Crypto(Alphabet, 69);

var message = "Hello!";
console.log(message);
// "Hello!"

message = Alice.encrypt(message, Bob.pubKey);
print(message);
// "Pl)7t&rfGueuL@|)H'P,*<K\.hxw+∆d*`?Io)lg~Adz-6xrR" or something like it.

message = Bob.decrypt(message);
console.log(message);
// "Hello!"
这里,
Alice
只是一个变量,
Alphabet
是我在代码顶部定义的29个符号的字母表,
69
是一个

然后,创建另一个加密对象来解密文本,然后保存它:

var Alice=Crypto(Alphabet, 69);
var Bob=Crypto(Alphabet, 69);
虽然创建
Bob
的方式与创建
Alice
的方式相同,但它们是不同的对象。Bob无法解密针对Alice的文本,Alice也无法解密针对Bob的文本

现在,使用Alice的encrypt方法对一些文本进行加密,并保存结果:

var codedMessage=Alice.encrypt("HELLO, WORLD.", Bob.pubKey);

这里,
message
是一个空变量,
“你好,世界。”
是要加密的文本(或文本文件的内容)。Bob.key是Bob的公钥。我们必须在加密中使用Bob的密钥,以便Bob(并且只有Bob)可以解密文本。生成的加密文本将如下所示:
“Pl)7t&rfGueuL@)H'p,*当你说“a.b”时,“a”是物体吗?或者,“.”是另一种语言的连接运算符?“a”和“b”是and对象。“a.b”的意思是a乘以b(a×b)。当你说“a.b”时,“a”是物体吗?或者,“.”是另一种语言的连接运算符?“a”和“b”是and对象。“a.b”是指a乘以b(a×b)。是的,先生。我还有一个问题,我如何用它来加密文本文件?你是说用我的代码?我已经实现了加密和解密函数,您可以在代码段的底部看到这些函数。我将编辑我的答案,以包含更具体的信息。@user3543541,我已经做了一些编辑,应该可以回答您的其他问题。我想将此应用于thunderbird插件,并且需要手动输入公钥(y、g和p),以便alice和bob可以交换密钥并手动加密和解密。我该怎么做?我很抱歉有这么多问题,先生。那么,我认为你没有做太多的JavaScript编码,对吗?我对Thunderbird了解不多,所以我不确定为它制作附加组件涉及到什么。在我看来,你想要的是Elgamal的用户界面。我会用HTML为您创建一个最小的,并发送一个链接。是的,先生。我还有一个问题,我如何用它来加密文本文件?你是说用我的代码?我已经实现了加密和解密函数,您可以在代码段的底部看到这些函数。我将编辑我的答案,以包含更具体的信息。@user3543541,我已经做了一些编辑,应该可以回答您的其他问题。我想将此应用于thunderbird插件,并且需要手动输入公钥(y、g和p),以便alice和bob可以交换密钥并手动加密和解密。我该怎么做?我很抱歉有这么多问题,先生。那么,我认为你没有做太多的JavaScript编码,对吗?我对Thunderbird了解不多,所以我不确定为它制作附加组件涉及到什么。在我看来,你想要的是Elgamal的用户界面。我将用HTML为您构建一个最小的,并向您发送一个链接。