6

This question by kenshi84 shows how the pseudoOuts and outPk fields can be validated by anyone (without knowing any of the private keys involved), by checking that sumIn === sumOut:

> var H = ge_scalarmult(cn_fast_hash(ge_scalarmult_base("0100000000000000000000000000000000000000000000000000000000000000")), "0800000000000000000000000000000000000000000000000000000000000000");
undefined
> H
"8b655970153799af2aeadc9ff1add0ea6c7251d54154cfa92c173a0dd39c1f94"
> var fee = swapEndian(d2h256("30000000000"));
undefined
> fee
"00AC23FC06000000000000000000000000000000000000000000000000000000"
> var feeH = ge_scalarmult(H, fee);
undefined
> feeH
"527e4c0b6e34f948fb59ab014ec8eedf9eccfda4930a0b30d12790a0ec0d91f2"
> var pseudoOuts = ["276f03ba8c7852cb545830f7fedcdcd08789675d2a6c265bea236d0de90f6b11", "c611cc551db3b05ad6e5dba4ce89a8eeeb18317d8b565031941e98b6b9b8db4f", "8a088f1ccd11dd1633a663538faa9cb18c157b4fd37c421697a6356b4d7a98f6", "9e1238add1c1a4712904e5d5d8913482dcd6d31af166bc73918fd8148a42f22b"];
undefined
> var outPk = [ "f9cabc6b0fd32822feb3e13c70b54b2cdc2a3ce7c88ac661c29ab20732e2974f", "cfb010382648e11d7d5744fe8051c8606f31c901f9ede5b7e392f73790f9e7f8"]
undefined
> var sumIn = ge_add(ge_add(ge_add(pseudoOuts[0], pseudoOuts[1]), pseudoOuts[2]), pseudoOuts[3]);
undefined
> var sumOut = ge_add(ge_add(outPk[0], outPk[1]), feeH);
undefined
> sumIn
"a340fb56b64d831d4f06079f1fc4d507a7a2d1b0107ea7814c626c7394190da6"
> sumOut
"a340fb56b64d831d4f06079f1fc4d507a7a2d1b0107ea7814c626c7394190da6"

It's nice to have working javascript code (you can try by opening a browser console here), and I wonder if my question can be answered in a similar way.

I've noticed that the ecdhInfo field wasn't used in the above javascript code. Is there a way to validate ecdhInfo too, without knowing any private keys? Or is this not necessary?

For reference, here's rct_signatures from kenshi84's question again:

{
    "type": 2, 
    "txnFee": 30000000000, 
    "pseudoOuts":["276f03ba8c7852cb545830f7fedcdcd08789675d2a6c265bea236d0de90f6b11", "c611cc551db3b05ad6e5dba4ce89a8eeeb18317d8b565031941e98b6b9b8db4f", "8a088f1ccd11dd1633a663538faa9cb18c157b4fd37c421697a6356b4d7a98f6", "9e1238add1c1a4712904e5d5d8913482dcd6d31af166bc73918fd8148a42f22b"], 
    "ecdhInfo": [ {
        "mask": "c626b75f726e88a26fc74c1bb508fa9358c0896a7635d0f1256c7f43f0217706", 
        "amount": "63c1d97047ff515ccd5ca271f4e5013b9c1092c25307207a0ff037b13f492c00"
      }, {
        "mask": "73b4367f9b143c0a453598f85761698c4548e890fa52a05b4e28183126525008", 
        "amount": "81b48b46e79b458a234ad36d3d0890f89e30d50cc18a687dd94fd0ef3417da0f"
      }], 
    "outPk": [ "f9cabc6b0fd32822feb3e13c70b54b2cdc2a3ce7c88ac661c29ab20732e2974f", "cfb010382648e11d7d5744fe8051c8606f31c901f9ede5b7e392f73790f9e7f8"]
 }

1 Answers1

4

Both the ecdhInfo mask and amount are encrypted by the sender of the transaction.

Both are encrypted (each in a slightly different way) using the transaction's shared secret (aR).

Therefore both encrypted values will be randomly distributed, and thus cannot be validated by a third party.

If the sender of the transaction had somehow written faulty values into the transaction, the only consequence would be that the outputs created by the transaction would be unspendable.

The code that encrypts and decrypts the ecdhInfo values is here: https://github.com/monero-project/monero/blob/2b00899bb28e09f0c44813689acc0add73832215/src/ringct/rctOps.cpp#L447

knaccc
  • 8,468
  • 16
  • 22
  • Just to be sure... so ecdhInfo and outPk must have the same length, and for all i, 0 <= i < outPk.length, the receiver would check that ge_add(ge_scalarmult_base(ecdhDecode(ecdhInfo[i].mask, aR)), ge_scalarmult(ecdhDecode(ecdhInfo[i].amount, aR), H)) equals outPk[i]? – Lustiger Astronaut Mar 04 '18 at 05:21
  • Yes, to both. Technically your code wouldn't compile, but you've clearly understood the principle that the ecdhInfo is there to communicate the components of the output Pedersen commitments to the recipient, so that the recipient is then able to properly construct a RingCT proof that references those outputs as inputs in a subsequent transaction. – knaccc Mar 04 '18 at 05:58