1

I am trying to generate LSAG KeyImage by myself in C which is K̃ = kπ*Hp(R).

And I take result of MiniNero as a reference..

def test_keyImage():
    private_key = "907cf0eb0e0bbd761a7ed9bc8777fa5530e8262792a3e718533a1a357a1e4199"
    public_keys = "a9931c8d70237a279b8d3181f947830f0c3a21032d22b5d6e81c3afeba51bb0c", "210330a31c3caab4087c19fbe770514e5e6b80eda552d1e5f8becabd12c4540e","824ec9615ece05e6f5707facd88abbfb79b32f97b6a68be5304b5b2dfc06df01"
    public_join = ''.join(pub)
    hashpj = MiniNero.cn_fast_hash(public_join)
    print(hashpj)

    HR = MiniNero.hashToPointCN(hashpj)
    print(HR)

The result:

hashpj:1dd1fdba911ce449e0d64ed4daf5ec7b9ab46465e7e60a4465e6c83f1152f332
HR:    996b4d50ed204c7f14b106c818a7268a9cd66166ff194e13beefb6880c8aac39

As code above, I join 3 public keys to form R and run with cn_fast_hash(), then using hashToPointCN() to get HR. However, can not get the same value from my C code implement.

ge_p2 point;
ge_p1p1 point2;
ge_p3 point3;

uint8_t hash_result[32];
uint8_t final_res[32];

keccak(pub_keys, 96, hash_result, 32); //keccak(PSK, 32, result, 32);

for(i=0; i<32; i++){
    printf("%02x", hash_result[i]);}

ge_fromfe_frombytes_vartime(&point, hash_result);
ge_mul8(&point2, &point);
ge_p1p1_to_p3(&point3, &point2);
ge_p3_tobytes(final_res, &point3);

printf("\n");
for(i=0; i<32; i++)
    printf("%02x", final_res[i]);

The result:

1dd1fdba911ce449e0d64ed4daf5ec7b9ab46465e7e60a4465e6c83f1152f332
4543c4d7a442df56119ea1fa97eee1d0b8a2e485b48b3741f498bb63d2d593b3

From the result, we can see that keccak hash is right, but I can not get the same result as what MiniNero.hashToPointCN() does.

Please help me on this problem, I am lost here...

Mooooo
  • 459
  • 2
  • 8

1 Answers1

3

Your tests are not the same.

If you look at the source for hashToPointCN, you will see:

def hashToPointCN(hexVal):
    u= hexToInt(cn_fast_hash(hexVal)) % q
    ...

It hashes the input.

So in your Python test, you are outputting the result of cn_fast_hash, which is being used as input to hashToPointCN, which is hashing again and then returning a result point.

Your C test is correct in that you are only hashing the input once.

Thus, if you amended your Python to:

HR = MiniNero.hashToPointCN(public_join)
print(HR)

You'd get the same result as the C version:

4543c4d7a442df56119ea1fa97eee1d0b8a2e485b48b3741f498bb63d2d593b3

As an FYI, you can see exactly how a key image is generated in the source code of Monero here: src/crypto/crypto.cpp#L481-L498

jtgrassie
  • 19,601
  • 4
  • 17
  • 54