serverMessages.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889
  1. /* Import core modules. */
  2. const _ = require('lodash')
  3. // const bch = require('bitcore-lib-cash')
  4. const debug = require('debug')('fusion:server-messages')
  5. const path = require('path')
  6. const protobuf = require('protobufjs')
  7. /* Import local modules. */
  8. // const BetterMessage = require('./BetterMessage.js')
  9. /* Initialize magic (bytes). */
  10. const magic = Buffer.from('765be8b4e4396dcf', 'hex')
  11. /* Initialize protobuf classes. */
  12. const pbEnums = ['Phase', 'Reason']
  13. /* Initialize protobuf types. */
  14. const pbTypes = [
  15. 'Signed', 'Packet', 'Coins', 'Signatures', 'Message', 'Address',
  16. 'Registration', 'VerificationKey', 'EncryptionKey', 'DecryptionKey',
  17. 'Hash', 'Signature', 'Transaction', 'Blame', 'Invalid', 'Inputs',
  18. 'Packets'
  19. ]
  20. /* Initialize protobuf. */
  21. const PB = {
  22. root: protobuf.loadSync(path.join(__dirname, 'fusion.proto'))
  23. }
  24. /* Loop through ALL protobuf types. */
  25. for (let oneTypeName of pbTypes) {
  26. PB[oneTypeName] = PB.root.lookupType(oneTypeName)
  27. }
  28. /* Loop through ALL protobuf classes. */
  29. for (let oneClassName of pbEnums) {
  30. PB[oneClassName] = PB.root.lookupEnum(oneClassName)
  31. }
  32. /**
  33. * Message to Buffers
  34. */
  35. // function messageToBuffers (someBase64Message) {
  36. // /* Initialize message buffer. */
  37. // const messageBuffer = Buffer.from(someBase64Message, 'base64')
  38. //
  39. // /* Validate message buffer. */
  40. // if (messageBuffer.length < 12) {
  41. // throw new Error('bad_length')
  42. // } else {
  43. // /* Set message magic (bytes). */
  44. // const messageMagic = messageBuffer.slice(0, 8)
  45. //
  46. // /* Validate message magic (bytes). */
  47. // if (messageMagic.toString('hex') !== magic.toString('hex')) {
  48. // throw new Error('message_magic')
  49. // }
  50. //
  51. // /* Initialize message length. */
  52. // let messageLength = messageBuffer.slice(8, 12)
  53. //
  54. // /* Set message length. */
  55. // messageLength = messageLength.readUInt32BE()
  56. //
  57. // /* Set message payload. */
  58. // // const messagePayload = messageBuffer.slice(12, ) // FIXME: Why do we have a trailing space??
  59. // const messagePayload = messageBuffer.slice(12) // FIXME: Why do we have a trailing space??
  60. //
  61. // /* Validate message payload. */
  62. // if (messagePayload.length !== messageLength) {
  63. // debug('Incorrect payload size:', messagePayload.length, '!==', messageLength)
  64. // throw new Error('message_payload')
  65. // } else {
  66. // /* Return message buffers. */
  67. // return {
  68. // magic: messageBuffer.slice(0, 8).toString('base64'),
  69. // length: messageBuffer.slice(8, 12).toString('base64'),
  70. // // payload: messageBuffer.slice(12, ).toString('base64'), // FIXME
  71. // payload: messageBuffer.slice(12).toString('base64'), // FIXME
  72. // buffer: messageBuffer.toString('base64')
  73. // }
  74. // }
  75. // }
  76. // }
  77. /**
  78. * Decode and Classify
  79. *
  80. * TODO: Clean this up so it better handles multi-packet messages.
  81. */
  82. // function decodeAndClassify (messageBuffer) {
  83. // if (messageBuffer.length < 12) {
  84. // throw new Error('bad_length')
  85. // } else {
  86. // /* Set message magic (bytes). */
  87. // const messageMagic = messageBuffer.slice(0, 8)
  88. //
  89. // /* Validate message magic (bytes). */
  90. // if (messageMagic.toString('hex') !== magic.toString('hex')) {
  91. // throw new Error('message_magic')
  92. // }
  93. //
  94. // /* Initialize message length. */
  95. // let messageLength = messageBuffer.slice(8, 12)
  96. //
  97. // /* Set message length. */
  98. // messageLength = messageLength.readUInt32BE()
  99. //
  100. // /* Set message payload. */
  101. // // const messagePayload = messageBuffer.slice(12, ) // FIXME
  102. // const messagePayload = messageBuffer.slice(12) // FIXME
  103. //
  104. // /* Build server message. */
  105. // const serverMessage = {
  106. // packets: [],
  107. // full: undefined,
  108. // pruned: undefined,
  109. // components: messageToBuffers(messageBuffer)
  110. // }
  111. //
  112. // /* Validate message payload. */
  113. // if (messagePayload.length !== messageLength) {
  114. // debug('Incorrect payload size:', messagePayload.length, '!==', messageLength)
  115. // throw new Error('message_payload')
  116. // } else {
  117. // /* Set decoded packets. */
  118. // const decodedPackets = PB.Packets.decode(messagePayload)
  119. //
  120. // /* Loop through ALL decoded packets. */
  121. // for (let onePacket of decodedPackets.packet) {
  122. // serverMessage.packets.push(onePacket)
  123. // }
  124. //
  125. // /* Set (full) server message. */
  126. // serverMessage.full = decodedPackets.toJSON()
  127. //
  128. // /* Set (pruned) server message. */
  129. // serverMessage.pruned = {
  130. // message: _.get(serverMessage.full, 'packet[0].packet'),
  131. // signature: _.get(serverMessage.full, 'packet[0].signature.signature')
  132. // }
  133. // }
  134. //
  135. // /* Validate (pruned) server message. */
  136. // if (!serverMessage.pruned.message) {
  137. // throw new Error('message_parsing')
  138. // }
  139. //
  140. // /* Initialize message types. */
  141. // // TODO: Pick more intuitive and more consistent message names.
  142. // let messageTypes = [
  143. // { name: 'playerCount', required: ['number'] },
  144. // { name: 'serverGreeting', required: ['number', 'session'] },
  145. // { name: 'announcementPhase', required: ['number', 'phase'] },
  146. // { name: 'incomingVerificationKeys', required: ['session', 'fromKey.key', 'message.inputs'] },
  147. // { name: 'incomingChangeAddress', required: ['session', 'number', 'fromKey.key', 'message.address.address', 'message.key.key', 'phase'] },
  148. //
  149. // /**
  150. // * This message name will be changed before the `serverMessage`
  151. // * event is emitted by the `CommChannel` class.
  152. // *
  153. // * We set the final message name there because that's where we
  154. // * have access to round state data and the purpose of the message
  155. // * (which should inform the name) changes based on the state of the
  156. // * round.
  157. // *
  158. // * Yep, this is yet another hack to deal with the fact that there
  159. // * is no support for a unique `messageName` field on the protocol
  160. // * messages.
  161. // */
  162. // { name: '_unicast', required: ['number', 'session', 'fromKey.key', 'toKey.key', 'message.str'] },
  163. // { name: 'incomingEquivCheck', required: ['number', 'session', 'phase', 'fromKey.key', 'message.hash.hash'] },
  164. // { name: 'incomingInputAndSig', required: ['number', 'session', 'phase', 'fromKey.key', 'message.signatures'] },
  165. // { name: 'finalTransactionOutputs', required: ['session', 'number', 'phase', 'fromKey.key', 'message.str'] },
  166. // { name: 'blame', required: ['number', 'session', 'fromKey.key', 'message.blame', 'phase'] }
  167. // ]
  168. //
  169. // // Order the message types so that the most
  170. // // specific descriptions are seen first by
  171. // // the function that attempts to find a match.
  172. // messageTypes = _.orderBy(
  173. // messageTypes,
  174. // function (ot) {
  175. // return ot.required.length
  176. // },
  177. // ['desc']
  178. // )
  179. //
  180. // /* Set matching message type. */
  181. // const matchingMessageType = _.reduce(messageTypes, function (winner, oneObject) {
  182. // /* Set required parameter values. */
  183. // const requiredParamValues = _.at(serverMessage.pruned.message, oneObject.required)
  184. //
  185. // /* Validate required parameter values. */
  186. // // NOTE: If none of the required parameters are missing,
  187. // // consider this object a match.
  188. // const isMatch = oneObject.required.length === _.compact(requiredParamValues).length
  189. //
  190. // /* Validate match. */
  191. // // NOTE: If our match has more matching params than
  192. // // our previous match, use this one instead
  193. // if (isMatch && winner.required.length < requiredParamValues.length) {
  194. // return oneObject
  195. // } else {
  196. // return winner
  197. // }
  198. // }, { required: [] })
  199. //
  200. // /* Update server message. */
  201. // _.extend(serverMessage.pruned, {
  202. // messageType: matchingMessageType.name || 'UNKNOWN'
  203. // })
  204. //
  205. // /* Return server message. */
  206. // return serverMessage
  207. // }
  208. // }
  209. /**
  210. * Registration
  211. */
  212. function registration (protocolVersion, amount, key) {
  213. /* Validate key. */
  214. if (_.isObject(key) && typeof key.toString) {
  215. key = key.toString()
  216. }
  217. /* Set message. */
  218. const message = PB.Signed.create({
  219. packet: PB.Packet.create({
  220. fromKey: PB.VerificationKey.create({ key }),
  221. registration: PB.Registration.create({
  222. amount: amount,
  223. version: protocolVersion,
  224. // type: 'DEFAULT' // WHY AREN'T WE USING THIS??
  225. type: 'DEFAULT'
  226. })
  227. })
  228. })
  229. /* Return packed message. */
  230. return packMessage(message)
  231. }
  232. /**
  233. * Broadcast Transaction Input
  234. *
  235. * This function reveals the coin our client wishes to shuffle as well as our
  236. * verificationKey. Although we revealed our verificationKey in our server
  237. * registration message, that message isn't relayed to our peers. This is the
  238. * first message where our peers see the vk.
  239. */
  240. // function broadcastTransactionInput (
  241. // inputsObject,
  242. // session,
  243. // playerNumber,
  244. // verificationPublicKey
  245. // ) {
  246. // /* Validate verification key. */
  247. // if (_.isObject(verificationPublicKey) && typeof verificationPublicKey.toString) {
  248. // verificationPublicKey = verificationPublicKey.toString()
  249. // }
  250. //
  251. // /* Initialize message. */
  252. // let message
  253. //
  254. // /* Set message. */
  255. // message = PB.Signed.create({
  256. // packet: PB.Packet.create({
  257. // fromKey: PB.VerificationKey.create({
  258. // key: verificationPublicKey
  259. // }),
  260. // message: PB.Message.create({
  261. // inputs: {}
  262. // }),
  263. // session: session,
  264. // number: playerNumber
  265. // })
  266. // })
  267. //
  268. // /* Loop through ALL input objects. */
  269. // for (let key in inputsObject) {
  270. // message.packet.message.inputs[key] = PB.Coins.create({
  271. // coins: inputsObject[key]
  272. // })
  273. // }
  274. //
  275. // /* Return packed message. */
  276. // return packMessage(message)
  277. // }
  278. /*
  279. {
  280. "packet": [
  281. {
  282. "packet": {
  283. "session": "aGFIYURRd0JBWFN5MkJJNnBhdzZ6OQ==",
  284. "number": 2,
  285. "from_key": {
  286. "key": "03b9bf1605aa851945bd72e575d42f7ca874d9d7099f686c70893f927512010853"
  287. },
  288. "to_key": {
  289. "key": "03aa863d01fd4c44043b73fccd820101f8bdc3bdf59a2472f1f1ecf6822ce4ad7b"
  290. },
  291. "phase": 2,
  292. "message": {
  293. "str": "QklFMQNiC79dSfQjlIRKY/nHYE9KblxLkT6na8kelVoL8OIHW9/QqooDxTgtNm5Xhfh3R6kMWslw+uF6sYdhYZ53ce2sJBaaRWMLO8twqjfJGBPt/97XAAIVA57KNfzJOzdx6a8e/oUZ99xKPp6MRDBPGmME"
  294. }
  295. },
  296. "signature": {
  297. "signature": "H/zYhGuMsptl9hL76Wn9ylNUmHKAzO+ZQbEHAkTPIp1aP0DiAjtvsyFmS1ZK03nTS5d5/4Vb5GoKnty7UijANds="
  298. }
  299. },
  300. {
  301. "packet": {
  302. "session": "aGFIYURRd0JBWFN5MkJJNnBhdzZ6OQ==",
  303. "number": 2,
  304. "from_key": {
  305. "key": "03b9bf1605aa851945bd72e575d42f7ca874d9d7099f686c70893f927512010853"
  306. },
  307. "to_key": {
  308. "key": "03aa863d01fd4c44043b73fccd820101f8bdc3bdf59a2472f1f1ecf6822ce4ad7b"
  309. },
  310. "phase": 2,
  311. "message": {
  312. "str": "QklFMQJtTrG5IQiUX1C0ZR67t5cQbN4v72uSzrCOuy1QEtOI41wQ2CGGK7lgtxyS9g8tzd9YHe+4DyMaSyrCIx/Ft/U27P6dU5xR6lVhf3ekV3mIW8/vH2lpb2AWY3Djl0egotBFrIylX+2W0nC9MVaU98xZ"
  313. }
  314. },
  315. "signature": {
  316. "signature": "H8zKYj3OsPF/EUstjST/pzI8AqwcsK8OySDIxm9WABUYHWODcoBAzKsnEh1I7gLfABpAqnYkM0WK0SiyBeVUuq8="
  317. }
  318. }
  319. ]
  320. }
  321. */
  322. // this.comms.sendMessage('forwardEncryptedOutputs', [
  323. // this.session, me.playerNumber, encryptedOutputAddresses.success,
  324. // this.phase.toUpperCase(), nextPlayer.verificationKey, this.ephemeralKeypair.publicKey,
  325. // this.ephemeralKeypair.privateKey
  326. // ])
  327. /**
  328. * Forward Encrypted Outputs
  329. */
  330. // function forwardEncryptedOutputs (
  331. // session,
  332. // fromPlayerNumber,
  333. // arrayOfOutputs,
  334. // phase,
  335. // toVerificationKey,
  336. // myVerificationPubKey,
  337. // myVerificationPrivKey
  338. // ) {
  339. // /* Validate verification public key. */
  340. // if (_.isObject(myVerificationPubKey) && typeof myVerificationPubKey.toString) {
  341. // myVerificationPubKey = myVerificationPubKey.toString()
  342. // }
  343. //
  344. // /* Validate (to) verification key. */
  345. // if (_.isObject(toVerificationKey) && typeof toVerificationKey.toString) {
  346. // toVerificationKey = toVerificationKey.toString()
  347. // }
  348. //
  349. // // TODO: Make these server messages consistent with
  350. // // respect to param validation and type checking.
  351. //
  352. // /* Initialize signed messages. */
  353. // const signedMessages = []
  354. //
  355. // /* Loop through ALL outputs. */
  356. // for (let oneEncryptedAddress of arrayOfOutputs) {
  357. // /* Set message. */
  358. // const message = PB.Signed.create({
  359. // packet: PB.Packet.create({
  360. // session: session,
  361. // number: fromPlayerNumber,
  362. // fromKey: PB.VerificationKey.create({
  363. // key: myVerificationPubKey
  364. // }),
  365. // toKey: PB.VerificationKey.create({
  366. // key: toVerificationKey
  367. // }),
  368. // phase: PB.Phase.values[phase.toUpperCase()],
  369. // message: PB.Message.create({
  370. // str: oneEncryptedAddress
  371. // })
  372. // })
  373. // })
  374. //
  375. // /* Set message. */
  376. // const msg = PB.Packet
  377. // .encode(message.packet)
  378. // .finish()
  379. // .toString('base64')
  380. //
  381. // /* Set signature. */
  382. // const signature = new BetterMessage(msg, 'base64')
  383. // .sign(bch.PrivateKey(myVerificationPrivKey))
  384. //
  385. // /* Set message signature. */
  386. // message.signature = PB.Signature.create({
  387. // signature: signature
  388. // })
  389. //
  390. // /* Add message to signed messages. */
  391. // signedMessages.push(message)
  392. // }
  393. //
  394. // /* Return packed signed messages. */
  395. // return packMessage(signedMessages)
  396. // }
  397. /*
  398. {
  399. "packet": [
  400. {
  401. "packet": {
  402. "session": "OGlTZkdsSTZUQVgwNkU4Yk4wMkowTw==",
  403. "number": 1,
  404. "from_key": {
  405. "key": "0202135e4f7217957db961f26e3856a239e89023f6cd6088d6303775c3a61572bf"
  406. },
  407. "phase": 6,
  408. "message": {
  409. "signatures": [
  410. {
  411. "utxo": "3a019c3a44d5269edf8a6ca2588ead452b03f8fcdda2b622906c98e4d1d5778f:0",
  412. "signature": {
  413. "signature": "MzA0NDAyMjAwYjZiYzIyMDMzZTQwYzA5ZjJhNTdiZjZhOTc1YTEwMTk0OGU5ODAzMGY2OWRjMWZhYzlmZWY5ZTk0YTcxZTMzMDIyMDY4MDFlYzMzYWZiOTU5ZDZlZGZiMDQyMDM2NzcwYjA4MjI1NzczM2ExMjBhMDdmMTgzM2RlZTdhZTUzNDhlNzM0MQ=="
  414. }
  415. }
  416. ]
  417. }
  418. },
  419. "signature": {
  420. "signature": "H0fwrr75/6GcPzPB6etyWyZD4mLlDGacVIs/j+VTldLCdE8yAfactL8jdXrJRwE7RqYhCFJ6vIHFpTu6Xa+SW2Y="
  421. }
  422. }
  423. ]
  424. }
  425. */
  426. /**
  427. * Broadcast Signature and UTXO
  428. */
  429. // function broadcastSignatureAndUtxo (
  430. // session,
  431. // fromPlayerNumber,
  432. // coinUtxoData,
  433. // signatureString,
  434. // phase,
  435. // myVerificationPubKey,
  436. // myVerificationPrivKey
  437. // ) {
  438. // /* Validate verification public key. */
  439. // if (_.isObject(myVerificationPubKey) && typeof myVerificationPubKey.toString) {
  440. // myVerificationPubKey = myVerificationPubKey.toString()
  441. // }
  442. //
  443. // /* Set message. */
  444. // const message = PB.Signed.create({
  445. // packet: PB.Packet.create({
  446. // session: session,
  447. // number: fromPlayerNumber,
  448. // fromKey: PB.VerificationKey.create({
  449. // key: myVerificationPubKey
  450. // }),
  451. // phase: PB.Phase.values[phase.toUpperCase()],
  452. // message: PB.Message.create({
  453. // signatures: []
  454. // })
  455. // })
  456. // })
  457. //
  458. // /* Add packet message signatures. */
  459. // message.packet.message.signatures.push(PB.Signature.create({
  460. // utxo: coinUtxoData,
  461. // signature: PB.Signature.create({
  462. // signature: signatureString
  463. // })
  464. // }))
  465. //
  466. // /* Set message. */
  467. // const msg = PB.Packet.encode(message.packet).finish().toString('base64')
  468. //
  469. // /* Set signature. */
  470. // const signature = new BetterMessage(msg, 'base64')
  471. // .sign(bch.PrivateKey(myVerificationPrivKey))
  472. //
  473. // /* Set message signature. */
  474. // message.signature = PB.Signature.create({
  475. // signature: signature
  476. // })
  477. //
  478. // /* Return packed message. */
  479. // return packMessage(message)
  480. // }
  481. /*
  482. {
  483. "packet": [
  484. {
  485. "packet": {
  486. "session": "c25hMmNwNm8xcXJIejlNMDhJdGFNZA==",
  487. "number": 2,
  488. "from_key": {
  489. "key": "03343954c832a7b870eb8758c1c280b954bfed8b8fb65a33d52f848aabdbf31dce"
  490. },
  491. "phase": 4,
  492. "message": {
  493. "hash": {
  494. "hash": "1WDdy4zstoNgSnuSjagCxL5P8aqDbBerN92WSs1c2hY="
  495. }
  496. }
  497. },
  498. "signature": {
  499. "signature": "ICz+h2V5JBhHTronVb2FB4rCLHrIDi3gmsCn/+VphuojdofZBx5LCjefnnoGhwyYVQ40pSPi1u+JPXduPurrOBo="
  500. }
  501. }
  502. ]
  503. }
  504. */
  505. /**
  506. * Broadcast Equivocation Check
  507. */
  508. // function broadcastEquivCheck (
  509. // session,
  510. // fromPlayerNumber,
  511. // equivCheckHash,
  512. // phase,
  513. // myVerificationPubKey,
  514. // myVerificationPrivKey
  515. // ) {
  516. // /* Validate verification public key. */
  517. // if (_.isObject(myVerificationPubKey) && typeof myVerificationPubKey.toString) {
  518. // myVerificationPubKey = myVerificationPubKey.toString()
  519. // }
  520. //
  521. // /* Set message. */
  522. // const message = PB.Signed.create({
  523. // packet: PB.Packet.create({
  524. // session: session,
  525. // number: fromPlayerNumber,
  526. // fromKey: PB.VerificationKey.create({
  527. // key: myVerificationPubKey
  528. // }),
  529. // phase: PB.Phase.values[phase.toUpperCase()],
  530. // message: PB.Message.create({
  531. // hash: PB.Hash.create({
  532. // hash: equivCheckHash
  533. // })
  534. // })
  535. // })
  536. // })
  537. //
  538. // /* Set message. */
  539. // const msg = PB.Packet.encode(message.packet).finish().toString('base64')
  540. //
  541. // /* Set signature. */
  542. // const signature = new BetterMessage(msg, 'base64')
  543. // .sign(bch.PrivateKey(myVerificationPrivKey))
  544. //
  545. // /* Set message signature. */
  546. // message.signature = PB.Signature.create({
  547. // signature: signature
  548. // })
  549. //
  550. // /* Return packed message. */
  551. // return packMessage(message)
  552. // }
  553. /**
  554. * Broadcast Final Output Addresses
  555. */
  556. // function broadcastFinalOutputAddresses (
  557. // session,
  558. // fromPlayerNumber,
  559. // arrayOfOutputs,
  560. // phase,
  561. // myVerificationPubKey,
  562. // myVerificationPrivKey
  563. // ) {
  564. // /* Validate verification public key. */
  565. // if (_.isObject(myVerificationPubKey) && typeof myVerificationPubKey.toString) {
  566. // myVerificationPubKey = myVerificationPubKey.toString()
  567. // }
  568. //
  569. // /* Initialize signed messages. */
  570. // const signedMessages = []
  571. //
  572. // /* Loop through ALL outputs. */
  573. // for (let onePlaintextAddress of arrayOfOutputs) {
  574. // /* Set message. */
  575. // const message = PB.Signed.create({
  576. // packet: PB.Packet.create({
  577. // session: session,
  578. // number: fromPlayerNumber,
  579. // fromKey: PB.VerificationKey.create({
  580. // key: myVerificationPubKey
  581. // }),
  582. // phase: PB.Phase.values[phase.toUpperCase()],
  583. // message: PB.Message.create({
  584. // str: onePlaintextAddress
  585. // })
  586. // })
  587. // })
  588. //
  589. // /* Set message. */
  590. // const msg = PB.Packet.encode(message.packet).finish().toString('base64')
  591. //
  592. // /* Set signature. */
  593. // const signature = new BetterMessage(msg, 'base64')
  594. // .sign(bch.PrivateKey(myVerificationPrivKey))
  595. //
  596. // /* Set message signature. */
  597. // message.signature = PB.Signature.create({
  598. // signature: signature
  599. // })
  600. //
  601. // /* Add message to signed messages. */
  602. // signedMessages.push(message)
  603. // }
  604. //
  605. // /* Return packed signed messages. */
  606. // return packMessage(signedMessages)
  607. // }
  608. /**
  609. * Change Address Announcement
  610. */
  611. // function changeAddressAnnounce (
  612. // session,
  613. // playerNumber,
  614. // changeAddress,
  615. // encryptionPublicKey,
  616. // phase,
  617. // verificationPublicKey,
  618. // verificationPrivateKey
  619. // ) {
  620. // /* Validate encryption public key. */
  621. // if (_.isObject(encryptionPublicKey) && typeof encryptionPublicKey.toString) {
  622. // encryptionPublicKey = encryptionPublicKey.toString()
  623. // }
  624. //
  625. // /* Validate verification public key. */
  626. // if (_.isObject(verificationPublicKey) && typeof verificationPublicKey.toString) {
  627. // verificationPublicKey = verificationPublicKey.toString()
  628. // }
  629. //
  630. // /* Initialize message. */
  631. // let message
  632. //
  633. // /* Set message. */
  634. // message = PB.Signed.create({
  635. // packet: PB.Packet.create({
  636. // session: session,
  637. // number: playerNumber,
  638. // fromKey: PB.VerificationKey.create({
  639. // key: verificationPublicKey
  640. // }),
  641. // phase: PB.Phase.values[phase.toUpperCase()],
  642. // message: PB.Message.create({
  643. // address: PB.Address.create({
  644. // address: changeAddress
  645. // }),
  646. // key: PB.VerificationKey.create({
  647. // key: encryptionPublicKey
  648. // })
  649. // })
  650. // })
  651. // })
  652. //
  653. // /* Set message. */
  654. // const msg = PB.Packet.encode(message.packet).finish().toString('base64')
  655. //
  656. // /* Set signature. */
  657. // const signature = new BetterMessage(msg, 'base64')
  658. // .sign(bch.PrivateKey(verificationPrivateKey))
  659. //
  660. // /* Set message signature. */
  661. // message.signature = PB.Signature.create({ signature })
  662. //
  663. // /* Return packed message. */
  664. // return packMessage(message)
  665. // }
  666. /**
  667. * Pack Message
  668. *
  669. * Encode (pack) a message into a prototype buffer (protobuf) object.
  670. */
  671. function packMessage (oneOrMorePackets) {
  672. oneOrMorePackets = _.isArray(oneOrMorePackets) ? oneOrMorePackets : [oneOrMorePackets]
  673. /* Set packets. */
  674. const packets = PB.Packets.create({ packet: oneOrMorePackets })
  675. /* Set message buffer. */
  676. const messageBuffer = PB.Packets.encode(packets).finish()
  677. /* Initialize length suffix. */
  678. const lengthSuffix = Buffer.alloc(4)
  679. /* Set length suffix. */
  680. lengthSuffix.writeUIntBE(messageBuffer.length, 0, 4)
  681. /* Set message components. */
  682. const messageComponents = [magic, lengthSuffix, messageBuffer]
  683. /* Set full message. */
  684. const fullMessage = Buffer.concat(messageComponents)
  685. /* Return message object. */
  686. return {
  687. unpacked: packets,
  688. packed: fullMessage,
  689. components: messageToBuffers(fullMessage)
  690. }
  691. }
  692. /**
  693. * Check Packet Signature
  694. */
  695. // function checkPacketSignature (oneSignedPacket) {
  696. // /* Initialize verification key. */
  697. // const verificationKey = oneSignedPacket.packet.fromKey.key
  698. //
  699. // /* Set signature. */
  700. // const signature = oneSignedPacket.signature.signature.toString('base64')
  701. //
  702. // /* Set packet. */
  703. // const packet = PB.Packet.encode(oneSignedPacket.packet)
  704. //
  705. // /* Set public key. */
  706. // const pubkey = new bch.PublicKey(verificationKey)
  707. //
  708. // /* Set address. */
  709. // const address = pubkey.toAddress().toString()
  710. //
  711. // /* Set message. */
  712. // const message = packet.finish().toString('base64')
  713. //
  714. // debug('checkPacketSignature',
  715. // verificationKey,
  716. // signature,
  717. // packet,
  718. // pubkey,
  719. // address,
  720. // message
  721. // )
  722. //
  723. // /* Initialize result. */
  724. // let result = false
  725. //
  726. // try {
  727. // /* Set result. */
  728. // result = new BetterMessage(message, 'base64').verify(address, signature)
  729. // } catch (someError) {
  730. // debug('Error checking signature:', someError)
  731. // }
  732. //
  733. // /* Return result. */
  734. // return result
  735. // }
  736. /*
  737. {
  738. reason: < enum string citing reason for blame accusation >,
  739. accused: < verification key in hex format of player who 's being accused >,
  740. invalid: < an array of protobuf packets that provide evidence of fault >,
  741. hash: < hash provided by accused which differs from our own >,
  742. keypair: {
  743. key: < private key >,
  744. public: < public key >
  745. }
  746. }
  747. Possible Ban Reasons:
  748. INSUFFICIENTFUNDS = 0
  749. DOUBLESPEND = 1
  750. EQUIVOCATIONFAILURE = 2
  751. SHUFFLEFAILURE = 3
  752. SHUFFLEANDEQUIVOCATIONFAILURE = 4
  753. INVALIDSIGNATURE = 5
  754. MISSINGOUTPUT = 6
  755. LIAR = 7
  756. INVALIDFORMAT = 8
  757. */
  758. /**
  759. * Blame Message
  760. */
  761. // function blameMessage (
  762. // options,
  763. // mySessionid,
  764. // myPlayerNumber,
  765. // myVerificationPublicKey,
  766. // myVerificationPrivateKey
  767. // ) {
  768. // /* Validate verification public key. */
  769. // if (_.isObject(myVerificationPublicKey) && typeof myVerificationPublicKey.toString) {
  770. // myVerificationPublicKey = myVerificationPublicKey.toString()
  771. // }
  772. //
  773. // /* Validate verification private key. */
  774. // if (_.isObject(myVerificationPrivateKey) && typeof myVerificationPrivateKey.toString) {
  775. // myVerificationPrivateKey = myVerificationPrivateKey.toString()
  776. // }
  777. //
  778. // /* Set blame message. */
  779. // const blameMessage = _.reduce(_.keys(options), function (msg, oneOptionName) {
  780. // switch (oneOptionName) {
  781. // case 'reason':
  782. // msg.packet.message.blame.reason = PB.Reason.values[options.reason ? options.reason.toUpperCase() : 'NONE']
  783. // break
  784. // case 'accused':
  785. // msg.packet.message.blame.accused = PB.VerificationKey.create({
  786. // key: options.accused
  787. // })
  788. // break
  789. // case 'invalid':
  790. // msg.packet.message.blame.invalue = PB.Invalid.create({ invalid: invalidPackets })
  791. // break
  792. // case 'hash':
  793. // msg.packet.message.hash = PB.Hash.create({ hash: options.hash })
  794. // break
  795. // case 'keypair':
  796. // msg.packet.message.blame.key = PB.DecryptionKey.create({
  797. // key: options.keypair.key,
  798. // public: options.keypair.public
  799. // })
  800. // break
  801. // // case '':
  802. // // msg.packet.message.
  803. // // break
  804. // default:
  805. // break
  806. // }
  807. //
  808. // /* Return message. */
  809. // return msg
  810. // }, PB.Signed.create({
  811. // packet: PB.Packet.create({
  812. // session: mySessionid,
  813. // number: myPlayerNumber,
  814. // fromKey: PB.VerificationKey.create({
  815. // key: myVerificationPublicKey
  816. // }),
  817. // message: PB.Message.create({
  818. // blame: PB.Blame.create({
  819. // })
  820. // }),
  821. // phase: PB.Phase.values['BLAME']
  822. // })
  823. // }))
  824. //
  825. // /* Set message. */
  826. // const msg = PB.Packet.encode(blameMessage.packet).finish().toString('base64')
  827. //
  828. // /* Set blame message signature. */
  829. // blameMessage.signature = PB.Signature.create({
  830. // signature: new BetterMessage(msg, 'base64')
  831. // .sign(bch.PrivateKey(myVerificationPrivateKey))
  832. // })
  833. //
  834. // debug('Compiled blame message:', blameMessage)
  835. //
  836. // /* Return packed message. */
  837. // return packMessage(blameMessage)
  838. // }
  839. /* Export module. */
  840. module.exports = {
  841. PB,
  842. // broadcastSignatureAndUtxo,
  843. // broadcastEquivCheck,
  844. // broadcastFinalOutputAddresses,
  845. // forwardEncryptedOutputs,
  846. // messageToBuffers,
  847. // decodeAndClassify,
  848. // registration,
  849. // broadcastTransactionInput,
  850. // changeAddressAnnounce,
  851. packMessage,
  852. // blameMessage,
  853. // checkPacketSignature
  854. }