iota.lib.js
Version:
Javascript Library for IOTA
210 lines (146 loc) • 4.55 kB
JavaScript
var Curl = require("../curl/curl");
var Converter = require("../converter/converter");
var Bundle = require("../bundle/bundle");
var add = require("../helpers/adder");
/**
* Signing related functions
*
**/
var key = function(seed, index, length) {
while ((seed.length % 243) !== 0) {
seed.push(0);
}
var indexTrits = Converter.fromValue( index );
var subseed = add( seed.slice( ), indexTrits );
var curl = new Curl( );
curl.initialize( );
curl.absorb(subseed, 0, subseed.length);
curl.squeeze(subseed, 0, subseed.length);
curl.initialize( );
curl.absorb(subseed, 0, subseed.length);
var key = [], offset = 0, buffer = [];
while (length-- > 0) {
for (var i = 0; i < 27; i++) {
curl.squeeze(buffer, 0, subseed.length);
for (var j = 0; j < 243; j++) {
key[offset++] = buffer[j];
}
}
}
return key;
}
/**
*
*
**/
var digests = function(key) {
var digests = [], buffer = [];
for (var i = 0; i < Math.floor(key.length / 6561); i++) {
var keyFragment = key.slice(i * 6561, (i + 1) * 6561);
for (var j = 0; j < 27; j++) {
buffer = keyFragment.slice(j * 243, (j + 1) * 243);
for (var k = 0; k < 26; k++) {
var kCurl = new Curl();
kCurl.initialize();
kCurl.absorb(buffer, 0, buffer.length);
kCurl.squeeze(buffer, 0, Curl.HASH_LENGTH);
}
for (var k = 0; k < 243; k++) {
keyFragment[j * 243 + k] = buffer[k];
}
}
var curl = new Curl()
curl.initialize();
curl.absorb(keyFragment, 0, keyFragment.length);
curl.squeeze(buffer, 0, Curl.HASH_LENGTH);
for (var j = 0; j < 243; j++) {
digests[i * 243 + j] = buffer[j];
}
}
return digests;
}
/**
*
*
**/
var address = function(digests) {
var addressTrits = [];
var curl = new Curl();
curl.initialize();
curl.absorb(digests, 0, digests.length);
curl.squeeze(addressTrits, 0, Curl.HASH_LENGTH);
return addressTrits;
}
/**
*
*
**/
var digest = function(normalizedBundleFragment, signatureFragment) {
var buffer = []
var curl = new Curl();
curl.initialize();
for (var i = 0; i< 27; i++) {
buffer = signatureFragment.slice(i * 243, (i + 1) * 243);
for (var j = normalizedBundleFragment[i] + 13; j-- > 0; ) {
var jCurl = new Curl();
jCurl.initialize();
jCurl.absorb(buffer, 0, buffer.length);
jCurl.squeeze(buffer, 0, Curl.HASH_LENGTH);
}
curl.absorb(buffer, 0, buffer.length);
}
curl.squeeze(buffer, 0, Curl.HASH_LENGTH);
return buffer;
}
/**
*
*
**/
var signatureFragment = function(normalizedBundleFragment, keyFragment) {
var signatureFragment = keyFragment.slice(), hash = [];
var curl = new Curl();
for (var i = 0; i < 27; i++) {
hash = signatureFragment.slice(i * 243, (i + 1) * 243);
for (var j = 0; j < 13 - normalizedBundleFragment[i]; j++) {
curl.initialize();
curl.absorb(hash, 0, hash.length);
curl.squeeze(hash, 0, Curl.HASH_LENGTH);
}
for (var j = 0; j < 243; j++) {
signatureFragment[i * 243 + j] = hash[j];
}
}
return signatureFragment;
}
/**
*
*
**/
var validateSignatures = function(expectedAddress, signatureFragments, bundleHash) {
var self = this;
var bundle = new Bundle();
var normalizedBundleFragments = [];
var normalizedBundleHash = bundle.normalizedBundle(bundleHash);
// Split hash into 3 fragments
for (var i = 0; i < 3; i++) {
normalizedBundleFragments[i] = normalizedBundleHash.slice(i * 27, (i + 1) * 27);
}
// Get digests
var digests = [];
for (var i = 0; i < signatureFragments.length; i++) {
var digestBuffer = digest(normalizedBundleFragments[i % 3], Converter.trits(signatureFragments[i]));
for (var j = 0; j < 243; j++) {
digests[i * 243 + j] = digestBuffer[j]
}
}
var address = Converter.trytes(self.address(digests));
return (expectedAddress === address);
}
module.exports = {
key : key,
digests : digests,
address : address,
digest : digest,
signatureFragment : signatureFragment,
validateSignatures : validateSignatures
}