Skip to content

Commit

Permalink
typo
Browse files Browse the repository at this point in the history
  • Loading branch information
rianhughes committed Oct 3, 2023
1 parent a381df5 commit d6fe349
Showing 1 changed file with 173 additions and 0 deletions.
173 changes: 173 additions & 0 deletions utils/keccak.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package utils

import (
"bytes"
"encoding/hex"
"fmt"
"hash"
"math/big"
"strings"

"github.com/NethermindEth/juno/core/felt"
"golang.org/x/crypto/sha3"
)

// KeccakState wraps sha3.state. In addition to the usual hash methods, it also supports
// Read to get a variable amount of data from the hash state. Read is faster than Sum
// because it doesn't copy the internal state, but also modifies the internal state.
type KeccakState interface {
hash.Hash
Read([]byte) (int, error)
}

// Convert utf8 string to big int
func UTF8StrToBig(str string) *big.Int {
hexStr := hex.EncodeToString([]byte(str))
b, _ := new(big.Int).SetString(hexStr, 16)

return b
}

// convert decimal string to big int
func StrToBig(str string) *big.Int {
b, _ := new(big.Int).SetString(str, 10)

return b
}

// convert hex string to Starknet 'short string'
func HexToShortStr(hexStr string) string {
numStr := strings.Replace(hexStr, "0x", "", -1)
hb, _ := new(big.Int).SetString(numStr, 16)

return string(hb.Bytes())
}

// trim "0x" prefix(if exists) and converts hexidecimal string to big int
func HexToBN(hexString string) *big.Int {
numStr := strings.Replace(hexString, "0x", "", -1)

n, _ := new(big.Int).SetString(numStr, 16)
return n
}

// trim "0x" prefix(if exists) and converts hexidecimal string to byte slice
func HexToBytes(hexString string) ([]byte, error) {
numStr := strings.Replace(hexString, "0x", "", -1)
if (len(numStr) % 2) != 0 {
numStr = fmt.Sprintf("%s%s", "0", numStr)
}

return hex.DecodeString(numStr)
}

func BytesToBig(bytes []byte) *big.Int {
return new(big.Int).SetBytes(bytes)
}

// convert big int to hexidecimal string
func BigToHex(in *big.Int) string {
return fmt.Sprintf("0x%x", in)
}

// todo(): this is used by the signer. Should it return a felt?
func GetSelectorFromName(funcName string) *big.Int {
kec := Keccak256([]byte(funcName))

maskedKec := MaskBits(250, 8, kec)

return new(big.Int).SetBytes(maskedKec)
}

func GetSelectorFromNameFelt(funcName string) *felt.Felt {
kec := Keccak256([]byte(funcName))

maskedKec := MaskBits(250, 8, kec)

return new(felt.Felt).SetBytes(maskedKec)
}

// Keccak256 calculates and returns the Keccak256 hash of the input data.
// (ref: https://github.com/ethereum/go-ethereum/blob/master/crypto/crypto.go)
func Keccak256(data ...[]byte) []byte {
b := make([]byte, 32)
d := NewKeccakState()
for _, b := range data {
d.Write(b)
}
d.Read(b)
return b
}

// NewKeccakState creates a new KeccakState
// (ref: https://github.com/ethereum/go-ethereum/blob/master/crypto/crypto.go)
func NewKeccakState() KeccakState {
return sha3.NewLegacyKeccak256().(KeccakState)
}

// mask excess bits
func MaskBits(mask, wordSize int, slice []byte) (ret []byte) {
excess := len(slice)*wordSize - mask
for _, by := range slice {
if excess > 0 {
if excess > wordSize {
excess = excess - wordSize
continue
}
by <<= excess
by >>= excess
excess = 0
}
ret = append(ret, by)
}
return ret
}

// compute the keccack fact given the program hash and outputs
func ComputeFact(programHash *big.Int, programOutputs []*big.Int) *big.Int {
var progOutBuf []byte
for _, programOutput := range programOutputs {
inBuf := FmtKecBytes(programOutput, 32)
progOutBuf = append(progOutBuf[:], inBuf...)
}

kecBuf := FmtKecBytes(programHash, 32)
kecBuf = append(kecBuf[:], Keccak256(progOutBuf)...)

return new(big.Int).SetBytes(Keccak256(kecBuf))
}

// split a fact into two felts
func SplitFactStr(fact string) (fact_low, fact_high string) {
factBN := HexToBN(fact)
factBytes := factBN.Bytes()
lpadfactBytes := bytes.Repeat([]byte{0x00}, 32-len(factBytes))
factBytes = append(lpadfactBytes, factBytes...)
low := BytesToBig(factBytes[16:])
high := BytesToBig(factBytes[:16])
return BigToHex(low), BigToHex(high)
}

// format the bytes in Keccak hash
func FmtKecBytes(in *big.Int, rolen int) (buf []byte) {
buf = append(buf, in.Bytes()...)

// pad with zeros if too short
if len(buf) < rolen {
padded := make([]byte, rolen)
copy(padded[rolen-len(buf):], buf)

return padded
}

return buf
}

// used in string conversions when interfacing with the APIs
func SNValToBN(str string) *big.Int {
if strings.Contains(str, "0x") {
return HexToBN(str)
} else {
return StrToBig(str)
}
}

0 comments on commit d6fe349

Please sign in to comment.