diff --git a/package.json b/package.json index 7ac2245..d80e2ac 100644 --- a/package.json +++ b/package.json @@ -22,5 +22,8 @@ "mocha": "3.4.2", "nyc": "10.3.2", "standard": "10.0.2" + }, + "dependencies": { + "typeforce": "1.11.1" } } diff --git a/src/prf.js b/src/prf.js new file mode 100644 index 0000000..4fd23ea --- /dev/null +++ b/src/prf.js @@ -0,0 +1,87 @@ +'use strict' + +var typeforce = require('typeforce') +var types = require('./types') + +var SHA256Compress = require('./sha256compress') + +function prf (a, b, c, d, x, y) { + typeforce(types.tuple( + types.BoolNum, + types.BoolNum, + types.BoolNum, + types.BoolNum, + types.Buffer252bit, + types.Buffer256bit + ), arguments) + + var blob = Buffer.alloc(64) + + x.copy(blob, 0) + y.copy(blob, 32) + + blob[0] &= 0x0F + blob[0] |= (a ? 1 << 7 : 0) | (b ? 1 << 6 : 0) | (c ? 1 << 5 : 0) | (d ? 1 << 4 : 0) + + var hasher = new SHA256Compress() + hasher.update(blob) + return hasher.hash() +} + +function prfAddr (aSk, t) { + typeforce(types.tuple(types.Buffer252bit, types.UInt8), arguments) + + var y = Buffer.alloc(32) + y.fill(0) + y[0] = t + + return prf(1, 1, 0, 0, aSk, y) +} + +function prfAddrAPk (aSk) { + return prfAddr(aSk, 0) +} + +function prfAddrSkEnc (aSk) { + return prfAddr(aSk, 1) +} + +function prfNf (aSk, rho) { + return prf(1, 1, 1, 0, aSk, rho) +} + +function prfPk (aSk, i0, hSig) { + typeforce(types.tuple( + types.Buffer252bit, + types.Number, + types.Buffer256bit + ), arguments) + + if ((i0 !== 0) && (i0 !== 1)) { + throw new Error('PRF_pk invoked with index out of bounds') + } + + return prf(0, i0, 0, 0, aSk, hSig) +} + +function prfRho (phi, i0, hSig) { + typeforce(types.tuple( + types.Buffer252bit, + types.Number, + types.Buffer256bit + ), arguments) + + if ((i0 !== 0) && (i0 !== 1)) { + throw new Error('PRF_rho invoked with index out of bounds') + } + + return prf(0, i0, 1, 0, phi, hSig) +} + +module.exports = { + PRF_addr_a_pk: prfAddrAPk, + PRF_addr_sk_enc: prfAddrSkEnc, + PRF_nf: prfNf, + PRF_pk: prfPk, + PRF_rho: prfRho +} diff --git a/src/sha256compress.js b/src/sha256compress.js new file mode 100644 index 0000000..dd8a854 --- /dev/null +++ b/src/sha256compress.js @@ -0,0 +1,128 @@ +/** + * Adapted from https://github.com/crypto-browserify/sha.js/blob/master/sha256.js + * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined + * in FIPS 180-2 + * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * + */ + +var 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 +] + +var W = new Array(64) + +function Sha256Compress () { + this.init() + + this._w = W // new Array(64) +} + +Sha256Compress.prototype.init = function () { + this._a = 0x6a09e667 + this._b = 0xbb67ae85 + this._c = 0x3c6ef372 + this._d = 0xa54ff53a + this._e = 0x510e527f + this._f = 0x9b05688c + this._g = 0x1f83d9ab + this._h = 0x5be0cd19 + + return this +} + +function ch (x, y, z) { + return z ^ (x & (y ^ z)) +} + +function maj (x, y, z) { + return (x & y) | (z & (x | y)) +} + +function sigma0 (x) { + return (x >>> 2 | x << 30) ^ (x >>> 13 | x << 19) ^ (x >>> 22 | x << 10) +} + +function sigma1 (x) { + return (x >>> 6 | x << 26) ^ (x >>> 11 | x << 21) ^ (x >>> 25 | x << 7) +} + +function gamma0 (x) { + return (x >>> 7 | x << 25) ^ (x >>> 18 | x << 14) ^ (x >>> 3) +} + +function gamma1 (x) { + return (x >>> 17 | x << 15) ^ (x >>> 19 | x << 13) ^ (x >>> 10) +} + +Sha256Compress.prototype.update = function (M) { + var W = this._w + + var a = this._a | 0 + var b = this._b | 0 + var c = this._c | 0 + var d = this._d | 0 + var e = this._e | 0 + var f = this._f | 0 + var g = this._g | 0 + var h = this._h | 0 + + for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4) + for (; i < 64; ++i) W[i] = (gamma1(W[i - 2]) + W[i - 7] + gamma0(W[i - 15]) + W[i - 16]) | 0 + + for (var j = 0; j < 64; ++j) { + var T1 = (h + sigma1(e) + ch(e, f, g) + K[j] + W[j]) | 0 + var T2 = (sigma0(a) + maj(a, b, c)) | 0 + + h = g + g = f + f = e + e = (d + T1) | 0 + d = c + c = b + b = a + a = (T1 + T2) | 0 + } + + this._a = (a + this._a) | 0 + this._b = (b + this._b) | 0 + this._c = (c + this._c) | 0 + this._d = (d + this._d) | 0 + this._e = (e + this._e) | 0 + this._f = (f + this._f) | 0 + this._g = (g + this._g) | 0 + this._h = (h + this._h) | 0 +} + +Sha256Compress.prototype.hash = function () { + var H = Buffer.alloc(32) + + H.writeInt32BE(this._a, 0) + H.writeInt32BE(this._b, 4) + H.writeInt32BE(this._c, 8) + H.writeInt32BE(this._d, 12) + H.writeInt32BE(this._e, 16) + H.writeInt32BE(this._f, 20) + H.writeInt32BE(this._g, 24) + H.writeInt32BE(this._h, 28) + + return H +} + +module.exports = Sha256Compress diff --git a/src/types.js b/src/types.js new file mode 100644 index 0000000..7abc0d5 --- /dev/null +++ b/src/types.js @@ -0,0 +1,24 @@ +var typeforce = require('typeforce') + +function Buffer252bit (value) { + return typeforce.BufferN(32)(value) && (value[0] & 0x0f) === value[0] +} + +function BoolNum (value) { + return typeforce.Number(value) && + value >= 0 && + value <= 1 +} + +// extend typeforce types with ours +var types = { + BoolNum: BoolNum, + Buffer252bit: Buffer252bit, + Buffer256bit: typeforce.BufferN(32) +} + +for (var typeName in typeforce) { + types[typeName] = typeforce[typeName] +} + +module.exports = types diff --git a/test/fixtures/prf.json b/test/fixtures/prf.json new file mode 100644 index 0000000..88ff6aa --- /dev/null +++ b/test/fixtures/prf.json @@ -0,0 +1,302 @@ +{ + "PRF_addr_a_pk": [ + { + "a_sk": "0a70d95366c96b4c8d1fd6a2db24f9b5e2cbc852a010ca2f2306bb6ee3fa682a", + "hex": "f2fe2b7eb6a15225bde42f0ca1c9160050c0a2e3a74a2eed2c314cdf61508f76" + }, + { + "a_sk": "08a6ff188da844abf0bf15444ecc592ff2e0806ca8f2660e512f4543adfacf15", + "hex": "8a636784a17ed4761a918101da365a103d99b3d40e5233bab70882297000671b" + }, + { + "a_sk": "091d5a3440b4ba3afab05c3edf35b123dab1320d97138242380c0766be740ce2", + "hex": "61d37756e36dcedd7ecc81d53a7f04442f4fb819b043faca2ae8b8997e2e4e30" + }, + { + "a_sk": "0717ffad6015eadce09846852edc38b25647c97053ae20f11abf4624f5bf7b9b", + "hex": "08f9d3b9f4da21f32db62366583770c668b1424fea18c6a40e10b096bec3046b" + }, + { + "a_sk": "0f686bffbadce9b0a0433256a4019a0b14df735bdd00326992be5464071a484c", + "hex": "ec87f3728bf2cb7b4923af2563c98a121d265a078c52fafdabb32baa9fa52342" + }, + { + "a_sk": "0dce04bb24701e5f7feb54c30fd509755305bd6c3a8e8520e3d71564a731e852", + "hex": "d65095e83245cdb8758ecb1bebd78ef2eeacb47521a7af77ba0647c25e389dc8" + }, + { + "a_sk": "0b3ea5ea10fc66021f5b04f2f3542cf459914ed3fe3dcfa007905aaaec840ec7", + "hex": "3cf68c8fd56c24a38c65dd05e14caa0b14717554f3c96a2c4fbef0a23ffadfa2" + }, + { + "a_sk": "0eb34f4bf9bbdb89db0b1524b58d1419d9c4bdd77277540a05148544a6920c85", + "hex": "b6379b84c70ee38f46ae51732c66774d5763962ff90adf84dd69f36034e13956" + }, + { + "a_sk": "0941c95e8076596122e04547189cee32d525e3728ab78f53e5b2d3a7f3444b2f", + "hex": "2fd6efc776bc4c84414fdffb68c18335c8c91b7659153c89037bbccb40b68e8e" + }, + { + "a_sk": "0b083e8ccfe006c62aaba0268f5a0280e41396af2460a496723b6074344b9aa9", + "hex": "c53fb32008fbdd3d6641028bf738e476a2eaff9872958d347ee45a65fb554d0c" + } + ], + "PRF_addr_sk_enc": [ + { + "a_sk": "0032a284efff5cb517603383b25e327f56c0517b6dc3529158f9c4a0eeb900a3", + "hex": "7186e908c6d7b271ce52b1721a6339263430d532a72c6756e1be5117ee244f19" + }, + { + "a_sk": "0d8accb8f7be25c7b6dcc62cbfea5bd2c77707bd1d0e01b0b95b09450604c175", + "hex": "873a161d53b4e8652542a218291bc8813703da0afeb82693c3ade2a39eaaa271" + }, + { + "a_sk": "08cc7b876388a8b267b3c46e55ebffbcbc34e9fd307ddd787c74145ba5d74a5e", + "hex": "47086ee1b0921acc570b31a0b23b394b74cf6a306872f36fc4163b6998c4616c" + }, + { + "a_sk": "09ed9ab7fb1d2ebf6173e2d1a6e1d56cc8d0030beeeabf8ef7fe4b9295260a65", + "hex": "6f7f7dd06f28398de20fd65097ec03c8c44217e4a48f7fcc883dd7ace9eaf31d" + }, + { + "a_sk": "087e66af610efe39c1d50cd3e3d3dc00c1fcbb3e4138aeda7daac00838f55668", + "hex": "9b32ee52f21d7556ccc090d4f7369097405f71d5dd3396e1f991fcda8fcdab47" + }, + { + "a_sk": "04df979a725d95ae49c2971300ea779a683eb763e149aae5486cb2eb9ecb6e50", + "hex": "dd1b85a9b68d8a9ed945369a139025d4ec7701df3e78dd2373bc617ce79aafdb" + }, + { + "a_sk": "0c1e42604710516fa31796d1e3b5784a5b39b616849022731ce7a7719bd19301", + "hex": "fa89d79ce14d007b75c06ab1c0f53ac54c6cd0694a4d645ed7becc65b0a5e124" + }, + { + "a_sk": "0a4010f50277872db38c7c64fa488e93c919f85a468e8bd36071053c7a3e9b03", + "hex": "d9c8b21c11616bf1e894aa99fc1a0d58b43d0698f83603c2e9cf4eb33c0a958b" + }, + { + "a_sk": "09e06f0cb7a6c85dde05a93eccb7edbb0e942afac39f05e89852b15290543b10", + "hex": "86bf95b44cc3d152a19bd4db0097acd2768d99cfa75831f7d3cbcd9b51ebf320" + }, + { + "a_sk": "0a2145be9aee0e0fd5cafb380f42b4994a8f72bb3545cbe5064f4458631e06d6", + "hex": "ad50ee3dc759fed8fc0b744d84116d8d7216698a68eb1a1afa790d255e5ce035" + } + ], + "PRF_nf": [ + { + "a_sk": "0a64cc4a9b15d63b02561793e5c2c8cd256c0296094f349549408784f646cea9", + "rho": "01b934061aea75896095ce74427b15b2f42d262dad70bb573bdd79cc973ad6b9", + "hex": "fafd1833e518b47bc899b5eee009d1c774e4bec2db25aa2348d0c48fce35b96b" + }, + { + "a_sk": "0e3cf5e9a8c076b5b7519aa5be7b680919cded314b5fff7f7a5592b2bee16e05", + "rho": "ee6888be0a8c5da3016e8a647aa314876c34b50da797094b960e5a75c5b37014", + "hex": "c9b8fac02fe0b94c94bf740694084cb2566f8b07d875ff313183371f23558a8f" + }, + { + "a_sk": "0f392afd53865e0fda16955e7b310f57f3f458aad3473909763150112d2d3ec1", + "rho": "9de92c684b90e34ac55fd55caa9e85fa903030be620b3418974c11926ff95457", + "hex": "8be40da115fcc890247e46e6f8d6f3d2db9745c0d6be9e346445ad22b15e4772" + }, + { + "a_sk": "0fd11f9b0cc21e2ca9f463f737db746083c3b847daec8ba2315745f02036243b", + "rho": "b6101c780c780a7b2e41966a88dd0569511ae4303b92876fe052e52d4ed27e7e", + "hex": "000756eff013f4354278687fb688e44d73380fad08134fd7056a9bcb63f327b0" + }, + { + "a_sk": "093c894249a6f741842b36791e81e59328f04b1b8d90c7264e8551c0e1884327", + "rho": "8f4eaec68e5d8766295896aa7e9934ac2a5bff267f7d079e8b6296c68c47eae9", + "hex": "4adff76f7717e0619739a9eca885f643b0599601f558e90e5714f75651d45653" + }, + { + "a_sk": "028503e3dcead6b3c8e93c862d2f2f19c25b30944e32879d994edf3c01bef84e", + "rho": "3dbb88eb29bcd5f3a271a1502b30c473c9d2fade358e2239c955757a35dd4327", + "hex": "8109e3e7746ac899253956c55528536141b8acd52132a7dbf2ffa8c775a1d4e3" + }, + { + "a_sk": "0704cc34621b77e9a2853e0c3f34aec16cbc3ed7f3ab8289cae03e876da5f9a6", + "rho": "e9d51a81e88c1cf07651bfa7f3caf3229c539a915940bd513c3660947faa2b4f", + "hex": "f3e67e4cbd6e2fcb6b5ce2c76f84d9eb1e0e94b24742f3abd4a84f7656eb0967" + }, + { + "a_sk": "03c5f7524e7c68252eea69ea002beee33e3fa630be15fa4b4cc5dfc48bca108f", + "rho": "2cbfe3c306fec3bb32ae9f020203ec5978056632ead689d04fccf7710c873140", + "hex": "e12f480f81fc028a5237b320127b0b7e5848ebd712139d92a146a57eb3371630" + }, + { + "a_sk": "03afd9cac5ff46c865e2332d1d7ebea18a33ef5ae342c66c39442e50d581a10c", + "rho": "21a97a4556b182e3ca25d35dee7c4dc107ccfee4345c24a8c2d6349cfd908012", + "hex": "919c2e7532928163386b55aeae51112e482a71ae371f2963e9a9a331e76ea582" + }, + { + "a_sk": "0176b8d534d640a400796692d7dd979d7fc89931a94755d398d2002ffa87b336", + "rho": "c118051c8b7886b24383385b54b0c0d53f10a322fff27d06dfe75ed9e392605d", + "hex": "683a1be98a3aea5f855a0fd8864c87c4270d7f4dcaf742b3e1e5e94a7598041c" + } + ], + "PRF_pk": [ + { + "a_sk": "02cc30edebeaba1d562c0791cadeaf75c24355d758f954c2e7daf75a224d4415", + "hSig": "2b56062f2bbf169748043dec1d6fe82574e3351cd8ea4f0b13952cef914b123c", + "hex": [ + "1cc456b94665468fdafe5697564f3ed75d893348ff1835625d963b8cecb3e373", + "d999943c24833e295422b55122a96a7b6959ce25ac9bdd1165574945f3128493" + ] + }, + { + "a_sk": "054178b2840f0dbc2a5d10f5817893352214dd8f7796482a511d3a7d3defc0f5", + "hSig": "9362614613f93532d7fe5c4fd64d308b8cc81dfd8ec6bfd157f65086d173a484", + "hex": [ + "0ff3ed74b43653c91640d6942894fa6b9207d94beadfc8fffe76c73329771cdf", + "5ad8b2c8a7bd7da96ca03932c6bf957765c5eb3f71c5855dd0d98f043a008c48" + ] + }, + { + "a_sk": "02d8c40e25251e03beddacebdb8ac62d879be9237abb0d6d55035fdddd65e2e6", + "hSig": "a5da0dba376218ab861e3cb612de67253e623cb72c8d09b280c5a5c7c6039f16", + "hex": [ + "694774cbb516be21872204cddde0c5488176fca2877e8ce07ee86025d3802bdc", + "9d90ef7c97cdcce67887fe2a5b267abec1e75657a9a05a7a07d7bc7c8f6a18f4" + ] + }, + { + "a_sk": "0b4ec12e5cd328beb8d34b2844a7fcc4af1a0451485cfb60ff547c2d8d2a5dc6", + "hSig": "fbda7f9c3910e60400cce856bb1f6973860316eef2c86a1ac76b8958961765b0", + "hex": [ + "2da9c1b74bedae5de1402b4a278c273bfbe6513802d70949d8363ec48846fe53", + "82eff5ad82da7ccaf20219f7d28ff121f7a00f2bbd60680df79ed7a44563e62d" + ] + }, + { + "a_sk": "0a9d99e8888bec9a801722a537858d9fc9cb2e7f1d50fcf941748c99d506fa0b", + "hSig": "2a112c65efcd40421239b399f54d5e79be400742785ca979cbf8ce32ddd8fe5d", + "hex": [ + "551a7766ce57300ac79def5e9a27edec22df32674992bd3f5933fe4033a2a826", + "c1316788721151f2daf3a937d238114a21e4b69d1310f131891488c15e4f5164" + ] + }, + { + "a_sk": "07774b9489fa7a9b96826287a2f5e61cbce01bcdad1a295a5f34047564618b92", + "hSig": "27d4525164bd46c9f7b709e7cecbf0dd79ad8fce6db382883f3e98bfdf87c359", + "hex": [ + "8f4b0f5dfcb997ef1d7585520d66361dda11843ede9f4091c48a15fb9230298a", + "da87c4b4f1899b3536039d246b2126440266b4c8b10e17e1dffea5329bc024a5" + ] + }, + { + "a_sk": "034f90c14332159e8baa24f4c67c6d3d343513a8c4f1a148d7aa9d85c7061bbe", + "hSig": "fa595c71d16cf3bf8fd11230b24621c76f398016bf946f8837c7ca22b982d478", + "hex": [ + "2d908d16c9da6a97656de102b882d4002b8f379419684e7a96d06e632b301e09", + "fa7c17d8d2c9ec8d3fcec056787ebbebb881c384e76e33fc3c7d6aea7492da32" + ] + }, + { + "a_sk": "06e28f3f2a773aba167e38b3f76106f0e3870ccd771e67bdb6f56a38dde2e1b5", + "hSig": "3a62e5d818983f42a83cac9974674ccc45fbc18226aa5f547189be553ceaaafd", + "hex": [ + "683553bc8e10fcc70a57907326105ad86c0d90f1434896a396b81bffeebceeb0", + "233045e486bd31ecd1660d438d67529dda0487a8cad6f217b7c7526ce9cbd78a" + ] + }, + { + "a_sk": "04cc388b781cf51be46d9d2851c321b614f4170f422ab26c4fcad7101616bc5d", + "hSig": "d13104e4af9ef0c4208956d1e6d5421fc721ab97e6a5ca24d1304e6cee40d447", + "hex": [ + "fa7bab157fbd7273d1cf53da96159480642279688ad3979d7839a21a89d23f48", + "610b71e5f553b290cde274b532e0d03b4283d34c04231ac62703c2391b6a1930" + ] + }, + { + "a_sk": "060671d950d59ebe09f5e89e95e3744a173dda34ecf777967c3af5381dd5a011", + "hSig": "d4e52bcb757f7642e0f98a1972e6ebd4a59b14f6657fdd1d8bd5d40d3bde49f6", + "hex": [ + "59d4dc58d1cdc3a801c91427a8793f35668553c3d2ccbe795be44f04e56ecd38", + "e87d07158ddeb03eedf7df75258cd5e1498acb71df426db9324c8cd0ca7756e0" + ] + } + ], + "PRF_rho": [ + { + "phi": "01765681a5499d0651eb844aee24a4043ecf3c5282b3e3c465aedb804302dfc0", + "hSig": "db27fe749e88e10b7ae74c5f19517874246ebaab083dc24edccfee7a865ba3d8", + "hex": [ + "5c50811ba4bb02c59c1d2417807f5e4ee9c067ce65fd0aeef0abd2c5a20c242a", + "b0103e47b762f45f25cb014f4629abc0b3dadb8cc5f3456bcdae63f7502b3e9e" + ] + }, + { + "phi": "0e0d28787de80b21b96be26e9b886e0b5f04dd04d29fd991d4716e397edea165", + "hSig": "38716f1e5791c3df4d82073b34f7f9d80831dfdfda1bd8764a5a505e2cf39d30", + "hex": [ + "3215d8ebe36a482062eb014c0784fbf074d288bcb34e9827d993963a83b1fd14", + "ac424bc3aac178d892df1708665d5cf8fc1b0d4eb2a5743de2a1bb487369f235" + ] + }, + { + "phi": "058449bf6b65ea8ed6e59b2c7788df75621c2d54806889c04d4e272e4965e34d", + "hSig": "4d0239a95fc5ed05f11551e3e6ec294a5e7572dc6cbdd98d302845e10d37ab05", + "hex": [ + "30db94fcd5eba2eeb55b24c1fa2feb7f5f93432066e620459fa6e890798e9f55", + "6a96879f57a15aec199acc9b872b9e485e60ad930c6875e9011b0dca4c945c0a" + ] + }, + { + "phi": "0588f8f3359849e98efbd3cfe4b0ab873f5b7e3133c2d179e6df40a89b286354", + "hSig": "31f0ce4a8c7947979b2e500324bd06319f466a5cdda2df13bae4cd0f262a4757", + "hex": [ + "786562968fc130798313d58bcf8b6a8b511236c21fe51e23cb66d15cb2a02001", + "f077a2a85508465e903e71b1298e619a00af3c33b13f68cd9ae0ae9183a01986" + ] + }, + { + "phi": "0993670a772f71b58d8353ab5ebc0bc9f629e8857db42b9dde377b32a44ce763", + "hSig": "dc480a5205527bdbe69113f3c13a7ec1edfed0a6634d09419763475b6305fe5a", + "hex": [ + "b4e6d3a525cd4883ea73ffea8c6503553a9176af64b0a79236c220d972e66344", + "ee22636ea046d665c430c359cb13b1308be02c420bba7cfd8f096dee6d26f403" + ] + }, + { + "phi": "02bf09979e98fa26b4b947808b7943d1f97387f4ee8abc958f0e77f68739279e", + "hSig": "cf8061bdfafd4504e135082b7ea2f9c0e2637cfe773be6b80d0a2a8aa9d78939", + "hex": [ + "13e6a6bd566b4611deb60c9583d7bd4a2d66f41ff9cc9b02631a281ed5ae4733", + "b50619f660a6b82ced7555affc33b2bbc7b5d5312f5c65f1b90ea23feb32ce0e" + ] + }, + { + "phi": "08d46f6a3a9cf4916561e4148363f860771ae162053496a63d3dfc04fb078afe", + "hSig": "2eea988e74ae7685741f4b98eae9923ee2f2e13055db403b65e5e1c71e0e05cb", + "hex": [ + "a9af139251e382399bff83aa9f41e8c612f0c329785312502e21e2b998a50e14", + "638ed435a7269da184fb798f2de9c83a860138b92e4738ead3342ff1a7d1fec6" + ] + }, + { + "phi": "0b949b579b540b6c7a2f6e61083fff09dae98c99d03870dd7a46ce75d2379df8", + "hSig": "eb13559e5fa9e8e2dd17555cd4477ed9734dded45454dad27ee0d73e9c142379", + "hex": [ + "c88c57d9dd482223c21fe52eec3e366d5e95bd269950c285631eefe2ebb260b0", + "bf808b13f64dcf25e62264a4aa6af0223d8aea6cdc1805a24289071fbf156786" + ] + }, + { + "phi": "0bacd9e75e8c23d427e0cea735b42784112c59535348ef97d26fb54eb59bcaf4", + "hSig": "e1d57a37c0384482e60b8cced52999977acf1e91a4bbddc342733a07694a1d9d", + "hex": [ + "d42d93b73f60a1df644e56809c3eb74921d79677a93249076d72e2ad63d47206", + "d8e63a9b5ebbdc2f69195b0be12ec0216a19d211e1cac7e8a0bc5dd6351f39d6" + ] + }, + { + "phi": "030c8fb461d7a2e4b3104eacd03ed57cb7da0129a54d1e2e320843a2eadc1635", + "hSig": "cc2fedf32975bec62da016ad5457dc8dd7e72270b5c1cb988ad2cf7809cdd6d6", + "hex": [ + "0b7a06192f8428951fb332395be410c4aa5761d766f67629fc92cdedb49a1d17", + "ea4d57744e9325b146d00018de6a73bcd1b740d90d158fc08db6b2515d8807ed" + ] + } + ] +} \ No newline at end of file diff --git a/test/prf.js b/test/prf.js new file mode 100644 index 0000000..e03657a --- /dev/null +++ b/test/prf.js @@ -0,0 +1,78 @@ +/* global describe, it */ +'use strict' + +var assert = require('assert') + +var prf = require('../src/prf') + +var fixtures = require('./fixtures/prf') + +describe('PRF', function () { + describe('PRF_addr_a_pk', function () { + fixtures.PRF_addr_a_pk.forEach(function (f) { + it('calculates ' + f.hex + ' correctly', function () { + var aSk = Buffer.from(f.a_sk, 'hex') + assert.strictEqual(prf.PRF_addr_a_pk(aSk).toString('hex'), f.hex) + }) + }) + }) + + describe('PRF_addr_sk_enc', function () { + fixtures.PRF_addr_sk_enc.forEach(function (f) { + it('calculates ' + f.hex + ' correctly', function () { + var aSk = Buffer.from(f.a_sk, 'hex') + assert.strictEqual(prf.PRF_addr_sk_enc(aSk).toString('hex'), f.hex) + }) + }) + }) + + describe('PRF_nf', function () { + fixtures.PRF_nf.forEach(function (f) { + it('calculates ' + f.hex + ' correctly', function () { + var aSk = Buffer.from(f.a_sk, 'hex') + var rho = Buffer.from(f.rho, 'hex') + assert.strictEqual(prf.PRF_nf(aSk, rho).toString('hex'), f.hex) + }) + }) + }) + + describe('PRF_pk', function () { + fixtures.PRF_pk.forEach(function (f) { + describe('a_sk [' + f.a_sk + ']', function () { + var aSk = Buffer.from(f.a_sk, 'hex') + var hSig = Buffer.from(f.hSig, 'hex') + f.hex.forEach(function (f, i) { + it('calculates ' + i + ' correctly', function () { + assert.strictEqual(prf.PRF_pk(aSk, i, hSig).toString('hex'), f) + }) + }) + }) + }) + + it('throws on out-of-bounds index', function () { + assert.throws(function () { + prf.PRF_pk(Buffer.alloc(32), 2, Buffer.alloc(32)) + }, new RegExp('PRF_pk invoked with index out of bounds')) + }) + }) + + describe('PRF_rho', function () { + fixtures.PRF_rho.forEach(function (f) { + describe('phi [' + f.phi + ']', function () { + var phi = Buffer.from(f.phi, 'hex') + var hSig = Buffer.from(f.hSig, 'hex') + f.hex.forEach(function (f, i) { + it('calculates ' + i + ' correctly', function () { + assert.strictEqual(prf.PRF_rho(phi, i, hSig).toString('hex'), f) + }) + }) + }) + }) + + it('throws on out-of-bounds index', function () { + assert.throws(function () { + prf.PRF_rho(Buffer.alloc(32), 2, Buffer.alloc(32)) + }, new RegExp('PRF_rho invoked with index out of bounds')) + }) + }) +})