improved domain separation

This commit is contained in:
Balazs Komuves 2026-04-22 22:44:09 +02:00
parent 89194656ae
commit 9a143870ad
No known key found for this signature in database
GPG Key ID: F63B7AEF18435562
6 changed files with 358 additions and 65 deletions

View File

@ -1,3 +1,7 @@
#
# Merkle trees, used a drop-in replacement for hash functions
#
import constantine/math/arithmetic
import constantine/math/io/io_fields
import ./types
@ -55,12 +59,14 @@ func finish*[which](merkle: var Merkle[which]): F =
return merkle.todo[0]
# Merkle root of a sequence of field elements (here the Merkle tree is used as a hash function!)
func digest*(_: type Merkle, elements: openArray[F], which: static Flavour = HorizenLabsOld): F =
var merkle = Merkle.init(which = which)
for element in elements:
merkle.update(element)
return merkle.finish()
# Merkle root of a sequence of bytes (here the Merkle tree is used as a hash function!)
func digest*(_: type Merkle, bytes: openArray[byte], which: static Flavour = HorizenLabsOld): F =
var merkle = Merkle.init(which = which)
for element in bytes.elements(F):

View File

@ -15,18 +15,45 @@ type
#-------------------------------------------------------------------------------
# rate = 1
func init[which](sponge: var Sponge[1,which]) =
# domain separation IV := (2^64 + 256*t + r)
const IV = F.fromHex("0x10000000000000301")
#
# domain separation convention:
#
# The sponge state is initialized to `(0,0,domsep)` with
#
# domsep IV := (2^64 + 2^24*padding + 2^16*inputfmt + 2^8*t + rate)
#
# - t = 3 (the state width)
# - rate = 1 or 2
# - input format is:
# - 254 when hashing BN254 field elements
# - 8 when hashing bytes
# - 1 when hashing bits (not implemented)
# - padding is
# - 1 the `10*` padding convention for field elements
# - 16 the `10*` padding convention for bytes only (to a multiple of 31 or 62, depending on rate)
# - 17 padding both bytes (to a multiple of 31) and then the resulting field elements (multiple of rate)
# - 255 for no padding
#
# note: domain separation is IMPORTANT, especially when mixing byte sequences
# with field element sequences, and not being very careful with padding!
#
const DOMSEP_IV_RATE1_FELTS*: F = F.fromHex("0x10000000001fe0301")
const DOMSEP_IV_RATE1_BYTES*: F = F.fromHex("0x10000000011080301")
const DOMSEP_IV_RATE2_FELTS*: F = F.fromHex("0x10000000001fe0302")
const DOMSEP_IV_RATE2_BYTES*: F = F.fromHex("0x10000000011080302")
func init[which](sponge: var Sponge[1,which], domSep: F = DOMSEP_IV_RATE1_FELTS) =
sponge.s0 = zero
sponge.s1 = zero
sponge.s2 = IV
sponge.s2 = domSep
func update*[which](sponge: var Sponge[1,which], element: F) = # , which: static Flavour = HorizenLabsOld) =
func update*[which](sponge: var Sponge[1,which], element: F) =
sponge.s0 += element
permInPlace(sponge.s0, sponge.s1, sponge.s2, which = which)
func finish*[which](sponge: var Sponge[1,which]): F = # , which: static Flavour = HorizenLabsOld): F =
func finish*[which](sponge: var Sponge[1,which]): F =
# padding
sponge.s0 += one
permInPlace(sponge.s0, sponge.s1, sponge.s2, which = which)
@ -35,15 +62,13 @@ func finish*[which](sponge: var Sponge[1,which]): F = # , which: static Flavour
#-------------------------------------------------------------------------------
# rate = 2
func init[which](sponge: var Sponge[2,which]) =
# domain separation IV := (2^64 + 256*t + r)
const IV = F.fromHex("0x10000000000000302")
func init[which](sponge: var Sponge[2,which], domSep: F = DOMSEP_IV_RATE2_FELTS) =
sponge.s0 = zero
sponge.s1 = zero
sponge.s2 = IV
sponge.s2 = domSep
sponge.even = true
func update*[which](sponge: var Sponge[2,which], element: F) = # , which: static Flavour = HorizenLabsOld) =
func update*[which](sponge: var Sponge[2,which], element: F) =
if sponge.even:
sponge.s0 += element
else:
@ -51,7 +76,7 @@ func update*[which](sponge: var Sponge[2,which], element: F) = # , which: static
permInPlace(sponge.s0, sponge.s1, sponge.s2, which = which)
sponge.even = not sponge.even
func finish*[which](sponge: var Sponge[2,which]): F = #: static Flavour = HorizenLabsOld): F =
func finish*[which](sponge: var Sponge[2,which]): F =
if sponge.even:
# padding even input
sponge.s0 += one
@ -70,14 +95,42 @@ func init*(_: type Sponge, rate: static int = 2, which: static Flavour = Horizen
{.error: "only rate 1 and 2 are supported".}
result.init
func initWithDomSep*(_: type Sponge, rate: static int = 2, domSep: F, which: static Flavour = HorizenLabsOld): Sponge[rate,which] =
when rate notin {1, 2}:
{.error: "only rate 1 and 2 are supported".}
result.init(domSep = domSep)
# spone.s2 = domSep
# digest of a sequence of field elements
func digest*(_: type Sponge, elements: openArray[F], rate: static int = 2, which: static Flavour = HorizenLabsOld): F =
var sponge = Sponge.init(rate = rate, which = which)
var domsep: F
if rate == 1:
domsep = DOMSEP_IV_RATE1_FELTS
elif rate == 2:
domsep = DOMSEP_IV_RATE2_FELTS
else:
discard
var sponge = Sponge.initWithDomSep(rate = rate, domSep = domsep, which = which)
for element in elements:
sponge.update(element)
return sponge.finish()
# digest of a sequence of bytes
func digest*(_: type Sponge, bytes: openArray[byte], rate: static int = 2, which: static Flavour = HorizenLabsOld): F =
var sponge = Sponge.init(rate = rate, which = which)
var domsep: F
if rate == 1:
domsep = DOMSEP_IV_RATE1_BYTES
elif rate == 2:
domsep = DOMSEP_IV_RATE2_BYTES
else:
discard
var sponge = Sponge.initWithDomSep(rate = rate, domSep = domsep, which = which)
for element in bytes.elements(F):
sponge.update(element)
return sponge.finish()
#-------------------------------------------------------------------------------

View File

@ -1,3 +1,7 @@
#
# Merkle trees over a sequence of bytestrings
#
import ./types
import ./merkle
import ./sponge
@ -18,7 +22,7 @@ func update*[which](spongemerkle: var SpongeMerkle[which], chunk: openArray[byte
func finish*[which](spongemerkle: var SpongeMerkle[which]): F =
return spongemerkle.merkle.finish()
func digest*(_: type SpongeMerkle, bytes: openArray[byte], chunkSize: int, which: static Flavour = HorizenLabsOld): F =
func digestFixedChunks*(_: type SpongeMerkle, bytes: openArray[byte], chunkSize: int, which: static Flavour = HorizenLabsOld): F =
## Hashes chunks of data with a sponge of rate 2, and combines the
## resulting chunk hashes in a merkle root.
var spongemerkle = SpongeMerkle.init(which = which)
@ -29,3 +33,11 @@ func digest*(_: type SpongeMerkle, bytes: openArray[byte], chunkSize: int, which
spongemerkle.update(bytes.toOpenArray(start, finish - 1))
index += chunkSize
return spongemerkle.finish()
func digest*(_: type SpongeMerkle, byteSeqs: openArray[seq[byte]], which: static Flavour = HorizenLabsOld): F =
## Hashes chunks of data with a sponge of rate 2, and combines the
## resulting chunk hashes in a merkle root.
var spongemerkle = SpongeMerkle.init(which = which)
for index in 0..<byteSeqs.len:
spongemerkle.update(byteSeqs[index])
return spongemerkle.finish()

View File

@ -106,7 +106,7 @@ suite "merkle root probabilistic test (seed: " & $fuzzing.seed & ")":
#-------------------------------------------------------------------------------
suite "merkle root test vectors (old round constants)":
suite "merkle root (used as a hash function!) test vectors (old round constants)":
test "field elements":
@ -251,7 +251,7 @@ suite "merkle root test vectors (old round constants)":
#-------------------------------------------------------------------------------
suite "merkle root test vectors (new round constants)":
suite "merkle root (used as a hash function!) test vectors (new round constants)":
test "field elements":
@ -395,5 +395,3 @@ suite "merkle root test vectors (new round constants)":
check root.toDecimal == expected[n]
#-------------------------------------------------------------------------------

View File

@ -11,53 +11,54 @@ import poseidon2
#-------------------------------------------------------------------------------
const expectedSpongeResultsRate1_oldConstants : array[9, string] =
[ "11474111961551684932675539562074905375756669035986300321099733737886849683321"
, "12075737409606154890751050839468327529267137715708285489737384891841319770833"
, "01607478768131843313297310704782442615640380643931196052095347138434114571392"
, "17583439011341576528906247721476731129932611848439423516301689821385840105693"
, "12983779044863516108508991186638610589212096523915590215701244866830295506005"
, "16646216251577650555646508049064625507758601195307236539843683725095763921505"
, "11914716034377431890952169039751213443286692885071871704776127977841051829452"
, "20798492850731331785912281726856492405884190236464781409482377236764537088662"
, "06540627055407175851799217748185038564362037151837725911893079868194265409140"
[ "09602279551593072781767869672876731992056744563146041630517050886365970636003"
, "10482658356029234675406545538312309989559675144291371554217154670816627355386"
, "21219451497454286976687787075722272763501660786972150636742566108535080181479"
, "08722715919324543554361251138508029319575030629222089689820594626285008029447"
, "05252479416071756925432047522706920823732701994843337274608383487213952562652"
, "14335681867091508859155432377770517006032816456578203813846625263518832139083"
, "01787518659902041499279810468457113017929918842893543992004146450251877175230"
, "05951872852437676666746911120894618677241724527492839948381478122628367478399"
, "01483169051171494649812096066993363178940115888705003734441901747432523068356"
]
const expectedSpongeResultsRate2_oldConstants : array[9, string] =
[ "15335097698975718583905618186682475632756177170667436996250626760551196078076"
, "05101758095924000127790537496504070769319625501671400349336709520206095219618"
, "07306734450287348725566606192910189982345130476287345231433021147457815478255"
, "18511919414269811073023003336929505285555117419480831606637506641708579940507"
, "17917165106036607360653786499368288558581739128065811663709392730081030901634"
, "04630821736691665506072583795473163860465039714428126246168623896083265248907"
, "02020506076765964149531002674962673761843846094901604358961533722934321735239"
, "11732533243633999579592740965735640217427639382365959787508754341969556105663"
, "10595863140043317128604467126415689825650822395227997061806436243673828413111"
[ "19499082269592267598445447545057958665614609297846978854367973542689225942769"
, "18575012789231469229884764324941297325518518125159947154666143736134627612926"
, "08497041170554791294461959662381834821683188757759653310126334787903454881833"
, "07477361136953606818741895260704612015724121297282898803513690475311354933324"
, "00124468679175306239235509344657309567209200730228442938605071013597332255858"
, "16623067489256565233778087665060282683386099247772442960143578746217625299219"
, "11486960019850145257815352297225482939271961443661416961989480881863168607026"
, "20420541301992412878354329495337915388337723490334029715201499395107517967097"
, "15368493599988308785714434050658408098972196808672741268698522157366881904768"
]
#-------------------------------------------------------------------------------
const expectedSpongeResultsRate1_newConstants : array[9, string] =
[ "16266571538186917378274620794715615871819075505012642331831740166402113589444"
, "01491928274163660244001918443018649243011497181896253665026327205550900025133"
, "02412839127042446155240125134683455485652987653749713765008668784861163705152"
, "13542922135264044648018285414420351411417846004082653245814369808833670302952"
, "07076213890494569790170137210157320757601820601990570639519400872306624103450"
, "14352524674388170989103113995374854592404343519856765997715183437545150946627"
, "09569766023135969668725409572485043887042089063331497639246627061832860243694"
, "07085371443491523419928170734321525595867567352592425091735470317423982305101"
, "08760489972278360817463581930800343241641769319369768058091167957311211828855"
[ "04377424091368814254584985932000325369434186561094943049988002427001371028682"
, "04882927658549556007721001327257767042687783024950239124517957916798755877693"
, "04780075560415732571153009499315189673966439308277303342424971291506882586108"
, "11474073528049602460823047474981999023141929996686953106018399735733847148245"
, "18497777614932774211335329486842841597372903251455898848830055848165198236001"
, "10604030222565816223616875651989127064440338459350084151593575075022111417457"
, "21776923324072869685005088338231207859554473518124587106175254723327312624225"
, "02792992288869135760313579543774377265869215242633606960230371229360776626275"
, "20693007341698461222515050179991203000899947120254813866359977866790502772966"
]
const expectedSpongeResultsRate2_newConstants : array[9, string] =
[ "09046401272760514841637528652889990409326782162327754989145589039437684339646"
, "15241474315923430535056537847443353616620358302434799334548590414322880571588"
, "21072215602003532013851767027226990768339943605363951211799157616055680003388"
, "01170974936269513349886180046259796461929600320496736075445632961164642599434"
, "01558215443543426787363296590025566689264472540550531923588672734783818772596"
, "09807480697990556434580623882838196982062075470026453062706673159266728569584"
, "02822720935161078698932842003982797241316889894694232376768120398512081493835"
, "02351886751449393975320062064400658126198560006081569452290595784036978037282"
, "18286883995665455411199910174038826133816802309376680038108548762581403366251"
[ "11798481567564189003554007054356793867771045155136537398977037610842664973086"
, "04295345858975036877726752063699022226529926252001084742973667726185976172546"
, "04843018033972723164735619122919964846723654438742840794484490585074757880377"
, "14366573672249189186063883832534066613008473033573013521169876759944167284847"
, "18980797754459442521759183174826646847662801133806115709836254071366539109721"
, "20835927296130700305485703890299389670765608010514411209585750532357495956217"
, "00376136331714847730896275946478129283551272685413282664899718356562373464640"
, "06676481722159775414384926904273367103332158165985849413600251374153631877410"
, "14702393876084904104384222772945859101087277678512774408869360595483438759502"
]
#-------------------------------------------------------------------------------
@ -82,9 +83,14 @@ suite "sponge (old round constants)":
test "sponge with byte array as input":
let bytes = toSeq 1'u8..80'u8
var sponge = Sponge.initWithDomSep(rate = 2, domSep = DOMSEP_IV_RATE2_BYTES, which = HorizenLabsOld)
let elements = toSeq bytes.elements(F)
let expected = Sponge.digest(elements, rate = 2, which = HorizenLabsOld)
check bool(Sponge.digest(bytes, rate = 2) == expected)
for element in bytes.elements(F):
sponge.update(element)
let expected = sponge.finish()
check bool(Sponge.digest(bytes, rate = 2, which = HorizenLabsOld) == expected)
#-------------------------------------------------------------------------------
@ -108,8 +114,13 @@ suite "sponge (new round constants)":
test "sponge with byte array as input":
let bytes = toSeq 1'u8..80'u8
var sponge = Sponge.initWithDomSep(rate = 2, domSep = DOMSEP_IV_RATE2_BYTES, which = HorizenLabsNew)
let elements = toSeq bytes.elements(F)
let expected = Sponge.digest(elements, rate = 2, which = HorizenLabsNew)
for element in bytes.elements(F):
sponge.update(element)
let expected = sponge.finish()
check bool(Sponge.digest(bytes, rate = 2, which = HorizenLabsNew) == expected)
#-------------------------------------------------------------------------------

View File

@ -1,7 +1,10 @@
import std/unittest
import std/sequtils
import std/random
import constantine/math/arithmetic
import constantine/math/io/io_fields
#import constantine/math/arithmetic
import poseidon2/sponge
import poseidon2/merkle
import poseidon2/spongemerkle
@ -9,7 +12,7 @@ import poseidon2/types
#-------------------------------------------------------------------------------
suite "sponge - merkle root (old round constants)":
suite "sponge-merkle root (old round constants)":
const KB = 1024
@ -21,7 +24,7 @@ suite "sponge - merkle root (old round constants)":
let digest = Sponge.digest(chunk, rate = 2)
merkle.update(digest)
let expected = merkle.finish()
check bool(SpongeMerkle.digest(bytes, chunkSize = 2*KB) == expected)
check bool(SpongeMerkle.digestFixedChunks(bytes, chunkSize = 2*KB) == expected)
test "handles partial chunk at the end":
let bytes = newSeqWith(63*KB, rand(byte))
@ -33,11 +36,11 @@ suite "sponge - merkle root (old round constants)":
let partialChunk = bytes[(62*KB)..<(63*KB)]
merkle.update(Sponge.digest(partialChunk, rate = 2))
let expected = merkle.finish()
check bool(SpongeMerkle.digest(bytes, chunkSize = 2*KB) == expected)
check bool(SpongeMerkle.digestFixedChunks(bytes, chunkSize = 2*KB) == expected)
#-------------------------------------------------------------------------------
suite "sponge - merkle root (new round constants)":
suite "sponge-merkle root (new round constants)":
const KB = 1024
@ -49,7 +52,7 @@ suite "sponge - merkle root (new round constants)":
let digest = Sponge.digest(chunk, rate = 2, which = HorizenLabsNew)
merkle.update(digest)
let expected = merkle.finish()
check bool(SpongeMerkle.digest(bytes, chunkSize = 2*KB, which = HorizenLabsNew) == expected)
check bool(SpongeMerkle.digestFixedChunks(bytes, chunkSize = 2*KB, which = HorizenLabsNew) == expected)
test "handles partial chunk at the end":
let bytes = newSeqWith(63*KB, rand(byte))
@ -61,6 +64,216 @@ suite "sponge - merkle root (new round constants)":
let partialChunk = bytes[(62*KB)..<(63*KB)]
merkle.update(Sponge.digest(partialChunk, rate = 2, which = HorizenLabsNew))
let expected = merkle.finish()
check bool(SpongeMerkle.digest(bytes, chunkSize = 2*KB, which = HorizenLabsNew) == expected)
check bool(SpongeMerkle.digestFixedChunks(bytes, chunkSize = 2*KB, which = HorizenLabsNew) == expected)
#-------------------------------------------------------------------------------
suite "sponge-merkle root test vectors (old round constants)":
const expectedSpongeMerkleResults_oldconstants : array[81, string] =
[ "07155779167346641598586294060017939329738865231697369459206721074285611550583",
"16979304295467004391331442952726564028180201868815692155326780942691814728116",
"08835387602022948309841100920745966203645416182699674026049013758457006105230",
"09110601335495890385657186840074556784380168543862441031608438539669214523602",
"16059834824167573102979814066609903642955490594145699484359108731858096387501",
"04575932196489673039991474402849713052806335753170174869278460911688074018753",
"20605778059988629644279983484077313847862361699143655158499725738917677212118",
"02457216051416536304904582340672761330958951435219656365441531138627413726425",
"04132919669050578308158591860525532227119222705294533276885578451780885551099",
"21636603014555032684318726114721414213433587521337285964486769515576783600046",
"02117554413877932444038863339049031344409634935515176632838670258445574154303",
"21770094161558114001814189049137527904325790327785310884625317528157931891323",
"05670668897648753621859166444898157164212971104532828315862128788831646286497",
"13298253804508132761761109357628461848654892491603177316374308595796366388327",
"01301928996486850258404236230798197407014842981631420746272861257969115128904",
"03714702146931717673254175346499584720576807966597601473116815266356047824045",
"08275264193916357625165549208830269542340182155932692502835053084072579112578",
"21264829590197505489000161273947805057851084058275666495846693754202258261743",
"01339147047154105666096879595946296999508025786031465013113634453772528504333",
"05022531211473105013008881594098995962697054173926992406557176468194573780190",
"19024680736373635358407764313980895278508235603392668706088841760874338503772",
"11197811795271495094442803193109457805839554374485149559759466407763841447577",
"17278693623582517874022814425114351409788557530801942454438316922954800142303",
"08528339028659546772879171184433508222870726467401360081377419417980891479984",
"18534283213225487965385961165973956193103132280440330788704042156856982452523",
"12481153234918589628480800573597425796443328339768515521880700609425154113221",
"20746529444812084994072409865316707554836442984158675081194404983675400090287",
"05923767255506782247089293411501332992364265149317326990233315858347469377882",
"05817142609831490997044669561942980500775628380453341201654110713462889003870",
"08820785141078632240699740739305451852938111379662658039295859969286970931431",
"08068109438569561223425499762739473770761839027046694380295327087634992769413",
"13283632376177000826256029054030771051456915648794971874730420733241736794943",
"07372523178899870579387285572739493194925304483575294713667715455028617533964",
"16065727898627364563512948843628802120647291235319529582597322946215919575722",
"13580986116080928995667888057848029887177427991444985363644011662845625697635",
"13397896706613829133688295553139287426165045170981752933517791130395181363927",
"20871111874128102830004351379201231196900389445773521774734644534910976831102",
"18487241545391882845055935960935499162709216451717459908291317279121949459739",
"13462444194493959279983800253978227583715884525959156634817262207032908345095",
"01232000382403585821272575974155663861096298091333308402739682831055949692586",
"06646458645255573456756436453052119455397469345425006634223875146304386461563",
"06218708586195904287639842537658940693618928368446292654594832138147679390447",
"09987157652739473551263802696135418647409823599904048209408430617609731145844",
"21844569784817319081676513934598195927344835503150020653667162232123052824845",
"14469261238141778683779125489122761922303337594231328134529506838241803299320",
"16531690210228148327936951756210004088203180584246472324049306325781650570707",
"09894327301660894364541584666222618088555319971898638666422255390322238540665",
"14068420347540713576744237733918690540232513001356661083187767882737686029166",
"05642008915402989102464678048820645971082355853900405024181195953479250960658",
"13032390542738828535958602196459592136708139394150400647387821451009741473196",
"20609823303727374082113258781482407134411431328288572265335561355284509299428",
"20382686831473670795710711460035048115699993109801222330928525473022720011109",
"12194331024327271305595332929411373112708992944742764380946867058494612151465",
"14020101440403676760310248047827571947750273978709652461690716082129101266189",
"19167194828139861585696413489021169053972206597501188417437896024810497333800",
"01501812840904633920413739494644719025387915369474760536144240700925961730652",
"07762825223870695880764997951944098372762165714618760093033905010283152314171",
"08731863481973012442068537462768123038979471510517821497136248550900073252102",
"14447233611786113948979756006982610892850460497142741951324566141883449262990",
"09671716940995853882208929559205814405216071641802501813585534421503914371938",
"15684210550626730817453075166358810481537163132372028999783434297296883019857",
"08642499339209858739150908043660662361321429414987606205188181033901999310801",
"16423814796751934066189047578358059896113418619160569472352779157825578773544",
"01998676524922642457395171123348610815072702053428234336514788925303270884712",
"19166586952493786476305430897415499038806028005252152329650878530323770226335",
"17165180953535884995236703629339889687308452001829360555232037863651776454505",
"16503725944739069614442554968977522267495227970396123872396115398242951643401",
"07407385650248088111972706038214866042511884459341204195123890577667976476342",
"02014018517339926781906351670727101350633021987905479949615701021596315293653",
"08848780663936288405660186195248235792380707589710524940376023586554954516526",
"06770106236509018605123414673551323137611885134994553129811978113388258228733",
"06931510447321226725484492848368621554352083681962202071012982239140122847304",
"21609033988262237586826090069988869807832357717891322908998610615559228075480",
"19995836099844162708093544404653525891357642818073457803254737802124177234611",
"01349942493124700659196941349756912976427294023950824367748409032854916520862",
"10657880251357986936381187980634329288089261536756115511871330730762500228040",
"13592085537219470770070138263587759908966410250810149463208818175725183270249",
"07619316007786170479429425638110997656229506725020170942032343422656732408064",
"14497764472083727926360014521137386379983287944151661445377622105137971770729",
"21814971929150917128311630168731919827273500876425241466562337391427917079771",
"14827272702481801254613296256040984260243434745210066672731918680584225163182",
]
#
# makeInput :: Int -> Int -> ByteString
# makeInput n j = B.pack $ map (fromIntegral :: Int -> Word8) [0..j-1]
#
# makeInputs :: Int -> [ByteString]
# makeInputs n = [ makeInput n j | j<-[1..n] ]
#
for n in 1..81:
var inputs: seq[seq[byte]] = newSeq[seq[byte]]()
for j in 1..n:
var bytes: seq[byte] = newSeq[byte](j)
for i in 0..j-1:
bytes[i] = byte(i)
inputs.add(bytes)
let root = SpongeMerkle.digest(inputs, which = HorizenLabsOld)
let expected = expectedSpongeMerkleResults_oldconstants[n-1]
check bool( toDecimal(root) == expected)
#-------------------------------------------------------------------------------
suite "sponge-merkle root test vectors (new round constants)":
const expectedSpongeMerkleResults_newconstants : array[81, string] =
[ "16106936217773488732114707136659579475039188182303473285991086909582255760813",
"21749399151008613146906992853707653458950578828151260507349888266882735090033",
"07615848664528200129121474265923162920724325782071238591017928661750099497118",
"04269040087840470508922342006390431168100458550394975870128858129394423837686",
"11909495372117408419064340432441167763732820969531486899351462734507847230120",
"09623551064734467841777505352687228831332065462156396123462342330498656107639",
"01923122361160389809840562134805645636119746122867292253865481252908692241636",
"09374656801801208201915510249757793623583371587325362370560767250768726761702",
"05380781044035989060288046707204064439518450659309200099374350654192946492732",
"20266035748238927774027269735432472351037817093683305679372405236706175735664",
"02416168066522983534720378587673069117497466620465720550127139662589501895384",
"21646315564996404895709641714887124859419926515588970989763359019227476431156",
"03599540780088241030700919263758096707042314521989714394236666205194167639292",
"16342064934103837174048129843168166937561837148488746961577631865123986227842",
"16508518618162518007275769956824846372370426317235608285105885953754139326849",
"00298618134235314604128618009387381464821437895788628314470737986441443733908",
"09132340604368324181809699721169450056473307660602077371154375460533257822910",
"09627689776724825827261802353716361529825159379894616381445783454707265764632",
"20597515270126452023579219644324538936499010488543190919288973617995170615083",
"02138881138580869794840608034391349171932744817542674152871775953181348597362",
"15840379631235293457048455683670448542220216878564098546761115325436270653082",
"06496588082060530023558206142803725199083883589113831025750573586050165485510",
"09096996941419280530522999878310766007172912259819889533479040624955987114936",
"06539079796069232976817752880500625737582033407513792289868656766230505369280",
"12136369185149927301667564117980104605983402989998935140032879392177752276949",
"17891418731598692782915178730675266400990557628342320066399249313681244046057",
"04970437575623654619207537243890797382875919069514429582444124497695825284766",
"09910621566300327115556949555006057474254862620812676329286506138269806168303",
"04927794288800780546142017971468992126674690061858294551922732994110952774055",
"04843699357438086063382848334512197828424626722797762331317888142473399784102",
"09280486434661104381386320501890371432681704710315212305963462426725442981532",
"10771884053877714733123323273165653990323162928924442408538867238579748893264",
"21519328836661449244592449156944420083318785273344153864319619838907089525712",
"09226735909908114913088419137790274963982519549138807409387415251315582594960",
"02889094603530823256270130378620319510697185098978542193238645190142732482171",
"04451133582913418958501568008330579360047913653419584057516702293936931177698",
"13087394952469092373767778107679085631016082317224984033414358183426901028024",
"20074269777739483959077084202692696332895240747453622100621166964735946483771",
"00994124961482610172956773256240164003415620665268537533785482050899591866637",
"10804785206270592442628609926083834977845866272408941750236115952533859766355",
"02368687109817313455166799040925587643597004200291791253163047920441253090435",
"12222337111630828777977981650531037487601367942523278746783946816611008474247",
"18864538446103571516222660327246455540056332692105020001468591895963612481707",
"20330810490097749656019521627006626144901588010272818694725428830664273851196",
"04161861927026241971299783840307709624707246412051375250314147112261412518099",
"04640000953918440669992971009867067034478595026322063124166163191898810376114",
"16066787535396169742674383023081280340994712360840025594454191215927092842016",
"00736034456941105961388640729582608482209338686510087601088518987119727347046",
"19218882574847262543462084675030725289535306720000572960850025935546380708622",
"06326041394779058261647394686665756637183347036048181459758008162052839089459",
"20524992412783385892230376054341084664503037052792685338735818272864502902467",
"06303244711291199980507571856813826291644485110042948017148936644950502800656",
"09687438763363502754353958780409137340373402881771663917442431795283762742200",
"07393721607299654338612163303611615927647381694304414902179001529565436304004",
"00769299206827118828423721238345795180980386231688050996247579479410142733573",
"15356142515946486412361064104631985279516652436112663877624123998857317846062",
"12944394552851636887823569941599653223264312735650698705280915856595690453423",
"19257744271863192120032576801551796358147018485046545304766477230029886225991",
"11553121321170226180235915708569160525393362863129643259015477852812918125982",
"10383932945432596020387936181196688777215063374740862187927809654011866463962",
"13698576125535108584081024020871121284718720353945957107340406960531378082899",
"14766738048837258982368663710755955729966053739719953129479420517306564286057",
"14150370579625075584176186632683221471463481813142770634617948838462973217297",
"15703901400482664258208036264087636185420814463522725816008587625070722774660",
"21628863922296828936108793664365083848175178900851798238279153167762247212544",
"17994964179538203022789294598594696226457805472794747773570869995060134870000",
"14173664202384290972662307152626682324715089270145146626777252634804182088198",
"10259818538204037395642496304708180387331957267869030925460874027794979016914",
"04348517106183457755278591374986616028657425266802126959553253893408186029650",
"15353841401401031036196880589610688940911038016281981833717765850488408078543",
"13184449229727484135058795690270607193246552342045159689255485399024532339099",
"01280799013898452490128673542335363702792730127220297813199628076315500079287",
"17724139026752938082955702370592493012916376150326371546398913067689930803474",
"19681190042322570232370779235592644315085065044612722237027324840799540250394",
"00923102699142118835876108627315848969604392841598826632855749214047808831233",
"12682658082539677084438931331375565342254547419452256411929547954379881796014",
"17246130195602399633915379969768231501448212613503611421115280072337576774889",
"16725278147270471780093184101611238021795389524370940739411544149792098435822",
"15028040181755179383105400700064688696134603419011146558420290355250062242223",
"08369173688811987172616372945331414080137308477947398758527907211441929340149",
"02992056413179761701460849741660292672349406441794960088886456752947775864767",
]
for n in 1..81:
var inputs: seq[seq[byte]] = newSeq[seq[byte]]()
for j in 1..n:
var bytes: seq[byte] = newSeq[byte](j)
for i in 0..j-1:
bytes[i] = byte(i)
inputs.add(bytes)
let root = SpongeMerkle.digest(inputs, which = HorizenLabsNew)
let expected = expectedSpongeMerkleResults_newconstants[n-1]
check bool( toDecimal(root) == expected)
#-------------------------------------------------------------------------------