1 |
|
2 | const { _9, _121665, gf, inv25519, pack25519, unpack25519, sel25519, A, M, Z, S } = require('./internal/ed25519')
|
3 |
|
4 | const crypto_scalarmult_BYTES = 32
|
5 | const crypto_scalarmult_SCALARBYTES = 32
|
6 |
|
7 | module.exports = {
|
8 | crypto_scalarmult,
|
9 | crypto_scalarmult_base,
|
10 | crypto_scalarmult_BYTES,
|
11 | crypto_scalarmult_SCALARBYTES
|
12 | }
|
13 |
|
14 | function crypto_scalarmult (q, n, p) {
|
15 | check(q, crypto_scalarmult_BYTES)
|
16 | check(n, crypto_scalarmult_SCALARBYTES)
|
17 | check(p, crypto_scalarmult_BYTES)
|
18 | var z = new Uint8Array(32)
|
19 | var x = new Float64Array(80), r, i
|
20 | var a = gf(), b = gf(), c = gf(),
|
21 | d = gf(), e = gf(), f = gf()
|
22 | for (i = 0; i < 31; i++) z[i] = n[i]
|
23 | z[31] = (n[31] & 127) | 64
|
24 | z[0] &= 248
|
25 | unpack25519(x, p)
|
26 | for (i = 0; i < 16; i++) {
|
27 | b[i] = x[i]
|
28 | d[i] = a[i] = c[i] = 0
|
29 | }
|
30 | a[0] = d[0] = 1
|
31 | for (i = 254; i >= 0; --i) {
|
32 | r = (z[i >>> 3] >>> (i & 7)) & 1
|
33 | sel25519(a, b, r)
|
34 | sel25519(c, d, r)
|
35 | A(e, a, c)
|
36 | Z(a, a, c)
|
37 | A(c, b, d)
|
38 | Z(b, b, d)
|
39 | S(d, e)
|
40 | S(f, a)
|
41 | M(a, c, a)
|
42 | M(c, b, e)
|
43 | A(e, a, c)
|
44 | Z(a, a, c)
|
45 | S(b, a)
|
46 | Z(c, d, f)
|
47 | M(a, c, _121665)
|
48 | A(a, a, d)
|
49 | M(c, c, a)
|
50 | M(a, d, f)
|
51 | M(d, b, x)
|
52 | S(b, e)
|
53 | sel25519(a, b, r)
|
54 | sel25519(c, d, r)
|
55 | }
|
56 | for (i = 0; i < 16; i++) {
|
57 | x[i + 16] = a[i]
|
58 | x[i + 32] = c[i]
|
59 | x[i + 48] = b[i]
|
60 | x[i + 64] = d[i]
|
61 | }
|
62 | var x32 = x.subarray(32)
|
63 | var x16 = x.subarray(16)
|
64 | inv25519(x32, x32)
|
65 | M(x16, x16, x32)
|
66 | pack25519(q, x16)
|
67 | return 0
|
68 | }
|
69 |
|
70 | function crypto_scalarmult_base (q, n) {
|
71 | return crypto_scalarmult(q, n, _9)
|
72 | }
|
73 |
|
74 | function check (buf, len) {
|
75 | if (!buf || (len && buf.length < len)) throw new Error('Argument must be a buffer' + (len ? ' of length ' + len : ''))
|
76 | }
|