Created
December 7, 2023 14:08
-
-
Save vmx/37e724c71fba9e40ee65bb89a8c8f0a6 to your computer and use it in GitHub Desktop.
Filecoin replica encoding in Go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"io/ioutil" | |
"log" | |
"os" | |
"github.com/consensys/gnark-crypto/ecc/bls12-381/fr" | |
) | |
func encode(valueBytes, keyBytes [32]byte) [32]byte { | |
key, err := fr.LittleEndian.Element(&keyBytes); | |
if err != nil { | |
log.Fatalf("Failed to create element: %v", err) | |
} | |
value, err := fr.LittleEndian.Element(&valueBytes); | |
if err != nil { | |
log.Fatalf("Failed to create element: %v", err) | |
} | |
// Do the actual encoding. | |
key.Add(&key, &value) | |
result := key.Bytes() | |
// Reverse the bytes to match the little-endian encoding that are used | |
// in Filecoin. | |
for i, j := 0, 31; i < j; i, j = i+1, j-1 { | |
result[i], result[j] = result[j], result[i] | |
} | |
return result | |
} | |
func main() { | |
// Check command-line arguments | |
if len(os.Args) != 4 { | |
log.Fatal("Usage: go run main.go <keyFilePath> <valueFilePath> <outputFilePath>") | |
} | |
// Read keyBytes from file | |
valueFilePath := os.Args[1] | |
valueBytes, err := ioutil.ReadFile(valueFilePath) | |
if err != nil { | |
log.Fatalf("Failed to read value file: %v", err) | |
} | |
// Read valueBytes from file | |
keyFilePath := os.Args[2] | |
keyBytes, err := ioutil.ReadFile(keyFilePath) | |
if err != nil { | |
log.Fatalf("Failed to read key file: %v", err) | |
} | |
// Check if input files have the same size and are divisible by 32 bytes | |
if len(valueBytes) != len(keyBytes) || len(valueBytes)%32 != 0 { | |
log.Fatal("Input file sizes are not compatible") | |
} | |
// Calculate the number of 32-byte chunks | |
numChunks := len(valueBytes) / 32 | |
// Create a slice to store the result | |
resultBytes := make([]byte, 0, numChunks*32) | |
// Process each 32-byte chunk | |
for i := 0; i < numChunks; i++ { | |
start := i * 32 | |
end := start + 32 | |
// Extract the value and key slices | |
valueChunk := valueBytes[start:end] | |
keyChunk := keyBytes[start:end] | |
// Perform encoding | |
chunkResult := encode([32]byte(valueChunk), [32]byte(keyChunk)) | |
// Append the encoded chunk to the result | |
resultBytes = append(resultBytes, chunkResult[:]...) | |
} | |
// Write result to file | |
outputFilePath := os.Args[3] | |
err = ioutil.WriteFile(outputFilePath, resultBytes, 0644) | |
if err != nil { | |
log.Fatalf("Failed to write result to file: %v", err) | |
} | |
fmt.Println("Encoding result written to file:", outputFilePath) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment