{"action":"created","issue":{"url":"https://api.github.com/repos/bitwiseshiftleft/sjcl/issues/227","labels_url":"https://api.github.com/repos/bitwiseshiftleft/sjcl/issues/227/labels{/name}","comments_url":"https://api.github.com/repos/bitwiseshiftleft/sjcl/issues/227/comments","events_url":"https://api.github.com/repos/bitwiseshiftleft/sjcl/issues/227/events","html_url":"https://github.com/bitwiseshiftleft/sjcl/pull/227","id":88244088,"number":227,"title":"Implemented scrypt.","user":{"login":"Bren2010","id":416022,"avatar_url":"https://avatars.githubusercontent.com/u/416022?v=3","gravatar_id":"","url":"https://api.github.com/users/Bren2010","html_url":"https://github.com/Bren2010","followers_url":"https://api.github.com/users/Bren2010/followers","following_url":"https://api.github.com/users/Bren2010/following{/other_user}","gists_url":"https://api.github.com/users/Bren2010/gists{/gist_id}","starred_url":"https://api.github.com/users/Bren2010/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Bren2010/subscriptions","organizations_url":"https://api.github.com/users/Bren2010/orgs","repos_url":"https://api.github.com/users/Bren2010/repos","events_url":"https://api.github.com/users/Bren2010/events{/privacy}","received_events_url":"https://api.github.com/users/Bren2010/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":9,"created_at":"2015-06-14T20:30:42Z","updated_at":"2015-06-17T06:37:03Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/bitwiseshiftleft/sjcl/pulls/227","html_url":"https://github.com/bitwiseshiftleft/sjcl/pull/227","diff_url":"https://github.com/bitwiseshiftleft/sjcl/pull/227.diff","patch_url":"https://github.com/bitwiseshiftleft/sjcl/pull/227.patch"},"body":"Pretty simple, straight from the [RFC](http://tools.ietf.org/html/draft-josefsson-scrypt-kdf-01) implementation.\r\n\r\nIt seems slow, and that's why the fourth test vector is disabled.  I'm not aware of anything, but if I missed some big performance optimization, lmk."},"comment":{"url":"https://api.github.com/repos/bitwiseshiftleft/sjcl/issues/comments/112673432","html_url":"https://github.com/bitwiseshiftleft/sjcl/pull/227#issuecomment-112673432","issue_url":"https://api.github.com/repos/bitwiseshiftleft/sjcl/issues/227","id":112673432,"user":{"login":"ggozad","id":183103,"avatar_url":"https://avatars.githubusercontent.com/u/183103?v=3","gravatar_id":"","url":"https://api.github.com/users/ggozad","html_url":"https://github.com/ggozad","followers_url":"https://api.github.com/users/ggozad/followers","following_url":"https://api.github.com/users/ggozad/following{/other_user}","gists_url":"https://api.github.com/users/ggozad/gists{/gist_id}","starred_url":"https://api.github.com/users/ggozad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ggozad/subscriptions","organizations_url":"https://api.github.com/users/ggozad/orgs","repos_url":"https://api.github.com/users/ggozad/repos","events_url":"https://api.github.com/users/ggozad/events{/privacy}","received_events_url":"https://api.github.com/users/ggozad/received_events","type":"User","site_admin":false},"created_at":"2015-06-17T06:37:03Z","updated_at":"2015-06-17T06:37:03Z","body":"@Bren2010 I am happy with the implementation. So that we don't have to do it afterwards, in separate pull requests, could you benchmark with a simpler one (which on occasion produces faster compilation)?\r\nYou can use something like jsperf.com for the comparison.\r\nHere's the implementation I was using and intended to make a PR after some refactoring.\r\n\r\n```\r\nsjcl.misc.scrypt = function(passwd, salt, N, r, p, dkLen) {\r\n\r\n    function flipEndian(x) {\r\n        var first = x & 0xFF,\r\n            second = (x >>> 8) & 0xFF,\r\n            third = (x >>> 16) & 0xFF,\r\n            fourth = (x >>> 24) & 0xFF;\r\n        return (first << 24) | (second << 16) | (third << 8) | fourth;\r\n    }\r\n\r\n    function sanityCheck() {\r\n        var SIZE_MAX = Math.pow(2, 32) - 1;\r\n\r\n        if (r * p >= Math.pow(2, 30))\r\n            throw \"The parameters r, p must satisfy r * p < 2^30\";\r\n        if ((N < 2) || (N & (N - 1) !== 0))\r\n            throw \"The parameter N must be a power of 2.\";\r\n        if (N > SIZE_MAX / 128 / r)\r\n            throw \"N too big.\";\r\n        if (r > SIZE_MAX / 128 / p)\r\n            throw \"r too big.\";\r\n    }\r\n\r\n    function scrypt(passwd, salt, N, r, p, dkLen) {\r\n        var B = sjcl.misc.pbkdf2(passwd, salt, 1, p * 128 * r * 8),\r\n            V = [],\r\n            XY = [];\r\n\r\n        for (var i = 0; i < p; i++)\r\n            smix(B, i * 128 * r, r, N, V, XY);\r\n\r\n        return sjcl.misc.pbkdf2(passwd, B, 1, dkLen * 8);\r\n    }\r\n\r\n    function salsa20_8(B) {\r\n        var x = [], B32 = [], i;\r\n\r\n        function R(a, b) {\r\n            return (a << b) | (a >>> (32 - b));\r\n        }\r\n\r\n        for (i = 0; i < 16; i++)\r\n            B32[i] = flipEndian(B[i]);\r\n\r\n        for (i = 0; i < 16; i++)\r\n            x[i] = B32[i] | 0;\r\n\r\n        for (i = 8; i > 0; i -= 2) {\r\n            x[4] ^= R(x[0] + x[12], 7);\r\n            x[8] ^= R(x[4] + x[0], 9);\r\n            x[12] ^= R(x[8] + x[4], 13);\r\n            x[0] ^= R(x[12] + x[8], 18);\r\n            x[9] ^= R(x[5] + x[1], 7);\r\n            x[13] ^= R(x[9] + x[5], 9);\r\n            x[1] ^= R(x[13] + x[9], 13);\r\n            x[5] ^= R(x[1] + x[13], 18);\r\n            x[14] ^= R(x[10] + x[6], 7);\r\n            x[2] ^= R(x[14] + x[10], 9);\r\n            x[6] ^= R(x[2] + x[14], 13);\r\n            x[10] ^= R(x[6] + x[2], 18);\r\n            x[3] ^= R(x[15] + x[11], 7);\r\n            x[7] ^= R(x[3] + x[15], 9);\r\n            x[11] ^= R(x[7] + x[3], 13);\r\n            x[15] ^= R(x[11] + x[7], 18);\r\n            x[1] ^= R(x[0] + x[3], 7);\r\n            x[2] ^= R(x[1] + x[0], 9);\r\n            x[3] ^= R(x[2] + x[1], 13);\r\n            x[0] ^= R(x[3] + x[2], 18);\r\n            x[6] ^= R(x[5] + x[4], 7);\r\n            x[7] ^= R(x[6] + x[5], 9);\r\n            x[4] ^= R(x[7] + x[6], 13);\r\n            x[5] ^= R(x[4] + x[7], 18);\r\n            x[11] ^= R(x[10] + x[9], 7);\r\n            x[8] ^= R(x[11] + x[10], 9);\r\n            x[9] ^= R(x[8] + x[11], 13);\r\n            x[10] ^= R(x[9] + x[8], 18);\r\n            x[12] ^= R(x[15] + x[14], 7);\r\n            x[13] ^= R(x[12] + x[15], 9);\r\n            x[14] ^= R(x[13] + x[12], 13);\r\n            x[15] ^= R(x[14] + x[13], 18);\r\n        }\r\n\r\n        for (i = 0; i<16; i++)\r\n            B32[i] = (B32[i] + x[i]) | 0;\r\n\r\n        for (i = 0; i < 16; i++)\r\n            B[i] = flipEndian(B32[i]);\r\n\r\n        return B;\r\n    }\r\n\r\n    function blockxor(S, Si, D, Di, len) {\r\n        len /= 4;\r\n        Si /= 4;\r\n        Di /= 4;\r\n        for (var i = 0; i < len; i++)\r\n            D[Di + i] ^= S[Si + i] | 0;\r\n    }\r\n\r\n    function blockcopy(S, Si, D, Di, len) {\r\n        var i;\r\n\r\n        len /= 4;\r\n        Si /= 4;\r\n        Di /= 4;\r\n\r\n        for (i = 0; i < len; i++)\r\n            D[Di + i] = S[Si + i] | 0;\r\n    }\r\n\r\n    function blockmix_salsa8(BY, Bi, Yi, r) {\r\n        var X = [], i;\r\n\r\n        blockcopy(BY, Bi + (2 * r - 1) * 64, X, 0, 64);\r\n\r\n        for (i = 0; i < 2 * r; i++) {\r\n            blockxor(BY, i * 64, X, 0, 64);\r\n            salsa20_8(X);\r\n            blockcopy(X, 0, BY, Yi + (i * 64), 64);\r\n        }\r\n\r\n        for (i = 0; i < r; i++)\r\n            blockcopy(BY, Yi + (i * 2) * 64, BY, Bi + (i * 64), 64);\r\n\r\n        for (i = 0; i < r; i++)\r\n            blockcopy(BY, Yi + (i * 2 + 1) * 64, BY, Bi + (i + r) * 64, 64);\r\n    }\r\n\r\n    function smix(B, Bi, r, N, V, XY) {\r\n        var Xi = 0,\r\n            Yi = 128 * r,\r\n            i, j;\r\n\r\n        blockcopy(B, Bi, XY, Xi, Yi);\r\n\r\n        for (i = 0; i < N; i++) {\r\n            blockcopy(XY, Xi, V, i * Yi, Yi);\r\n            blockmix_salsa8(XY, Xi, Yi, r);\r\n        }\r\n\r\n        for (i = 0; i < N; i++) {\r\n            j = integerify(XY, Xi, r) & (N - 1);\r\n            blockxor(V, j * Yi, XY, Xi, Yi);\r\n            blockmix_salsa8(XY, Xi, Yi, r);\r\n        }\r\n\r\n        blockcopy(XY, Xi, B, Bi, Yi);\r\n    }\r\n\r\n    function integerify(B, Bi, r) {\r\n        Bi = Bi + (2 * r - 1) * 64;\r\n        return flipEndian(B[Bi / 4]);\r\n    }\r\n\r\n    sanityCheck();\r\n    return scrypt(passwd, salt, N, r, p, dkLen);\r\n};\r\n```\r\n\r\n"}}