UNPKG

ares-ide

Version:

A browser-based code editor and UI designer for Enyo 2 projects

188 lines (168 loc) 5.64 kB
# HMAC-SHA1 implementation heavily inspired from # http://pajhome.org.uk/crypt/md5/sha1.js # Base64-encoded HMAC-SHA1. # # @param {String} string the ASCII string to be signed # @param {String} key the HMAC key # @return {String} a base64-encoded HMAC of the given string and key base64HmacSha1 = (string, key) -> arrayToBase64 hmacSha1(stringToArray(string), stringToArray(key), string.length, key.length) # Base64-encoded SHA1. # # @param {String} string the ASCII string to be hashed # @return {String} a base64-encoded SHA1 hash of the given string base64Sha1 = (string) -> arrayToBase64 sha1(stringToArray(string), string.length) # SHA1 and HMAC-SHA1 versions that use the node.js builtin crypto. if typeof require isnt 'undefined' try crypto = require 'crypto' if crypto.createHmac and crypto.createHash base64HmacSha1 = (string, key) -> hmac = crypto.createHmac 'sha1', key hmac.update string hmac.digest 'base64' base64Sha1 = (string) -> hash = crypto.createHash 'sha1' hash.update string hash.digest 'base64' catch requireError # The slow versions defined at the top of the file work everywhere. Dropbox.Util.hmac = base64HmacSha1 Dropbox.Util.sha1 = base64Sha1 # HMAC-SHA1 implementation. # # @param {Array} string the HMAC input, as an array of 32-bit numbers # @param {Array} key the HMAC input, as an array of 32-bit numbers # @param {Number} length the length of the HMAC input, in bytes # @return {Array} the HMAC output, as an array of 32-bit numbers hmacSha1 = (string, key, length, keyLength) -> if key.length > 16 key = sha1 key, keyLength ipad = (key[i] ^ 0x36363636 for i in [0...16]) opad = (key[i] ^ 0x5C5C5C5C for i in [0...16]) hash1 = sha1 ipad.concat(string), 64 + length sha1 opad.concat(hash1), 64 + 20 # SHA1 implementation. # # @param {Array} string the SHA1 input, as an array of 32-bit numbers; the # computation trashes the array # @param {Number} length the number of bytes in the SHA1 input; used in the # SHA1 padding algorithm # @return {Array<Number>} the SHA1 output, as an array of 32-bit numbers sha1 = (string, length) -> string[length >> 2] |= 1 << (31 - ((length & 0x03) << 3)) string[(((length + 8) >> 6) << 4) + 15] = length << 3 state = Array 80 a = 1732584193 # 0x67452301 b = -271733879 # 0xefcdab89 c = -1732584194 # 0x98badcfe d = 271733878 # 0x10325476 e = -1009589776 # 0xc3d2e1f0 i = 0 limit = string.length # Uncomment the line below to debug packing. # console.log string.map(xxx) while i < limit a0 = a b0 = b c0 = c d0 = d e0 = e for j in [0...80] if j < 16 state[j] = string[i + j] else state[j] = rotateLeft32 state[j - 3] ^ state[j - 8] ^ state[j - 14] ^ state[j - 16], 1 if j < 20 ft = (b & c) | ((~b) & d) kt = 1518500249 # 0x5a827999 else if j < 40 ft = b ^ c ^ d kt = 1859775393 # 0x6ed9eba1 else if j < 60 ft = (b & c) | (b & d) | (c & d) kt = -1894007588 # 0x8f1bbcdc else ft = b ^ c ^ d kt = -899497514 # 0xca62c1d6 t = add32 add32(rotateLeft32(a, 5), ft), add32(add32(e, state[j]), kt) e = d d = c c = rotateLeft32 b, 30 b = a a = t # Uncomment the line below to debug block computation. # console.log [xxx(a), xxx(b), xxx(c), xxx(d), xxx(e)] a = add32 a, a0 b = add32 b, b0 c = add32 c, c0 d = add32 d, d0 e = add32 e, e0 i += 16 # Uncomment the line below to see the input to the base64 encoder. # console.log [xxx(a), xxx(b), xxx(c), xxx(d), xxx(e)] [a, b, c, d, e] ### # Uncomment the definition below for debugging. # # Returns the hexadecimal representation of a 32-bit number. xxx = (n) -> if n < 0 n = (1 << 30) * 4 + n n.toString 16 ### # Rotates a 32-bit word. # # @param {Number} value the 32-bit number to be rotated # @param {Number} count the number of bits (0..31) to rotate by # @return {Number} the rotated value rotateLeft32 = (value, count) -> (value << count) | (value >>> (32 - count)) # 32-bit unsigned addition. # # @param {Number} a, b the 32-bit numbers to be added modulo 2^32 # @return {Number} the 32-bit representation of a + b add32 = (a, b) -> low = (a & 0xFFFF) + (b & 0xFFFF) high = (a >> 16) + (b >> 16) + (low >> 16) (high << 16) | (low & 0xFFFF) # Converts a 32-bit number array into a base64-encoded string. # # @param {Array} an array of big-endian 32-bit numbers # @return {String} base64 encoding of the given array of numbers arrayToBase64 = (array) -> string = "" i = 0 limit = array.length * 4 while i < limit i2 = i trit = ((array[i2 >> 2] >> ((3 - (i2 & 3)) << 3)) & 0xFF) << 16 i2 += 1 trit |= ((array[i2 >> 2] >> ((3 - (i2 & 3)) << 3)) & 0xFF) << 8 i2 += 1 trit |= (array[i2 >> 2] >> ((3 - (i2 & 3)) << 3)) & 0xFF string += _base64Digits[(trit >> 18) & 0x3F] string += _base64Digits[(trit >> 12) & 0x3F] i += 1 if i >= limit string += '=' else string += _base64Digits[(trit >> 6) & 0x3F] i += 1 if i >= limit string += '=' else string += _base64Digits[trit & 0x3F] i += 1 string _base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; # Converts an ASCII string into array of 32-bit numbers. stringToArray = (string) -> array = [] mask = 0xFF for i in [0...string.length] array[i >> 2] |= (string.charCodeAt(i) & mask) << ((3 - (i & 3)) << 3) array