dist/util/ed25519/common.js   A
last analyzed

Complexity

Total Complexity 37
Complexity/F 2.31

Size

Lines of Code 307
Function Count 16

Duplication

Duplicated Lines 0
Ratio 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 179
dl 0
loc 307
ccs 147
cts 147
cp 1
rs 9.44
c 0
b 0
f 0
wmc 37
mnd 21
bc 21
fnc 16
bpm 1.3125
cpm 2.3125
noi 0

16 Functions

Rating   Name   Duplication   Size   Complexity  
A common.js ➔ fnA 0 5 2
A common.js ➔ fnZ 0 5 2
A common.js ➔ fnM 0 15 4
A common.js ➔ add 0 29 1
A common.js ➔ modLSub 0 17 4
A common.js ➔ scalarmult 0 13 2
A common.js ➔ pack 0 10 1
A common.js ➔ pack25519 0 23 4
A common.js ➔ inv25519 0 11 3
A common.js ➔ cswap 0 5 2
A common.js ➔ scalarbase 0 8 1
A common.js ➔ modL 0 16 3
A common.js ➔ reduce 0 5 1
A common.js ➔ car25519 0 9 4
A common.js ➔ par25519 0 5 1
A common.js ➔ sel25519 0 8 2
1
/**
2
 * @license
3
 * Copyright (c) 2020 UMI
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a copy
6
 * of this software and associated documentation files (the "Software"), to deal
7
 * in the Software without restriction, including without limitation the rights
8
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the Software is
10
 * furnished to do so, subject to the following conditions:
11
 *
12
 * The above copyright notice and this permission notice shall be included in all
13
 * copies or substantial portions of the Software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
 * SOFTWARE.
22
 */
23
24
'use strict'
25
26 1
const array = require('../array.js')
27
28 1
const gf0 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
29 1
const gf1 = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
30 1
const D2 = [
31
  0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0,
32
  0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406
33
]
34 1
const X = [
35
  0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c,
36
  0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169
37
]
38 1
const Y = [
39
  0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666,
40
  0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666
41
]
42 1
const L = [
43
  0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2,
44
  0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10
45
]
46
/**
47
 * @param {number[]} r
48
 * @private
49
 */
50
function reduce (r) {
51 7
  const x = r.slice(0)
52 7
  array.arrayFill(r, 64)
53 7
  modL(r, x)
54
}
55
/**
56
 * @param {number[]} r
57
 * @param {number[]} x
58
 * @returns {number[]}
59
 * @private
60
 */
61
function modL (r, x) {
62
  let carry
63
  let j
64
  let k
65 9
  for (let i = 63; i >= 32; --i) {
66 288
    carry = 0
67 288
    for (j = i - 32, k = i - 12; j < k; ++j) {
68 5760
      x[j] += carry - 16 * x[i] * L[j - (i - 32)]
69 5760
      carry = Math.floor((x[j] + 128) / 256)
70 5760
      x[j] -= carry * 256
71
    }
72 288
    x[j] += carry
73 288
    x[i] = 0
74
  }
75 9
  return modLSub(r, x)
76
}
77
/**
78
 * @param {number[]} r
79
 * @param {number[]} x
80
 * @returns {number[]}
81
 * @private
82
 */
83
function modLSub (r, x) {
84 9
  let carry = 0
85
  let i
86 9
  for (i = 0; i < 32; i++) {
87 288
    x[i] += carry - (x[31] >> 4) * L[i]
88 288
    carry = x[i] >> 8
89 288
    x[i] &= 255
90
  }
91 9
  for (i = 0; i < 32; i++) {
92 288
    x[i] -= carry * L[i]
93
  }
94 9
  for (i = 0; i < 32; i++) {
95 288
    x[i + 1] += x[i] >> 8
96 288
    r[i] = x[i] & 255
97
  }
98 9
  return r
99
}
100
/**
101
 * @param {number[][]} p
102
 * @param {number[][]} q
103
 * @param {number[]} s
104
 * @private
105
 */
