UNPKG

mam.ts

Version:
282 lines (253 loc) 8.16 kB
const IOTA = require('./IOTA.js') ////////////////////////////////////////////////////////////////// /* ======= CTrits bindings ======= */ const TritEncoding = { BYTE: 1, TRIT: 2, TRYTE: 3 } /* ======= Rust bindings ======= */ const iota_ctrits_drop = IOTA.cwrap('iota_ctrits_drop', '', ['number']) const iota_ctrits_convert = IOTA.cwrap('iota_ctrits_convert', 'number', [ 'number', 'number' ]) const iota_ctrits_ctrits_from_trytes = IOTA.cwrap( 'iota_ctrits_ctrits_from_trytes', 'number', ['string', 'number'] ) const iota_ctrits_ctrits_from_bytes = IOTA.cwrap( 'iota_ctrits_ctrits_from_bytes', 'number', ['number', 'number'] ) const iota_ctrits_ctrits_from_trits = IOTA.cwrap( 'iota_ctrits_ctrits_from_trits', 'number', ['number', 'number'] ) // For accessing the struct members const iota_ctrits_ctrits_encoding = IOTA.cwrap( 'iota_ctrits_ctrits_encoding', 'number', ['number'] ) const iota_ctrits_ctrits_length = IOTA.cwrap( 'iota_ctrits_ctrits_length', 'number', ['number'] ) const iota_ctrits_ctrits_data = IOTA.cwrap( 'iota_ctrits_ctrits_data', 'number', ['number'] ) const iota_ctrits_ctrits_byte_length = IOTA.cwrap( 'iota_ctrits_ctrits_byte_length', 'number', ['number'] ) const iota_mam_id = IOTA.cwrap('iota_mam_id', 'number', [ 'number', 'number' ]) // (seed, message, key, root, siblings, next_root, start, index, security) -> encoded_message const iota_mam_create = IOTA.cwrap('iota_mam_create', 'number', [ 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number', 'number' ]) // (encoded_message, key, root, index) -> message const iota_mam_parse = IOTA.cwrap('iota_mam_parse', 'number', [ 'number', 'number', 'number', 'number' ]) // (seed, index, count, securit) -> MerkleTree instance const iota_merkle_create = IOTA.cwrap('iota_merkle_create', 'number', [ 'number', 'number', 'number', 'number' ]) // (MerkleTree instance) -> () const iota_merkle_drop = IOTA.cwrap('iota_merkle_drop', '', ['number']) // (MerkleTree instance) -> (siblings as number) const iota_merkle_siblings = IOTA.cwrap('iota_merkle_siblings', 'number', [ 'number' ]) // (MerkleTree instance, index) -> (MerkleBranch instance) const iota_merkle_branch = IOTA.cwrap('iota_merkle_branch', 'number', [ 'number', 'number' ]) // (MerkleBranch instance) -> () const iota_merkle_branch_drop = IOTA.cwrap('iota_merkle_branch_drop', '', [ 'number' ]) // (MerkleBranch instance) -> (number) const iota_merkle_branch_len = IOTA.cwrap('iota_merkle_branch_len', '', [ 'number' ]) // (address, siblings, index) -> (root as number) const iota_merkle_root = IOTA.cwrap('iota_merkle_root', 'number', [ 'number', 'number', 'number' ]) // (MerkleTree instance) -> root hash const iota_merkle_slice = IOTA.cwrap('iota_merkle_slice', 'number', ['number']) const string_to_ctrits_trits = str => { let strin = iota_ctrits_ctrits_from_trytes(str, str.length) let out = iota_ctrits_convert(strin, TritEncoding.TRIT) iota_ctrits_drop(strin) return out } const ctrits_trits_to_string = ctrits => { let str_trits = iota_ctrits_convert(ctrits, TritEncoding.TRYTE) let ptr = iota_ctrits_ctrits_data(str_trits) let len = iota_ctrits_ctrits_length(str_trits) let out = IOTA.Pointer_stringify(ptr, len) iota_ctrits_drop(str_trits) return out } const getMamRoot = (SEED, CHANNEL) => { let SEED_trits = string_to_ctrits_trits(SEED) let root_merkle = iota_merkle_create( SEED_trits, CHANNEL.start, CHANNEL.count, CHANNEL.security ) return ctrits_trits_to_string(iota_merkle_slice(root_merkle)) } const getMamAddress = (KEY, ROOT) => { let KEY_trits = string_to_ctrits_trits(KEY) let ROOT_trits = string_to_ctrits_trits(ROOT) let address = iota_mam_id( KEY_trits, ROOT_trits ) return ctrits_trits_to_string(address) } const createMessage = (SEED, MESSAGE, SIDE_KEY, CHANNEL) => { if (!SIDE_KEY) SIDE_KEY = '999999999999999999999999999999999999999999999999999999999999999999999999999999999' // MAM settings let SEED_trits = string_to_ctrits_trits(SEED) let MESSAGE_trits = string_to_ctrits_trits(MESSAGE) let SIDE_KEY_trits = string_to_ctrits_trits(SIDE_KEY) const SECURITY = CHANNEL.security const START = CHANNEL.start const COUNT = CHANNEL.count const NEXT_START = START + COUNT const NEXT_COUNT = CHANNEL.next_count const INDEX = CHANNEL.index const HASH_LENGTH = 81 // set up merkle tree let root_merkle = iota_merkle_create(SEED_trits, START, COUNT, SECURITY) let next_root_merkle = iota_merkle_create( SEED_trits, NEXT_START, NEXT_COUNT, SECURITY ) let root_branch = iota_merkle_branch(root_merkle, INDEX) let root_siblings = iota_merkle_siblings(root_branch) let next_root_branch = iota_merkle_branch(next_root_merkle, INDEX) let root = iota_merkle_slice(root_merkle) let next_root = iota_merkle_slice(next_root_merkle) let masked_payload = iota_mam_create( SEED_trits, MESSAGE_trits, SIDE_KEY_trits, root, root_siblings, next_root, START, INDEX, SECURITY ) const response = { payload: ctrits_trits_to_string(masked_payload), root: ctrits_trits_to_string(root), next_root: ctrits_trits_to_string(next_root), side_key: SIDE_KEY } // Clean up memory. Unneccessary for this example script, but should be done when running in a production // environment. iota_merkle_branch_drop(root_branch) iota_merkle_branch_drop(next_root_branch) iota_merkle_drop(root_merkle) iota_merkle_drop(next_root_merkle) ;[ SEED_trits, MESSAGE_trits, SIDE_KEY_trits, root, next_root, masked_payload, root_siblings ].forEach(iota_ctrits_drop) return response } const decodeMessage = (PAYLOAD, SIDE_KEY, ROOT) => { if (!SIDE_KEY) SIDE_KEY = '999999999999999999999999999999999999999999999999999999999999999999999999999999999' let PAYLOAD_trits = string_to_ctrits_trits(PAYLOAD) let SIDE_KEY_trits = string_to_ctrits_trits(SIDE_KEY) let ROOT_trits = string_to_ctrits_trits(ROOT) let parse_result; try { parse_result = iota_mam_parse(PAYLOAD_trits, SIDE_KEY_trits, ROOT_trits); } catch (err) { console.log("Payload Trits:"); console.log(PAYLOAD_trits); console.log("Sidekey Trits:"); console.log(SIDE_KEY_trits); console.log("Root Trits:"); console.log(ROOT_trits); console.log("Result Error:"); console.log(parse_result); console.log("Parse Error: " + err); } let unmasked_payload_ctrits = IOTA.getValue(parse_result, 'i32') let unmasked_payload = ctrits_trits_to_string(unmasked_payload_ctrits) let unmasked_next_root_ctrits = IOTA.getValue(parse_result + 4, 'i32') let unmasked_next_root = ctrits_trits_to_string(unmasked_next_root_ctrits) ;[ PAYLOAD_trits, SIDE_KEY_trits, ROOT_trits, unmasked_payload_ctrits, unmasked_next_root_ctrits ].forEach(iota_ctrits_drop) IOTA._free(parse_result) return { payload: unmasked_payload, next_root: unmasked_next_root } } export const Mam = { decodeMessage, createMessage, getMamAddress, getMamRoot } export const MamDetails = { string_to_ctrits_trits, iota_merkle_create, iota_merkle_branch, iota_merkle_siblings, iota_merkle_slice, ctrits_trits_to_string } // Feed Mam functions into the main file //Main.setupEnv(Mam) // Export //export = Main;