mirror of
https://github.com/QuilibriumNetwork/ceremonyclient.git
synced 2026-02-21 10:27:26 +08:00
* v2.1.0 [omit consensus and adjacent] - this commit will be amended with the full release after the file copy is complete * 2.1.0 main node rollup
176 lines
3.9 KiB
Go
176 lines
3.9 KiB
Go
//
|
|
// Copyright (c) 2019-2024 Markku Rossi
|
|
//
|
|
// All rights reserved.
|
|
//
|
|
|
|
package bedlam
|
|
|
|
import (
|
|
"fmt"
|
|
"math/big"
|
|
"reflect"
|
|
"unicode"
|
|
|
|
"source.quilibrium.com/quilibrium/monorepo/bedlam/circuit"
|
|
"source.quilibrium.com/quilibrium/monorepo/bedlam/types"
|
|
)
|
|
|
|
// PrintResults prints the result values.
|
|
func PrintResults(results []*big.Int, outputs circuit.IO) {
|
|
for idx, value := range Results(results, outputs) {
|
|
fmt.Printf("Result[%d]: ", idx)
|
|
switch v := value.(type) {
|
|
case []byte:
|
|
fmt.Printf("%x\n", v)
|
|
default:
|
|
fmt.Printf("%v\n", v)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Results return the result values as an array of Go values.
|
|
func Results(results []*big.Int, outputs circuit.IO) []interface{} {
|
|
var ret []interface{}
|
|
|
|
for idx, result := range results {
|
|
var r interface{}
|
|
if outputs == nil {
|
|
r = Result(result, circuit.IOArg{
|
|
Type: types.Info{
|
|
Type: types.TUint,
|
|
IsConcrete: true,
|
|
Bits: 1024, // Anything >64 returns big.Int
|
|
},
|
|
})
|
|
} else {
|
|
r = Result(result, outputs[idx])
|
|
}
|
|
ret = append(ret, r)
|
|
}
|
|
return ret
|
|
}
|
|
|
|
// Result converts the result to Go value.
|
|
func Result(result *big.Int, output circuit.IOArg) interface{} {
|
|
switch output.Type.Type {
|
|
case types.TString:
|
|
mask := big.NewInt(0xff)
|
|
|
|
var str string
|
|
for i := 0; i < int(output.Type.Bits)/8; i++ {
|
|
tmp := new(big.Int).Rsh(result, uint(i*8))
|
|
r := rune(tmp.And(tmp, mask).Uint64())
|
|
if unicode.IsPrint(r) {
|
|
str += string(r)
|
|
} else {
|
|
str += fmt.Sprintf("\\u%04x", r)
|
|
}
|
|
}
|
|
return str
|
|
|
|
case types.TUint:
|
|
if output.Type.Bits <= 8 {
|
|
return uint8(result.Uint64())
|
|
} else if output.Type.Bits <= 16 {
|
|
return uint16(result.Uint64())
|
|
} else if output.Type.Bits <= 32 {
|
|
return uint32(result.Uint64())
|
|
} else if output.Type.Bits <= 64 {
|
|
return result.Uint64()
|
|
} else {
|
|
return result
|
|
}
|
|
|
|
case types.TInt:
|
|
bits := int(output.Type.Bits)
|
|
if result.Bit(bits-1) == 1 {
|
|
// Negative number.
|
|
tmp := new(big.Int)
|
|
tmp.SetBit(tmp, bits, 1)
|
|
result.Sub(tmp, result)
|
|
result.Neg(result)
|
|
}
|
|
if output.Type.Bits <= 8 {
|
|
return int8(result.Int64())
|
|
} else if output.Type.Bits <= 16 {
|
|
return int16(result.Int64())
|
|
} else if output.Type.Bits <= 32 {
|
|
return int32(result.Int64())
|
|
} else if output.Type.Bits <= 64 {
|
|
return result.Int64()
|
|
} else {
|
|
return result
|
|
}
|
|
|
|
case types.TBool:
|
|
return result.Uint64() != 0
|
|
|
|
case types.TArray, types.TSlice:
|
|
count := int(output.Type.ArraySize)
|
|
elSize := int(output.Type.ElementType.Bits)
|
|
|
|
mask := new(big.Int)
|
|
for i := 0; i < elSize; i++ {
|
|
mask.SetBit(mask, i, 1)
|
|
}
|
|
|
|
var slice reflect.Value
|
|
var elementType reflect.Type
|
|
|
|
switch output.Type.ElementType.Type {
|
|
case types.TString:
|
|
elementType = reflect.TypeOf("")
|
|
|
|
case types.TUint:
|
|
if elSize <= 8 {
|
|
elementType = reflect.TypeOf(uint8(0))
|
|
} else if elSize <= 16 {
|
|
elementType = reflect.TypeOf(uint16(0))
|
|
} else if elSize <= 32 {
|
|
elementType = reflect.TypeOf(uint32(0))
|
|
} else if elSize <= 64 {
|
|
elementType = reflect.TypeOf(uint64(0))
|
|
} else {
|
|
elementType = reflect.TypeOf((*big.Int)(nil))
|
|
}
|
|
|
|
case types.TInt:
|
|
if elSize <= 8 {
|
|
elementType = reflect.TypeOf(int8(0))
|
|
} else if elSize <= 16 {
|
|
elementType = reflect.TypeOf(int16(0))
|
|
} else if elSize <= 32 {
|
|
elementType = reflect.TypeOf(int32(0))
|
|
} else if elSize <= 64 {
|
|
elementType = reflect.TypeOf(int64(0))
|
|
} else {
|
|
elementType = reflect.TypeOf((*big.Int)(nil))
|
|
}
|
|
|
|
case types.TBool:
|
|
elementType = reflect.TypeOf(true)
|
|
|
|
default:
|
|
elementType = reflect.TypeOf(nil)
|
|
}
|
|
|
|
slice = reflect.MakeSlice(reflect.SliceOf(elementType), 0, count)
|
|
|
|
for i := 0; i < count; i++ {
|
|
r := new(big.Int).Rsh(result, uint(i*elSize))
|
|
r = r.And(r, mask)
|
|
|
|
v := reflect.ValueOf(Result(r, circuit.IOArg{
|
|
Type: *output.Type.ElementType,
|
|
}))
|
|
|
|
slice = reflect.Append(slice, v)
|
|
}
|
|
return slice.Interface()
|
|
|
|
default:
|
|
return fmt.Sprintf("%v (%s)", result, output.Type)
|
|
}
|
|
}
|