106
function scalarmult (p, q, s) {
107 13
  array.arraySet(p[0], gf0)
108 13
  array.arraySet(p[1], gf1)
109 13
  array.arraySet(p[2], gf1)
110 13
  array.arraySet(p[3], gf0)
111 13
  for (let i = 255; i >= 0; --i) {
112 3328
    const b = (s[(i / 8) | 0] >> (i & 7)) & 1
113 3328
    cswap(p, q, b)
114 3328
    add(q, p)
115 3328
    add(p, p)
116 3328
    cswap(p, q, b)
117
  }
118
}
119
/**
120
 * @param {number[][]} p
121
 * @param {number[][]} q
122
 * @param {number} b
123
 * @private
124
 */
125
function cswap (p, q, b) {
126 6656
  for (let i = 0; i < 4; i++) {
127 26624
    sel25519(p[i], q[i], b)
128
  }
129
}
130
/**
131
 * @param {number[][]} p
132
 * @param {number[][]} q
133
 * @private
134
 */
135
function add (p, q) {
136 6659
  const a = []
137 6659
  const b = []
138 6659
  const c = []
139 6659
  const d = []
140 6659
  const e = []
141 6659
  const f = []
142 6659
  const g = []
143 6659
  const h = []
144 6659
  const t = []
145 6659
  fnZ(a, p[1], p[0])
146 6659
  fnZ(t, q[1], q[0])
147 6659
  fnM(a, a, t)
148 6659
  fnA(b, p[0], p[1])
149 6659
  fnA(t, q[0], q[1])
150 6659
  fnM(b, b, t)
151 6659
  fnM(c, p[3], q[3])
152 6659
  fnM(c, c, D2)
153 6659
  fnM(d, p[2], q[2])
154 6659
  fnA(d, d, d)
155 6659
  fnZ(e, b, a)
156 6659
  fnZ(f, d, c)
157 6659
  fnA(g, d, c)
158 6659
  fnA(h, b, a)
159 6659
  fnM(p[0], e, f)
160 6659
  fnM(p[1], h, g)
161 6659
  fnM(p[2], g, f)
162 6659
  fnM(p[3], e, h)
163
}
164
/**
165
 * @param {number[]} o
166
 * @param {number[]} a
167
 * @param {number[]} b
168
 * @private
169
 */
170
function fnA (o, a, b) {
171 33298
  for (let i = 0; i < 16; i++) {
172 532768
    o[i] = a[i] + b[i]
173
  }
174
}
175
/**
176
 * @param {number[]} o
177
 * @param {number[]} a
178
 * @param {number[]} b
179
 * @private
180
 */
181
function fnM (o, a, b) {
182 66573
  const t = array.arrayNew(31)
183
  let i
184 66573
  for (i = 0; i < 16; i++) {
185 1065168
    for (let j = 0; j < 16; j++) {
186 17042688
      t[i + j] += a[i] * b[j]
187
    }
188
  }
189 66573
  for (i = 0; i < 15; i++) {
190 998595
    t[i] += 38 * t[i + 16]
191
  }
192 66573
  array.arraySet(o, t, 0, 16)
193 66573
  car25519(o)
194 66573
  car25519(o)
195
}
196
/**
197
 * @param {number[]} o
198
 * @param {number[]} a
199
 * @param {number[]} b
200
 * @private
201
 */
202
function fnZ (o, a, b) {
203 26640
  for (let i = 0; i < 16; i++) {
204 426240
    o[i] = a[i] - b[i]
205
  }
206
}
207
/**
208
 * @param {number[][]} p
209
 * @param {number[]} s
210
 * @private
211
 */
