RSA随机生成大素数C语言,使用伪造(或其他JavaScript方法)生成随机大素数

更新2014年6月11日:现在,使用forge版本0.6.6,您可以使用:

var bits = 1024;

forge.prime.generateProbablePrime(bits, function(err, num) {

console.log('random prime', num.toString(16));

});

在JavaScript中查找大质数是很困难的 – 它很慢并且你不想阻止主线程.它需要一些相当自定义的代码才能正确执行,而forge中的代码专门用于生成RSA密钥.没有API调用只是简单地产生一个大的随机素数.

如果您只是寻找单个素数,那么运行中的RSA代码会运行一些额外的操作,而您不需要这些操作.话虽这么说,过程中最慢的部分是实际找到素数,而不是那些额外的操作.但是,RSA代码还会生成两个素数(当您只需要一个素数时),它们与您正在寻找的不同.因此,如果你正在使用伪造的API,你必须传递一个8196的比特(我相信……这是我的头脑,所以它可能是不准确的)获得4096位素数.

找到大随机素数的一种方法如下:

>生成具有所需位数的随机数(确保设置了MSB).

>将数字对齐在30k 1边界上,因为所有素数都具有此属性.

>对你的号码进行素性测试(慢速部分);如果它通过,你就完成了,如果没有,加上数字到达下一个30k 1边界并重复. “快速”素性测试是检查低素数,然后使用Miller-Rabin(参见Handbook of Applied Cryptography 4.24).

步骤#3可以运行很长时间 – 这对于JavaScript(w / node或浏览器)来说通常是不可取的.为了缓解这种情况,您可以尝试将执行素性测试所花费的时间限制在某个可接受的时间段(N毫秒),或者您可以使用Web Workers来处理该过程.当然,这两种方法都使代码复杂化.

这里有一些代码用于生成不应该阻塞主线程的4096位随机素数:

var forge = require('node-forge');

var BigInteger = forge.jsbn.BigInteger;

// primes are 30k+i for i = 1, 7, 11, 13, 17, 19, 23, 29

var GCD_30_DELTA = [6, 4, 2, 4, 2, 4, 6, 2];

var THIRTY = new BigInteger(null);

THIRTY.fromInt(30);

// generate random BigInteger

var num = generateRandom(4096);

// find prime nearest to random number

findPrime(num, function(num) {

console.log('random', num.toString(16));

});

function generateRandom(bits) {

var rng = {

// x is an array to fill with bytes

nextBytes: function(x) {

var b = forge.random.getBytes(x.length);

for(var i = 0; i < x.length; ++i) {

x[i] = b.charCodeAt(i);

}

}

};

var num = new BigInteger(bits, rng);

// force MSB set

var bits1 = bits - 1;

if(!num.testBit(bits1)) {

var op_or = function(x,y) {return x|y;};

num.bitwiseTo(BigInteger.ONE.shiftLeft(bits1), op_or, num);

}

// align number on 30k+1 boundary

num.dAddOffset(31 - num.mod(THIRTY).byteValue(), 0);

return num;

}

function findPrime(num, callback) {

/* Note: All primes are of the form 30k+i for i < 30 and gcd(30, i)=1. The

number we are given is always aligned at 30k + 1. Each time the number is

determined not to be prime we add to get to the next 'i', eg: if the number

was at 30k + 1 we add 6. */

var deltaIdx = 0;

// find prime nearest to 'num' for 100ms

var start = Date.now();

while(Date.now() - start < 100) {

// do primality test (only 2 iterations assumes at

// least 1251 bits for num)

if(num.isProbablePrime(2)) {

return callback(num);

}

// get next potential prime

num.dAddOffset(GCD_30_DELTA[deltaIdx++ % 8], 0);

}

// keep trying (setImmediate would be better here)

setTimeout(function() {

findPrime(num, callback);

});

}

可以进行各种调整以根据您的需要进行调整,例如设置时间量(这只是一个估计值)来运行素数测试器,然后再次尝试下一个计划的滴答.每次保释时,您可能都需要某种UI反馈.如果您正在使用节点或支持setImmediate的浏览器,您可以使用它而不是setTimeout来避免钳位以加快速度.但是,请注意,在JavaScript中生成4096位随机素数需要一段时间(至少在撰写本文时).

Forge还有一个用于生成RSA密钥的Web Worker实现,旨在通过让多个线程使用不同的输入运行素性测试来加速进程.您可以查看forge源(例如prime.worker.js)以查看其中的操作,但它本身就是一个正常工作的项目.不过,IMO是加快速度的最佳方式.

无论如何,希望上面的代码可以帮助你.我用较小的比特来运行它来测试它.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值