From ffa164796aa87560c8b1baab00e973e8e39dae44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Soko=C5=82owski?= Date: Thu, 6 Feb 2020 12:08:05 +0100 Subject: [PATCH] improve comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jakub SokoĊ‚owski --- src/lsfr.js | 33 ++++++++++++++++++++++----------- src/main.js | 38 +++++++++++++++++++++++++------------- 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/src/lsfr.js b/src/lsfr.js index 0f279a5..80767bf 100644 --- a/src/lsfr.js +++ b/src/lsfr.js @@ -1,20 +1,31 @@ +/** + * All operations need to be done using BigInt values. + **/ const ZERO = BigInt(0) const ONE = BigInt(1) -// In `go` we use `uint64` for both `bit` and `data`. -// This is capped to 64bits. -// When shifting left, this value might "overflow", meaning that any bit in position greater than 64 will be set to `0` (in golang it just does not exist). -// In the js implementation we use bigInt, which are not capped, therefore shifting left actually preserves those bytes, and results in a different calculation. -// To avoid this we always `and` any value with the mask `0xffffffffffffffff` which only preserves the 64 least significant bits. +/** + * In GoLang we use uint64 for both `bit` and `data`. This is capped to 64bits. + * When shifting left, this value might "overflow", meaning that + * any bit in position greater than 64 will be set to `0` (in Go it just does not exist). + * In the JavaScript implementation we use BigInt, which are not capped, + * therefore shifting left actually preserves those bytes, and results in a different calculation. + * To avoid this we always binary `AND` any value with the mask `0xffffffffffffffff` + * which only preserves the 64 least significant bits. + **/ const UINT64 = BigInt("0xFFFFFFFFFFFFFFFF") +/** + * This implementation is based on the GoLang one in status-go: + * https://github.com/status-im/status-go/tree/develop/protocol/identity/alias + **/ class LSFR { constructor(poly, seed) { - this.poly = poly; - this.data = seed; + this.poly = poly + this.data = seed } next() { - let bit = ZERO; + let bit = ZERO for (let i = ZERO; i < BigInt(64); i++) { let c = (this.poly & (ONE << i)) & UINT64 @@ -22,13 +33,13 @@ class LSFR { bit = (bit ^ (this.data >> i)) & UINT64 } } - bit = (bit & ONE) & UINT64; + bit = (bit & ONE) & UINT64 let w = (this.data << ONE) & UINT64 - this.data = w | bit; + this.data = w | bit - return this.data; + return this.data } } diff --git a/src/main.js b/src/main.js index 40a2bca..c3067e4 100755 --- a/src/main.js +++ b/src/main.js @@ -1,29 +1,41 @@ import { animals, adjectives } from './data.js' import LSFR from './lsfr.js' -function dropHexPrefix(str) { - return str.substring(2) +function dropHexPrefixAndControlByt(str) { + return str.substring(4) } -function dropControlByte(str) { - return str.substring(2) -} - -function parseHexString(str) { +function extractXFromPubKey(str) { if (str.length != 128) { throw "Wrong Hex length for public key!" } + /** + * We need to parse the 8 least significant bytes of X. + * This means we need to take the last 16 characters + * from the first 64 character hexadecimal. + **/ return BigInt("0x"+str.substring(48, 64), 16) } -function uncompressedPublicKeyToChatName(pubKeyStr) { - if (!pubKeyStr.startsWith("0x")) { - throw "Not a viable uncompressed public key" +function chatKeyToChatName(pubKeyStr) { + if (typeof pubKeyStr != "string") { + throw "Only type string argument is accepted." } - let pubKey = dropControlByte(dropHexPrefix(pubKeyStr)) - let parsedKey = parseHexString(pubKey) + /** + * 0x indicates the hexadecimal format of string. + * 04 is the prefix of an uncompressed public key. + * For more details see: + * https://github.com/bitcoin-core/secp256k1/blob/0d9540b1/include/secp256k1.h#L180 + **/ + if (!pubKeyStr.startsWith("0x04")) { + throw "Not a viable uncompressed public key." + } + /* The actual data is after the control byte. */ + let pubKey = dropHexPrefixAndControlByt(pubKeyStr) + /* Public key consists of two values, X and Y. */ + let pubKeyX = extractXFromPubKey(pubKey) - let seed = parsedKey; + let seed = pubKeyX; let poly = BigInt(184); let gen = new LSFR(poly, seed);