-
-
Notifications
You must be signed in to change notification settings - Fork 205
xmr: monero crypto functions, tests #169
Conversation
25f1c6f
to
fa8332f
Compare
9c1dd96 - moved stuff not related to monero into:
|
9c1dd96
to
8afd73a
Compare
I see. Just a quick question:
Notes to myself:
|
Unsure for now, I might move them to test-ge25519 and test-modm
I don't plan to change this |
I suggest
What do you think, @prusnak? There are a lot of unused functions in |
The following issue is related to the trezor-core monero pull request. Perhaps, it'll be a subject of a long-term plan with trezor-crypto. I don't like the interface between trezor-crypto and trezor-core. It doesn't properly encapsulate cryptographic primitives. For example:
|
Some functions are already used internally in the trezor-crypto, e.g., The functions you list are not used at the moment in trezor-core, may be later used when implementing multisigs / bulletproofs. |
@onvej-sl I don't share the opinion that having range sig being in trezor-crypto and MLSAG in trezor-core is some kind of a problem. Here is my reasoning: Range signatures Range signature is a well-contained problem with no allocations needed, simple API. For memory and timing reasons its implemented directly in trezor-crypto (as it brings real benefit to the user). On the other hand, MLASG and other ring signatures are built from building blocks in python for easier development, code readability, maintenance and debugging. Porting to C is not that straightforward and I really don't see any benefit here. The memory and CPU is not the problem as in the case of range signatures so I think it is fine to have it in Python. Porting to C would also increase complexity of trezor-crypto and could lead to bugs. Using small and easily auditable & testable building blocks, such as Having access to low-level features also speeds up development of new features, such as multisigs / bulletproofs. And frankly I don't see why trezor-core should not have access to crypto primitives such as |
After some time, when Monero code in trezor-core stabilizes, proves over time and new features are added the trezor-crypto <-> trezor-core probably changes but I don't think this is the first phase stuff. MLSAG may need to be slightly changed when implementing multisigs (I made some preparations already but we will see after this phase starts) so I think it is definitelly better to have it in Python for now. |
I was also looking into Bulletproofs for a while and due to large memory allocations I will implement it in Python, as a prototype. As I will need to dynamically allocate large key vectors and |
Because it's difficult to develop and maintain such a low-level code. It requires trezor-core developers to understand how ed25519-donna works. Which isn't easy since it uses several coordinates formates, reduced and fully reduced form of numbers, consttime and vartime functions. I see you prefer trezor-crypto consists only of those functions which are CPU or memory intensive and/or easy to implement in C, which I partially agree with. But I'd rather trezor-crypto be a cryptographic library with a well-defined interface. |
I see. This is one of the reasons why the API I export from the trezor-crypto abstracts from the point coordinate representation. In the API there is only one form of the point representation - Extended Edwards API: Eg. The work with scalars is even simpler as those are just simple numbers mod curve order. In the API design, I tried to avoid pitfalls like partially reduced points and different point formats. I also assumed that if somebody is going to change MLSAG code (which uses ge25519 primitives) has some minimal background on elliptic curves. |
Just a side note: I think we're touching an issue of trezor-crypto becoming a library having two goals. First it is a cryptographic library, but second it is also becoming a place of all performance sensitive code. It's something we were discussing internally briefly and I think it is on the long term roadmap. The ideal state IMHO is to have a cryptographic library (trezor-crypto) and then a simple way how to incorporate performance sensitive C code into trezor-core. Each trezor-core app would have some C code directly in the trezor-core app folder, which would also significantly increase its readability. That being said, I think it's beyond the scope of this issue and is something we should tackle later on. |
What about |
Point-related functions, (such as point addition, scalar multiplication) in trezor-core should return already normalized points (z=1). If the norming is to be left out, the operations could not be chained arbitrarily as the result is invalid. UPDATE: |
Note: Point normalization operation is typically performed when compressing coordinate point representation to the 32 B array as On the other hand, the original Monero C++ code typically operates on 32 B byte arrays (points, scalars) by decompressing and compressing it after each result so they are doing normalization in each step, basically. There are some optimized chunks in the Monero C++ code, e.g., range sig verification, which improves blockchain scanning (still takes 3 days to verify the blockchain). Optimized chunks are using different point representations to avoid redundant normalizations but in general cases, it is not a performance issue for the sake of correct computation, easy development and maintenance. |
I don't think they do. Try:
|
Ah I see. Normalization is performed there explicitly: void ge25519_scalarmult_base_wrapper(ge25519 *r, const bignum256modm s){
ge25519_scalarmult_base_niels(r, ge25519_niels_base_multiples, s);
ge25519_norm(r, r);
}
void ge25519_scalarmult_wrapper(ge25519 *r, const ge25519 *P, const bignum256modm a){
ge25519_scalarmult(r, P, a);
ge25519_norm(r, r);
}
So the question is:
|
Honestly, I don't know what (or when) operations do require normalised points. I'll try to figure it out. |
Hm.. It seems we could get rid of the point normalization in general. I think there is just a problem with |
So, Extended Edwards coordinates
Thus lets have:
To check if That would be:
Which should be equal as: (pls check)
Is that correct? |
OK found it. The first thing: Another thing: The problem is that
I've fixed so it returns always fully valid extended Edwards point. Because of this no normalization is required. This saves also performance as we avoid modular inversion. @prusnak @onvej-sl pls consider cherry-picking 3f4cfec commit which contains changes described in this comment, also the a6d34c9. I did also a separate PR fixing mentioned issues of |
You also need to check
It does work since the equation you are using (
Could you explain it to me? I can't see a connection between normalisation and extended coordinates. |
Aah OK then. Thanks! So I will add a check for the z coordinate.
I will double check why I assumed the ge25519_check is not working but I
think it was because of invalid T coordinate from scalarmult.
Normalization was just a workaround to get full and valid extended edwards
point. As scalarmult computed only with _partial the T coordinate was
invalid. Normalization recomputes T coordinate from X, Y, Z which are OK
for partially computed point so normalization fixed it. But it is not
needed if scalarmult returns proper full point - just one more
multiplication is needed.
|
Just to sum-up discussion with @onvej-sl:
Correct? |
Absolutely. And we decided |
Thanks! |
original PR: #162