js decoding of ring ct amounts added

master
moneroexamples 7 years ago
parent 1459b30dd4
commit d27904098d

@ -165,10 +165,54 @@
</div>
<script>
// here we handle button presses from the above forms
// to decode and prove txs.
$(document).ready(function() {
var H = "8b655970153799af2aeadc9ff1add0ea6c7251d54154cfa92c173a0dd39c1f94";
//decode amount and mask and check against commitment
// from https://xmr.llcoins.net/js/site.js
function decodeRct(rv, i, der){
var key = derivation_to_scalar(der, i);
var ecdh = decode_rct_ecdh(rv.ecdhInfo[i], key);
console.log(ecdh);
var Ctmp = commit(ecdh.amount, ecdh.mask);
console.log(Ctmp);
if (Ctmp !== rv.outPk[i]){
throw "mismatched commitments!";
}
ecdh.amount = s2d(ecdh.amount);
return ecdh;
}
//creates a Pedersen commitment from an amount (in scalar form) and a mask
//C = bG + aH where b = mask, a = amount
// from https://xmr.llcoins.net/js/site.js
function commit(amount, mask){
if (!valid_hex(mask) || mask.length !== 64 || !valid_hex(amount) || amount.length !== 64){
throw "invalid amount or mask!";
}
var C = ge_double_scalarmult_base_vartime(amount, H, mask);
return C;
}
// // from https://xmr.llcoins.net/js/site.js
function s2d(scalar){
return JSBigInt.parse(swapEndian(scalar), 16).toString();
}
//switch byte order for hex string
// from https://xmr.llcoins.net/js/site.js
function swapEndian(hex){
if (hex.length % 2 !== 0){return "length must be a multiple of 2!";}
var data = "";
for (var i=1; i <= hex.length / 2; i++){
data += hex.substr(0 - 2 * i, 2);
}
return data;
}
// we need output pubplic keys, their indexes and amounts.
// all this is already avaliable on the html, but we can use
@ -176,7 +220,7 @@
var tx_json = {{#tx_json_raw}}{{/tx_json_raw}};
console.log(tx_json);
//console.log(tx_json);
var is_rct = ($("#is_ringct").val() === "yes");
var rct_type = parseInt($("#ringct_type").val());
@ -217,7 +261,7 @@
var output_idx = parseInt(output[0]);
var output_pub_key = output[1];
var amount = output[2];
var amount = parseInt(output[2]);
var pubkey_generated = derive_public_key(key_derivation, output_idx, address_decoded.spend);
@ -226,7 +270,18 @@
var mine_output_str = "false";
if (mine_output) {
mine_output_str = '<span style="color: #008009;font-weight: bold">true</span>';
if (is_rct) {
try {
var ecdh = decodeRct(tx_json.rct_signatures, output_idx, key_derivation);
amount = ecdh.amount / 1e12;
} catch (err) {
decoding_results_str += "<span class='validNo'>RingCT amount for output " + i + " with pubkey: " + output_pub_key + " decoded incorrectly! It will not be spendable." + "</span>" + "<br>"; //rct commitment != computed
//throw "invalid rct amount";
}
}
}
decoding_results_str += "<tr>"
@ -259,47 +314,6 @@
});
//decode amount and mask and check against commitment
// from https://xmr.llcoins.net/js/site.js
function decodeRct(rv, i, der){
var key = derivation_to_scalar(der, i);
var ecdh = decode_rct_ecdh(rv.ecdhInfo[i], key);
console.log(ecdh);
var Ctmp = commit(ecdh.amount, ecdh.mask);
console.log(Ctmp);
if (Ctmp !== rv.outPk[i]){
throw "mismatched commitments!";
}
ecdh.amount = s2d(ecdh.amount);
return ecdh;
}
//creates a Pedersen commitment from an amount (in scalar form) and a mask
//C = bG + aH where b = mask, a = amount
// from https://xmr.llcoins.net/js/site.js
function commit(amount, mask){
if (!valid_hex(mask) || mask.length !== 64 || !valid_hex(amount) || amount.length !== 64){
throw "invalid amount or mask!";
}
var C = ge_double_scalarmult_base_vartime(amount, H, mask);
return C;
}
// // from https://xmr.llcoins.net/js/site.js
function s2d(scalar){
return JSBigInt.parse(swapEndian(scalar), 16).toString();
}
//switch byte order for hex string
// from https://xmr.llcoins.net/js/site.js
function swapEndian(hex){
if (hex.length % 2 !== 0){return "length must be a multiple of 2!";}
var data = "";
for (var i=1; i <= hex.length / 2; i++){
data += hex.substr(0 - 2 * i, 2);
}
return data;
}
});

Loading…
Cancel
Save