UNPKG

scryptlib

Version:

Javascript SDK for integration of Bitcoin SV Smart Contracts written in sCrypt language.

167 lines 6.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.sha256ByPartialHash = exports.partialSha256 = void 0; const K = [ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ]; /** * * @param message origin message to sha256 * @param index The partial hash returned is the hash of 0~index chunks, 512 bits per chunk. * @returns [partialHash, partialPreimage, padding] */ function partialSha256(message, index) { const bytesHashed = message.length; const padLength = (bytesHashed % 64 < 56) ? 64 - (bytesHashed % 64) : 128 - (bytesHashed % 64); const suffix = Buffer.alloc(padLength); const padded = Buffer.concat([message, suffix]); const bitLenHi = (bytesHashed / 0x20000000) | 0; const bitLenLo = bytesHashed << 3; padded[bytesHashed] = 0x80; for (let i = bytesHashed + 1; i < padded.length - 8; i++) { padded[i] = 0; } padded[padded.length - 8] = (bitLenHi >>> 24) & 0xff; padded[padded.length - 7] = (bitLenHi >>> 16) & 0xff; padded[padded.length - 6] = (bitLenHi >>> 8) & 0xff; padded[padded.length - 5] = (bitLenHi >>> 0) & 0xff; padded[padded.length - 4] = (bitLenLo >>> 24) & 0xff; padded[padded.length - 3] = (bitLenLo >>> 16) & 0xff; padded[padded.length - 2] = (bitLenLo >>> 8) & 0xff; padded[padded.length - 1] = (bitLenLo >>> 0) & 0xff; const broken = []; for (let i = 0; i < padded.length / 64; i++) { broken.push(padded.slice(i * 64, i * 64 + 64)); } const h0 = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]; let hi = h0; for (let i = 0; i < broken.length; i++) { const chunk = broken[i]; hi = g(hi, chunk); if (bytesHashed > 64 && i == index) { break; } } const partialHash = toHash(hi); if (index > -1 && bytesHashed > 64) { const partialPreimage = message.slice((index + 1) * 64); const padding = padded.slice(message.length); return [partialHash, partialPreimage.toString('hex'), padding.toString('hex')]; } return [partialHash, '', '']; } exports.partialSha256 = partialSha256; /** * * @param partialHash * @param partialPreimage * @param padding * @returns sha256 of the origin message */ function sha256ByPartialHash(partialHash, partialPreimage, padding) { const partialHashBuffer = Buffer.from(partialHash, 'hex'); const padded = Buffer.from(partialPreimage + padding, 'hex'); const broken = []; for (let i = 0; i < padded.length / 64; i++) { broken.push(padded.slice(i * 64, i * 64 + 64)); } const h0 = [byteToUint32(partialHashBuffer.slice(0, 4)), byteToUint32(partialHashBuffer.slice(4, 8)), byteToUint32(partialHashBuffer.slice(8, 12)), byteToUint32(partialHashBuffer.slice(12, 16)), byteToUint32(partialHashBuffer.slice(16, 20)), byteToUint32(partialHashBuffer.slice(20, 24)), byteToUint32(partialHashBuffer.slice(24, 28)), byteToUint32(partialHashBuffer.slice(28, 32)) ]; let hi = h0; for (let i = 0; i < broken.length; i++) { const chunk = broken[i]; hi = g(hi, chunk); } return toHash(hi); } exports.sha256ByPartialHash = sha256ByPartialHash; function byteToUint32(b) { return b.readUInt32BE(); } function ToInteger(x) { x = Number(x); return x < 0 ? Math.ceil(x) : Math.floor(x); } function modulo(a, b) { return a - Math.floor(a / b) * b; } function ToUint32(x) { return modulo(ToInteger(x), Math.pow(2, 32)); } //sha256 compression function function g(hprev, chunk) { let a = hprev[0]; let b = hprev[1]; let c = hprev[2]; let d = hprev[3]; let e = hprev[4]; let f = hprev[5]; let g = hprev[6]; let h = hprev[7]; const W = []; // Computation for (let i = 0; i < 64; i++) { if (i < 16) { W[i] = (chunk.slice(i * 4, i * 4 + 4).readUInt32BE()); } else { const gamma0x = W[i - 15]; const gamma0 = (((gamma0x << 25) | (gamma0x >>> 7)) ^ ((gamma0x << 14) | (gamma0x >>> 18)) ^ (gamma0x >>> 3)); const gamma1x = W[i - 2]; const gamma1 = (((gamma1x << 15) | (gamma1x >>> 17)) ^ ((gamma1x << 13) | (gamma1x >>> 19)) ^ (gamma1x >>> 10)); W[i] = (gamma0 + W[i - 7] + gamma1 + W[i - 16]); } const ch = ((e & f) ^ (~e & g)); const maj = ((a & b) ^ (a & c) ^ (b & c)); const sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22)); const sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25)); const t1 = (h + sigma1 + ch + K[i] + W[i]); const t2 = (sigma0 + maj); h = g; g = f; f = e; e = (d + t1); d = c; c = b; b = a; a = (t1 + t2); } return [ToUint32(hprev[0] + a), ToUint32(hprev[1] + b), ToUint32(hprev[2] + c), ToUint32(hprev[3] + d), ToUint32(hprev[4] + e), ToUint32(hprev[5] + f), ToUint32(hprev[6] + g), ToUint32(hprev[7] + h)]; } function iToB(i) { const bs = Buffer.from([0, 0, 0, 0]); bs.writeUInt32BE(i); return bs; } function toHash(hi) { const hashBytes = [iToB(hi[0]), iToB(hi[1]), iToB(hi[2]), iToB(hi[3]), iToB(hi[4]), iToB(hi[5]), iToB(hi[6]), iToB(hi[7])]; return hashBytes.reduce((acc, cur) => { return Buffer.concat([acc, cur]); }, Buffer.from([])).toString('hex'); } //# sourceMappingURL=partialSha256.js.map