diff options
author | Florian Dold <florian.dold@gmail.com> | 2019-11-21 23:10:17 +0100 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2019-11-21 23:10:24 +0100 |
commit | de9f8867d5141940f47951c51648becec74959cb (patch) | |
tree | 84a1f224af86c5ca8fda65b12e22af741510c517 | |
parent | c6233094306cd264f8faa2041388dff01ff8cf01 (diff) |
missing files / native encode/decode
-rw-r--r-- | src/crypto/nativeCrypto-test.ts | 32 | ||||
-rw-r--r-- | src/crypto/nativeCrypto.ts | 140 | ||||
-rw-r--r-- | src/logging.ts | 25 |
3 files changed, 197 insertions, 0 deletions
diff --git a/src/crypto/nativeCrypto-test.ts b/src/crypto/nativeCrypto-test.ts new file mode 100644 index 000000000..7b9fcf256 --- /dev/null +++ b/src/crypto/nativeCrypto-test.ts @@ -0,0 +1,32 @@ +/* + This file is part of GNU Taler + (C) 2019 GNUnet e.V. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +/** + * Imports + */ +import test from "ava"; +import { encodeCrock, decodeCrock } from "./nativeCrypto"; + + +test("encoding", (t) => { + const utf8decoder = new TextDecoder("utf-8"); + const utf8encoder = new TextEncoder(); + const s = "Hello, World"; + const encStr = encodeCrock(utf8encoder.encode(s)); + const outBuf = decodeCrock(encStr); + const sOut = utf8decoder.decode(outBuf); + t.deepEqual(s, sOut); +});
\ No newline at end of file diff --git a/src/crypto/nativeCrypto.ts b/src/crypto/nativeCrypto.ts new file mode 100644 index 000000000..853ece6c7 --- /dev/null +++ b/src/crypto/nativeCrypto.ts @@ -0,0 +1,140 @@ +/* + This file is part of GNU Taler + (C) 2019 GNUnet e.V. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +/** + * Native implementation of GNU Taler crypto. + */ + +let isNode; + +let myGetRandom: (n: number) => ArrayBuffer; + +if (require) { + // node.js + const cr = require("crypto"); + myGetRandom = (n: number) => { + const buf = cr.randomBytes(n); + return Uint8Array.from(buf); + } +} else { + // Browser + myGetRandom = (n: number) => { + const ret = new Uint8Array(n); + window.crypto.getRandomValues(ret); + return ret; + } +} + +export function getRandomBytes(n: number): ArrayBuffer { + return myGetRandom(n); +} + +const encTable = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; + +class EncodingError extends Error { + constructor() { + super("Encoding error"); + Object.setPrototypeOf(this, EncodingError.prototype); + } +} + +function getValue(chr: string): number { + let a = chr; + switch (chr) { + case "O": + case "o": + a = "0;"; + break; + case "i": + case "I": + case "l": + case "L": + a = "1"; + break; + case "u": + case "U": + a = "V"; + } + + if (a >= "0" && a <= "9") { + return a.charCodeAt(0) - "0".charCodeAt(0); + } + + if (a >= "a" && a <= "z") a = a.toUpperCase(); + let dec = 0; + if (a >= "A" && a <= "Z") { + if ("I" < a) dec++; + if ("L" < a) dec++; + if ("O" < a) dec++; + if ("U" < a) dec++; + return a.charCodeAt(0) - "A".charCodeAt(0) + 10 - dec; + } + throw new EncodingError(); +} + +export function encodeCrock(data: ArrayBuffer): string { + const dataBytes = new Uint8Array(data); + let sb = ""; + const size = data.byteLength; + let bitBuf = 0; + let numBits = 0; + let pos = 0; + while (pos < size || numBits > 0) { + if (pos < size && numBits < 5) { + const d = dataBytes[pos++]; + bitBuf = (bitBuf << 8) | d; + numBits += 8; + } + if (numBits < 5) { + // zero-padding + bitBuf = bitBuf << (5 - numBits); + numBits = 5; + } + const v = (bitBuf >>> (numBits - 5)) & 31; + sb += encTable[v]; + numBits -= 5; + } + return sb; +} + +export function decodeCrock(encoded: string): ArrayBuffer { + const size = encoded.length; + let bitpos = 0; + let bitbuf = 0; + let readPosition = 0; + const outLen = Math.floor((size * 5) / 8); + const out = new Int8Array(outLen); + let outPos = 0; + + while (readPosition < size || bitpos > 0) { + //println("at position $readPosition with bitpos $bitpos") + if (readPosition < size) { + const v = getValue(encoded[readPosition++]); + bitbuf = (bitbuf << 5) | v; + bitpos += 5; + } + while (bitpos >= 8) { + const d = (bitbuf >>> (bitpos - 8)) & 0xff; + out[outPos++] = d; + bitpos -= 8; + } + if (readPosition == size && bitpos > 0) { + bitbuf = (bitbuf << (8 - bitpos)) & 0xff; + bitpos = bitbuf == 0 ? 0 : 8; + } + } + return out; +} diff --git a/src/logging.ts b/src/logging.ts new file mode 100644 index 000000000..a21943e6e --- /dev/null +++ b/src/logging.ts @@ -0,0 +1,25 @@ +/* + This file is part of TALER + (C) 2019 GNUnet e.V. + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +export class Logger { + constructor(private tag: string) {} + info(message: string, ...args: any[]) { + console.log(`${new Date().toISOString()} ${this.tag} INFO ` + message, ...args); + } + trace(message: string, ...args: any[]) { + console.log(`${new Date().toISOString()} ${this.tag} TRACE ` + message, ...args) + } +}
\ No newline at end of file |