212
function scalarbase (p, s) {
213 10
  const q = [[], [], [], []]
214 10
  array.arraySet(q[0], X)
215 10
  array.arraySet(q[1], Y)
216 10
  array.arraySet(q[2], gf1)
217 10
  fnM(q[3], X, Y)
218 10
  scalarmult(p, q, s)
219
}
220
/**
221
 * @param {number[]} o
222
 * @private
223
 */
224
function car25519 (o) {
225
  let c
226 133251
  for (let i = 0; i < 16; i++) {
227 2132016
    o[i] += 65536
228 2132016
    c = (o[i] - (o[i] & 0xffff)) / 65536
229 2132016
    o[(i + 1) * (i < 15 ? 1 : 0)] += c - 1 + 37 * (c - 1) * (i === 15 ? 1 : 0)
230 2132016
    o[i] -= c * 65536
231
  }
232
}
233
/**
234
 * @param {number[]} r
235
 * @param {number[][]} p
236
 * @private
237
 */
238
function pack (r, p) {
239 10
  const tx = []
240 10
  const ty = []
241 10
  const zi = []
242 10
  inv25519(zi, p[2])
243 10
  fnM(tx, p[0], zi)
244 10
  fnM(ty, p[1], zi)
245 10
  pack25519(r, ty)
246 10
  r[31] ^= par25519(tx) << 7
247
}
248
/**
249
 * @param {number[]} a
250
 * @returns {number}
251
 * @private
252
 */
253
function par25519 (a) {
254 13
  const d = []
255 13
  pack25519(d, a)
256 13
  return d[0] & 1
257
}
258
/**
259
 * @param {number[]} o
260
 * @param {number[]} i
261
 * @private
262
 */
263
function inv25519 (o, i) {
264 10
  const c = []
265 10
  array.arraySet(c, i)
266 10
  for (let a = 253; a >= 0; a--) {
267 2540
    fnM(c, c, c)
268 2540
    if (a !== 2 && a !== 4) {
269 2520
      fnM(c, c, i)
270
    }
271
  }
272 10
  array.arraySet(o, c)
273
}
274
/**
275
 * @param {number[]} p
276
 * @param {number[]} q
277
 * @param {number} b
278
 * @private
279
 */
280
function sel25519 (p, q, b) {
281 26694
  const c = ~(b - 1)
282 26694
  for (let i = 0; i < 16; i++) {
283 427104
    const t = c & (p[i] ^ q[i])
284 427104
    p[i] ^= t
285 427104
    q[i] ^= t
286
  }
287
}
288
/**
289
 * @param {number[]} o
290
 * @param {number[]} n
291
 * @private
292
 */
293
function pack25519 (o, n) {
294 35
  const m = []
295 35
  const t = n.slice(0)
296 35
  car25519(t)
297 35
  car25519(t)
298 35
  car25519(t)
299
  let i
300 35
  for (let j = 0; j < 2; j++) {
301 70
    m[0] = t[0] - 0xffed
302 70
    for (i = 1; i < 15; i++) {
303 980
      m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1)
304 980
      m[i - 1] &= 0xffff
305
    }
306 70
    m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1)
307 70
    const b = (m[15] >> 16) & 1
308 70
    m[14] &= 0xffff
309 70
    sel25519(t, m, 1 - b)
310
  }
311 35
  for (i = 0; i < 16; i++) {
312 560
    o[2 * i] = t[i] & 0xff
313 560
    o[2 * i + 1] = t[i] >> 8
314
  }
315
}
316
317 1
exports.add = add
318 1
exports.car25519 = car25519
319 1
exports.fnA = fnA
320 1
exports.fnM = fnM
321 1
exports.fnZ = fnZ
322 1
exports.gf0 = gf0
323 1
exports.gf1 = gf1
324 1
exports.modL = modL
325 1
exports.pack = pack
326 1
exports.pack25519 = pack25519
327 1
exports.par25519 = par25519
328 1
exports.reduce = reduce
329 1
exports.scalarbase = scalarbase
330
exports.scalarmult = scalarmult
331