Fix ecrecover, pad ripemd result and use sha256 vs keccak256
This commit is contained in:
parent
6cd1964238
commit
67df44e917
|
@ -4,7 +4,7 @@ import
|
||||||
message, math, nimcrypto, bncurve/[fields, groups]
|
message, math, nimcrypto, bncurve/[fields, groups]
|
||||||
|
|
||||||
type
|
type
|
||||||
PrecompileAddresses = enum
|
PrecompileAddresses* = enum
|
||||||
paEcRecover = 1,
|
paEcRecover = 1,
|
||||||
paSha256,
|
paSha256,
|
||||||
paRipeMd160,
|
paRipeMd160,
|
||||||
|
@ -15,12 +15,24 @@ type
|
||||||
paEcMul,
|
paEcMul,
|
||||||
paPairing = 8
|
paPairing = 8
|
||||||
|
|
||||||
proc getSignature*(computation: BaseComputation): Signature =
|
proc getSignature*(computation: BaseComputation): (array[32, byte], Signature) =
|
||||||
var bytes: array[128, byte]
|
# input is Hash, V, R, S
|
||||||
bytes[0..31] = computation.msg.data[32..63] # V
|
template data: untyped = computation.msg.data
|
||||||
bytes[32..63] = computation.msg.data[64..95] # R
|
var bytes: array[65, byte]
|
||||||
bytes[64..63] = computation.msg.data[96..128] # S
|
let maxPos = min(data.high, 127)
|
||||||
result = initSignature(bytes) # Can raise
|
if maxPos >= 32:
|
||||||
|
# extract message hash
|
||||||
|
result[0][0..31] = data[0..31]
|
||||||
|
if maxPos >= 127:
|
||||||
|
# Copy message data to buffer
|
||||||
|
# Note that we need to rearrange to R, S, V
|
||||||
|
bytes[0..63] = data[64..127]
|
||||||
|
let v = data[63] # TODO: Endian
|
||||||
|
assert v.int in 27..28
|
||||||
|
bytes[64] = v - 27
|
||||||
|
|
||||||
|
if recoverSignature(bytes, result[1]) != EthKeysStatus.Success:
|
||||||
|
raise newException(ValidationError, "Could not recover signature computation")
|
||||||
|
|
||||||
proc getPoint[T: G1|G2](t: typedesc[T], data: openarray[byte]): Point[T] =
|
proc getPoint[T: G1|G2](t: typedesc[T], data: openarray[byte]): Point[T] =
|
||||||
when T is G1:
|
when T is G1:
|
||||||
|
@ -50,17 +62,15 @@ proc ecRecover*(computation: var BaseComputation) =
|
||||||
GasECRecover,
|
GasECRecover,
|
||||||
reason="ECRecover Precompile")
|
reason="ECRecover Precompile")
|
||||||
|
|
||||||
# TODO: Check endian
|
|
||||||
# Assumes V is 27 or 28
|
|
||||||
var
|
var
|
||||||
sig = computation.getSignature()
|
(msgHash, sig) = computation.getSignature()
|
||||||
pubKey: PublicKey
|
pubKey: PublicKey
|
||||||
let msgHash = computation.msg.data[0..31]
|
|
||||||
|
|
||||||
if sig.recoverSignatureKey(msgHash, pubKey) != EthKeysStatus.Success:
|
if sig.recoverSignatureKey(msgHash, pubKey) != EthKeysStatus.Success:
|
||||||
raise newException(ValidationError, "Could not derive public key from computation")
|
raise newException(ValidationError, "Could not derive public key from computation")
|
||||||
|
|
||||||
computation.rawOutput = @(pubKey.toCanonicalAddress())
|
computation.rawOutput.setLen(32)
|
||||||
|
computation.rawOutput[12..31] = pubKey.toCanonicalAddress()
|
||||||
debug "ECRecover precompile", derivedKey = pubKey.toCanonicalAddress()
|
debug "ECRecover precompile", derivedKey = pubKey.toCanonicalAddress()
|
||||||
|
|
||||||
proc sha256*(computation: var BaseComputation) =
|
proc sha256*(computation: var BaseComputation) =
|
||||||
|
@ -69,17 +79,18 @@ proc sha256*(computation: var BaseComputation) =
|
||||||
gasFee = GasSHA256 + wordCount * GasSHA256Word
|
gasFee = GasSHA256 + wordCount * GasSHA256Word
|
||||||
|
|
||||||
computation.gasMeter.consumeGas(gasFee, reason="SHA256 Precompile")
|
computation.gasMeter.consumeGas(gasFee, reason="SHA256 Precompile")
|
||||||
computation.rawOutput = @(keccak_256.digest(computation.msg.data).data)
|
computation.rawOutput = @(nimcrypto.sha_256.digest(computation.msg.data).data)
|
||||||
debug "SHA256 precompile", output = computation.rawOutput
|
debug "SHA256 precompile", output = computation.rawOutput.toHex
|
||||||
|
|
||||||
proc ripemd160(computation: var BaseComputation) =
|
proc ripemd160*(computation: var BaseComputation) =
|
||||||
let
|
let
|
||||||
wordCount = computation.msg.data.len div 32
|
wordCount = computation.msg.data.len div 32
|
||||||
gasFee = GasRIPEMD160 + wordCount * GasRIPEMD160Word
|
gasFee = GasRIPEMD160 + wordCount * GasRIPEMD160Word
|
||||||
|
|
||||||
computation.gasMeter.consumeGas(gasFee, reason="RIPEMD160 Precompile")
|
computation.gasMeter.consumeGas(gasFee, reason="RIPEMD160 Precompile")
|
||||||
computation.rawOutput = @(nimcrypto.ripemd160.digest(computation.msg.data).data)
|
computation.rawOutput.setLen(32)
|
||||||
debug "RIPEMD160 precompile", output = computation.rawOutput
|
computation.rawOutput[12..31] = @(nimcrypto.ripemd160.digest(computation.msg.data).data)
|
||||||
|
debug "RIPEMD160 precompile", output = computation.rawOutput.toHex
|
||||||
|
|
||||||
proc identity*(computation: var BaseComputation) =
|
proc identity*(computation: var BaseComputation) =
|
||||||
let
|
let
|
||||||
|
@ -88,9 +99,9 @@ proc identity*(computation: var BaseComputation) =
|
||||||
|
|
||||||
computation.gasMeter.consumeGas(gasFee, reason="Identity Precompile")
|
computation.gasMeter.consumeGas(gasFee, reason="Identity Precompile")
|
||||||
computation.rawOutput = computation.msg.data
|
computation.rawOutput = computation.msg.data
|
||||||
debug "Identity precompile", output = computation.rawOutput
|
debug "Identity precompile", output = computation.rawOutput.toHex
|
||||||
|
|
||||||
proc modExp(computation: var BaseComputation) =
|
proc modExp*(computation: var BaseComputation) =
|
||||||
## Modular exponentiation precompiled contract
|
## Modular exponentiation precompiled contract
|
||||||
# Parsing the data
|
# Parsing the data
|
||||||
template rawMsg: untyped {.dirty.} =
|
template rawMsg: untyped {.dirty.} =
|
||||||
|
|
Loading…
Reference in New Issue