+++ /dev/null
-// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-import blake2b from 'blake2b'
-
-/**
-* Derived from:
-* - mipher
-* - tweetnacl
-* - ed2curve-js
-*
-* With added types etc
-*/
-export default class Curve25519 {
- gf0: Int32Array
- gf1: Int32Array
- D: Int32Array
- D2: Int32Array
- I: Int32Array
- _9: Uint8Array
- _121665: Int32Array
- _0: Uint8Array
- sigma: Uint8Array
- minusp: Uint32Array
-
- constructor () {
- this.gf0 = this.gf()
- this.gf1 = this.gf([1])
- this._9 = new Uint8Array(32)
- this._9[0] = 9
- this._121665 = this.gf([0xdb41, 1])
- this.D = this.gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203])
- this.D2 = this.gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406])
- this.I = this.gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83])
- this._0 = new Uint8Array(16)
- this.sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107])
- this.minusp = new Uint32Array([5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252])
- }
-
- gf (init?: number[]): Int32Array {
- const r = new Int32Array(16)
- if (init) {
- for (let i = 0; i < init.length; i++) {
- r[i] = init[i]
- }
- }
-
- return r
- }
-
- A (o: Int32Array, a: Int32Array, b: Int32Array): void {
- for (let i = 0; i < 16; i++) {
- o[i] = a[i] + b[i]
- }
- }
-
- Z (o: Int32Array, a: Int32Array, b: Int32Array): void {
- for (let i = 0; i < 16; i++) {
- o[i] = a[i] - b[i]
- }
- }
-
- // Avoid loops for better performance
- M (o: Int32Array, a: Int32Array, b: Int32Array): void {
- let v, c,
- t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0,
- t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0,
- t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0,
- t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0
- const b0 = b[0],
- b1 = b[1],
- b2 = b[2],
- b3 = b[3],
- b4 = b[4],
- b5 = b[5],
- b6 = b[6],
- b7 = b[7],
- b8 = b[8],
- b9 = b[9],
- b10 = b[10],
- b11 = b[11],
- b12 = b[12],
- b13 = b[13],
- b14 = b[14],
- b15 = b[15]
-
- v = a[0]
- t0 += v * b0
- t1 += v * b1
- t2 += v * b2
- t3 += v * b3
- t4 += v * b4
- t5 += v * b5
- t6 += v * b6
- t7 += v * b7
- t8 += v * b8
- t9 += v * b9
- t10 += v * b10
- t11 += v * b11
- t12 += v * b12
- t13 += v * b13
- t14 += v * b14
- t15 += v * b15
- v = a[1]
- t1 += v * b0
- t2 += v * b1
- t3 += v * b2
- t4 += v * b3
- t5 += v * b4
- t6 += v * b5
- t7 += v * b6
- t8 += v * b7
- t9 += v * b8
- t10 += v * b9
- t11 += v * b10
- t12 += v * b11
- t13 += v * b12
- t14 += v * b13
- t15 += v * b14
- t16 += v * b15
- v = a[2]
- t2 += v * b0
- t3 += v * b1
- t4 += v * b2
- t5 += v * b3
- t6 += v * b4
- t7 += v * b5
- t8 += v * b6
- t9 += v * b7
- t10 += v * b8
- t11 += v * b9
- t12 += v * b10
- t13 += v * b11
- t14 += v * b12
- t15 += v * b13
- t16 += v * b14
- t17 += v * b15
- v = a[3]
- t3 += v * b0
- t4 += v * b1
- t5 += v * b2
- t6 += v * b3
- t7 += v * b4
- t8 += v * b5
- t9 += v * b6
- t10 += v * b7
- t11 += v * b8
- t12 += v * b9
- t13 += v * b10
- t14 += v * b11
- t15 += v * b12
- t16 += v * b13
- t17 += v * b14
- t18 += v * b15
- v = a[4]
- t4 += v * b0
- t5 += v * b1
- t6 += v * b2
- t7 += v * b3
- t8 += v * b4
- t9 += v * b5
- t10 += v * b6
- t11 += v * b7
- t12 += v * b8
- t13 += v * b9
- t14 += v * b10
- t15 += v * b11
- t16 += v * b12
- t17 += v * b13
- t18 += v * b14
- t19 += v * b15
- v = a[5]
- t5 += v * b0
- t6 += v * b1
- t7 += v * b2
- t8 += v * b3
- t9 += v * b4
- t10 += v * b5
- t11 += v * b6
- t12 += v * b7
- t13 += v * b8
- t14 += v * b9
- t15 += v * b10
- t16 += v * b11
- t17 += v * b12
- t18 += v * b13
- t19 += v * b14
- t20 += v * b15
- v = a[6]
- t6 += v * b0
- t7 += v * b1
- t8 += v * b2
- t9 += v * b3
- t10 += v * b4
- t11 += v * b5
- t12 += v * b6
- t13 += v * b7
- t14 += v * b8
- t15 += v * b9
- t16 += v * b10
- t17 += v * b11
- t18 += v * b12
- t19 += v * b13
- t20 += v * b14
- t21 += v * b15
- v = a[7]
- t7 += v * b0
- t8 += v * b1
- t9 += v * b2
- t10 += v * b3
- t11 += v * b4
- t12 += v * b5
- t13 += v * b6
- t14 += v * b7
- t15 += v * b8
- t16 += v * b9
- t17 += v * b10
- t18 += v * b11
- t19 += v * b12
- t20 += v * b13
- t21 += v * b14
- t22 += v * b15
- v = a[8]
- t8 += v * b0
- t9 += v * b1
- t10 += v * b2
- t11 += v * b3
- t12 += v * b4
- t13 += v * b5
- t14 += v * b6
- t15 += v * b7
- t16 += v * b8
- t17 += v * b9
- t18 += v * b10
- t19 += v * b11
- t20 += v * b12
- t21 += v * b13
- t22 += v * b14
- t23 += v * b15
- v = a[9]
- t9 += v * b0
- t10 += v * b1
- t11 += v * b2
- t12 += v * b3
- t13 += v * b4
- t14 += v * b5
- t15 += v * b6
- t16 += v * b7
- t17 += v * b8
- t18 += v * b9
- t19 += v * b10
- t20 += v * b11
- t21 += v * b12
- t22 += v * b13
- t23 += v * b14
- t24 += v * b15
- v = a[10]
- t10 += v * b0
- t11 += v * b1
- t12 += v * b2
- t13 += v * b3
- t14 += v * b4
- t15 += v * b5
- t16 += v * b6
- t17 += v * b7
- t18 += v * b8
- t19 += v * b9
- t20 += v * b10
- t21 += v * b11
- t22 += v * b12
- t23 += v * b13
- t24 += v * b14
- t25 += v * b15
- v = a[11]
- t11 += v * b0
- t12 += v * b1
- t13 += v * b2
- t14 += v * b3
- t15 += v * b4
- t16 += v * b5
- t17 += v * b6
- t18 += v * b7
- t19 += v * b8
- t20 += v * b9
- t21 += v * b10
- t22 += v * b11
- t23 += v * b12
- t24 += v * b13
- t25 += v * b14
- t26 += v * b15
- v = a[12]
- t12 += v * b0
- t13 += v * b1
- t14 += v * b2
- t15 += v * b3
- t16 += v * b4
- t17 += v * b5
- t18 += v * b6
- t19 += v * b7
- t20 += v * b8
- t21 += v * b9
- t22 += v * b10
- t23 += v * b11
- t24 += v * b12
- t25 += v * b13
- t26 += v * b14
- t27 += v * b15
- v = a[13]
- t13 += v * b0
- t14 += v * b1
- t15 += v * b2
- t16 += v * b3
- t17 += v * b4
- t18 += v * b5
- t19 += v * b6
- t20 += v * b7
- t21 += v * b8
- t22 += v * b9
- t23 += v * b10
- t24 += v * b11
- t25 += v * b12
- t26 += v * b13
- t27 += v * b14
- t28 += v * b15
- v = a[14]
- t14 += v * b0
- t15 += v * b1
- t16 += v * b2
- t17 += v * b3
- t18 += v * b4
- t19 += v * b5
- t20 += v * b6
- t21 += v * b7
- t22 += v * b8
- t23 += v * b9
- t24 += v * b10
- t25 += v * b11
- t26 += v * b12
- t27 += v * b13
- t28 += v * b14
- t29 += v * b15
- v = a[15]
- t15 += v * b0
- t16 += v * b1
- t17 += v * b2
- t18 += v * b3
- t19 += v * b4
- t20 += v * b5
- t21 += v * b6
- t22 += v * b7
- t23 += v * b8
- t24 += v * b9
- t25 += v * b10
- t26 += v * b11
- t27 += v * b12
- t28 += v * b13
- t29 += v * b14
- t30 += v * b15
-
- t0 += 38 * t16
- t1 += 38 * t17
- t2 += 38 * t18
- t3 += 38 * t19
- t4 += 38 * t20
- t5 += 38 * t21
- t6 += 38 * t22
- t7 += 38 * t23
- t8 += 38 * t24
- t9 += 38 * t25
- t10 += 38 * t26
- t11 += 38 * t27
- t12 += 38 * t28
- t13 += 38 * t29
- t14 += 38 * t30
-
- c = 1
- v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536
- v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536
- v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536
- v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536
- v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536
- v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536
- v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536
- v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536
- v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536
- v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536
- v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536
- v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536
- v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536
- v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536
- v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536
- v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536
- t0 += c - 1 + 37 * (c - 1)
-
- c = 1
- v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536
- v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536
- v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536
- v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536
- v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536
- v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536
- v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536
- v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536
- v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536
- v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536
- v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536
- v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536
- v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536
- v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536
- v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536
- v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536
- t0 += c - 1 + 37 * (c - 1)
-
- o[0] = t0
- o[1] = t1
- o[2] = t2
- o[3] = t3
- o[4] = t4
- o[5] = t5
- o[6] = t6
- o[7] = t7
- o[8] = t8
- o[9] = t9
- o[10] = t10
- o[11] = t11
- o[12] = t12
- o[13] = t13
- o[14] = t14
- o[15] = t15
- }
-
- S (o: Int32Array, a: Int32Array): void {
- this.M(o, a, a)
- }
-
- add (p: Int32Array[], q: Int32Array[]): void {
- const a = this.gf(), b = this.gf(), c = this.gf(),
- d = this.gf(), e = this.gf(), f = this.gf(),
- g = this.gf(), h = this.gf(), t = this.gf()
-
- this.Z(a, p[1], p[0])
- this.Z(t, q[1], q[0])
- this.M(a, a, t)
- this.A(b, p[0], p[1])
- this.A(t, q[0], q[1])
- this.M(b, b, t)
- this.M(c, p[3], q[3])
- this.M(c, c, this.D2)
- this.M(d, p[2], q[2])
- this.A(d, d, d)
- this.Z(e, b, a)
- this.Z(f, d, c)
- this.A(g, d, c)
- this.A(h, b, a)
- this.M(p[0], e, f)
- this.M(p[1], h, g)
- this.M(p[2], g, f)
- this.M(p[3], e, h)
- }
-
- set25519 (r: Int32Array, a: Int32Array): void {
- for (let i = 0; i < 16; i++) {
- r[i] = a[i]
- }
- }
-
- car25519 (o: Int32Array): void {
- let i, v, c = 1
- for (i = 0; i < 16; i++) {
- v = o[i] + c + 65535
- c = Math.floor(v / 65536)
- o[i] = v - c * 65536
- }
-
- o[0] += c - 1 + 37 * (c - 1)
- }
-
- // b is 0 or 1
- sel25519 (p: Int32Array, q: Int32Array, b: number): void {
- let i, t
- const c = ~(b - 1)
- for (i = 0; i < 16; i++) {
- t = c & (p[i] ^ q[i])
- p[i] ^= t
- q[i] ^= t
- }
- }
-
- inv25519 (o: Int32Array, i: Int32Array): void {
- let a
- const c = this.gf()
- for (a = 0; a < 16; a++) {
- c[a] = i[a]
- }
-
- for (a = 253; a >= 0; a--) {
- this.S(c, c)
- if (a !== 2 && a !== 4) {
- this.M(c, c, i)
- }
- }
-
- for (a = 0; a < 16; a++) {
- o[a] = c[a]
- }
- }
-
- neq25519 (a: Int32Array, b: Int32Array): boolean {
- const c = new Uint8Array(32), d = new Uint8Array(32)
- this.pack25519(c, a)
- this.pack25519(d, b)
- if (c.length !== d.length) return true
- for (let i = 0; i < c.length; i++) {
- if (c[i] !== d[i]) return true
- }
- return false
- }
-
- par25519 (a: Int32Array): number {
- const d = new Uint8Array(32)
- this.pack25519(d, a)
- return d[0] & 1
- }
-
- pow2523 (o: Int32Array, i: Int32Array): void {
- let a
- const c = this.gf()
- for (a = 0; a < 16; a++) {
- c[a] = i[a]
- }
-
- for (a = 250; a >= 0; a--) {
- this.S(c, c)
- if (a !== 1) this.M(c, c, i)
- }
-
- for (a = 0; a < 16; a++) {
- o[a] = c[a]
- }
- }
-
- cswap (p: Int32Array[], q: Int32Array[], b: number): void {
- for (let i = 0; i < 4; i++) {
- this.sel25519(p[i], q[i], b)
- }
- }
-
- pack25519 (o: Uint8Array, n: Int32Array): void {
- let i
- const m = this.gf()
- const t = this.gf()
- for (i = 0; i < 16; i++) {
- t[i] = n[i]
- }
-
- this.car25519(t)
- this.car25519(t)
- this.car25519(t)
- for (let j = 0; j < 2; j++) {
- m[0] = t[0] - 0xffed
- for (i = 1; i < 15; i++) {
- m[i] = t[i] - 0xffff - ((m[i - 1] >>> 16) & 1)
- m[i - 1] &= 0xffff
- }
-
- m[15] = t[15] - 0x7fff - ((m[14] >>> 16) & 1)
- const b = (m[15] >>> 16) & 1
- m[14] &= 0xffff
- this.sel25519(t, m, 1 - b)
- }
-
- for (i = 0; i < 16; i++) {
- o[2 * i] = t[i] & 0xff
- o[2 * i + 1] = t[i] >>> 8
- }
- }
-
- unpack25519 (o: Int32Array, n: Uint8Array): void {
- for (let i = 0; i < 16; i++) {
- o[i] = n[2 * i] + (n[2 * i + 1] << 8)
- }
-
- o[15] &= 0x7fff
- }
-
- unpackNeg (r: Int32Array[], p: Uint8Array): number {
- const t = this.gf(),
- chk = this.gf(),
- num = this.gf(),
- den = this.gf(),
- den2 = this.gf(),
- den4 = this.gf(),
- den6 = this.gf()
-
- this.set25519(r[2], this.gf1)
- this.unpack25519(r[1], p)
- this.S(num, r[1])
- this.M(den, num, this.D)
- this.Z(num, num, r[2])
- this.A(den, r[2], den)
-
- this.S(den2, den)
- this.S(den4, den2)
- this.M(den6, den4, den2)
- this.M(t, den6, num)
- this.M(t, t, den)
-
- this.pow2523(t, t)
- this.M(t, t, num)
- this.M(t, t, den)
- this.M(t, t, den)
- this.M(r[0], t, den)
-
- this.S(chk, r[0])
- this.M(chk, chk, den)
- if (this.neq25519(chk, num)) {
- this.M(r[0], r[0], this.I)
- }
-
- this.S(chk, r[0])
- this.M(chk, chk, den)
- if (this.neq25519(chk, num)) {
- return -1
- }
-
- if (this.par25519(r[0]) === (p[31] >>> 7)) {
- this.Z(r[0], this.gf0, r[0])
- }
-
- this.M(r[3], r[0], r[1])
-
- return 0
- }
-
- /**
- * Converts a ed25519 public key to Curve25519 to be used in
- * Diffie-Hellman key exchange
- */
- convertEd25519PublicKeyToCurve25519 (pk: Uint8Array) {
- const z = new Uint8Array(32)
- const q = [this.gf(), this.gf(), this.gf(), this.gf()]
- const a = this.gf()
- const b = this.gf()
-
- if (this.unpackNeg(q, pk)) {
- return null
- }
-
- const y = q[1]
-
- this.A(a, this.gf1, y)
- this.Z(b, this.gf1, y)
- this.inv25519(b, b)
- this.M(a, a, b)
-
- this.pack25519(z, a)
-
- return z
- }
-
- /**
- * Converts a ed25519 private key to Curve25519 to be used in
- * Diffie-Hellman key exchange
- */
- convertEd25519PrivateKeyToCurve25519 (sk: Uint8Array) {
- const d = new Uint8Array(64)
- const o = new Uint8Array(32)
- let i
-
- this.cryptoHash(d, sk, 32)
- d[0] &= 248
- d[31] &= 127
- d[31] |= 64
-
- for (i = 0; i < 32; i++) {
- o[i] = d[i]
- }
- for (i = 0; i < 64; i++) {
- d[i] = 0
- }
- return o
- }
-
- cryptoHash (out: Uint8Array, m: Uint8Array, n: number): number {
- const input = new Uint8Array(n)
- for (let i = 0; i < n; ++i) {
- input[i] = m[i]
- }
- const hash = blake2b(64).update(input).digest()
- for (let i = 0; i < 64; ++i) {
- out[i] = hash[i]
- }
- return 0
- }
-}
+++ /dev/null
-// SPDX-FileCopyrightText: 2024 Chris Duncan <chris@zoso.dev>\r
-// SPDX-License-Identifier: GPL-3.0-or-later\r
-\r
-import blake2b from 'blake2b'\r
-import { bytes, hex } from './convert.js'\r
-import Curve25519 from './curve25519.js'\r
-\r
-type KeyPair = {\r
- privateKey: string\r
- publicKey: string\r
-}\r
-\r
-const curve = new Curve25519()\r
-const X: Int32Array = curve.gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169])\r
-const Y: Int32Array = curve.gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666])\r
-const L: Uint8Array = new Uint8Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10])\r
-\r
-/**\r
-* Generate a public key from a private key using the Ed25519 algorithm. The key\r
-* should be a cryptographically strong random value.\r
-*\r
-* @param {string} privateKey - 32-byte hexadecimal private key\r
-* @returns {string} 32-byte hexadecimal public key\r
-*/\r
-function getPublicKey (privateKey: string): string {\r
- const pk = new Uint8Array(32)\r
- const p = [curve.gf(), curve.gf(), curve.gf(), curve.gf()]\r
- const h = blake2b(64).update(hex.toBytes(privateKey)).digest().slice(0, 32)\r
-\r
- h[0] &= 0xf8\r
- h[31] &= 0x7f\r
- h[31] |= 0x40\r
-\r
- scalarbase(p, h)\r
- pack(pk, p)\r
-\r
- return bytes.toHex(pk)\r
-}\r
-\r
-/**\r
-* Convert Ed25519 keypair to Curve25519 keypair suitable for Diffie-Hellman key exchange\r
-*\r
-* @param {KeyPair} keyPair - Ed25519 keypair\r
-* @returns {KeyPair} Curve25519 keypair\r
-*/\r
-function convertKeys (keyPair: KeyPair): KeyPair {\r
- const pubKeyBuf = hex.toBytes(keyPair.publicKey)\r
- const ab: (Uint8Array | null) = curve.convertEd25519PublicKeyToCurve25519(pubKeyBuf)\r
- if (ab == null) {\r
- throw new Error('Invalid key pair')\r
- }\r
- const publicKey = bytes.toHex(ab) ?? ''\r
- if (publicKey === '') {\r
- throw new Error('Invalid key pair')\r
- }\r
- const privKeyBuf = hex.toBytes(keyPair.privateKey)\r
- const privateKey = bytes.toHex(curve.convertEd25519PrivateKeyToCurve25519(privKeyBuf))\r
- return {\r
- publicKey,\r
- privateKey,\r
- }\r
-}\r
-\r
-/**\r
-* Generate a message signature\r
-* @param {Uint8Array} msg - Message to be signed\r
-* @param {Uint8Array} privateKey - Private key to use for signing\r
-* @returns {Uint8Array} 64-byte signature\r
-*/\r
-function sign (msg: Uint8Array, privateKey: Uint8Array): Uint8Array {\r
- return naclSign(msg, privateKey).slice(0, 64)\r
-}\r
-\r
-/**\r
-* Verify a message signature\r
-* @param {Uint8Array} msg - Message to be signed as byte array\r
-* @param {Uint8Array} publicKey - Public key as byte array\r
-* @param {Uint8Array} signature - Signature as byte array\r
-* @returns {boolean} True if `msg` was signed by `publicKey`, else false\r
-*/\r
-function verify (msg: Uint8Array, publicKey: Uint8Array, signature: Uint8Array): boolean {\r
- const CURVE = curve\r
- const p = [CURVE.gf(), CURVE.gf(), CURVE.gf(), CURVE.gf()]\r
- const q = [CURVE.gf(), CURVE.gf(), CURVE.gf(), CURVE.gf()]\r
-\r
- if (signature.length !== 64) {\r
- return false\r
- }\r
- if (publicKey.length !== 32) {\r
- return false\r
- }\r
- if (CURVE.unpackNeg(q, publicKey)) {\r
- return false\r
- }\r
-\r
- const k = blake2b(64)\r
- .update(signature.subarray(0, 32))\r
- .update(publicKey)\r
- .update(msg)\r
- .digest()\r
- reduce(k)\r
- scalarmult(p, q, k)\r
-\r
- let t = new Uint8Array(32)\r
- scalarbase(q, signature.subarray(32))\r
- CURVE.add(p, q)\r
- pack(t, p)\r
-\r
- if (signature.subarray(0, 32).length !== t.length) return false\r
- for (let i = 0; i < t.length; i++) {\r
- if (signature.subarray(0, 32)[i] !== t[i]) return false\r
- }\r
- return true\r
-}\r
-\r
-function pack (r: Uint8Array, p: Int32Array[]): void {\r
- const CURVE = curve\r
- const tx = CURVE.gf(),\r
- ty = CURVE.gf(),\r
- zi = CURVE.gf()\r
- CURVE.inv25519(zi, p[2])\r
- CURVE.M(tx, p[0], zi)\r
- CURVE.M(ty, p[1], zi)\r
- CURVE.pack25519(r, ty)\r
- r[31] ^= CURVE.par25519(tx) << 7\r
-}\r
-\r
-function modL (r: Uint8Array, x: Uint32Array | Float64Array): void {\r
- let carry, i, j, k\r
- for (i = 63; i >= 32; --i) {\r
- carry = 0\r
- for (j = i - 32, k = i - 12; j < k; ++j) {\r
- x[j] += carry - 16 * x[i] * L[j - (i - 32)]\r
- carry = (x[j] + 128) >> 8\r
- x[j] -= carry * 256\r
- }\r
- x[j] += carry\r
- x[i] = 0\r
- }\r
-\r
- carry = 0\r
- for (j = 0; j < 32; j++) {\r
- x[j] += carry - (x[31] >> 4) * L[j]\r
- carry = x[j] >> 8\r
- x[j] &= 255\r
- }\r
- for (j = 0; j < 32; j++) {\r
- x[j] -= carry * L[j]\r
- }\r
- for (i = 0; i < 32; i++) {\r
- x[i + 1] += x[i] >>> 8\r
- r[i] = x[i] & 0xff\r
- }\r
-}\r
-\r
-function reduce (r: Uint8Array): void {\r
- const x = new Uint32Array(64)\r
- for (let i = 0; i < 64; i++) {\r
- x[i] = r[i]\r
- }\r
- modL(r, x)\r
-}\r
-\r
-function scalarmult (p: Int32Array[], q: Int32Array[], s: Uint8Array): void {\r
- const CURVE = curve\r
- CURVE.set25519(p[0], CURVE.gf0)\r
- CURVE.set25519(p[1], CURVE.gf1)\r
- CURVE.set25519(p[2], CURVE.gf1)\r
- CURVE.set25519(p[3], CURVE.gf0)\r
- for (let i = 255; i >= 0; --i) {\r
- const b = (s[(i / 8) | 0] >>> (i & 7)) & 1\r
- CURVE.cswap(p, q, b)\r
- CURVE.add(q, p)\r
- CURVE.add(p, p)\r
- CURVE.cswap(p, q, b)\r
- }\r
-}\r
-\r
-function scalarbase (p: Int32Array[], s: Uint8Array): void {\r
- const CURVE = curve\r
- const q = [CURVE.gf(), CURVE.gf(), CURVE.gf(), CURVE.gf()]\r
- CURVE.set25519(q[0], X)\r
- CURVE.set25519(q[1], Y)\r
- CURVE.set25519(q[2], CURVE.gf1)\r
- CURVE.M(q[3], X, Y)\r
- scalarmult(p, q, s)\r
-}\r
-\r
-function naclSign (msg: Uint8Array, privateKey: Uint8Array): Uint8Array {\r
- if (privateKey.length !== 32) {\r
- throw new Error('bad private key size')\r
- }\r
- const signedMsg = new Uint8Array(64 + msg.length)\r
- cryptoSign(signedMsg, msg, msg.length, privateKey)\r
- return signedMsg\r
-}\r
-\r
-function cryptoSign (sm: Uint8Array, m: Uint8Array, n: number, sk: Uint8Array): number {\r
- const CURVE = curve\r
- const d = new Uint8Array(64)\r
- const h = new Uint8Array(64)\r
- const r = new Uint8Array(64)\r
- const x = new Float64Array(64)\r
- const p = [CURVE.gf(), CURVE.gf(), CURVE.gf(), CURVE.gf()]\r
-\r
- let i\r
- let j\r
-\r
- const pubKey = getPublicKey(bytes.toHex(sk))\r
- const pk = hex.toBytes(pubKey)\r
-\r
- curve.cryptoHash(d, sk, 32)\r
- d[0] &= 248\r
- d[31] &= 127\r
- d[31] |= 64\r
-\r
- const smlen = n + 64\r
- for (i = 0; i < n; i++) {\r
- sm[64 + i] = m[i]\r
- }\r
- for (i = 0; i < 32; i++) {\r
- sm[32 + i] = d[32 + i]\r
- }\r
-\r
- curve.cryptoHash(r, sm.subarray(32), n + 32)\r
- reduce(r)\r
- scalarbase(p, r)\r
- pack(sm, p)\r
-\r
- for (i = 32; i < 64; i++) {\r
- sm[i] = pk[i - 32]\r
- }\r
-\r
- curve.cryptoHash(h, sm, n + 64)\r
- reduce(h)\r
-\r
- for (i = 0; i < 64; i++) {\r
- x[i] = 0\r
- }\r
- for (i = 0; i < 32; i++) {\r
- x[i] = r[i]\r
- }\r
- for (i = 0; i < 32; i++) {\r
- for (j = 0; j < 32; j++) {\r
- x[i + j] += h[i] * d[j]\r
- }\r
- }\r
-\r
- modL(sm.subarray(32), x)\r
-\r
- return smlen\r
-}\r
-\r
-export default { convertKeys, getPublicKey, sign, verify }\r