diff options
Diffstat (limited to 'contrib/examples/keygen-html')
-rw-r--r-- | contrib/examples/keygen-html/Makefile | 6 | ||||
-rw-r--r-- | contrib/examples/keygen-html/keygen.html | 2 | ||||
-rw-r--r-- | contrib/examples/keygen-html/src/curve25519_generate.c | 97 | ||||
-rw-r--r-- | contrib/examples/keygen-html/src/glue.js | 25 | ||||
-rw-r--r-- | contrib/examples/keygen-html/wireguard.js | 186 |
5 files changed, 187 insertions, 129 deletions
diff --git a/contrib/examples/keygen-html/Makefile b/contrib/examples/keygen-html/Makefile deleted file mode 100644 index a3acec0..0000000 --- a/contrib/examples/keygen-html/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -curve25519_generate.js: src/curve25519_generate.c src/glue.js - emcc -O2 --memory-init-file 0 --closure 1 --post-js src/glue.js -s 'EXTRA_EXPORTED_RUNTIME_METHODS=["Pointer_stringify"]' -o $@ src/curve25519_generate.c -clean: - rm -f curve25519_generate.js -all: curve25519_generate.js -.PHONY: clean all diff --git a/contrib/examples/keygen-html/keygen.html b/contrib/examples/keygen-html/keygen.html index 45efec7..694e1ff 100644 --- a/contrib/examples/keygen-html/keygen.html +++ b/contrib/examples/keygen-html/keygen.html @@ -1,4 +1,4 @@ -<script src="curve25519_generate.js" onError='document.write("<h3>Did you forget to run \"make\" to compile curve25519_generate.js?</h3><!--");'></script> +<script src="wireguard.js"></script> <script> /* SPDX-License-Identifier: GPL-2.0 * diff --git a/contrib/examples/keygen-html/src/curve25519_generate.c b/contrib/examples/keygen-html/src/curve25519_generate.c deleted file mode 100644 index fc47575..0000000 --- a/contrib/examples/keygen-html/src/curve25519_generate.c +++ /dev/null @@ -1,97 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * Copyright (C) 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. - */ - -#include <emscripten.h> - -typedef unsigned long long u64; -typedef unsigned int u32; -typedef unsigned char u8; -typedef u32 __le32; - -enum { CURVE25519_POINT_SIZE = 32 }; - -#ifndef __always_inline -#define __always_inline __inline __attribute__((__always_inline__)) -#endif -#ifndef noinline -#define noinline __attribute__((noinline)) -#endif -#ifndef __aligned -#define __aligned(x) __attribute__((aligned(x))) -#endif -#ifndef __force -#define __force -#endif - -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define le32_to_cpup(a) (*(a)) -#else -#define le32_to_cpup(a) __builtin_bswap32(*(a)) -#endif - -#define memset(a, b, c) __builtin_memset(a, b, c) -#define memcpy(a, b, c) __builtin_memcpy(a, b, c) -#define memmove(a, b, c) __builtin_memmove(a, b, c) -/* We don't even attempt to deal with this in javascript. */ -#define memzero_explicit(a, b) - -static __always_inline void normalize_secret(u8 secret[CURVE25519_POINT_SIZE]) -{ - secret[0] &= 248; - secret[31] &= 127; - secret[31] |= 64; -} - -#include "../../../../src/crypto/curve25519-fiat32.h" - -EMSCRIPTEN_KEEPALIVE void curve25519_generate_public(u8 public[static 32], const u8 private[static 32]) -{ - static const u8 basepoint[32] = { 9 }; - - curve25519_generic(public, private, basepoint); -} - -EMSCRIPTEN_KEEPALIVE void curve25519_generate_private(u8 private[static 32]) -{ - int i; - - EM_ASM({ - /* Same trick as libsodium */ - var getRandomValue = function() { - var buf = new Uint32Array(1); - window.crypto.getRandomValues(buf); - return buf[0] >>> 0; - }; - Module.getRandomValue = getRandomValue; - }); - - for (i = 0; i < 32; ++i) - private[i] = EM_ASM_INT_V({ return Module.getRandomValue(); }); - normalize_secret(private); -} - -static inline void encode_base64(char dest[4], const u8 src[3]) -{ - const u8 input[] = { (src[0] >> 2) & 63, ((src[0] << 4) | (src[1] >> 4)) & 63, ((src[1] << 2) | (src[2] >> 6)) & 63, src[2] & 63 }; - - for (unsigned int i = 0; i < 4; ++i) - dest[i] = input[i] + 'A' - + (((25 - input[i]) >> 8) & 6) - - (((51 - input[i]) >> 8) & 75) - - (((61 - input[i]) >> 8) & 15) - + (((62 - input[i]) >> 8) & 3); - -} - -EMSCRIPTEN_KEEPALIVE void key_to_base64(char base64[static 45], const u8 key[static 32]) -{ - unsigned int i; - - for (i = 0; i < 32 / 3; ++i) - encode_base64(&base64[i * 4], &key[i * 3]); - encode_base64(&base64[i * 4], (const u8[]){ key[i * 3 + 0], key[i * 3 + 1], 0 }); - base64[45 - 2] = '='; - base64[45 - 1] = '\0'; -} diff --git a/contrib/examples/keygen-html/src/glue.js b/contrib/examples/keygen-html/src/glue.js deleted file mode 100644 index 981e533..0000000 --- a/contrib/examples/keygen-html/src/glue.js +++ /dev/null @@ -1,25 +0,0 @@ -/*! SPDX-License-Identifier: GPL-2.0 - * - * Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. - */ -window["WireGuard"] = { - "generateKeypair": function() { - var privateKey = Module["_malloc"](32); - var publicKey = Module["_malloc"](32); - Module["_curve25519_generate_private"](privateKey); - Module["_curve25519_generate_public"](publicKey, privateKey); - var privateBase64 = Module["_malloc"](45); - var publicBase64 = Module["_malloc"](45); - Module["_key_to_base64"](privateBase64, privateKey); - Module["_key_to_base64"](publicBase64, publicKey); - Module["_free"](privateKey); - Module["_free"](publicKey); - var keypair = { - publicKey: Module["Pointer_stringify"](publicBase64), - privateKey: Module["Pointer_stringify"](privateBase64) - }; - Module["_free"](privateBase64); - Module["_free"](publicBase64); - return keypair; - } -}; diff --git a/contrib/examples/keygen-html/wireguard.js b/contrib/examples/keygen-html/wireguard.js new file mode 100644 index 0000000..b77dec8 --- /dev/null +++ b/contrib/examples/keygen-html/wireguard.js @@ -0,0 +1,186 @@ +/*! SPDX-License-Identifier: GPL-2.0 + * + * Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. + */ + +(function() { + function gf(init) { + var r = new Float64Array(16); + if (init) { + for (var i = 0; i < init.length; ++i) + r[i] = init[i]; + } + return r; + } + + function pack(o, n) { + var b, m = gf(), t = gf(); + for (var i = 0; i < 16; ++i) + t[i] = n[i]; + carry(t); + carry(t); + carry(t); + for (var j = 0; j < 2; ++j) { + m[0] = t[0] - 0xffed; + for (var 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); + b = (m[15] >> 16) & 1; + m[14] &= 0xffff; + cswap(t, m, 1 - b); + } + for (var i = 0; i < 16; ++i) { + o[2 * i] = t[i] & 0xff; + o[2 * i + 1] = t[i] >> 8; + } + } + + function carry(o) { + var c; + for (var i = 0; i < 16; ++i) { + o[i] += 65536; + c = Math.floor(o[i] / 65536); + o[(i + 1) * (i < 15 ? 1 : 0)] += c - 1 + 37 * (c - 1) * (i === 15 ? 1 : 0); + o[i] -= (c * 65536); + } + } + + function cswap(p, q, b) { + var t, c = ~(b - 1); + for (var i = 0; i < 16; ++i) { + t = c & (p[i] ^ q[i]); + p[i] ^= t; + q[i] ^= t; + } + } + + function add(o, a, b) { + for (var i = 0; i < 16; ++i) + o[i] = (a[i] + b[i]) | 0; + } + + function subtract(o, a, b) { + for (var i = 0; i < 16; ++i) + o[i] = (a[i] - b[i]) | 0; + } + + function multmod(o, a, b) { + var t = new Float64Array(31); + for (var i = 0; i < 16; ++i) { + for (var j = 0; j < 16; ++j) + t[i + j] += a[i] * b[j]; + } + for (var i = 0; i < 15; ++i) + t[i] += 38 * t[i + 16]; + for (var i = 0; i < 16; ++i) + o[i] = t[i]; + carry(o); + carry(o); + } + + function invert(o, i) { + var c = gf(); + for (var a = 0; a < 16; ++a) + c[a] = i[a]; + for (var a = 253; a >= 0; --a) { + multmod(c, c, c); + if (a !== 2 && a !== 4) + multmod(c, c, i); + } + for (var a = 0; a < 16; ++a) + o[a] = c[a]; + } + + function normalizeKey(z) { + z[31] = (z[31] & 127) | 64; + z[0] &= 248; + } + + function generatePublicKey(privateKey) { + var r, z = new Uint8Array(32); + var a = gf([1]), + b = gf([9]), + c = gf(), + d = gf([1]), + e = gf(), + f = gf(), + _121665 = gf([0xdb41, 1]), + _9 = gf([9]); + for (var i = 0; i < 32; ++i) + z[i] = privateKey[i]; + normalizeKey(z); + for (var i = 254; i >= 0; --i) { + r = (z[i >>> 3] >>> (i & 7)) & 1; + cswap(a, b, r); + cswap(c, d, r); + add(e, a, c); + subtract(a, a, c); + add(c, b, d); + subtract(b, b, d); + multmod(d, e, e); + multmod(f, a, a); + multmod(a, c, a); + multmod(c, b, e); + add(e, a, c); + subtract(a, a, c); + multmod(b, a, a); + subtract(c, d, f); + multmod(a, c, _121665); + add(a, a, d); + multmod(c, c, a); + multmod(a, d, f); + multmod(d, b, _9); + multmod(b, e, e); + cswap(a, b, r); + cswap(c, d, r); + } + invert(c, c); + multmod(a, a, c); + pack(z, a); + return z; + } + + function generatePresharedKey() { + var privateKey = new Uint8Array(32); + window.crypto.getRandomValues(privateKey); + return privateKey; + } + + function generatePrivateKey() { + var privateKey = generatePresharedKey(); + normalizeKey(privateKey); + return privateKey; + } + + function encodeBase64(dest, src) { + var input = Uint8Array.from([(src[0] >> 2) & 63, ((src[0] << 4) | (src[1] >> 4)) & 63, ((src[1] << 2) | (src[2] >> 6)) & 63, src[2] & 63]); + for (var i = 0; i < 4; ++i) + dest[i] = input[i] + 65 + + (((25 - input[i]) >> 8) & 6) - + (((51 - input[i]) >> 8) & 75) - + (((61 - input[i]) >> 8) & 15) + + (((62 - input[i]) >> 8) & 3); + } + + function keyToBase64(key) { + var i, base64 = new Uint8Array(44); + for (i = 0; i < 32 / 3; ++i) + encodeBase64(base64.subarray(i * 4), key.subarray(i * 3)); + encodeBase64(base64.subarray(i * 4), Uint8Array.from([key[i * 3 + 0], key[i * 3 + 1], 0])); + base64[43] = 61; + return String.fromCharCode.apply(null, base64); + } + + window["WireGuard"] = { + "generateKeypair": function() { + var privateKey = generatePrivateKey(); + var publicKey = generatePublicKey(privateKey); + return { + publicKey: keyToBase64(publicKey), + privateKey: keyToBase64(privateKey) + }; + } + }; +})(); |