Skip to content

Commit

Permalink
core/vm: review changes: mod-pad, contract addrs, bn256-arith, f&r
Browse files Browse the repository at this point in the history
* Right pad return data of  native contract big mod exp to same length
as the modulo input
* Spelling
* Make LOG{n} write operations so the throw during readonly
* Right pad native contracts input with zeros
* Fixed bn256{add, mul}
  • Loading branch information
obscuren committed Jun 4, 2017
1 parent 917be30 commit f90b410
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 63 deletions.
47 changes: 22 additions & 25 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ var PrecompiledContractsMetropolis = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{4}): &dataCopy{},
common.BytesToAddress([]byte{5}): &bigModexp{},
common.BytesToAddress([]byte{6}): &bn256Add{},
common.BytesToAddress([]byte{6}): &bn256ScalarMul{},
common.BytesToAddress([]byte{7}): &bn256ScalarMul{},
common.BytesToAddress([]byte{8}): &pairing{},
}

Expand Down Expand Up @@ -206,7 +206,7 @@ func (c *bigModexp) Run(input []byte) ([]byte, error) {
}
mod := new(big.Int).SetBytes(input[:modLen])

return base.Exp(base, exp, mod).Bytes(), nil
return common.LeftPadBytes(base.Exp(base, exp, mod).Bytes(), len(input[:modLen])), nil
}

type bn256Add struct{}
Expand All @@ -220,21 +220,28 @@ func (c *bn256Add) RequiredGas(input []byte) uint64 {
}

