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...

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

| improve this answer | |
  • 1
    Thanks! It really helps!! – Mooooo Apr 15 at 14:05
  • BTW, I notice it's different between keyImage(x) in LLW_Sigs.py with keyImageV(x) in MLSAG2.py. The first one uses hashToPoint_ct and the second one uses hashToPointCN. May I know which one is right? – Mooooo Apr 15 at 14:10
  • As I just tested with monero-project/tests/crypto/test.txt I found the test data match result of using hashToPointCN. Is it true? – Mooooo Apr 15 at 14:28
  • I saw the comment. #a simple hash function I was using to test C.T. stuff #for the actual one, see the function just previous to this Thank you! – Mooooo Apr 15 at 14:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.