-
Notifications
You must be signed in to change notification settings - Fork 504
Expand file tree
/
Copy pathcommitment.go
More file actions
65 lines (56 loc) · 1.89 KB
/
commitment.go
File metadata and controls
65 lines (56 loc) · 1.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package rsema1d
import (
"crypto/sha256"
"encoding/binary"
"github.com/celestiaorg/celestia-app/v9/pkg/rsema1d/field"
)
// deriveCoefficients generates RLC coefficients via Fiat-Shamir (internal)
func deriveCoefficients(rowRoot [32]byte, config *Config) []field.GF128 {
seed := sha256.Sum256(rowRoot[:])
numSymbols := config.RowSize / 2 // Each GF16 symbol is 2 bytes
coeffs := make([]field.GF128, numSymbols)
var input [32 + 4]byte
copy(input[:32], seed[:])
// Reuse a single SHA256 hasher with Reset() between iterations.
// This avoids re-initializing the digest state from scratch on each call
// to sha256.Sum256, saving ~12% on coefficient derivation.
h := sha256.New()
var digest [32]byte
for i := range numSymbols {
binary.LittleEndian.PutUint32(input[32:], uint32(i))
h.Reset()
h.Write(input[:])
h.Sum(digest[:0])
coeffs[i] = field.HashToGF128(digest[:])
}
return coeffs
}
// computeRLC computes random linear combination for a row (internal)
func computeRLC(row []byte, coeffs []field.GF128) field.GF128 {
result := field.Zero()
numChunks := len(row) / chunkSize
for c := range numChunks {
chunk := row[c*chunkSize : (c+1)*chunkSize]
symbols := extractSymbols(chunk)
for j, sym := range symbols {
// result += symbol * coefficient
symbolIndex := c*32 + j // Overall symbol index in the row
product := field.Mul128(sym, coeffs[symbolIndex])
result = field.Add128(result, product)
}
}
return result
}
// extractSymbols extracts GF16 symbols from Leopard-formatted chunk (internal)
// Implements Appendix A.1 from spec
func extractSymbols(chunk []byte) []field.GF16 {
if len(chunk) != chunkSize {
panic("extractSymbols requires exactly 64-byte chunk")
}
symbols := make([]field.GF16, 32)
for i := range 32 {
// Leopard format: bytes 0-31 are low bytes, 32-63 are high bytes
symbols[i] = field.GF16(chunk[32+i])<<8 | field.GF16(chunk[i])
}
return symbols
}