Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80559 views
1
var assert = require('assert');
2
var BN = require('../').BN;
3
var fixtures = require('./fixtures');
4
5
describe('BN.js/Reduction context', function() {
6
function testMethod(name, fn) {
7
describe(name + ' method', function() {
8
it('should support add, iadd, sub, isub operations', function() {
9
var p = new BN(257);
10
var m = fn(p);
11
var a = new BN(123).toRed(m);
12
var b = new BN(231).toRed(m);
13
14
assert.equal(a.redAdd(b).fromRed().toString(10), '97');
15
assert.equal(a.redSub(b).fromRed().toString(10), '149');
16
assert.equal(b.redSub(a).fromRed().toString(10), '108');
17
18
assert.equal(a.clone().redIAdd(b).fromRed().toString(10), '97');
19
assert.equal(a.clone().redISub(b).fromRed().toString(10), '149');
20
assert.equal(b.clone().redISub(a).fromRed().toString(10), '108');
21
});
22
23
it('should support pow and mul operations', function() {
24
var p192 = new BN(
25
'fffffffffffffffffffffffffffffffeffffffffffffffff',
26
16);
27
var m = fn(p192);
28
var a = new BN(123);
29
var b = new BN(231);
30
var c = a.toRed(m).redMul(b.toRed(m)).fromRed();
31
assert(c.cmp(a.mul(b).mod(p192)) === 0);
32
33
assert.equal(a.toRed(m).redPow(new BN(3)).fromRed()
34
.cmp(a.sqr().mul(a)), 0);
35
assert.equal(a.toRed(m).redPow(new BN(4)).fromRed()
36
.cmp(a.sqr().sqr()), 0);
37
assert.equal(a.toRed(m).redPow(new BN(8)).fromRed()
38
.cmp(a.sqr().sqr().sqr()), 0);
39
assert.equal(a.toRed(m).redPow(new BN(9)).fromRed()
40
.cmp(a.sqr().sqr().sqr().mul(a)), 0);
41
assert.equal(a.toRed(m).redPow(new BN(17)).fromRed()
42
.cmp(a.sqr().sqr().sqr().sqr().mul(a)), 0);
43
});
44
45
it('should sqrtm numbers', function() {
46
var p = new BN(263);
47
var m = fn(p);
48
var q = new BN(11).toRed(m);
49
var qr = q.redSqrt(true, p);
50
assert.equal(qr.redSqr().cmp(q), 0);
51
var qr = q.redSqrt(false, p);
52
assert.equal(qr.redSqr().cmp(q), 0);
53
54
var p = new BN(
55
'fffffffffffffffffffffffffffffffeffffffffffffffff',
56
16);
57
var m = fn(p);
58
var q = new BN(13).toRed(m);
59
var qr = q.redSqrt(true, p);
60
assert.equal(qr.redSqr().cmp(q), 0);
61
var qr = q.redSqrt(false, p);
62
assert.equal(qr.redSqr().cmp(q), 0);
63
64
// Tonelli-shanks
65
var p = new BN(13);
66
var m = fn(p);
67
var q = new BN(10).toRed(m);
68
assert.equal(q.redSqrt().fromRed().toString(10), '7');
69
});
70
71
it('should invm numbers', function() {
72
var p = new BN(257);
73
var m = fn(p);
74
var a = new BN(3).toRed(m);
75
var b = a.redInvm(p);
76
assert.equal(a.redMul(b).fromRed().toString(16), '1');
77
});
78
79
it('should imul numbers', function() {
80
var p = new BN(
81
'fffffffffffffffffffffffffffffffeffffffffffffffff',
82
16);
83
var m = fn(p);
84
85
var a = new BN('deadbeefabbadead', 16);
86
var b = new BN('abbadeadbeefdead', 16);
87
var c = a.mul(b).mod(p);
88
89
assert.equal(a.toRed(m).redIMul(b.toRed(m)).fromRed().toString(16),
90
c.toString(16));
91
});
92
93
it('should pow(base, 0) == 1', function() {
94
var base = new BN(256).toRed( BN.red('k256'));
95
var exponent = new BN(0);
96
var result = base.redPow(exponent);
97
assert.equal(result.toString(), '1');
98
});
99
100
it('should reduce when converting to red', function() {
101
var p = new BN(257);
102
var m = fn(p);
103
var a = new BN(5).toRed(m);
104
105
assert.doesNotThrow(function() {
106
var b = a.redISub(new BN(512).toRed(m));
107
b.redISub(new BN(512).toRed(m));
108
});
109
});
110
});
111
}
112
113
testMethod('Plain', BN.red);
114
testMethod('Montgomery', BN.mont);
115
116
describe('Pseudo-Mersenne Primes', function() {
117
it('should reduce numbers mod k256', function() {
118
var p = BN._prime('k256');
119
120
assert.equal(p.ireduce(new BN(0xdead)).toString(16), 'dead');
121
assert.equal(p.ireduce(new BN('deadbeef', 16)).toString(16), 'deadbeef');
122
123
var num = new BN('fedcba9876543210fedcba9876543210dead' +
124
'fedcba9876543210fedcba9876543210dead',
125
16);
126
var exp = num.mod(p.p).toString(16);
127
assert.equal(p.ireduce(num).toString(16), exp);
128
129
var regr = new BN('f7e46df64c1815962bf7bc9c56128798' +
130
'3f4fcef9cb1979573163b477eab93959' +
131
'335dfb29ef07a4d835d22aa3b6797760' +
132
'70a8b8f59ba73d56d01a79af9',
133
16);
134
var exp = regr.mod(p.p).toString(16);
135
assert.equal(p.ireduce(regr).toString(16), exp);
136
});
137
138
it('should not fail to invm number mod k256', function() {
139
var regr2 = new BN(
140
'6c150c4aa9a8cf1934485d40674d4a7cd494675537bda36d49405c5d2c6f496f', 16);
141
regr2 = regr2.toRed(BN.red('k256'));
142
assert.equal(regr2.redInvm().redMul(regr2).fromRed().cmpn(1), 0);
143
});
144
145
it('should correctly square the number', function() {
146
var p = BN._prime('k256').p;
147
var red = BN.red('k256');
148
149
var n = new BN('9cd8cb48c3281596139f147c1364a3ed' +
150
'e88d3f310fdb0eb98c924e599ca1b3c9',
151
16);
152
var expected = n.sqr().mod(p);
153
var actual = n.toRed(red).redSqr().fromRed();
154
155
assert.equal(actual.toString(16), expected.toString(16));
156
});
157
});
158
});
159
160