mirror of
https://github.com/discountry/ritmex-bot.git
synced 2026-09-11 17:28:08 +00:00
feat: 添加 Lighter 适配器及相关功能,支持 trailing stops 和新的交易逻辑
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
package poseidon2_plonky2
|
||||
|
||||
import g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
|
||||
const (
|
||||
WIDTH = 12
|
||||
RATE = 8
|
||||
OUT = 4
|
||||
D = 7
|
||||
// Generated by `poseidon2_round_numbers_128`
|
||||
ROUNDS_F = 8
|
||||
ROUNDS_F_HALF = 4
|
||||
ROUNDS_P = 22
|
||||
)
|
||||
|
||||
var (
|
||||
// Generated randomly for ROUNDS_F
|
||||
EXTERNAL_CONSTANTS = [ROUNDS_F][WIDTH]g.GoldilocksField{
|
||||
{
|
||||
15492826721047263190,
|
||||
11728330187201910315,
|
||||
8836021247773420868,
|
||||
16777404051263952451,
|
||||
5510875212538051896,
|
||||
6173089941271892285,
|
||||
2927757366422211339,
|
||||
10340958981325008808,
|
||||
8541987352684552425,
|
||||
9739599543776434497,
|
||||
15073950188101532019,
|
||||
12084856431752384512,
|
||||
},
|
||||
{
|
||||
4584713381960671270,
|
||||
8807052963476652830,
|
||||
54136601502601741,
|
||||
4872702333905478703,
|
||||
5551030319979516287,
|
||||
12889366755535460989,
|
||||
16329242193178844328,
|
||||
412018088475211848,
|
||||
10505784623379650541,
|
||||
9758812378619434837,
|
||||
7421979329386275117,
|
||||
375240370024755551,
|
||||
},
|
||||
{
|
||||
3331431125640721931,
|
||||
15684937309956309981,
|
||||
578521833432107983,
|
||||
14379242000670861838,
|
||||
17922409828154900976,
|
||||
8153494278429192257,
|
||||
15904673920630731971,
|
||||
11217863998460634216,
|
||||
3301540195510742136,
|
||||
9937973023749922003,
|
||||
3059102938155026419,
|
||||
1895288289490976132,
|
||||
},
|
||||
{
|
||||
5580912693628927540,
|
||||
10064804080494788323,
|
||||
9582481583369602410,
|
||||
10186259561546797986,
|
||||
247426333829703916,
|
||||
13193193905461376067,
|
||||
6386232593701758044,
|
||||
17954717245501896472,
|
||||
1531720443376282699,
|
||||
2455761864255501970,
|
||||
11234429217864304495,
|
||||
4746959618548874102,
|
||||
},
|
||||
{
|
||||
13571697342473846203,
|
||||
17477857865056504753,
|
||||
15963032953523553760,
|
||||
16033593225279635898,
|
||||
14252634232868282405,
|
||||
8219748254835277737,
|
||||
7459165569491914711,
|
||||
15855939513193752003,
|
||||
16788866461340278896,
|
||||
7102224659693946577,
|
||||
3024718005636976471,
|
||||
13695468978618890430,
|
||||
},
|
||||
{
|
||||
8214202050877825436,
|
||||
2670727992739346204,
|
||||
16259532062589659211,
|
||||
11869922396257088411,
|
||||
3179482916972760137,
|
||||
13525476046633427808,
|
||||
3217337278042947412,
|
||||
14494689598654046340,
|
||||
15837379330312175383,
|
||||
8029037639801151344,
|
||||
2153456285263517937,
|
||||
8301106462311849241,
|
||||
},
|
||||
{
|
||||
13294194396455217955,
|
||||
17394768489610594315,
|
||||
12847609130464867455,
|
||||
14015739446356528640,
|
||||
5879251655839607853,
|
||||
9747000124977436185,
|
||||
8950393546890284269,
|
||||
10765765936405694368,
|
||||
14695323910334139959,
|
||||
16366254691123000864,
|
||||
15292774414889043182,
|
||||
10910394433429313384,
|
||||
},
|
||||
{
|
||||
17253424460214596184,
|
||||
3442854447664030446,
|
||||
3005570425335613727,
|
||||
10859158614900201063,
|
||||
9763230642109343539,
|
||||
6647722546511515039,
|
||||
909012944955815706,
|
||||
18101204076790399111,
|
||||
11588128829349125809,
|
||||
15863878496612806566,
|
||||
5201119062417750399,
|
||||
176665553780565743,
|
||||
},
|
||||
}
|
||||
|
||||
// Generated randomly for ROUNDS_P
|
||||
INTERNAL_CONSTANTS = [ROUNDS_P]g.GoldilocksField{
|
||||
11921381764981422944,
|
||||
10318423381711320787,
|
||||
8291411502347000766,
|
||||
229948027109387563,
|
||||
9152521390190983261,
|
||||
7129306032690285515,
|
||||
15395989607365232011,
|
||||
8641397269074305925,
|
||||
17256848792241043600,
|
||||
6046475228902245682,
|
||||
12041608676381094092,
|
||||
12785542378683951657,
|
||||
14546032085337914034,
|
||||
3304199118235116851,
|
||||
16499627707072547655,
|
||||
10386478025625759321,
|
||||
13475579315436919170,
|
||||
16042710511297532028,
|
||||
1411266850385657080,
|
||||
9024840976168649958,
|
||||
14047056970978379368,
|
||||
838728605080212101,
|
||||
}
|
||||
|
||||
// Taken from Plonk3 Poseidon2 implementation. https://github.com/Plonky3/Plonky3/blob/eeb4e37b20127c4daa871b2bad0df30a7c7380db/goldilocks/src/poseidon2.rs#L28
|
||||
MATRIX_DIAG_12_U64 = [WIDTH]g.GoldilocksField{
|
||||
0xc3b6c08e23ba9300,
|
||||
0xd84b5de94a324fb6,
|
||||
0x0d0c371c5b35b84f,
|
||||
0x7964f570e7188037,
|
||||
0x5daf18bbd996604b,
|
||||
0x6743bc47b9595257,
|
||||
0x5528b9362c59bb70,
|
||||
0xac45e25b7127b68b,
|
||||
0xa2077d7dfbb606b5,
|
||||
0xf3faac6faee378ae,
|
||||
0x0c6388b51545e883,
|
||||
0xd27dbb6944917b60,
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,262 @@
|
||||
package poseidon2_plonky2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"hash"
|
||||
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
gFp5 "github.com/elliottech/poseidon_crypto/field/goldilocks_quintic_extension"
|
||||
)
|
||||
|
||||
type HashOut [4]g.GoldilocksField
|
||||
type NumericalHashOut [4]uint64
|
||||
|
||||
func EmptyHashOut() HashOut {
|
||||
return HashOut{g.ZeroF(), g.ZeroF(), g.ZeroF(), g.ZeroF()}
|
||||
}
|
||||
|
||||
func (h HashOut) ToLittleEndianBytes() []byte {
|
||||
res := make([]byte, 0, 4*g.Bytes)
|
||||
for _, elem := range h {
|
||||
res = append(res, g.ToLittleEndianBytesF(elem)...)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func HashOutFromLittleEndianBytes(b []byte) (HashOut, error) {
|
||||
if len(b) != 4*g.Bytes {
|
||||
return HashOut{}, fmt.Errorf("input bytes len should be 32 but is %d", len(b))
|
||||
}
|
||||
var res HashOut
|
||||
for i := 0; i < 4; i++ {
|
||||
res[i] = g.FromCanonicalLittleEndianBytesF(b[i*g.Bytes : (i+1)*g.Bytes])
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (h HashOut) ToUint64Array() [4]uint64 {
|
||||
return [4]uint64{uint64(h[0]), uint64(h[1]), uint64(h[2]), uint64(h[3])}
|
||||
}
|
||||
|
||||
func HashOutFromUint64Array(arr [4]uint64) HashOut {
|
||||
return HashOut{g.GoldilocksField(arr[0]), g.GoldilocksField(arr[1]), g.GoldilocksField(arr[2]), g.GoldilocksField(arr[3])}
|
||||
}
|
||||
|
||||
func HashToQuinticExtension(m []g.GoldilocksField) gFp5.Element {
|
||||
res := HashNToMNoPad(m, 5)
|
||||
return gFp5.FromPlonky2GoldilocksField(res[:])
|
||||
}
|
||||
|
||||
type Poseidon2 struct{}
|
||||
|
||||
func HashNoPad(input []g.GoldilocksField) HashOut {
|
||||
return HashNToHashNoPad(input)
|
||||
}
|
||||
|
||||
func HashNToOne(input []HashOut) HashOut {
|
||||
if len(input) == 1 {
|
||||
return input[0]
|
||||
}
|
||||
|
||||
res := HashTwoToOne(input[0], input[1])
|
||||
for i := 2; i < len(input); i++ {
|
||||
res = HashTwoToOne(res, input[i])
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func HashTwoToOne(input1, input2 HashOut) HashOut {
|
||||
return HashNToHashNoPad([]g.GoldilocksField{input1[0], input1[1], input1[2], input1[3], input2[0], input2[1], input2[2], input2[3]})
|
||||
}
|
||||
|
||||
func HashNToHashNoPad(input []g.GoldilocksField) HashOut {
|
||||
res := HashNToMNoPad(input, 4)
|
||||
return HashOut{res[0], res[1], res[2], res[3]}
|
||||
}
|
||||
|
||||
func HashNToMNoPad(input []g.GoldilocksField, numOutputs int) []g.GoldilocksField {
|
||||
var perm [WIDTH]g.GoldilocksField
|
||||
for i := 0; i < len(input); i += RATE {
|
||||
for j := 0; j < RATE && i+j < len(input); j++ {
|
||||
perm[j] = input[i+j]
|
||||
}
|
||||
Permute(&perm)
|
||||
}
|
||||
|
||||
outputs := make([]g.GoldilocksField, 0, numOutputs)
|
||||
for {
|
||||
for i := 0; i < RATE; i++ {
|
||||
outputs = append(outputs, perm[i])
|
||||
if len(outputs) == numOutputs {
|
||||
return outputs
|
||||
}
|
||||
}
|
||||
Permute(&perm)
|
||||
}
|
||||
}
|
||||
|
||||
func HashNToMNoPadBytes(input []byte, numOutputs int) []g.GoldilocksField {
|
||||
if len(input)%g.Bytes != 0 {
|
||||
panic("input length should be multiple of 8")
|
||||
}
|
||||
|
||||
inputLen := len(input) / g.Bytes
|
||||
|
||||
var perm [WIDTH]g.GoldilocksField
|
||||
for i := 0; i < inputLen; i += RATE {
|
||||
for j := 0; j < RATE && i+j < inputLen; j++ {
|
||||
index := (i + j) * g.Bytes
|
||||
perm[j] = g.FromCanonicalLittleEndianBytesF(input[index : index+g.Bytes])
|
||||
}
|
||||
Permute(&perm)
|
||||
}
|
||||
|
||||
outputs := make([]g.GoldilocksField, 0, numOutputs)
|
||||
for {
|
||||
for i := 0; i < RATE; i++ {
|
||||
outputs = append(outputs, perm[i])
|
||||
if len(outputs) == numOutputs {
|
||||
return outputs
|
||||
}
|
||||
}
|
||||
Permute(&perm)
|
||||
}
|
||||
}
|
||||
|
||||
func Permute(input *[WIDTH]g.GoldilocksField) {
|
||||
externalLinearLayer(input)
|
||||
fullRounds(input, 0)
|
||||
partialRounds(input)
|
||||
fullRounds(input, ROUNDS_F_HALF)
|
||||
}
|
||||
|
||||
func fullRounds(state *[WIDTH]g.GoldilocksField, start int) {
|
||||
for r := start; r < start+ROUNDS_F_HALF; r++ {
|
||||
addRC(state, r)
|
||||
sbox(state)
|
||||
externalLinearLayer(state)
|
||||
}
|
||||
}
|
||||
|
||||
func partialRounds(state *[WIDTH]g.GoldilocksField) {
|
||||
for r := 0; r < ROUNDS_P; r++ {
|
||||
addRCI(state, r)
|
||||
sboxP(0, state)
|
||||
internalLinearLayer(state)
|
||||
}
|
||||
}
|
||||
|
||||
func externalLinearLayer(s *[WIDTH]g.GoldilocksField) {
|
||||
for i := 0; i < 3; i++ { // 4 size window
|
||||
var t0, t1, t2, t3, t4, t5, t6 g.GoldilocksField
|
||||
t0 = g.AddF(s[4*i], s[4*i+1]) // s0+s1
|
||||
t1 = g.AddF(s[4*i+2], s[4*i+3]) // s2+s3
|
||||
t2 = g.AddF(t0, t1) // t0+t1 = s0+s1+s2+s3
|
||||
t3 = g.AddF(t2, s[4*i+1]) // t2+s1 = s0+2s1+s2+s3
|
||||
t4 = g.AddF(t2, s[4*i+3]) // t2+s3 = s0+s1+s2+2s3
|
||||
t5 = g.DoubleF(s[4*i]) // 2s0
|
||||
t6 = g.DoubleF(s[4*i+2]) // 2s2
|
||||
s[4*i] = g.AddF(t3, t0)
|
||||
s[4*i+1] = g.AddF(t6, t3)
|
||||
s[4*i+2] = g.AddF(t1, t4)
|
||||
s[4*i+3] = g.AddF(t5, t4)
|
||||
}
|
||||
|
||||
sums := [4]g.GoldilocksField{}
|
||||
for k := 0; k < 4; k++ {
|
||||
for j := 0; j < WIDTH; j += 4 {
|
||||
sums[k] = g.AddF(sums[k], s[j+k])
|
||||
}
|
||||
}
|
||||
for i := 0; i < WIDTH; i++ {
|
||||
s[i] = g.AddF(s[i], sums[i%4])
|
||||
}
|
||||
}
|
||||
|
||||
func internalLinearLayer(state *[WIDTH]g.GoldilocksField) {
|
||||
sum := state[0]
|
||||
for i := 1; i < WIDTH; i++ {
|
||||
sum = g.AddF(sum, state[i])
|
||||
}
|
||||
for i := 0; i < WIDTH; i++ {
|
||||
state[i] = g.MulF(state[i], MATRIX_DIAG_12_U64[i])
|
||||
state[i] = g.AddF(state[i], sum)
|
||||
}
|
||||
}
|
||||
|
||||
func addRC(state *[WIDTH]g.GoldilocksField, externalRound int) {
|
||||
for i := 0; i < WIDTH; i++ {
|
||||
state[i] = g.AddF(state[i], EXTERNAL_CONSTANTS[externalRound][i])
|
||||
}
|
||||
}
|
||||
|
||||
func addRCI(state *[WIDTH]g.GoldilocksField, round int) {
|
||||
state[0] = g.AddF(state[0], INTERNAL_CONSTANTS[round])
|
||||
}
|
||||
|
||||
func sbox(state *[WIDTH]g.GoldilocksField) {
|
||||
for i := range state {
|
||||
sboxP(i, state)
|
||||
}
|
||||
}
|
||||
|
||||
func sboxP(index int, state *[WIDTH]g.GoldilocksField) {
|
||||
tmp := state[index]
|
||||
tmpSquare := g.SquareF(tmp)
|
||||
|
||||
var tmpSixth g.GoldilocksField
|
||||
tmpSixth = g.MulF(tmpSquare, tmp)
|
||||
tmpSixth = g.SquareF(tmpSixth)
|
||||
|
||||
state[index] = g.MulF(tmpSixth, tmp)
|
||||
}
|
||||
|
||||
const BlockSize = g.Bytes * WIDTH // BlockSize size that poseidon consumes
|
||||
|
||||
type digest struct {
|
||||
data []byte
|
||||
len int
|
||||
}
|
||||
|
||||
func NewPoseidon2() hash.Hash {
|
||||
d := new(digest)
|
||||
return d
|
||||
}
|
||||
|
||||
// Reset resets the Hash to its initial state.
|
||||
func (d *digest) Reset() {
|
||||
d.data = d.data[:0]
|
||||
d.len = 0
|
||||
}
|
||||
|
||||
// Get element by element.
|
||||
func (d *digest) Write(p []byte) (n int, err error) {
|
||||
d.data = append(d.data, p...)
|
||||
d.len += len(p)
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// Sum appends the current hash to b and returns the resulting slice.
|
||||
// It does not change the underlying hash state.
|
||||
func (d *digest) Sum(b []byte) []byte {
|
||||
h := HashNToMNoPadBytes(d.data, 4)
|
||||
d.Reset()
|
||||
|
||||
for _, elem := range h {
|
||||
b = append(b, g.ToLittleEndianBytesF(elem)...)
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func (d *digest) Size() int {
|
||||
return BlockSize
|
||||
}
|
||||
|
||||
// BlockSize returns the number of bytes Sum will return.
|
||||
func (d *digest) BlockSize() int {
|
||||
return BlockSize
|
||||
}
|
||||
+285
@@ -0,0 +1,285 @@
|
||||
package poseidon2_plonky2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
g "github.com/elliottech/poseidon_crypto/field/goldilocks"
|
||||
)
|
||||
|
||||
func TestPermute(t *testing.T) {
|
||||
inp := [WIDTH]g.GoldilocksField{
|
||||
5417613058500526590,
|
||||
2481548824842427254,
|
||||
6473243198879784792,
|
||||
1720313757066167274,
|
||||
2806320291675974571,
|
||||
7407976414706455446,
|
||||
1105257841424046885,
|
||||
7613435757403328049,
|
||||
3376066686066811538,
|
||||
5888575799323675710,
|
||||
6689309723188675948,
|
||||
2468250420241012720,
|
||||
}
|
||||
|
||||
Permute(&inp)
|
||||
|
||||
expected := [WIDTH]g.GoldilocksField{
|
||||
5364184781011389007,
|
||||
15309475861242939136,
|
||||
5983386513087443499,
|
||||
886942118604446276,
|
||||
14903657885227062600,
|
||||
7742650891575941298,
|
||||
1962182278500985790,
|
||||
10213480816595178755,
|
||||
3510799061817443836,
|
||||
4610029967627506430,
|
||||
7566382334276534836,
|
||||
2288460879362380348,
|
||||
}
|
||||
|
||||
for i := 0; i < WIDTH; i++ {
|
||||
if inp[i] != expected[i] {
|
||||
t.Logf("Expected: %d, got: %d\n", expected[i], inp[i])
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHashNToMNoPad(t *testing.T) {
|
||||
inp := [WIDTH]g.GoldilocksField{
|
||||
2963773914414780088,
|
||||
8389525300242074234,
|
||||
3700959901615818008,
|
||||
6116199383751757212,
|
||||
3418607418699599889,
|
||||
8793277256263635044,
|
||||
448623437464918480,
|
||||
1857310021116627925,
|
||||
6145634616307237342,
|
||||
1548353948794474539,
|
||||
2318110128254703527,
|
||||
8347759953730634762,
|
||||
}
|
||||
|
||||
res := HashNToMNoPad(inp[:], 12)
|
||||
|
||||
expected := [WIDTH]g.GoldilocksField{
|
||||
3627923032009111551,
|
||||
1460752551327577353,
|
||||
1084214837491058067,
|
||||
1841622875286057462,
|
||||
3996252440506437984,
|
||||
1276718204392552803,
|
||||
8564515621134952155,
|
||||
9252927025993202701,
|
||||
1147435538714642916,
|
||||
16407277821156164797,
|
||||
11997661877740155273,
|
||||
12485021000320141292,
|
||||
}
|
||||
|
||||
for i := 0; i < 12; i++ {
|
||||
if res[i] != expected[i] {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDigest(t *testing.T) {
|
||||
hFunc := NewPoseidon2()
|
||||
|
||||
inputs := make([][]byte, 2)
|
||||
inputs[0] = make([]byte, 8)
|
||||
inputs[0][0] = 1
|
||||
inputs[0][1] = 2
|
||||
inputs[0][2] = 3
|
||||
inputs[0][3] = 4
|
||||
inputs[0][4] = 5
|
||||
inputs[0][5] = 6
|
||||
inputs[0][6] = 7
|
||||
inputs[0][7] = 0
|
||||
inputs[1] = make([]byte, 8)
|
||||
inputs[1][0] = 7
|
||||
inputs[1][1] = 6
|
||||
inputs[1][2] = 5
|
||||
inputs[1][3] = 4
|
||||
inputs[1][4] = 3
|
||||
inputs[1][5] = 2
|
||||
inputs[1][6] = 1
|
||||
inputs[1][7] = 0
|
||||
|
||||
g1 := g.FromCanonicalLittleEndianBytesF(inputs[0]) // 289077004332300282
|
||||
g2 := g.FromCanonicalLittleEndianBytesF(inputs[1]) // 289644378102298614
|
||||
|
||||
hFunc.Write(inputs[0])
|
||||
hFunc.Write(inputs[1])
|
||||
|
||||
hash := hFunc.Sum(nil)
|
||||
|
||||
hash2Elems := HashNoPad([]g.GoldilocksField{g1, g2})
|
||||
hash2 := hash2Elems.ToLittleEndianBytes()
|
||||
|
||||
if !bytes.Equal(hash, hash2) {
|
||||
t.Logf("Expected: %v, got: %v\n", hash2, hash)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
reconstructed, err := HashOutFromLittleEndianBytes(hash)
|
||||
if err != nil {
|
||||
t.Logf("Error: %v\n", err)
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
for i := 0; i < 4; i++ {
|
||||
if hash2Elems[i] != reconstructed[i] {
|
||||
t.Logf("Expected: %d, got: %d\n", hash2Elems[i], reconstructed[i])
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHashNToHashNoPad(t *testing.T) {
|
||||
res := HashNToHashNoPad([]g.GoldilocksField{
|
||||
11295517158488612626,
|
||||
10669470463693797151,
|
||||
17232114065640264171,
|
||||
4175927072186299193,
|
||||
13985285184240204531,
|
||||
7901017084268693144,
|
||||
4326299618263946178,
|
||||
14787024750292535041,
|
||||
894520636503353046,
|
||||
12556655399058578835,
|
||||
3097737892474696200,
|
||||
7515335668060050861,
|
||||
})
|
||||
|
||||
expected := HashOut{
|
||||
15396602476382546759,
|
||||
12422280135166335470,
|
||||
8165681190607828974,
|
||||
3475588160239961712,
|
||||
}
|
||||
|
||||
for i := 0; i < 4; i++ {
|
||||
if res[i] != expected[i] {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHashNToHashNoPadLarge(t *testing.T) {
|
||||
res := HashNToHashNoPad([]g.GoldilocksField{
|
||||
g.GoldilocksField(g.ORDER + 1),
|
||||
g.GoldilocksField(g.ORDER + 2),
|
||||
g.GoldilocksField(g.ORDER + 3),
|
||||
g.GoldilocksField(math.MaxUint64),
|
||||
g.GoldilocksField(math.MaxUint64 - 1),
|
||||
})
|
||||
|
||||
expected := HashOut{
|
||||
14216040864787980138,
|
||||
17275303675000904868,
|
||||
11831395338463193314,
|
||||
281267649235863375,
|
||||
}
|
||||
|
||||
for i := 0; i < 4; i++ {
|
||||
if res[i] != expected[i] {
|
||||
t.Logf("Expected: %v, got: %v\n", expected, res)
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHashTwoToOne(t *testing.T) {
|
||||
input1 := HashOut{
|
||||
3777312593917610528,
|
||||
6858608920877200812,
|
||||
5269611035257552853,
|
||||
10607733449481270434,
|
||||
}
|
||||
|
||||
input2 := HashOut{
|
||||
10355703322562521155,
|
||||
1039917189921776884,
|
||||
10844249567941924238,
|
||||
14291130953945924124,
|
||||
}
|
||||
|
||||
expected := HashOut{
|
||||
1453933811752520343,
|
||||
16186418140372484281,
|
||||
9207215809524681813,
|
||||
10182182911172027974,
|
||||
}
|
||||
|
||||
res := HashTwoToOne(input1, input2)
|
||||
for i := 0; i < 4; i++ {
|
||||
if res[i] != expected[i] {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHashNToOne(t *testing.T) {
|
||||
hashIns := []HashOut{HashNToHashNoPad([]g.GoldilocksField{
|
||||
18231458557829081414,
|
||||
16449039301999856654,
|
||||
14758090268883299362,
|
||||
10271725147130672875,
|
||||
6253304685402495037,
|
||||
16079709420464120062,
|
||||
10838593640248082543,
|
||||
2974225335734585509,
|
||||
6365466669981419503,
|
||||
12964544245312854826,
|
||||
3161534615047618958,
|
||||
15109271288782125222,
|
||||
})}
|
||||
for i := 1; i < 12; i++ {
|
||||
hashIns = append(hashIns, HashTwoToOne(hashIns[i-1], hashIns[i-1]))
|
||||
}
|
||||
|
||||
res := HashNToOne(hashIns)
|
||||
expected := HashOut{
|
||||
3346041518891302234,
|
||||
10181430332820953144,
|
||||
14852547783810217847,
|
||||
17043509806476508794,
|
||||
}
|
||||
for i := 0; i < 4; i++ {
|
||||
if res[i] != expected[i] {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHashToQuinticExtension(t *testing.T) {
|
||||
result := HashToQuinticExtension([]g.GoldilocksField{
|
||||
3451004116618606032,
|
||||
11263134342958518251,
|
||||
10957204882857370932,
|
||||
5369763041201481933,
|
||||
7695734348563036858,
|
||||
1393419330378128434,
|
||||
7387917082382606332,
|
||||
})
|
||||
expected := [5]uint64{
|
||||
17992684813643984528,
|
||||
5243896189906434327,
|
||||
7705560276311184368,
|
||||
2785244775876017560,
|
||||
14449776097783372302,
|
||||
}
|
||||
for i := 0; i < 5; i++ {
|
||||
if result[i] != g.FromUint64(expected[i]) {
|
||||
t.Logf("Expected limb %d to be %x, but got %x", i, expected[i], result[i])
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user