func (c *bn256Add) Run(in []byte) ([]byte, error) {
if len(in) != 96 {
return nil, errBadPrecompileInput
in = common.RightPadBytes(in, 128)

x, onCurve := new(bn256.G1).Unmarshal(in[:64])
if !onCurve {
return nil, errNotOnCurve
}
gx, gy, _, _ := x.CurvePoints()
if gx.Cmp(bn256.P) >= 0 || gy.Cmp(bn256.P) >= 0 {
return nil, errInvalidCurvePoint
}

g1, onCurve := new(bn256.G1).Unmarshal(in[:64])
y, onCurve := new(bn256.G1).Unmarshal(in[:64])
if !onCurve {
return nil, errNotOnCurve
}
x, y, _, _ := g1.CurvePoints()
if x.Cmp(bn256.P) >= 0 || y.Cmp(bn256.P) >= 0 {
gx, gy, _, _ = x.CurvePoints()
if gx.Cmp(bn256.P) >= 0 || gy.Cmp(bn256.P) >= 0 {
return nil, errInvalidCurvePoint
}
g1.ScalarMult(g1, new(big.Int).SetBytes(in[64:]))
x.Add(x, y)

return g1.Marshal(), nil
return x.Marshal(), nil
}

type bn256ScalarMul struct{}
Expand All @@ -248,29 +255,19 @@ func (c *bn256ScalarMul) RequiredGas(input []byte) uint64 {
}

func (c *bn256ScalarMul) Run(in []byte) ([]byte, error) {
if len(in) != 128 {
return nil, errBadPrecompileInput
}
in = common.RightPadBytes(in, 96)

x, onCurve := new(bn256.G1).Unmarshal(in[:64])
if !onCurve {
return nil, errNotOnCurve
}
gx, gy, _, _ := x.CurvePoints()
if gx.Cmp(bn256.P) >= 0 || gy.Cmp(bn256.P) >= 0 {
return nil, errInvalidCurvePoint
}

y, onCurve := new(bn256.G1).Unmarshal(in[:64])
g1, onCurve := new(bn256.G1).Unmarshal(in[:64])
if !onCurve {
return nil, errNotOnCurve
}
gx, gy, _, _ = x.CurvePoints()
if gx.Cmp(bn256.P) >= 0 || gy.Cmp(bn256.P) >= 0 {
x, y, _, _ := g1.CurvePoints()
if x.Cmp(bn256.P) >= 0 || y.Cmp(bn256.P) >= 0 {
return nil, errInvalidCurvePoint
}
g1.ScalarMult(g1, new(big.Int).SetBytes(in[64:96]))

return x.Add(x, y).Marshal(), nil
return g1.Marshal(), nil
}

// pairing implements a pairing pre-compile for the bn256 curve
Expand Down
6 changes: 3 additions & 3 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ type EVM struct {
abort int32
}

// NewEVM retutrns a new EVM evmironment. The returned EVM is not thread safe
// and should only ever be used *once*.
// NewEVM retutrns a new EVM . The returned EVM is not thread safe and should
// only ever be used *once*.
func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM {
evm := &EVM{
Context: ctx,
Expand Down Expand Up @@ -153,7 +153,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
}

// initialise a new contract and set the code that is to be used by the
// E The contract is a scoped evmironment for this execution context
// EVM. The contract is a scoped evmironment for this execution context
// only.
contract := NewContract(caller, to, new(big.Int), gas)
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr))
Expand Down
44 changes: 9 additions & 35 deletions core/vm/jump_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,43 +56,12 @@ type operation struct {
}

var (
frontierInstructionSet = NewFrontierInstructionSet()
homesteadInstructionSet = NewHomesteadInstructionSet()
metropolisInstructionSet = NewMetropolisInstructionSet()
frontierInstructionSet = NewFrontierInstructionSet()
homesteadInstructionSet = NewHomesteadInstructionSet()
)

func NewMetropolisInstructionSet() [256]operation {
instructionSet := NewHomesteadInstructionSet()
instructionSet[STATIC_CALL] = operation{
execute: opStaticCall,
gasCost: gasStaticCall,
validateStack: makeStackFunc(6, 1),
memorySize: memoryStaticCall,
valid: true,
}
instructionSet[REVERT] = operation{
execute: opRevert,
gasCost: constGasFunc(GasFastestStep),
validateStack: makeStackFunc(2, 0),
valid: true,
reverts: true,
}
instructionSet[RETURNDATASIZE] = operation{
execute: opReturnDataSize,
gasCost: constGasFunc(0), // TODO
validateStack: makeStackFunc(0, 1),
valid: true,
}
instructionSet[RETURNDATACOPY] = operation{
execute: opReturnDataCopy,
gasCost: gasReturnDataCopy,
validateStack: makeStackFunc(3, 0),
memorySize: memoryReturnDataCopy,
valid: true,
}
return instructionSet
}

// NewHomesteadInstructionSet returns the frontier and homestead
// instructions that can be executed during the homestead phase.
func NewHomesteadInstructionSet() [256]operation {
instructionSet := NewFrontierInstructionSet()
instructionSet[DELEGATECALL] = operation{
Expand Down Expand Up @@ -841,34 +810,39 @@ func NewFrontierInstructionSet() [256]operation {
validateStack: makeStackFunc(2, 0),
memorySize: memoryLog,
valid: true,
writes: true,
},
LOG1: {
execute: makeLog(1),
gasCost: makeGasLog(1),
validateStack: makeStackFunc(3, 0),
memorySize: memoryLog,
valid: true,
writes: true,
},
LOG2: {
execute: makeLog(2),
gasCost: makeGasLog(2),
validateStack: makeStackFunc(4, 0),
memorySize: memoryLog,
valid: true,
writes: true,
},
LOG3: {
execute: makeLog(3),
gasCost: makeGasLog(3),
validateStack: makeStackFunc(5, 0),
memorySize: memoryLog,
valid: true,
writes: true,
},
LOG4: {
execute: makeLog(4),
gasCost: makeGasLog(4),
validateStack: makeStackFunc(6, 0),
memorySize: memoryLog,
valid: true,
writes: true,
},
CREATE: {
execute: opCreate,
Expand Down

0 comments on commit f90b410

Please sign in to comment.