├── .npmignore ├── .gitignore ├── .prettierrc ├── tslint.json ├── tsconfig.json ├── examples └── index.js ├── package.json ├── LICENSE ├── README.md └── src └── index.ts /.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | examples/ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | npm-debug.log 3 | lib/ -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "trailingComma": "all", 4 | "singleQuote": true, 5 | "tabWidth": 2 6 | } -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:recommended", "tslint-config-prettier"], 3 | "linterOptions": { 4 | "exclude": ["node_modules/**/*.ts"] 5 | }, 6 | "rules": { 7 | "no-bitwise": false, 8 | "no-console": false 9 | } 10 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "outDir": "./lib", 7 | "experimentalDecorators": true, 8 | "emitDecoratorMetadata": true, 9 | "allowSyntheticDefaultImports": true, 10 | "strict": true, 11 | "skipLibCheck": true, 12 | "declaration": true, 13 | "noUnusedLocals": false 14 | }, 15 | "exclude": [ 16 | "node_modules", 17 | "lib", 18 | "examples" 19 | ] 20 | } -------------------------------------------------------------------------------- /examples/index.js: -------------------------------------------------------------------------------- 1 | const crypto = require('crypto'); 2 | const sharedKey = require('../lib/index.js').sharedKey; 3 | const generateKeyPair = require('../lib/index.js').generateKeyPair; 4 | 5 | const ALICE_PRIV = '77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a'; 6 | const BOB_PUB = 'de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f'; 7 | 8 | const alicePriv = Uint8Array.from(Buffer.from(ALICE_PRIV, 'hex')); 9 | 10 | const bobPub = Uint8Array.from(Buffer.from(BOB_PUB, 'hex')); 11 | 12 | const secret = sharedKey(alicePriv, bobPub); 13 | 14 | const keyPair = generateKeyPair(crypto.randomBytes(32)); 15 | const privKey = Buffer.from(keyPair.private).toString('hex'); 16 | const pubKey = Buffer.from(keyPair.public).toString('hex') 17 | 18 | console.log('Secret: ', Buffer.from(secret).toString('hex')) 19 | console.log('Private: ', privKey) 20 | console.log('Public: ', pubKey) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "curve25519-js", 3 | "version": "0.0.4", 4 | "description": "Javascript implementation of Curve25519", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "build": "tsc", 8 | "format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"", 9 | "lint": "tslint -p tsconfig.json" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/harveyconnor/curve25519-js.git" 14 | }, 15 | "author": "Harvey Connor ", 16 | "license": "MIT", 17 | "bugs": { 18 | "url": "https://github.com/harveyconnor/curve25519-js/issues" 19 | }, 20 | "homepage": "https://github.com/harveyconnor/curve25519-js#readme", 21 | "keywords": [ 22 | "sign", 23 | "curve25519", 24 | "x25519", 25 | "ed25519" 26 | ], 27 | "devDependencies": { 28 | "@types/node": "^12.6.9", 29 | "prettier": "^1.18.2", 30 | "tslint": "^5.18.0", 31 | "tslint-config-prettier": "^1.18.0", 32 | "typescript": "^3.5.3" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 Smart Guide Pty Ltd 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 19 | OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # curve25519-js 2 | 3 | Curve25519 signatures with X25519 keys. 4 | 5 | ![NPM Version](https://img.shields.io/npm/v/curve25519-js) 6 | ![NPM Downloads](https://img.shields.io/npm/dm/curve25519-js) 7 | 8 | ## Installation 9 | 10 | ``` 11 | npm i curve25519-js 12 | ``` 13 | 14 | ## Usage 15 | 16 | ```js 17 | import { sharedKey } from 'curve25519-js'; 18 | 19 | const ALICE_PRIV = '77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a'; 20 | const BOB_PUB = 'de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f'; 21 | 22 | const alicePriv = Uint8Array.from(Buffer.from(ALICE_PRIV, 'hex')); 23 | 24 | const bobPub = Uint8Array.from(Buffer.from(BOB_PUB, 'hex')); 25 | 26 | const secret = sharedKey(alicePriv, bobPub); 27 | 28 | console.log('Secret:', Buffer.from(secret).toString('hex')) 29 | ``` 30 | 31 | ## Functions 32 | 33 | ### generateKeyPair 34 | Generates a new key pair from the given 32-byte secret seed (which should be generated with a CSPRNG) and returns it as object: 35 | ```ts 36 | generateKeyPair(seed: Uint8Array(32)): { 37 | private: Uint8Array(32); 38 | public: Uint8Array(32); 39 | } 40 | ``` 41 | The returned keys can be used for signing and key agreement. 42 | 43 | ### sign 44 | 45 | Signs the given message using the private key and returns signature. 46 | 47 | ```ts 48 | sign(secretKey: Uint8Array(32), message: any, [random: Uint8Array(64)]): Uint8Array(64) 49 | ``` 50 | 51 | Optional random data argument (which must have 64 random bytes) turns on 52 | hash separation and randomization to make signatures non-deterministic. 53 | 54 | ### verify 55 | 56 | Verifies the given signature for the message using the given private key. 57 | Returns `true` if the signature is valid, `false` otherwise. 58 | 59 | ```ts 60 | verify(publicKey: Uint8Array(32), message: any, signature: Uint8Array(64)): boolean 61 | ``` 62 | 63 | ### signMessage 64 | 65 | Signs the given message using the private key and returns 66 | a signed message (signature concatenated with the message copy). 67 | 68 | ```ts 69 | signMessage(secretKey: Uint8Array(32), message: any, [random: Uint8Array(64)]): any 70 | ``` 71 | 72 | Optional random data argument (which must have 64 random bytes) turns on 73 | hash separation and randomization to make signatures non-deterministic. 74 | 75 | ### openMessage 76 | 77 | Verifies signed message with the public key and returns the original message 78 | without signature if it's correct or `null` if verification fails. 79 | 80 | ```ts 81 | openMessage(publicKey: Uint8Array(32), signedMessage: any): Message | null 82 | ``` 83 | 84 | 85 | ### sharedKey 86 | Returns a raw shared key between own private key and peer's public key (in other words, this is an ECC Diffie-Hellman function X25519, performing scalar multiplication). 87 | 88 | The result should not be used directly as a key, but should be processed with a one-way function (e.g. HSalsa20 as in NaCl, or any secure cryptographic hash function, such as SHA-256, or key derivation function, such as HKDF). 89 | ```ts 90 | sharedKey(privateKey: Uint8Array(32), publicKey: Uint8Array(32)): Uint8Array(32) 91 | ``` 92 | 93 | ## How is it different from Ed25519? 94 | Axlsign allows calculating key agreement and signing using just a single X25519 key instead of two different X25519 and Ed25519 keys. 95 | 96 | It uses keys in X25519 format (Montgomery), while Ed25519 uses keys in a different representation (Twisted Edwards). Internally, it converts keys to the correct format, but since such conversion would lose a sign bit, it also embeds the sign bit from public key into signature during signing, and puts it back into the key during verification. 97 | 98 | Note: if signing and performing key agreement with a single key is needed, but using keys in X25519 format is not a requrement, a better choice is to use Ed25519 keys, and then convert them to X25519 keys for key agreement (e.g. using ). This allows using only an external conversion functions without changing signature algorithms and formats. 99 | 100 | ## Credits 101 | 102 | Re-written in 2019 with TypeScript support by Harvey Connor. 103 | 104 | Written in 2016 by Dmitry Chestnykh. 105 | You can use it under MIT or CC0 license. 106 | 107 | Curve25519 signatures idea and math by Trevor Perrin 108 | 109 | 110 | Derived from TweetNaCl.js . 111 | Ported in 2014 by Dmitry Chestnykh and Devi Mandiri. Public domain. 112 | Implementation derived from TweetNaCl version 20140427 113 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | let _0 = new Uint8Array(16); 2 | let _9 = new Uint8Array(32); 3 | _9[0] = 9; 4 | 5 | function gf(init?: any) { 6 | var i, r = new Float64Array(16); 7 | if (init) for (i = 0; i < init.length; i++) r[i] = init[i]; 8 | return r; 9 | }; 10 | 11 | const gf0 = gf(), 12 | gf1 = gf([1]), 13 | _121665 = gf([0xdb41, 1]), 14 | D = gf([ 15 | 0x78a3, 16 | 0x1359, 17 | 0x4dca, 18 | 0x75eb, 19 | 0xd8ab, 20 | 0x4141, 21 | 0x0a4d, 22 | 0x0070, 23 | 0xe898, 24 | 0x7779, 25 | 0x4079, 26 | 0x8cc7, 27 | 0xfe73, 28 | 0x2b6f, 29 | 0x6cee, 30 | 0x5203, 31 | ]), 32 | D2 = gf([ 33 | 0xf159, 34 | 0x26b2, 35 | 0x9b94, 36 | 0xebd6, 37 | 0xb156, 38 | 0x8283, 39 | 0x149a, 40 | 0x00e0, 41 | 0xd130, 42 | 0xeef3, 43 | 0x80f2, 44 | 0x198e, 45 | 0xfce7, 46 | 0x56df, 47 | 0xd9dc, 48 | 0x2406, 49 | ]), 50 | X = gf([ 51 | 0xd51a, 52 | 0x8f25, 53 | 0x2d60, 54 | 0xc956, 55 | 0xa7b2, 56 | 0x9525, 57 | 0xc760, 58 | 0x692c, 59 | 0xdc5c, 60 | 0xfdd6, 61 | 0xe231, 62 | 0xc0a4, 63 | 0x53fe, 64 | 0xcd6e, 65 | 0x36d3, 66 | 0x2169, 67 | ]), 68 | Y = gf([ 69 | 0x6658, 70 | 0x6666, 71 | 0x6666, 72 | 0x6666, 73 | 0x6666, 74 | 0x6666, 75 | 0x6666, 76 | 0x6666, 77 | 0x6666, 78 | 0x6666, 79 | 0x6666, 80 | 0x6666, 81 | 0x6666, 82 | 0x6666, 83 | 0x6666, 84 | 0x6666, 85 | ]), 86 | I = gf([ 87 | 0xa0b0, 88 | 0x4a0e, 89 | 0x1b27, 90 | 0xc4ee, 91 | 0xe478, 92 | 0xad2f, 93 | 0x1806, 94 | 0x2f43, 95 | 0xd7a7, 96 | 0x3dfb, 97 | 0x0099, 98 | 0x2b4d, 99 | 0xdf0b, 100 | 0x4fc1, 101 | 0x2480, 102 | 0x2b83, 103 | ]); 104 | 105 | function ts64(x: any, i: any, h: any, l: any) { 106 | x[i] = (h >> 24) & 0xff; 107 | x[i + 1] = (h >> 16) & 0xff; 108 | x[i + 2] = (h >> 8) & 0xff; 109 | x[i + 3] = h & 0xff; 110 | x[i + 4] = (l >> 24) & 0xff; 111 | x[i + 5] = (l >> 16) & 0xff; 112 | x[i + 6] = (l >> 8) & 0xff; 113 | x[i + 7] = l & 0xff; 114 | } 115 | 116 | function vn(x: any, xi: any, y: any, yi: any, n: any) { 117 | var i, 118 | d = 0; 119 | for (i = 0; i < n; i++) d |= x[xi + i] ^ y[yi + i]; 120 | return (1 & ((d - 1) >>> 8)) - 1; 121 | } 122 | 123 | function crypto_verify_32(x: any, xi: any, y: any, yi: any) { 124 | return vn(x, xi, y, yi, 32); 125 | } 126 | 127 | function set25519(r: any, a: any) { 128 | var i; 129 | for (i = 0; i < 16; i++) r[i] = a[i] | 0; 130 | } 131 | 132 | function car25519(o: any) { 133 | var i, 134 | v, 135 | c = 1; 136 | for (i = 0; i < 16; i++) { 137 | v = o[i] + c + 65535; 138 | c = Math.floor(v / 65536); 139 | o[i] = v - c * 65536; 140 | } 141 | o[0] += c - 1 + 37 * (c - 1); 142 | } 143 | 144 | function sel25519(p: any, q: any, b: any) { 145 | var t, 146 | c = ~(b - 1); 147 | for (var i = 0; i < 16; i++) { 148 | t = c & (p[i] ^ q[i]); 149 | p[i] ^= t; 150 | q[i] ^= t; 151 | } 152 | } 153 | 154 | function pack25519(o: any, n: any) { 155 | var i, j, b; 156 | var m = gf(), 157 | t = gf(); 158 | for (i = 0; i < 16; i++) t[i] = n[i]; 159 | car25519(t); 160 | car25519(t); 161 | car25519(t); 162 | for (j = 0; j < 2; j++) { 163 | m[0] = t[0] - 0xffed; 164 | for (i = 1; i < 15; i++) { 165 | m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1); 166 | m[i - 1] &= 0xffff; 167 | } 168 | m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1); 169 | b = (m[15] >> 16) & 1; 170 | m[14] &= 0xffff; 171 | sel25519(t, m, 1 - b); 172 | } 173 | for (i = 0; i < 16; i++) { 174 | o[2 * i] = t[i] & 0xff; 175 | o[2 * i + 1] = t[i] >> 8; 176 | } 177 | } 178 | 179 | function neq25519(a: any, b: any) { 180 | var c = new Uint8Array(32), 181 | d = new Uint8Array(32); 182 | pack25519(c, a); 183 | pack25519(d, b); 184 | return crypto_verify_32(c, 0, d, 0); 185 | } 186 | 187 | function par25519(a: any) { 188 | var d = new Uint8Array(32); 189 | pack25519(d, a); 190 | return d[0] & 1; 191 | } 192 | 193 | function unpack25519(o: any, n: any) { 194 | var i; 195 | for (i = 0; i < 16; i++) o[i] = n[2 * i] + (n[2 * i + 1] << 8); 196 | o[15] &= 0x7fff; 197 | } 198 | 199 | function A(o: any, a: any, b: any) { 200 | for (var i = 0; i < 16; i++) o[i] = a[i] + b[i]; 201 | } 202 | 203 | function Z(o: any, a: any, b: any) { 204 | for (var i = 0; i < 16; i++) o[i] = a[i] - b[i]; 205 | } 206 | 207 | function M(o: any, a: any, b: any) { 208 | var v, 209 | c, 210 | t0 = 0, 211 | t1 = 0, 212 | t2 = 0, 213 | t3 = 0, 214 | t4 = 0, 215 | t5 = 0, 216 | t6 = 0, 217 | t7 = 0, 218 | t8 = 0, 219 | t9 = 0, 220 | t10 = 0, 221 | t11 = 0, 222 | t12 = 0, 223 | t13 = 0, 224 | t14 = 0, 225 | t15 = 0, 226 | t16 = 0, 227 | t17 = 0, 228 | t18 = 0, 229 | t19 = 0, 230 | t20 = 0, 231 | t21 = 0, 232 | t22 = 0, 233 | t23 = 0, 234 | t24 = 0, 235 | t25 = 0, 236 | t26 = 0, 237 | t27 = 0, 238 | t28 = 0, 239 | t29 = 0, 240 | t30 = 0, 241 | b0 = b[0], 242 | b1 = b[1], 243 | b2 = b[2], 244 | b3 = b[3], 245 | b4 = b[4], 246 | b5 = b[5], 247 | b6 = b[6], 248 | b7 = b[7], 249 | b8 = b[8], 250 | b9 = b[9], 251 | b10 = b[10], 252 | b11 = b[11], 253 | b12 = b[12], 254 | b13 = b[13], 255 | b14 = b[14], 256 | b15 = b[15]; 257 | 258 | v = a[0]; 259 | t0 += v * b0; 260 | t1 += v * b1; 261 | t2 += v * b2; 262 | t3 += v * b3; 263 | t4 += v * b4; 264 | t5 += v * b5; 265 | t6 += v * b6; 266 | t7 += v * b7; 267 | t8 += v * b8; 268 | t9 += v * b9; 269 | t10 += v * b10; 270 | t11 += v * b11; 271 | t12 += v * b12; 272 | t13 += v * b13; 273 | t14 += v * b14; 274 | t15 += v * b15; 275 | v = a[1]; 276 | t1 += v * b0; 277 | t2 += v * b1; 278 | t3 += v * b2; 279 | t4 += v * b3; 280 | t5 += v * b4; 281 | t6 += v * b5; 282 | t7 += v * b6; 283 | t8 += v * b7; 284 | t9 += v * b8; 285 | t10 += v * b9; 286 | t11 += v * b10; 287 | t12 += v * b11; 288 | t13 += v * b12; 289 | t14 += v * b13; 290 | t15 += v * b14; 291 | t16 += v * b15; 292 | v = a[2]; 293 | t2 += v * b0; 294 | t3 += v * b1; 295 | t4 += v * b2; 296 | t5 += v * b3; 297 | t6 += v * b4; 298 | t7 += v * b5; 299 | t8 += v * b6; 300 | t9 += v * b7; 301 | t10 += v * b8; 302 | t11 += v * b9; 303 | t12 += v * b10; 304 | t13 += v * b11; 305 | t14 += v * b12; 306 | t15 += v * b13; 307 | t16 += v * b14; 308 | t17 += v * b15; 309 | v = a[3]; 310 | t3 += v * b0; 311 | t4 += v * b1; 312 | t5 += v * b2; 313 | t6 += v * b3; 314 | t7 += v * b4; 315 | t8 += v * b5; 316 | t9 += v * b6; 317 | t10 += v * b7; 318 | t11 += v * b8; 319 | t12 += v * b9; 320 | t13 += v * b10; 321 | t14 += v * b11; 322 | t15 += v * b12; 323 | t16 += v * b13; 324 | t17 += v * b14; 325 | t18 += v * b15; 326 | v = a[4]; 327 | t4 += v * b0; 328 | t5 += v * b1; 329 | t6 += v * b2; 330 | t7 += v * b3; 331 | t8 += v * b4; 332 | t9 += v * b5; 333 | t10 += v * b6; 334 | t11 += v * b7; 335 | t12 += v * b8; 336 | t13 += v * b9; 337 | t14 += v * b10; 338 | t15 += v * b11; 339 | t16 += v * b12; 340 | t17 += v * b13; 341 | t18 += v * b14; 342 | t19 += v * b15; 343 | v = a[5]; 344 | t5 += v * b0; 345 | t6 += v * b1; 346 | t7 += v * b2; 347 | t8 += v * b3; 348 | t9 += v * b4; 349 | t10 += v * b5; 350 | t11 += v * b6; 351 | t12 += v * b7; 352 | t13 += v * b8; 353 | t14 += v * b9; 354 | t15 += v * b10; 355 | t16 += v * b11; 356 | t17 += v * b12; 357 | t18 += v * b13; 358 | t19 += v * b14; 359 | t20 += v * b15; 360 | v = a[6]; 361 | t6 += v * b0; 362 | t7 += v * b1; 363 | t8 += v * b2; 364 | t9 += v * b3; 365 | t10 += v * b4; 366 | t11 += v * b5; 367 | t12 += v * b6; 368 | t13 += v * b7; 369 | t14 += v * b8; 370 | t15 += v * b9; 371 | t16 += v * b10; 372 | t17 += v * b11; 373 | t18 += v * b12; 374 | t19 += v * b13; 375 | t20 += v * b14; 376 | t21 += v * b15; 377 | v = a[7]; 378 | t7 += v * b0; 379 | t8 += v * b1; 380 | t9 += v * b2; 381 | t10 += v * b3; 382 | t11 += v * b4; 383 | t12 += v * b5; 384 | t13 += v * b6; 385 | t14 += v * b7; 386 | t15 += v * b8; 387 | t16 += v * b9; 388 | t17 += v * b10; 389 | t18 += v * b11; 390 | t19 += v * b12; 391 | t20 += v * b13; 392 | t21 += v * b14; 393 | t22 += v * b15; 394 | v = a[8]; 395 | t8 += v * b0; 396 | t9 += v * b1; 397 | t10 += v * b2; 398 | t11 += v * b3; 399 | t12 += v * b4; 400 | t13 += v * b5; 401 | t14 += v * b6; 402 | t15 += v * b7; 403 | t16 += v * b8; 404 | t17 += v * b9; 405 | t18 += v * b10; 406 | t19 += v * b11; 407 | t20 += v * b12; 408 | t21 += v * b13; 409 | t22 += v * b14; 410 | t23 += v * b15; 411 | v = a[9]; 412 | t9 += v * b0; 413 | t10 += v * b1; 414 | t11 += v * b2; 415 | t12 += v * b3; 416 | t13 += v * b4; 417 | t14 += v * b5; 418 | t15 += v * b6; 419 | t16 += v * b7; 420 | t17 += v * b8; 421 | t18 += v * b9; 422 | t19 += v * b10; 423 | t20 += v * b11; 424 | t21 += v * b12; 425 | t22 += v * b13; 426 | t23 += v * b14; 427 | t24 += v * b15; 428 | v = a[10]; 429 | t10 += v * b0; 430 | t11 += v * b1; 431 | t12 += v * b2; 432 | t13 += v * b3; 433 | t14 += v * b4; 434 | t15 += v * b5; 435 | t16 += v * b6; 436 | t17 += v * b7; 437 | t18 += v * b8; 438 | t19 += v * b9; 439 | t20 += v * b10; 440 | t21 += v * b11; 441 | t22 += v * b12; 442 | t23 += v * b13; 443 | t24 += v * b14; 444 | t25 += v * b15; 445 | v = a[11]; 446 | t11 += v * b0; 447 | t12 += v * b1; 448 | t13 += v * b2; 449 | t14 += v * b3; 450 | t15 += v * b4; 451 | t16 += v * b5; 452 | t17 += v * b6; 453 | t18 += v * b7; 454 | t19 += v * b8; 455 | t20 += v * b9; 456 | t21 += v * b10; 457 | t22 += v * b11; 458 | t23 += v * b12; 459 | t24 += v * b13; 460 | t25 += v * b14; 461 | t26 += v * b15; 462 | v = a[12]; 463 | t12 += v * b0; 464 | t13 += v * b1; 465 | t14 += v * b2; 466 | t15 += v * b3; 467 | t16 += v * b4; 468 | t17 += v * b5; 469 | t18 += v * b6; 470 | t19 += v * b7; 471 | t20 += v * b8; 472 | t21 += v * b9; 473 | t22 += v * b10; 474 | t23 += v * b11; 475 | t24 += v * b12; 476 | t25 += v * b13; 477 | t26 += v * b14; 478 | t27 += v * b15; 479 | v = a[13]; 480 | t13 += v * b0; 481 | t14 += v * b1; 482 | t15 += v * b2; 483 | t16 += v * b3; 484 | t17 += v * b4; 485 | t18 += v * b5; 486 | t19 += v * b6; 487 | t20 += v * b7; 488 | t21 += v * b8; 489 | t22 += v * b9; 490 | t23 += v * b10; 491 | t24 += v * b11; 492 | t25 += v * b12; 493 | t26 += v * b13; 494 | t27 += v * b14; 495 | t28 += v * b15; 496 | v = a[14]; 497 | t14 += v * b0; 498 | t15 += v * b1; 499 | t16 += v * b2; 500 | t17 += v * b3; 501 | t18 += v * b4; 502 | t19 += v * b5; 503 | t20 += v * b6; 504 | t21 += v * b7; 505 | t22 += v * b8; 506 | t23 += v * b9; 507 | t24 += v * b10; 508 | t25 += v * b11; 509 | t26 += v * b12; 510 | t27 += v * b13; 511 | t28 += v * b14; 512 | t29 += v * b15; 513 | v = a[15]; 514 | t15 += v * b0; 515 | t16 += v * b1; 516 | t17 += v * b2; 517 | t18 += v * b3; 518 | t19 += v * b4; 519 | t20 += v * b5; 520 | t21 += v * b6; 521 | t22 += v * b7; 522 | t23 += v * b8; 523 | t24 += v * b9; 524 | t25 += v * b10; 525 | t26 += v * b11; 526 | t27 += v * b12; 527 | t28 += v * b13; 528 | t29 += v * b14; 529 | t30 += v * b15; 530 | 531 | t0 += 38 * t16; 532 | t1 += 38 * t17; 533 | t2 += 38 * t18; 534 | t3 += 38 * t19; 535 | t4 += 38 * t20; 536 | t5 += 38 * t21; 537 | t6 += 38 * t22; 538 | t7 += 38 * t23; 539 | t8 += 38 * t24; 540 | t9 += 38 * t25; 541 | t10 += 38 * t26; 542 | t11 += 38 * t27; 543 | t12 += 38 * t28; 544 | t13 += 38 * t29; 545 | t14 += 38 * t30; 546 | // t15 left as is 547 | 548 | // first car 549 | c = 1; 550 | v = t0 + c + 65535; 551 | c = Math.floor(v / 65536); 552 | t0 = v - c * 65536; 553 | v = t1 + c + 65535; 554 | c = Math.floor(v / 65536); 555 | t1 = v - c * 65536; 556 | v = t2 + c + 65535; 557 | c = Math.floor(v / 65536); 558 | t2 = v - c * 65536; 559 | v = t3 + c + 65535; 560 | c = Math.floor(v / 65536); 561 | t3 = v - c * 65536; 562 | v = t4 + c + 65535; 563 | c = Math.floor(v / 65536); 564 | t4 = v - c * 65536; 565 | v = t5 + c + 65535; 566 | c = Math.floor(v / 65536); 567 | t5 = v - c * 65536; 568 | v = t6 + c + 65535; 569 | c = Math.floor(v / 65536); 570 | t6 = v - c * 65536; 571 | v = t7 + c + 65535; 572 | c = Math.floor(v / 65536); 573 | t7 = v - c * 65536; 574 | v = t8 + c + 65535; 575 | c = Math.floor(v / 65536); 576 | t8 = v - c * 65536; 577 | v = t9 + c + 65535; 578 | c = Math.floor(v / 65536); 579 | t9 = v - c * 65536; 580 | v = t10 + c + 65535; 581 | c = Math.floor(v / 65536); 582 | t10 = v - c * 65536; 583 | v = t11 + c + 65535; 584 | c = Math.floor(v / 65536); 585 | t11 = v - c * 65536; 586 | v = t12 + c + 65535; 587 | c = Math.floor(v / 65536); 588 | t12 = v - c * 65536; 589 | v = t13 + c + 65535; 590 | c = Math.floor(v / 65536); 591 | t13 = v - c * 65536; 592 | v = t14 + c + 65535; 593 | c = Math.floor(v / 65536); 594 | t14 = v - c * 65536; 595 | v = t15 + c + 65535; 596 | c = Math.floor(v / 65536); 597 | t15 = v - c * 65536; 598 | t0 += c - 1 + 37 * (c - 1); 599 | 600 | // second car 601 | c = 1; 602 | v = t0 + c + 65535; 603 | c = Math.floor(v / 65536); 604 | t0 = v - c * 65536; 605 | v = t1 + c + 65535; 606 | c = Math.floor(v / 65536); 607 | t1 = v - c * 65536; 608 | v = t2 + c + 65535; 609 | c = Math.floor(v / 65536); 610 | t2 = v - c * 65536; 611 | v = t3 + c + 65535; 612 | c = Math.floor(v / 65536); 613 | t3 = v - c * 65536; 614 | v = t4 + c + 65535; 615 | c = Math.floor(v / 65536); 616 | t4 = v - c * 65536; 617 | v = t5 + c + 65535; 618 | c = Math.floor(v / 65536); 619 | t5 = v - c * 65536; 620 | v = t6 + c + 65535; 621 | c = Math.floor(v / 65536); 622 | t6 = v - c * 65536; 623 | v = t7 + c + 65535; 624 | c = Math.floor(v / 65536); 625 | t7 = v - c * 65536; 626 | v = t8 + c + 65535; 627 | c = Math.floor(v / 65536); 628 | t8 = v - c * 65536; 629 | v = t9 + c + 65535; 630 | c = Math.floor(v / 65536); 631 | t9 = v - c * 65536; 632 | v = t10 + c + 65535; 633 | c = Math.floor(v / 65536); 634 | t10 = v - c * 65536; 635 | v = t11 + c + 65535; 636 | c = Math.floor(v / 65536); 637 | t11 = v - c * 65536; 638 | v = t12 + c + 65535; 639 | c = Math.floor(v / 65536); 640 | t12 = v - c * 65536; 641 | v = t13 + c + 65535; 642 | c = Math.floor(v / 65536); 643 | t13 = v - c * 65536; 644 | v = t14 + c + 65535; 645 | c = Math.floor(v / 65536); 646 | t14 = v - c * 65536; 647 | v = t15 + c + 65535; 648 | c = Math.floor(v / 65536); 649 | t15 = v - c * 65536; 650 | t0 += c - 1 + 37 * (c - 1); 651 | 652 | o[0] = t0; 653 | o[1] = t1; 654 | o[2] = t2; 655 | o[3] = t3; 656 | o[4] = t4; 657 | o[5] = t5; 658 | o[6] = t6; 659 | o[7] = t7; 660 | o[8] = t8; 661 | o[9] = t9; 662 | o[10] = t10; 663 | o[11] = t11; 664 | o[12] = t12; 665 | o[13] = t13; 666 | o[14] = t14; 667 | o[15] = t15; 668 | } 669 | 670 | function S(o: any, a: any) { 671 | M(o, a, a); 672 | } 673 | 674 | function inv25519(o: any, i: any) { 675 | var c = gf(); 676 | var a; 677 | for (a = 0; a < 16; a++) c[a] = i[a]; 678 | for (a = 253; a >= 0; a--) { 679 | S(c, c); 680 | if (a !== 2 && a !== 4) M(c, c, i); 681 | } 682 | for (a = 0; a < 16; a++) o[a] = c[a]; 683 | } 684 | 685 | function pow2523(o: any, i: any) { 686 | var c = gf(); 687 | var a; 688 | for (a = 0; a < 16; a++) c[a] = i[a]; 689 | for (a = 250; a >= 0; a--) { 690 | S(c, c); 691 | if (a !== 1) M(c, c, i); 692 | } 693 | for (a = 0; a < 16; a++) o[a] = c[a]; 694 | } 695 | 696 | function crypto_scalarmult(q: any, n: any, p: any) { 697 | var z = new Uint8Array(32); 698 | var x = new Float64Array(80), 699 | r, 700 | i; 701 | var a = gf(), 702 | b = gf(), 703 | c = gf(), 704 | d = gf(), 705 | e = gf(), 706 | f = gf(); 707 | for (i = 0; i < 31; i++) z[i] = n[i]; 708 | z[31] = (n[31] & 127) | 64; 709 | z[0] &= 248; 710 | unpack25519(x, p); 711 | for (i = 0; i < 16; i++) { 712 | b[i] = x[i]; 713 | d[i] = a[i] = c[i] = 0; 714 | } 715 | a[0] = d[0] = 1; 716 | for (i = 254; i >= 0; --i) { 717 | r = (z[i >>> 3] >>> (i & 7)) & 1; 718 | sel25519(a, b, r); 719 | sel25519(c, d, r); 720 | A(e, a, c); 721 | Z(a, a, c); 722 | A(c, b, d); 723 | Z(b, b, d); 724 | S(d, e); 725 | S(f, a); 726 | M(a, c, a); 727 | M(c, b, e); 728 | A(e, a, c); 729 | Z(a, a, c); 730 | S(b, a); 731 | Z(c, d, f); 732 | M(a, c, _121665); 733 | A(a, a, d); 734 | M(c, c, a); 735 | M(a, d, f); 736 | M(d, b, x); 737 | S(b, e); 738 | sel25519(a, b, r); 739 | sel25519(c, d, r); 740 | } 741 | for (i = 0; i < 16; i++) { 742 | x[i + 16] = a[i]; 743 | x[i + 32] = c[i]; 744 | x[i + 48] = b[i]; 745 | x[i + 64] = d[i]; 746 | } 747 | var x32 = x.subarray(32); 748 | var x16 = x.subarray(16); 749 | inv25519(x32, x32); 750 | M(x16, x16, x32); 751 | pack25519(q, x16); 752 | return 0; 753 | } 754 | 755 | function crypto_scalarmult_base(q: any, n: any) { 756 | return crypto_scalarmult(q, n, _9); 757 | } 758 | 759 | var K = [ 760 | 0x428a2f98, 761 | 0xd728ae22, 762 | 0x71374491, 763 | 0x23ef65cd, 764 | 0xb5c0fbcf, 765 | 0xec4d3b2f, 766 | 0xe9b5dba5, 767 | 0x8189dbbc, 768 | 0x3956c25b, 769 | 0xf348b538, 770 | 0x59f111f1, 771 | 0xb605d019, 772 | 0x923f82a4, 773 | 0xaf194f9b, 774 | 0xab1c5ed5, 775 | 0xda6d8118, 776 | 0xd807aa98, 777 | 0xa3030242, 778 | 0x12835b01, 779 | 0x45706fbe, 780 | 0x243185be, 781 | 0x4ee4b28c, 782 | 0x550c7dc3, 783 | 0xd5ffb4e2, 784 | 0x72be5d74, 785 | 0xf27b896f, 786 | 0x80deb1fe, 787 | 0x3b1696b1, 788 | 0x9bdc06a7, 789 | 0x25c71235, 790 | 0xc19bf174, 791 | 0xcf692694, 792 | 0xe49b69c1, 793 | 0x9ef14ad2, 794 | 0xefbe4786, 795 | 0x384f25e3, 796 | 0x0fc19dc6, 797 | 0x8b8cd5b5, 798 | 0x240ca1cc, 799 | 0x77ac9c65, 800 | 0x2de92c6f, 801 | 0x592b0275, 802 | 0x4a7484aa, 803 | 0x6ea6e483, 804 | 0x5cb0a9dc, 805 | 0xbd41fbd4, 806 | 0x76f988da, 807 | 0x831153b5, 808 | 0x983e5152, 809 | 0xee66dfab, 810 | 0xa831c66d, 811 | 0x2db43210, 812 | 0xb00327c8, 813 | 0x98fb213f, 814 | 0xbf597fc7, 815 | 0xbeef0ee4, 816 | 0xc6e00bf3, 817 | 0x3da88fc2, 818 | 0xd5a79147, 819 | 0x930aa725, 820 | 0x06ca6351, 821 | 0xe003826f, 822 | 0x14292967, 823 | 0x0a0e6e70, 824 | 0x27b70a85, 825 | 0x46d22ffc, 826 | 0x2e1b2138, 827 | 0x5c26c926, 828 | 0x4d2c6dfc, 829 | 0x5ac42aed, 830 | 0x53380d13, 831 | 0x9d95b3df, 832 | 0x650a7354, 833 | 0x8baf63de, 834 | 0x766a0abb, 835 | 0x3c77b2a8, 836 | 0x81c2c92e, 837 | 0x47edaee6, 838 | 0x92722c85, 839 | 0x1482353b, 840 | 0xa2bfe8a1, 841 | 0x4cf10364, 842 | 0xa81a664b, 843 | 0xbc423001, 844 | 0xc24b8b70, 845 | 0xd0f89791, 846 | 0xc76c51a3, 847 | 0x0654be30, 848 | 0xd192e819, 849 | 0xd6ef5218, 850 | 0xd6990624, 851 | 0x5565a910, 852 | 0xf40e3585, 853 | 0x5771202a, 854 | 0x106aa070, 855 | 0x32bbd1b8, 856 | 0x19a4c116, 857 | 0xb8d2d0c8, 858 | 0x1e376c08, 859 | 0x5141ab53, 860 | 0x2748774c, 861 | 0xdf8eeb99, 862 | 0x34b0bcb5, 863 | 0xe19b48a8, 864 | 0x391c0cb3, 865 | 0xc5c95a63, 866 | 0x4ed8aa4a, 867 | 0xe3418acb, 868 | 0x5b9cca4f, 869 | 0x7763e373, 870 | 0x682e6ff3, 871 | 0xd6b2b8a3, 872 | 0x748f82ee, 873 | 0x5defb2fc, 874 | 0x78a5636f, 875 | 0x43172f60, 876 | 0x84c87814, 877 | 0xa1f0ab72, 878 | 0x8cc70208, 879 | 0x1a6439ec, 880 | 0x90befffa, 881 | 0x23631e28, 882 | 0xa4506ceb, 883 | 0xde82bde9, 884 | 0xbef9a3f7, 885 | 0xb2c67915, 886 | 0xc67178f2, 887 | 0xe372532b, 888 | 0xca273ece, 889 | 0xea26619c, 890 | 0xd186b8c7, 891 | 0x21c0c207, 892 | 0xeada7dd6, 893 | 0xcde0eb1e, 894 | 0xf57d4f7f, 895 | 0xee6ed178, 896 | 0x06f067aa, 897 | 0x72176fba, 898 | 0x0a637dc5, 899 | 0xa2c898a6, 900 | 0x113f9804, 901 | 0xbef90dae, 902 | 0x1b710b35, 903 | 0x131c471b, 904 | 0x28db77f5, 905 | 0x23047d84, 906 | 0x32caab7b, 907 | 0x40c72493, 908 | 0x3c9ebe0a, 909 | 0x15c9bebc, 910 | 0x431d67c4, 911 | 0x9c100d4c, 912 | 0x4cc5d4be, 913 | 0xcb3e42b6, 914 | 0x597f299c, 915 | 0xfc657e2a, 916 | 0x5fcb6fab, 917 | 0x3ad6faec, 918 | 0x6c44198c, 919 | 0x4a475817, 920 | ]; 921 | 922 | function crypto_hashblocks_hl(hh: Int32Array, hl: Int32Array, m: any, n: any) { 923 | var wh = new Int32Array(16), 924 | wl = new Int32Array(16), 925 | bh0, 926 | bh1, 927 | bh2, 928 | bh3, 929 | bh4, 930 | bh5, 931 | bh6, 932 | bh7, 933 | bl0, 934 | bl1, 935 | bl2, 936 | bl3, 937 | bl4, 938 | bl5, 939 | bl6, 940 | bl7, 941 | th, 942 | tl, 943 | i, 944 | j, 945 | h, 946 | l, 947 | a, 948 | b, 949 | c, 950 | d; 951 | 952 | var ah0 = hh[0], 953 | ah1 = hh[1], 954 | ah2 = hh[2], 955 | ah3 = hh[3], 956 | ah4 = hh[4], 957 | ah5 = hh[5], 958 | ah6 = hh[6], 959 | ah7 = hh[7], 960 | al0 = hl[0], 961 | al1 = hl[1], 962 | al2 = hl[2], 963 | al3 = hl[3], 964 | al4 = hl[4], 965 | al5 = hl[5], 966 | al6 = hl[6], 967 | al7 = hl[7]; 968 | 969 | var pos = 0; 970 | while (n >= 128) { 971 | for (i = 0; i < 16; i++) { 972 | j = 8 * i + pos; 973 | wh[i] = (m[j + 0] << 24) | (m[j + 1] << 16) | (m[j + 2] << 8) | m[j + 3]; 974 | wl[i] = (m[j + 4] << 24) | (m[j + 5] << 16) | (m[j + 6] << 8) | m[j + 7]; 975 | } 976 | for (i = 0; i < 80; i++) { 977 | bh0 = ah0; 978 | bh1 = ah1; 979 | bh2 = ah2; 980 | bh3 = ah3; 981 | bh4 = ah4; 982 | bh5 = ah5; 983 | bh6 = ah6; 984 | bh7 = ah7; 985 | 986 | bl0 = al0; 987 | bl1 = al1; 988 | bl2 = al2; 989 | bl3 = al3; 990 | bl4 = al4; 991 | bl5 = al5; 992 | bl6 = al6; 993 | bl7 = al7; 994 | 995 | // add 996 | h = ah7; 997 | l = al7; 998 | 999 | a = l & 0xffff; 1000 | b = l >>> 16; 1001 | c = h & 0xffff; 1002 | d = h >>> 16; 1003 | 1004 | // Sigma1 1005 | h = 1006 | ((ah4 >>> 14) | (al4 << (32 - 14))) ^ 1007 | ((ah4 >>> 18) | (al4 << (32 - 18))) ^ 1008 | ((al4 >>> (41 - 32)) | (ah4 << (32 - (41 - 32)))); 1009 | l = 1010 | ((al4 >>> 14) | (ah4 << (32 - 14))) ^ 1011 | ((al4 >>> 18) | (ah4 << (32 - 18))) ^ 1012 | ((ah4 >>> (41 - 32)) | (al4 << (32 - (41 - 32)))); 1013 | 1014 | a += l & 0xffff; 1015 | b += l >>> 16; 1016 | c += h & 0xffff; 1017 | d += h >>> 16; 1018 | 1019 | // Ch 1020 | h = (ah4 & ah5) ^ (~ah4 & ah6); 1021 | l = (al4 & al5) ^ (~al4 & al6); 1022 | 1023 | a += l & 0xffff; 1024 | b += l >>> 16; 1025 | c += h & 0xffff; 1026 | d += h >>> 16; 1027 | 1028 | // K 1029 | h = K[i * 2]; 1030 | l = K[i * 2 + 1]; 1031 | 1032 | a += l & 0xffff; 1033 | b += l >>> 16; 1034 | c += h & 0xffff; 1035 | d += h >>> 16; 1036 | 1037 | // w 1038 | h = wh[i % 16]; 1039 | l = wl[i % 16]; 1040 | 1041 | a += l & 0xffff; 1042 | b += l >>> 16; 1043 | c += h & 0xffff; 1044 | d += h >>> 16; 1045 | 1046 | b += a >>> 16; 1047 | c += b >>> 16; 1048 | d += c >>> 16; 1049 | 1050 | th = (c & 0xffff) | (d << 16); 1051 | tl = (a & 0xffff) | (b << 16); 1052 | 1053 | // add 1054 | h = th; 1055 | l = tl; 1056 | 1057 | a = l & 0xffff; 1058 | b = l >>> 16; 1059 | c = h & 0xffff; 1060 | d = h >>> 16; 1061 | 1062 | // Sigma0 1063 | h = 1064 | ((ah0 >>> 28) | (al0 << (32 - 28))) ^ 1065 | ((al0 >>> (34 - 32)) | (ah0 << (32 - (34 - 32)))) ^ 1066 | ((al0 >>> (39 - 32)) | (ah0 << (32 - (39 - 32)))); 1067 | l = 1068 | ((al0 >>> 28) | (ah0 << (32 - 28))) ^ 1069 | ((ah0 >>> (34 - 32)) | (al0 << (32 - (34 - 32)))) ^ 1070 | ((ah0 >>> (39 - 32)) | (al0 << (32 - (39 - 32)))); 1071 | 1072 | a += l & 0xffff; 1073 | b += l >>> 16; 1074 | c += h & 0xffff; 1075 | d += h >>> 16; 1076 | 1077 | // Maj 1078 | h = (ah0 & ah1) ^ (ah0 & ah2) ^ (ah1 & ah2); 1079 | l = (al0 & al1) ^ (al0 & al2) ^ (al1 & al2); 1080 | 1081 | a += l & 0xffff; 1082 | b += l >>> 16; 1083 | c += h & 0xffff; 1084 | d += h >>> 16; 1085 | 1086 | b += a >>> 16; 1087 | c += b >>> 16; 1088 | d += c >>> 16; 1089 | 1090 | bh7 = (c & 0xffff) | (d << 16); 1091 | bl7 = (a & 0xffff) | (b << 16); 1092 | 1093 | // add 1094 | h = bh3; 1095 | l = bl3; 1096 | 1097 | a = l & 0xffff; 1098 | b = l >>> 16; 1099 | c = h & 0xffff; 1100 | d = h >>> 16; 1101 | 1102 | h = th; 1103 | l = tl; 1104 | 1105 | a += l & 0xffff; 1106 | b += l >>> 16; 1107 | c += h & 0xffff; 1108 | d += h >>> 16; 1109 | 1110 | b += a >>> 16; 1111 | c += b >>> 16; 1112 | d += c >>> 16; 1113 | 1114 | bh3 = (c & 0xffff) | (d << 16); 1115 | bl3 = (a & 0xffff) | (b << 16); 1116 | 1117 | ah1 = bh0; 1118 | ah2 = bh1; 1119 | ah3 = bh2; 1120 | ah4 = bh3; 1121 | ah5 = bh4; 1122 | ah6 = bh5; 1123 | ah7 = bh6; 1124 | ah0 = bh7; 1125 | 1126 | al1 = bl0; 1127 | al2 = bl1; 1128 | al3 = bl2; 1129 | al4 = bl3; 1130 | al5 = bl4; 1131 | al6 = bl5; 1132 | al7 = bl6; 1133 | al0 = bl7; 1134 | 1135 | if (i % 16 === 15) { 1136 | for (j = 0; j < 16; j++) { 1137 | // add 1138 | h = wh[j]; 1139 | l = wl[j]; 1140 | 1141 | a = l & 0xffff; 1142 | b = l >>> 16; 1143 | c = h & 0xffff; 1144 | d = h >>> 16; 1145 | 1146 | h = wh[(j + 9) % 16]; 1147 | l = wl[(j + 9) % 16]; 1148 | 1149 | a += l & 0xffff; 1150 | b += l >>> 16; 1151 | c += h & 0xffff; 1152 | d += h >>> 16; 1153 | 1154 | // sigma0 1155 | th = wh[(j + 1) % 16]; 1156 | tl = wl[(j + 1) % 16]; 1157 | h = ((th >>> 1) | (tl << (32 - 1))) ^ ((th >>> 8) | (tl << (32 - 8))) ^ (th >>> 7); 1158 | l = ((tl >>> 1) | (th << (32 - 1))) ^ ((tl >>> 8) | (th << (32 - 8))) ^ ((tl >>> 7) | (th << (32 - 7))); 1159 | 1160 | a += l & 0xffff; 1161 | b += l >>> 16; 1162 | c += h & 0xffff; 1163 | d += h >>> 16; 1164 | 1165 | // sigma1 1166 | th = wh[(j + 14) % 16]; 1167 | tl = wl[(j + 14) % 16]; 1168 | h = ((th >>> 19) | (tl << (32 - 19))) ^ ((tl >>> (61 - 32)) | (th << (32 - (61 - 32)))) ^ (th >>> 6); 1169 | l = 1170 | ((tl >>> 19) | (th << (32 - 19))) ^ 1171 | ((th >>> (61 - 32)) | (tl << (32 - (61 - 32)))) ^ 1172 | ((tl >>> 6) | (th << (32 - 6))); 1173 | 1174 | a += l & 0xffff; 1175 | b += l >>> 16; 1176 | c += h & 0xffff; 1177 | d += h >>> 16; 1178 | 1179 | b += a >>> 16; 1180 | c += b >>> 16; 1181 | d += c >>> 16; 1182 | 1183 | wh[j] = (c & 0xffff) | (d << 16); 1184 | wl[j] = (a & 0xffff) | (b << 16); 1185 | } 1186 | } 1187 | } 1188 | 1189 | // add 1190 | h = ah0; 1191 | l = al0; 1192 | 1193 | a = l & 0xffff; 1194 | b = l >>> 16; 1195 | c = h & 0xffff; 1196 | d = h >>> 16; 1197 | 1198 | h = hh[0]; 1199 | l = hl[0]; 1200 | 1201 | a += l & 0xffff; 1202 | b += l >>> 16; 1203 | c += h & 0xffff; 1204 | d += h >>> 16; 1205 | 1206 | b += a >>> 16; 1207 | c += b >>> 16; 1208 | d += c >>> 16; 1209 | 1210 | hh[0] = ah0 = (c & 0xffff) | (d << 16); 1211 | hl[0] = al0 = (a & 0xffff) | (b << 16); 1212 | 1213 | h = ah1; 1214 | l = al1; 1215 | 1216 | a = l & 0xffff; 1217 | b = l >>> 16; 1218 | c = h & 0xffff; 1219 | d = h >>> 16; 1220 | 1221 | h = hh[1]; 1222 | l = hl[1]; 1223 | 1224 | a += l & 0xffff; 1225 | b += l >>> 16; 1226 | c += h & 0xffff; 1227 | d += h >>> 16; 1228 | 1229 | b += a >>> 16; 1230 | c += b >>> 16; 1231 | d += c >>> 16; 1232 | 1233 | hh[1] = ah1 = (c & 0xffff) | (d << 16); 1234 | hl[1] = al1 = (a & 0xffff) | (b << 16); 1235 | 1236 | h = ah2; 1237 | l = al2; 1238 | 1239 | a = l & 0xffff; 1240 | b = l >>> 16; 1241 | c = h & 0xffff; 1242 | d = h >>> 16; 1243 | 1244 | h = hh[2]; 1245 | l = hl[2]; 1246 | 1247 | a += l & 0xffff; 1248 | b += l >>> 16; 1249 | c += h & 0xffff; 1250 | d += h >>> 16; 1251 | 1252 | b += a >>> 16; 1253 | c += b >>> 16; 1254 | d += c >>> 16; 1255 | 1256 | hh[2] = ah2 = (c & 0xffff) | (d << 16); 1257 | hl[2] = al2 = (a & 0xffff) | (b << 16); 1258 | 1259 | h = ah3; 1260 | l = al3; 1261 | 1262 | a = l & 0xffff; 1263 | b = l >>> 16; 1264 | c = h & 0xffff; 1265 | d = h >>> 16; 1266 | 1267 | h = hh[3]; 1268 | l = hl[3]; 1269 | 1270 | a += l & 0xffff; 1271 | b += l >>> 16; 1272 | c += h & 0xffff; 1273 | d += h >>> 16; 1274 | 1275 | b += a >>> 16; 1276 | c += b >>> 16; 1277 | d += c >>> 16; 1278 | 1279 | hh[3] = ah3 = (c & 0xffff) | (d << 16); 1280 | hl[3] = al3 = (a & 0xffff) | (b << 16); 1281 | 1282 | h = ah4; 1283 | l = al4; 1284 | 1285 | a = l & 0xffff; 1286 | b = l >>> 16; 1287 | c = h & 0xffff; 1288 | d = h >>> 16; 1289 | 1290 | h = hh[4]; 1291 | l = hl[4]; 1292 | 1293 | a += l & 0xffff; 1294 | b += l >>> 16; 1295 | c += h & 0xffff; 1296 | d += h >>> 16; 1297 | 1298 | b += a >>> 16; 1299 | c += b >>> 16; 1300 | d += c >>> 16; 1301 | 1302 | hh[4] = ah4 = (c & 0xffff) | (d << 16); 1303 | hl[4] = al4 = (a & 0xffff) | (b << 16); 1304 | 1305 | h = ah5; 1306 | l = al5; 1307 | 1308 | a = l & 0xffff; 1309 | b = l >>> 16; 1310 | c = h & 0xffff; 1311 | d = h >>> 16; 1312 | 1313 | h = hh[5]; 1314 | l = hl[5]; 1315 | 1316 | a += l & 0xffff; 1317 | b += l >>> 16; 1318 | c += h & 0xffff; 1319 | d += h >>> 16; 1320 | 1321 | b += a >>> 16; 1322 | c += b >>> 16; 1323 | d += c >>> 16; 1324 | 1325 | hh[5] = ah5 = (c & 0xffff) | (d << 16); 1326 | hl[5] = al5 = (a & 0xffff) | (b << 16); 1327 | 1328 | h = ah6; 1329 | l = al6; 1330 | 1331 | a = l & 0xffff; 1332 | b = l >>> 16; 1333 | c = h & 0xffff; 1334 | d = h >>> 16; 1335 | 1336 | h = hh[6]; 1337 | l = hl[6]; 1338 | 1339 | a += l & 0xffff; 1340 | b += l >>> 16; 1341 | c += h & 0xffff; 1342 | d += h >>> 16; 1343 | 1344 | b += a >>> 16; 1345 | c += b >>> 16; 1346 | d += c >>> 16; 1347 | 1348 | hh[6] = ah6 = (c & 0xffff) | (d << 16); 1349 | hl[6] = al6 = (a & 0xffff) | (b << 16); 1350 | 1351 | h = ah7; 1352 | l = al7; 1353 | 1354 | a = l & 0xffff; 1355 | b = l >>> 16; 1356 | c = h & 0xffff; 1357 | d = h >>> 16; 1358 | 1359 | h = hh[7]; 1360 | l = hl[7]; 1361 | 1362 | a += l & 0xffff; 1363 | b += l >>> 16; 1364 | c += h & 0xffff; 1365 | d += h >>> 16; 1366 | 1367 | b += a >>> 16; 1368 | c += b >>> 16; 1369 | d += c >>> 16; 1370 | 1371 | hh[7] = ah7 = (c & 0xffff) | (d << 16); 1372 | hl[7] = al7 = (a & 0xffff) | (b << 16); 1373 | 1374 | pos += 128; 1375 | n -= 128; 1376 | } 1377 | 1378 | return n; 1379 | } 1380 | 1381 | function crypto_hash(out: any, m: any, n: any) { 1382 | var hh = new Int32Array(8), 1383 | hl = new Int32Array(8), 1384 | x = new Uint8Array(256), 1385 | i, 1386 | b = n; 1387 | 1388 | hh[0] = 0x6a09e667; 1389 | hh[1] = 0xbb67ae85; 1390 | hh[2] = 0x3c6ef372; 1391 | hh[3] = 0xa54ff53a; 1392 | hh[4] = 0x510e527f; 1393 | hh[5] = 0x9b05688c; 1394 | hh[6] = 0x1f83d9ab; 1395 | hh[7] = 0x5be0cd19; 1396 | 1397 | hl[0] = 0xf3bcc908; 1398 | hl[1] = 0x84caa73b; 1399 | hl[2] = 0xfe94f82b; 1400 | hl[3] = 0x5f1d36f1; 1401 | hl[4] = 0xade682d1; 1402 | hl[5] = 0x2b3e6c1f; 1403 | hl[6] = 0xfb41bd6b; 1404 | hl[7] = 0x137e2179; 1405 | 1406 | crypto_hashblocks_hl(hh, hl, m, n); 1407 | n %= 128; 1408 | 1409 | for (i = 0; i < n; i++) x[i] = m[b - n + i]; 1410 | x[n] = 128; 1411 | 1412 | n = 256 - 128 * (n < 112 ? 1 : 0); 1413 | x[n - 9] = 0; 1414 | ts64(x, n - 8, (b / 0x20000000) | 0, b << 3); 1415 | crypto_hashblocks_hl(hh, hl, x, n); 1416 | 1417 | for (i = 0; i < 8; i++) ts64(out, 8 * i, hh[i], hl[i]); 1418 | 1419 | return 0; 1420 | } 1421 | 1422 | function add(p: any, q: any) { 1423 | var a = gf(), 1424 | b = gf(), 1425 | c = gf(), 1426 | d = gf(), 1427 | e = gf(), 1428 | f = gf(), 1429 | g = gf(), 1430 | h = gf(), 1431 | t = gf(); 1432 | 1433 | Z(a, p[1], p[0]); 1434 | Z(t, q[1], q[0]); 1435 | M(a, a, t); 1436 | A(b, p[0], p[1]); 1437 | A(t, q[0], q[1]); 1438 | M(b, b, t); 1439 | M(c, p[3], q[3]); 1440 | M(c, c, D2); 1441 | M(d, p[2], q[2]); 1442 | A(d, d, d); 1443 | Z(e, b, a); 1444 | Z(f, d, c); 1445 | A(g, d, c); 1446 | A(h, b, a); 1447 | 1448 | M(p[0], e, f); 1449 | M(p[1], h, g); 1450 | M(p[2], g, f); 1451 | M(p[3], e, h); 1452 | } 1453 | 1454 | function cswap(p: any, q: any, b: any) { 1455 | var i; 1456 | for (i = 0; i < 4; i++) { 1457 | sel25519(p[i], q[i], b); 1458 | } 1459 | } 1460 | 1461 | function pack(r: any, p: any) { 1462 | var tx = gf(), 1463 | ty = gf(), 1464 | zi = gf(); 1465 | inv25519(zi, p[2]); 1466 | M(tx, p[0], zi); 1467 | M(ty, p[1], zi); 1468 | pack25519(r, ty); 1469 | r[31] ^= par25519(tx) << 7; 1470 | } 1471 | 1472 | function scalarmult(p: any, q: any, s: any) { 1473 | var b, i; 1474 | set25519(p[0], gf0); 1475 | set25519(p[1], gf1); 1476 | set25519(p[2], gf1); 1477 | set25519(p[3], gf0); 1478 | for (i = 255; i >= 0; --i) { 1479 | b = (s[(i / 8) | 0] >> (i & 7)) & 1; 1480 | cswap(p, q, b); 1481 | add(q, p); 1482 | add(p, p); 1483 | cswap(p, q, b); 1484 | } 1485 | } 1486 | 1487 | function scalarbase(p: any, s: any) { 1488 | var q = [gf(), gf(), gf(), gf()]; 1489 | set25519(q[0], X); 1490 | set25519(q[1], Y); 1491 | set25519(q[2], gf1); 1492 | M(q[3], X, Y); 1493 | scalarmult(p, q, s); 1494 | } 1495 | 1496 | var L = new Float64Array([ 1497 | 0xed, 1498 | 0xd3, 1499 | 0xf5, 1500 | 0x5c, 1501 | 0x1a, 1502 | 0x63, 1503 | 0x12, 1504 | 0x58, 1505 | 0xd6, 1506 | 0x9c, 1507 | 0xf7, 1508 | 0xa2, 1509 | 0xde, 1510 | 0xf9, 1511 | 0xde, 1512 | 0x14, 1513 | 0, 1514 | 0, 1515 | 0, 1516 | 0, 1517 | 0, 1518 | 0, 1519 | 0, 1520 | 0, 1521 | 0, 1522 | 0, 1523 | 0, 1524 | 0, 1525 | 0, 1526 | 0, 1527 | 0, 1528 | 0x10, 1529 | ]); 1530 | 1531 | function modL(r: any, x: any) { 1532 | var carry, i, j, k; 1533 | for (i = 63; i >= 32; --i) { 1534 | carry = 0; 1535 | for (j = i - 32, k = i - 12; j < k; ++j) { 1536 | x[j] += carry - 16 * x[i] * L[j - (i - 32)]; 1537 | carry = (x[j] + 128) >> 8; 1538 | x[j] -= carry * 256; 1539 | } 1540 | x[j] += carry; 1541 | x[i] = 0; 1542 | } 1543 | carry = 0; 1544 | for (j = 0; j < 32; j++) { 1545 | x[j] += carry - (x[31] >> 4) * L[j]; 1546 | carry = x[j] >> 8; 1547 | x[j] &= 255; 1548 | } 1549 | for (j = 0; j < 32; j++) x[j] -= carry * L[j]; 1550 | for (i = 0; i < 32; i++) { 1551 | x[i + 1] += x[i] >> 8; 1552 | r[i] = x[i] & 255; 1553 | } 1554 | } 1555 | 1556 | function reduce(r: any) { 1557 | var x = new Float64Array(64), 1558 | i; 1559 | for (i = 0; i < 64; i++) x[i] = r[i]; 1560 | for (i = 0; i < 64; i++) r[i] = 0; 1561 | modL(r, x); 1562 | } 1563 | 1564 | // Like crypto_sign, but uses secret key directly in hash. 1565 | function crypto_sign_direct(sm: any, m: any, n: any, sk: any) { 1566 | var h = new Uint8Array(64), 1567 | r = new Uint8Array(64); 1568 | var i, 1569 | j, 1570 | x = new Float64Array(64); 1571 | var p = [gf(), gf(), gf(), gf()]; 1572 | 1573 | for (i = 0; i < n; i++) sm[64 + i] = m[i]; 1574 | for (i = 0; i < 32; i++) sm[32 + i] = sk[i]; 1575 | 1576 | crypto_hash(r, sm.subarray(32), n + 32); 1577 | reduce(r); 1578 | scalarbase(p, r); 1579 | pack(sm, p); 1580 | 1581 | for (i = 0; i < 32; i++) sm[i + 32] = sk[32 + i]; 1582 | crypto_hash(h, sm, n + 64); 1583 | reduce(h); 1584 | 1585 | for (i = 0; i < 64; i++) x[i] = 0; 1586 | for (i = 0; i < 32; i++) x[i] = r[i]; 1587 | for (i = 0; i < 32; i++) { 1588 | for (j = 0; j < 32; j++) { 1589 | x[i + j] += h[i] * sk[j]; 1590 | } 1591 | } 1592 | 1593 | modL(sm.subarray(32), x); 1594 | return n + 64; 1595 | } 1596 | 1597 | // Note: sm must be n+128. 1598 | function crypto_sign_direct_rnd(sm: any, m: any, n: any, sk: any, rnd: any) { 1599 | var h = new Uint8Array(64), 1600 | r = new Uint8Array(64); 1601 | var i, 1602 | j, 1603 | x = new Float64Array(64); 1604 | var p = [gf(), gf(), gf(), gf()]; 1605 | 1606 | // Hash separation. 1607 | sm[0] = 0xfe; 1608 | for (i = 1; i < 32; i++) sm[i] = 0xff; 1609 | 1610 | // Secret key. 1611 | for (i = 0; i < 32; i++) sm[32 + i] = sk[i]; 1612 | 1613 | // Message. 1614 | for (i = 0; i < n; i++) sm[64 + i] = m[i]; 1615 | 1616 | // Random suffix. 1617 | for (i = 0; i < 64; i++) sm[n + 64 + i] = rnd[i]; 1618 | 1619 | crypto_hash(r, sm, n + 128); 1620 | reduce(r); 1621 | scalarbase(p, r); 1622 | pack(sm, p); 1623 | 1624 | for (i = 0; i < 32; i++) sm[i + 32] = sk[32 + i]; 1625 | crypto_hash(h, sm, n + 64); 1626 | reduce(h); 1627 | 1628 | // Wipe out random suffix. 1629 | for (i = 0; i < 64; i++) sm[n + 64 + i] = 0; 1630 | 1631 | for (i = 0; i < 64; i++) x[i] = 0; 1632 | for (i = 0; i < 32; i++) x[i] = r[i]; 1633 | for (i = 0; i < 32; i++) { 1634 | for (j = 0; j < 32; j++) { 1635 | x[i + j] += h[i] * sk[j]; 1636 | } 1637 | } 1638 | 1639 | modL(sm.subarray(32, n + 64), x); 1640 | 1641 | return n + 64; 1642 | } 1643 | 1644 | function curve25519_sign(sm: any, m: any, n: any, sk: any, opt_rnd?: any) { 1645 | // If opt_rnd is provided, sm must have n + 128, 1646 | // otherwise it must have n + 64 bytes. 1647 | 1648 | // Convert Curve25519 secret key into Ed25519 secret key (includes pub key). 1649 | var edsk = new Uint8Array(64); 1650 | var p = [gf(), gf(), gf(), gf()]; 1651 | 1652 | for (var i = 0; i < 32; i++) edsk[i] = sk[i]; 1653 | // Ensure private key is in the correct format. 1654 | edsk[0] &= 248; 1655 | edsk[31] &= 127; 1656 | edsk[31] |= 64; 1657 | 1658 | scalarbase(p, edsk); 1659 | pack(edsk.subarray(32), p); 1660 | 1661 | // Remember sign bit. 1662 | var signBit = edsk[63] & 128; 1663 | var smlen; 1664 | 1665 | if (opt_rnd) { 1666 | smlen = crypto_sign_direct_rnd(sm, m, n, edsk, opt_rnd); 1667 | } else { 1668 | smlen = crypto_sign_direct(sm, m, n, edsk); 1669 | } 1670 | 1671 | // Copy sign bit from public key into signature. 1672 | sm[63] |= signBit; 1673 | return smlen; 1674 | } 1675 | 1676 | function unpackneg(r: any, p: any) { 1677 | var t = gf(), 1678 | chk = gf(), 1679 | num = gf(), 1680 | den = gf(), 1681 | den2 = gf(), 1682 | den4 = gf(), 1683 | den6 = gf(); 1684 | 1685 | set25519(r[2], gf1); 1686 | unpack25519(r[1], p); 1687 | S(num, r[1]); 1688 | M(den, num, D); 1689 | Z(num, num, r[2]); 1690 | A(den, r[2], den); 1691 | 1692 | S(den2, den); 1693 | S(den4, den2); 1694 | M(den6, den4, den2); 1695 | M(t, den6, num); 1696 | M(t, t, den); 1697 | 1698 | pow2523(t, t); 1699 | M(t, t, num); 1700 | M(t, t, den); 1701 | M(t, t, den); 1702 | M(r[0], t, den); 1703 | 1704 | S(chk, r[0]); 1705 | M(chk, chk, den); 1706 | if (neq25519(chk, num)) M(r[0], r[0], I); 1707 | 1708 | S(chk, r[0]); 1709 | M(chk, chk, den); 1710 | if (neq25519(chk, num)) return -1; 1711 | 1712 | if (par25519(r[0]) === p[31] >> 7) Z(r[0], gf0, r[0]); 1713 | 1714 | M(r[3], r[0], r[1]); 1715 | return 0; 1716 | } 1717 | 1718 | function crypto_sign_open(m: any, sm: any, n: any, pk: any) { 1719 | var i, mlen; 1720 | var t = new Uint8Array(32), 1721 | h = new Uint8Array(64); 1722 | var p = [gf(), gf(), gf(), gf()], 1723 | q = [gf(), gf(), gf(), gf()]; 1724 | 1725 | mlen = -1; 1726 | if (n < 64) return -1; 1727 | 1728 | if (unpackneg(q, pk)) return -1; 1729 | 1730 | for (i = 0; i < n; i++) m[i] = sm[i]; 1731 | for (i = 0; i < 32; i++) m[i + 32] = pk[i]; 1732 | crypto_hash(h, m, n); 1733 | reduce(h); 1734 | scalarmult(p, q, h); 1735 | 1736 | scalarbase(q, sm.subarray(32)); 1737 | add(p, q); 1738 | pack(t, p); 1739 | 1740 | n -= 64; 1741 | if (crypto_verify_32(sm, 0, t, 0)) { 1742 | for (i = 0; i < n; i++) m[i] = 0; 1743 | return -1; 1744 | } 1745 | 1746 | for (i = 0; i < n; i++) m[i] = sm[i + 64]; 1747 | mlen = n; 1748 | return mlen; 1749 | } 1750 | 1751 | // Converts Curve25519 public key back to Ed25519 public key. 1752 | // edwardsY = (montgomeryX - 1) / (montgomeryX + 1) 1753 | function convertPublicKey(pk: any) { 1754 | var z = new Uint8Array(32), 1755 | x = gf(), 1756 | a = gf(), 1757 | b = gf(); 1758 | 1759 | unpack25519(x, pk); 1760 | 1761 | A(a, x, gf1); 1762 | Z(b, x, gf1); 1763 | inv25519(a, a); 1764 | M(a, a, b); 1765 | 1766 | pack25519(z, a); 1767 | return z; 1768 | } 1769 | 1770 | function curve25519_sign_open(m: any, sm: any, n: any, pk: any) { 1771 | // Convert Curve25519 public key into Ed25519 public key. 1772 | var edpk = convertPublicKey(pk); 1773 | 1774 | // Restore sign bit from signature. 1775 | edpk[31] |= sm[63] & 128; 1776 | 1777 | // Remove sign bit from signature. 1778 | sm[63] &= 127; 1779 | 1780 | // Verify signed message. 1781 | return crypto_sign_open(m, sm, n, edpk); 1782 | } 1783 | 1784 | /* High-level API */ 1785 | 1786 | function checkArrayTypes(...args: any) { 1787 | var t, i; 1788 | for (i = 0; i < arguments.length; i++) { 1789 | if ((t = Object.prototype.toString.call(arguments[i])) !== '[object Uint8Array]') 1790 | throw new TypeError('unexpected type ' + t + ', use Uint8Array'); 1791 | } 1792 | } 1793 | 1794 | /** 1795 | * Returns a raw shared key between own private key and peer's public key (in other words, this is an ECC Diffie-Hellman function X25519, performing scalar multiplication). 1796 | * 1797 | * The result should not be used directly as a key, but should be processed with a one-way function (e.g. HSalsa20 as in NaCl, or any secure cryptographic hash function, such as SHA-256, or key derivation function, such as HKDF). 1798 | * 1799 | * @export 1800 | * @param {Uint8Array} secretKey 1801 | * @param {Uint8Array} publicKey 1802 | * @returns Uint8Array 1803 | */ 1804 | export function sharedKey(secretKey: any, publicKey: any) { 1805 | checkArrayTypes(publicKey, secretKey); 1806 | if (publicKey.length !== 32) throw new Error('wrong public key length'); 1807 | if (secretKey.length !== 32) throw new Error('wrong secret key length'); 1808 | var sharedKey = new Uint8Array(32); 1809 | crypto_scalarmult(sharedKey, secretKey, publicKey); 1810 | return sharedKey; 1811 | } 1812 | 1813 | /** 1814 | * Signs the given message using the private key and returns a signed message (signature concatenated with the message copy). 1815 | * 1816 | * Optional random data argument (which must have 64 random bytes) turns on hash separation and randomization to make signatures non-deterministic. 1817 | * 1818 | * @export 1819 | * @param {Uint8Array} secretKey 1820 | * @param {*} msg 1821 | * @param {Uint8Array} opt_random 1822 | * @returns 1823 | */ 1824 | export function signMessage(secretKey: any, msg: any, opt_random: any) { 1825 | checkArrayTypes(msg, secretKey); 1826 | if (secretKey.length !== 32) throw new Error('wrong secret key length'); 1827 | if (opt_random) { 1828 | checkArrayTypes(opt_random); 1829 | if (opt_random.length !== 64) throw new Error('wrong random data length'); 1830 | var buf = new Uint8Array(128 + msg.length); 1831 | curve25519_sign(buf, msg, msg.length, secretKey, opt_random); 1832 | return new Uint8Array(buf.subarray(0, 64 + msg.length)); 1833 | } else { 1834 | var signedMsg = new Uint8Array(64 + msg.length); 1835 | curve25519_sign(signedMsg, msg, msg.length, secretKey); 1836 | return signedMsg; 1837 | } 1838 | } 1839 | 1840 | /** 1841 | * Verifies signed message with the public key and returns the original message without signature if it's correct or null if verification fails. 1842 | * 1843 | * @export 1844 | * @param {Uint8Array} publicKey 1845 | * @param {*} signedMsg 1846 | * @returns Message 1847 | */ 1848 | export function openMessage(publicKey: any, signedMsg: any) { 1849 | checkArrayTypes(signedMsg, publicKey); 1850 | if (publicKey.length !== 32) throw new Error('wrong public key length'); 1851 | var tmp = new Uint8Array(signedMsg.length); 1852 | var mlen = curve25519_sign_open(tmp, signedMsg, signedMsg.length, publicKey); 1853 | if (mlen < 0) return null; 1854 | var m = new Uint8Array(mlen); 1855 | for (var i = 0; i < m.length; i++) m[i] = tmp[i]; 1856 | return m; 1857 | } 1858 | 1859 | /** 1860 | * Signs the given message using the private key and returns signature. 1861 | * 1862 | * Optional random data argument (which must have 64 random bytes) turns on hash separation and randomization to make signatures non-deterministic. 1863 | * 1864 | * @export 1865 | * @param {Uint8Array} secretKey 1866 | * @param {*} msg 1867 | * @param {Uint8Array} opt_random 1868 | * @returns 1869 | */ 1870 | export function sign(secretKey: any, msg: any, opt_random: any) { 1871 | checkArrayTypes(secretKey, msg); 1872 | if (secretKey.length !== 32) throw new Error('wrong secret key length'); 1873 | if (opt_random) { 1874 | checkArrayTypes(opt_random); 1875 | if (opt_random.length !== 64) throw new Error('wrong random data length'); 1876 | } 1877 | var buf = new Uint8Array((opt_random ? 128 : 64) + msg.length); 1878 | curve25519_sign(buf, msg, msg.length, secretKey, opt_random); 1879 | var signature = new Uint8Array(64); 1880 | for (var i = 0; i < signature.length; i++) signature[i] = buf[i]; 1881 | return signature; 1882 | } 1883 | 1884 | /** 1885 | * Verifies the given signature for the message using the given private key. Returns true if the signature is valid, false otherwise. 1886 | * 1887 | * @export 1888 | * @param {Uint8Array} publicKey 1889 | * @param {*} msg 1890 | * @param {*} signature 1891 | * @returns 1892 | */ 1893 | export function verify(publicKey: any, msg: any, signature: any) { 1894 | checkArrayTypes(msg, signature, publicKey); 1895 | if (signature.length !== 64) throw new Error('wrong signature length'); 1896 | if (publicKey.length !== 32) throw new Error('wrong public key length'); 1897 | var sm = new Uint8Array(64 + msg.length); 1898 | var m = new Uint8Array(64 + msg.length); 1899 | var i; 1900 | for (i = 0; i < 64; i++) sm[i] = signature[i]; 1901 | for (i = 0; i < msg.length; i++) sm[i + 64] = msg[i]; 1902 | return curve25519_sign_open(m, sm, sm.length, publicKey) >= 0; 1903 | } 1904 | 1905 | /** 1906 | * Generates a new key pair from the given 32-byte secret seed (which should be generated with a CSPRNG) and returns it as object. 1907 | * 1908 | * The returned keys can be used for signing and key agreement. 1909 | * 1910 | * @export 1911 | * @param {Uint8Array} seed required 1912 | * @returns 1913 | */ 1914 | export function generateKeyPair(seed: any) { 1915 | checkArrayTypes(seed); 1916 | if (seed.length !== 32) throw new Error('wrong seed length'); 1917 | var sk = new Uint8Array(32); 1918 | var pk = new Uint8Array(32); 1919 | 1920 | for (var i = 0; i < 32; i++) sk[i] = seed[i]; 1921 | 1922 | crypto_scalarmult_base(pk, sk); 1923 | 1924 | // Turn secret key into the correct format. 1925 | sk[0] &= 248; 1926 | sk[31] &= 127; 1927 | sk[31] |= 64; 1928 | 1929 | // Remove sign bit from public key. 1930 | pk[31] &= 127; 1931 | 1932 | return { 1933 | public: pk, 1934 | private: sk, 1935 | }; 1936 | } 1937 | 1938 | export default {}; 1939 | --------------------------------------------------------------------------------