UNPKG

17.7 kBSource Map (JSON)View Raw
1{"version":3,"file":"rabin-gf2-polynomial.cjs","sources":["../hash/rabin-gf2-polynomial.js"],"sourcesContent":["/**\n * The idea of the Rabin fingerprint algorithm is to represent the binary as a polynomial in a\n * finite field (Galois Field G(2)). The polynomial will then be taken \"modulo\" by an irreducible\n * polynomial of the desired size.\n *\n * This implementation is inefficient and is solely used to verify the actually performant\n * implementation in `./rabin.js`.\n *\n * @module rabin-gf2-polynomial\n */\n\nimport * as math from '../math.js'\nimport * as webcrypto from 'lib0/webcrypto'\nimport * as array from '../array.js'\nimport * as buffer from '../buffer.js'\n\n/**\n * @param {number} degree\n */\nconst _degreeToMinByteLength = degree => math.floor(degree / 8) + 1\n\n/**\n * This is a GF2 Polynomial abstraction that is not meant for production!\n *\n * It is easy to understand and it's correctness is as obvious as possible. It can be used to verify\n * efficient implementations of algorithms on GF2.\n */\nexport class GF2Polynomial {\n constructor () {\n /**\n * @type {Set<number>}\n */\n this.degrees = new Set()\n }\n}\n\n/**\n * From Uint8Array (MSB).\n *\n * @param {Uint8Array} bytes\n */\nexport const createFromBytes = bytes => {\n const p = new GF2Polynomial()\n for (let bsi = bytes.length - 1, currDegree = 0; bsi >= 0; bsi--) {\n const currByte = bytes[bsi]\n for (let i = 0; i < 8; i++) {\n if (((currByte >>> i) & 1) === 1) {\n p.degrees.add(currDegree)\n }\n currDegree++\n }\n }\n return p\n}\n\n/**\n * Transform to Uint8Array (MSB).\n *\n * @param {GF2Polynomial} p\n * @param {number} byteLength\n */\nexport const toUint8Array = (p, byteLength = _degreeToMinByteLength(getHighestDegree(p))) => {\n const buf = buffer.createUint8ArrayFromLen(byteLength)\n /**\n * @param {number} i\n */\n const setBit = i => {\n const bi = math.floor(i / 8)\n buf[buf.length - 1 - bi] |= (1 << (i % 8))\n }\n p.degrees.forEach(setBit)\n return buf\n}\n\n/**\n * Create from unsigned integer (max 32bit uint) - read most-significant-byte first.\n *\n * @param {number} uint\n */\nexport const createFromUint = uint => {\n const buf = new Uint8Array(4)\n for (let i = 0; i < 4; i++) {\n buf[i] = uint >>> 8 * (3 - i)\n }\n return createFromBytes(buf)\n}\n\n/**\n * Create a random polynomial of a specified degree.\n *\n * @param {number} degree\n */\nexport const createRandom = degree => {\n const bs = new Uint8Array(_degreeToMinByteLength(degree))\n webcrypto.getRandomValues(bs)\n // Get first byte and explicitly set the bit of \"degree\" to 1 (the result must have the specified\n // degree).\n const firstByte = bs[0] | 1 << (degree % 8)\n // Find out how many bits of the first byte need to be filled with zeros because they are >degree.\n const zeros = 7 - (degree % 8)\n bs[0] = ((firstByte << zeros) & 0xff) >>> zeros\n return createFromBytes(bs)\n}\n\n/**\n * @param {GF2Polynomial} p\n * @return number\n */\nexport const getHighestDegree = p => array.fold(array.from(p.degrees), 0, math.max)\n\n/**\n * Add (+) p2 int the p1 polynomial.\n *\n * Addition is defined as xor in F2. Substraction is equivalent to addition in F2.\n *\n * @param {GF2Polynomial} p1\n * @param {GF2Polynomial} p2\n */\nexport const addInto = (p1, p2) => {\n p2.degrees.forEach(degree => {\n if (p1.degrees.has(degree)) {\n p1.degrees.delete(degree)\n } else {\n p1.degrees.add(degree)\n }\n })\n}\n\n/**\n * Or (|) p2 into the p1 polynomial.\n *\n * Addition is defined as xor in F2. Substraction is equivalent to addition in F2.\n *\n * @param {GF2Polynomial} p1\n * @param {GF2Polynomial} p2\n */\nexport const orInto = (p1, p2) => {\n p2.degrees.forEach(degree => {\n p1.degrees.add(degree)\n })\n}\n\n/**\n * Add (+) p2 to the p1 polynomial.\n *\n * Addition is defined as xor in F2. Substraction is equivalent to addition in F2.\n *\n * @param {GF2Polynomial} p1\n * @param {GF2Polynomial} p2\n */\nexport const add = (p1, p2) => {\n const result = new GF2Polynomial()\n p2.degrees.forEach(degree => {\n if (!p1.degrees.has(degree)) {\n result.degrees.add(degree)\n }\n })\n p1.degrees.forEach(degree => {\n if (!p2.degrees.has(degree)) {\n result.degrees.add(degree)\n }\n })\n return result\n}\n\n/**\n * Add (+) p2 to the p1 polynomial.\n *\n * Addition is defined as xor in F2. Substraction is equivalent to addition in F2.\n *\n * @param {GF2Polynomial} p\n */\nexport const clone = (p) => {\n const result = new GF2Polynomial()\n p.degrees.forEach(d => result.degrees.add(d))\n return result\n}\n\n/**\n * Add (+) p2 to the p1 polynomial.\n *\n * Addition is defined as xor in F2. Substraction is equivalent to addition in F2.\n *\n * @param {GF2Polynomial} p\n * @param {number} degree\n */\nexport const addDegreeInto = (p, degree) => {\n if (p.degrees.has(degree)) {\n p.degrees.delete(degree)\n } else {\n p.degrees.add(degree)\n }\n}\n\n/**\n * Multiply (•) p1 with p2 and store the result in p1.\n *\n * @param {GF2Polynomial} p1\n * @param {GF2Polynomial} p2\n */\nexport const multiply = (p1, p2) => {\n const result = new GF2Polynomial()\n p1.degrees.forEach(degree1 => {\n p2.degrees.forEach(degree2 => {\n addDegreeInto(result, degree1 + degree2)\n })\n })\n return result\n}\n\n/**\n * Multiply (•) p1 with p2 and store the result in p1.\n *\n * @param {GF2Polynomial} p\n * @param {number} shift\n */\nexport const shiftLeft = (p, shift) => {\n const result = new GF2Polynomial()\n p.degrees.forEach(degree => {\n const r = degree + shift\n r >= 0 && result.degrees.add(r)\n })\n return result\n}\n\n/**\n * Computes p1 % p2. I.e. the remainder of p1/p2.\n *\n * @param {GF2Polynomial} p1\n * @param {GF2Polynomial} p2\n */\nexport const mod = (p1, p2) => {\n const maxDeg1 = getHighestDegree(p1)\n const maxDeg2 = getHighestDegree(p2)\n const result = clone(p1)\n for (let i = maxDeg1 - maxDeg2; i >= 0; i--) {\n if (result.degrees.has(maxDeg2 + i)) {\n const shifted = shiftLeft(p2, i)\n addInto(result, shifted)\n }\n }\n return result\n}\n\n/**\n * Computes (p^e mod m).\n *\n * http://en.wikipedia.org/wiki/Modular_exponentiation\n *\n * @param {GF2Polynomial} p\n * @param {number} e\n * @param {GF2Polynomial} m\n */\nexport const modPow = (p, e, m) => {\n let result = ONE\n while (true) {\n if ((e & 1) === 1) {\n result = mod(multiply(result, p), m)\n }\n e >>>= 1\n if (e === 0) {\n return result\n }\n p = mod(multiply(p, p), m)\n }\n}\n\n/**\n * Find the greatest common divisor using Euclid's Algorithm.\n *\n * @param {GF2Polynomial} p1\n * @param {GF2Polynomial} p2\n */\nexport const gcd = (p1, p2) => {\n while (p2.degrees.size > 0) {\n const modded = mod(p1, p2)\n p1 = p2\n p2 = modded\n }\n return p1\n}\n\n/**\n * true iff p1 equals p2\n *\n * @param {GF2Polynomial} p1\n * @param {GF2Polynomial} p2\n */\nexport const equals = (p1, p2) => {\n if (p1.degrees.size !== p2.degrees.size) return false\n for (const d of p1.degrees) {\n if (!p2.degrees.has(d)) return false\n }\n return true\n}\n\nconst X = createFromBytes(new Uint8Array([2]))\nconst ONE = createFromBytes(new Uint8Array([1]))\n\n/**\n * Computes ( x^(2^p) - x ) mod f\n *\n * (shamelessly copied from\n * https://github.com/opendedup/rabinfingerprint/blob/master/src/org/rabinfingerprint/polynomial/Polynomial.java)\n *\n * @param {GF2Polynomial} f\n * @param {number} p\n */\nconst reduceExponent = (f, p) => {\n // compute (x^q^p mod f)\n const q2p = math.pow(2, p)\n const x2q2p = modPow(X, q2p, f)\n // subtract (x mod f)\n return mod(add(x2q2p, X), f)\n}\n\n/**\n * BenOr Reducibility Test\n *\n * Tests and Constructions of Irreducible Polynomials over Finite Fields\n * (1997) Shuhong Gao, Daniel Panario\n *\n * http://citeseer.ist.psu.edu/cache/papers/cs/27167/http:zSzzSzwww.math.clemson.eduzSzfacultyzSzGaozSzpaperszSzGP97a.pdf/gao97tests.pdf\n *\n * @param {GF2Polynomial} p\n */\nexport const isIrreducibleBenOr = p => {\n const degree = getHighestDegree(p)\n for (let i = 1; i < degree / 2; i++) {\n const b = reduceExponent(p, i)\n const g = gcd(p, b)\n if (!equals(g, ONE)) {\n return false\n }\n }\n return true\n}\n\n/**\n * @param {number} degree\n */\nexport const createIrreducible = degree => {\n while (true) {\n const p = createRandom(degree)\n if (isIrreducibleBenOr(p)) return p\n }\n}\n\n/**\n * Create a fingerprint of buf using the irreducible polynomial m.\n *\n * @param {Uint8Array} buf\n * @param {GF2Polynomial} m\n */\nexport const fingerprint = (buf, m) => toUint8Array(mod(createFromBytes(buf), m), _degreeToMinByteLength(getHighestDegree(m) - 1))\n\nexport class RabinPolynomialEncoder {\n /**\n * @param {GF2Polynomial} m The irreducible polynomial\n */\n constructor (m) {\n this.fingerprint = new GF2Polynomial()\n this.m = m\n }\n\n /**\n * @param {number} b\n */\n write (b) {\n const bp = createFromBytes(new Uint8Array([b]))\n const fingerprint = shiftLeft(this.fingerprint, 8)\n orInto(fingerprint, bp)\n this.fingerprint = mod(fingerprint, this.m)\n }\n\n getFingerprint () {\n return toUint8Array(this.fingerprint, _degreeToMinByteLength(getHighestDegree(this.m) - 1))\n }\n}\n"],"names":["math.floor","buffer.createUint8ArrayFromLen","webcrypto","array.fold","array.from","math.max","math.pow"],"mappings":"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"}
\No newline at end of file