-
Notifications
You must be signed in to change notification settings - Fork 145
Implementation of MODPOW opcode #77
Comments
We can prefix the public key so that it is easy to choose a curve or algorithm when executing |
What about RSA? We may need to support onchain decryption too. This could also be done by modpow. |
Does onchain decryption not reveal the private key? |
It reveals, but the key is only used in a single step and dropped if this command is activated, so it does not matter being exposed anymore (at this point the users loses his bond if smart contract manages to decrypt hidden info). I agree this looks like an unusual application, but other blockchains are migrating to this model too, allowing users to implement manually their own crypto. In this sense its better to have an opcode like this than one for decryption, por example. I think that curve parameters may be put on storage, and user account could be basically : load curve data, perform point verification. |
I will try to devise an alternative without RSA (perhaps ECDH, although this will require point multiplication...), because we need to get this going asap, but community should strongly consider this modpow, perhaps as interop if more acceptable ("Neo.Crypto.ModPow" and "Neo.Crypto.ModInverse") |
Onchain decryption sounds broken to me; couldn’t the message be intercepted and an alternative one relayed to consensus nodes first? |
I think that the idea is that we really want to decrypt it, @jsolman, no matter who sends the invoke. |
One example for application is the AnonyTree on SciChain. For now, it's beggining as a part of DRandLib, but soon will be moved to SciChain repo: https://github.com/igormcoelho/DRandLib |
@erikzhang just to exemplify a simple application that uses this (considering ECDSA). |
As a syscall it couldn't damage to anyone, so is fine for me. |
ahueahuehaea, I did not remember about that Milestone. @shargon, let's do it, I remember that this would proportionate very good applications! |
This should be an EXTENSION to neovm...not in blockchain itself.. lets see ;) |
@igormcoelho what are next steps? Is this going to be added to this repository? |
I found that the |
Indeed the first multiplication can be done separately.. no need to require 4 params. |
Does it have other scenarios besides on-chain decryption? |
Not just decryption, which is strange (but useful for commit-reveal schemes), as the most amazing use-case is the ability of a user provide its own cryptography. To fulfill that in a practical manner (not being costly), and to avoid stateless situation during verifications (not depend on storage), I would suggest on Neo project to have some ability to store global constants. Maybe put a very high GAS cost on that (on Put, and very cheap on Get), but we could deploy constants for elliptic curve parameters, and just load them on verification, without breaking stateless invariants (as they will not change). The interesting thing is that, with constants, we cannot break stateless invariants, because if we try to read them before deploying, verification would fail (so it couldn't be put on blocks or mempool). And after it's on block, any constant it requires must be kept forever (so it will never break any state invariant). So I propose to have this MODPOW here, together with "Neo.Const.Put" (expensive on GAS) and "Neo.Const.Get" (cheap on GAS), on the Neo core project (see neo-project/neo#2040) |
We propose the implementation of a modular exponentiation opcode for NeoVM.
The reason is that some dapp may require implementing RSA cryptography (which is our case on SciChain) and this is also fundamental for other number theory implementations, including zero-knowledge.
Currently, BigIntegers are limited to 32-bytes, but modular exponentiation may require a bit more than this, so one solution is to threat inputs and outputs as bytearrays (currently limited to 1024 bytes).
The initial proposal for MODPOW is to calculate:
x = mul*base^{exponent} mod p
Values
base
,exponent
,p
andmul
could be possibly passed in two options: (i) as an array [base
,exponent
,p
,mul
]; (ii) four independent elements taken from stack.I prefer option (i), and it would be nice to allow
mul
to be optional and naturally assume value1
.If
exponent
is negative, it would be nice to have the calculation of the modular inverse.All elements would be converted to BigInteger for the calculation (from bytearray), and the final result would be returned as bytearray (thus, not strictly violating BigInteger limits on NeoVM).
On C#, BigInteger ModPow could do the exponentiation and ModularInverse function could do the inverse.
The
mul
could be eliminated by replacing it by two quadratic exponents with a subtraction and division (as Ethereum did on EIP 198), however that would require us to allow subtraction and division of huge numbers too (over BigInteger limit). We need to see if thismul
already solves most general problems involving modular exp applications.To establish a fair price for the operation it would be nice to have some time experiments and see the actual impact, but it won't be more costly than VERIFY itself.
MODPOW opcode could possibly have opcode
0xb0
, although this is a discussion for later.MODPOW could be acompanied later with another interesting operation which is scalar multiplication for elliptic curve points (possibly opcode
0xb1
). This would allow us to implementCHECKSIG
,CHECKMULTISIG
andVERIFY
directly on NeoVM, allowing users to switch cryptographic curves if they desire.It would be a pleasure to have some voices of the crypto specialists in the community, in order to ensure a nice proposal (we can also create a NEP for this, if necessary).
The text was updated successfully, but these errors were encountered: