-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a3ed35e
commit 73919dd
Showing
3 changed files
with
243 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
package mimc7 | ||
|
||
import ( | ||
"math/big" | ||
|
||
"github.com/consensys/gnark/std/algebra/emulated/sw_bn254" | ||
"github.com/consensys/gnark/std/math/emulated" | ||
) | ||
|
||
const nRounds = 91 | ||
|
||
var ( | ||
q emulated.Element[sw_bn254.ScalarField] | ||
constants []emulated.Element[sw_bn254.ScalarField] | ||
) | ||
|
||
func init() { | ||
biQ, _ := new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10) | ||
q = emulated.ValueOf[sw_bn254.ScalarField](biQ) | ||
|
||
constants = make([]emulated.Element[sw_bn254.ScalarField], nRounds) | ||
for i := 1; i < nRounds; i++ { | ||
contstant, _ := new(big.Int).SetString(strConstants[i-1], 10) | ||
constants[i] = emulated.ValueOf[sw_bn254.ScalarField](contstant) | ||
} | ||
} | ||
|
||
// strConstants contains the constants for the encryption rounds, they were | ||
// generated the method generateConstatsData of iden3 mimc7 implementation: | ||
// https://github.com/iden3/go-iden3-crypto/blob/master/mimc7/mimc7.go | ||
var strConstants = []string{ | ||
"20888961410941983456478427210666206549300505294776164667214940546594746570981", | ||
"15265126113435022738560151911929040668591755459209400716467504685752745317193", | ||
"8334177627492981984476504167502758309043212251641796197711684499645635709656", | ||
"1374324219480165500871639364801692115397519265181803854177629327624133579404", | ||
"11442588683664344394633565859260176446561886575962616332903193988751292992472", | ||
"2558901189096558760448896669327086721003508630712968559048179091037845349145", | ||
"11189978595292752354820141775598510151189959177917284797737745690127318076389", | ||
"3262966573163560839685415914157855077211340576201936620532175028036746741754", | ||
"17029914891543225301403832095880481731551830725367286980611178737703889171730", | ||
"4614037031668406927330683909387957156531244689520944789503628527855167665518", | ||
"19647356996769918391113967168615123299113119185942498194367262335168397100658", | ||
"5040699236106090655289931820723926657076483236860546282406111821875672148900", | ||
"2632385916954580941368956176626336146806721642583847728103570779270161510514", | ||
"17691411851977575435597871505860208507285462834710151833948561098560743654671", | ||
"11482807709115676646560379017491661435505951727793345550942389701970904563183", | ||
"8360838254132998143349158726141014535383109403565779450210746881879715734773", | ||
"12663821244032248511491386323242575231591777785787269938928497649288048289525", | ||
"3067001377342968891237590775929219083706800062321980129409398033259904188058", | ||
"8536471869378957766675292398190944925664113548202769136103887479787957959589", | ||
"19825444354178182240559170937204690272111734703605805530888940813160705385792", | ||
"16703465144013840124940690347975638755097486902749048533167980887413919317592", | ||
"13061236261277650370863439564453267964462486225679643020432589226741411380501", | ||
"10864774797625152707517901967943775867717907803542223029967000416969007792571", | ||
"10035653564014594269791753415727486340557376923045841607746250017541686319774", | ||
"3446968588058668564420958894889124905706353937375068998436129414772610003289", | ||
"4653317306466493184743870159523234588955994456998076243468148492375236846006", | ||
"8486711143589723036499933521576871883500223198263343024003617825616410932026", | ||
"250710584458582618659378487568129931785810765264752039738223488321597070280", | ||
"2104159799604932521291371026105311735948154964200596636974609406977292675173", | ||
"16313562605837709339799839901240652934758303521543693857533755376563489378839", | ||
"6032365105133504724925793806318578936233045029919447519826248813478479197288", | ||
"14025118133847866722315446277964222215118620050302054655768867040006542798474", | ||
"7400123822125662712777833064081316757896757785777291653271747396958201309118", | ||
"1744432620323851751204287974553233986555641872755053103823939564833813704825", | ||
"8316378125659383262515151597439205374263247719876250938893842106722210729522", | ||
"6739722627047123650704294650168547689199576889424317598327664349670094847386", | ||
"21211457866117465531949733809706514799713333930924902519246949506964470524162", | ||
"13718112532745211817410303291774369209520657938741992779396229864894885156527", | ||
"5264534817993325015357427094323255342713527811596856940387954546330728068658", | ||
"18884137497114307927425084003812022333609937761793387700010402412840002189451", | ||
"5148596049900083984813839872929010525572543381981952060869301611018636120248", | ||
"19799686398774806587970184652860783461860993790013219899147141137827718662674", | ||
"19240878651604412704364448729659032944342952609050243268894572835672205984837", | ||
"10546185249390392695582524554167530669949955276893453512788278945742408153192", | ||
"5507959600969845538113649209272736011390582494851145043668969080335346810411", | ||
"18177751737739153338153217698774510185696788019377850245260475034576050820091", | ||
"19603444733183990109492724100282114612026332366576932662794133334264283907557", | ||
"10548274686824425401349248282213580046351514091431715597441736281987273193140", | ||
"1823201861560942974198127384034483127920205835821334101215923769688644479957", | ||
"11867589662193422187545516240823411225342068709600734253659804646934346124945", | ||
"18718569356736340558616379408444812528964066420519677106145092918482774343613", | ||
"10530777752259630125564678480897857853807637120039176813174150229243735996839", | ||
"20486583726592018813337145844457018474256372770211860618687961310422228379031", | ||
"12690713110714036569415168795200156516217175005650145422920562694422306200486", | ||
"17386427286863519095301372413760745749282643730629659997153085139065756667205", | ||
"2216432659854733047132347621569505613620980842043977268828076165669557467682", | ||
"6309765381643925252238633914530877025934201680691496500372265330505506717193", | ||
"20806323192073945401862788605803131761175139076694468214027227878952047793390", | ||
"4037040458505567977365391535756875199663510397600316887746139396052445718861", | ||
"19948974083684238245321361840704327952464170097132407924861169241740046562673", | ||
"845322671528508199439318170916419179535949348988022948153107378280175750024", | ||
"16222384601744433420585982239113457177459602187868460608565289920306145389382", | ||
"10232118865851112229330353999139005145127746617219324244541194256766741433339", | ||
"6699067738555349409504843460654299019000594109597429103342076743347235369120", | ||
"6220784880752427143725783746407285094967584864656399181815603544365010379208", | ||
"6129250029437675212264306655559561251995722990149771051304736001195288083309", | ||
"10773245783118750721454994239248013870822765715268323522295722350908043393604", | ||
"4490242021765793917495398271905043433053432245571325177153467194570741607167", | ||
"19596995117319480189066041930051006586888908165330319666010398892494684778526", | ||
"837850695495734270707668553360118467905109360511302468085569220634750561083", | ||
"11803922811376367215191737026157445294481406304781326649717082177394185903907", | ||
"10201298324909697255105265958780781450978049256931478989759448189112393506592", | ||
"13564695482314888817576351063608519127702411536552857463682060761575100923924", | ||
"9262808208636973454201420823766139682381973240743541030659775288508921362724", | ||
"173271062536305557219323722062711383294158572562695717740068656098441040230", | ||
"18120430890549410286417591505529104700901943324772175772035648111937818237369", | ||
"20484495168135072493552514219686101965206843697794133766912991150184337935627", | ||
"19155651295705203459475805213866664350848604323501251939850063308319753686505", | ||
"11971299749478202793661982361798418342615500543489781306376058267926437157297", | ||
"18285310723116790056148596536349375622245669010373674803854111592441823052978", | ||
"7069216248902547653615508023941692395371990416048967468982099270925308100727", | ||
"6465151453746412132599596984628739550147379072443683076388208843341824127379", | ||
"16143532858389170960690347742477978826830511669766530042104134302796355145785", | ||
"19362583304414853660976404410208489566967618125972377176980367224623492419647", | ||
"1702213613534733786921602839210290505213503664731919006932367875629005980493", | ||
"10781825404476535814285389902565833897646945212027592373510689209734812292327", | ||
"4212716923652881254737947578600828255798948993302968210248673545442808456151", | ||
"7594017890037021425366623750593200398174488805473151513558919864633711506220", | ||
"18979889247746272055963929241596362599320706910852082477600815822482192194401", | ||
"13602139229813231349386885113156901793661719180900395818909719758150455500533", | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package mimc7 | ||
|
||
import ( | ||
"github.com/consensys/gnark/frontend" | ||
"github.com/consensys/gnark/std/algebra/emulated/sw_bn254" | ||
"github.com/consensys/gnark/std/math/emulated" | ||
) | ||
|
||
type MiMC struct { | ||
params []emulated.Element[sw_bn254.ScalarField] // slice containing constants for the encryption rounds | ||
h emulated.Element[sw_bn254.ScalarField] // current vector in the Miyaguchi–Preneel scheme | ||
data []emulated.Element[sw_bn254.ScalarField] // state storage. data is updated when Write() is called. Sum sums the data. | ||
field *emulated.Field[sw_bn254.ScalarField] | ||
} | ||
|
||
// NewMiMC function returns a initialized MiMC hash function into the BabyJubJub | ||
// curve for the emulated BN254 ScalarField. | ||
func NewMiMC(api frontend.API) (MiMC, error) { | ||
field, err := emulated.NewField[sw_bn254.ScalarField](api) | ||
if err != nil { | ||
return MiMC{}, err | ||
} | ||
return MiMC{ | ||
params: constants, | ||
h: emulated.ValueOf[sw_bn254.ScalarField](nil), | ||
field: field, | ||
}, nil | ||
} | ||
|
||
// Write adds more data to the running hash. | ||
func (h *MiMC) Write(data ...emulated.Element[sw_bn254.ScalarField]) { | ||
h.data = append(h.data, data...) | ||
} | ||
|
||
// Reset resets the Hash to its initial state. | ||
func (h *MiMC) Reset() { | ||
h.data = nil | ||
h.h = emulated.ValueOf[sw_bn254.ScalarField](nil) | ||
} | ||
|
||
// Sum hash using [Miyaguchi–Preneel] where the XOR operation is replaced by | ||
// field addition. | ||
func (h *MiMC) Sum() emulated.Element[sw_bn254.ScalarField] { | ||
for _, stream := range h.data { | ||
r := h.encrypt(stream) | ||
h.h = *h.field.Add(&h.h, &r) | ||
h.h = *h.field.ModAdd(&h.h, &stream, &q) | ||
} | ||
h.data = nil // flush the data already hashed | ||
return h.h | ||
} | ||
|
||
// AssertSumIsEqual asserts that the hash of the data is equal to the expected | ||
// hash. | ||
func (h *MiMC) AssertSumIsEqual(expected emulated.Element[sw_bn254.ScalarField]) { | ||
res := h.Sum() | ||
h.field.AssertIsEqual(&res, &expected) | ||
} | ||
|
||
func (h *MiMC) pow7(x emulated.Element[sw_bn254.ScalarField]) emulated.Element[sw_bn254.ScalarField] { | ||
x2 := h.field.Mul(&x, &x) | ||
x3 := h.field.Mul(x2, &x) | ||
x5 := h.field.Mul(x2, x3) | ||
return *h.field.Mul(x2, x5) | ||
} | ||
|
||
func (h *MiMC) encrypt(m emulated.Element[sw_bn254.ScalarField]) emulated.Element[sw_bn254.ScalarField] { | ||
x := m | ||
for i := 0; i < nRounds; i++ { | ||
sum := h.field.Add(&x, &h.h) | ||
sum = h.field.Add(sum, &h.params[i]) | ||
x = h.pow7(*sum) | ||
} | ||
return *h.field.Add(&x, &h.h) | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package mimc7 | ||
|
||
import ( | ||
"math/big" | ||
"testing" | ||
|
||
"github.com/consensys/gnark-crypto/ecc" | ||
"github.com/consensys/gnark/backend" | ||
"github.com/consensys/gnark/frontend" | ||
"github.com/consensys/gnark/std/algebra/emulated/sw_bn254" | ||
"github.com/consensys/gnark/std/math/emulated" | ||
"github.com/consensys/gnark/test" | ||
qt "github.com/frankban/quicktest" | ||
"github.com/iden3/go-iden3-crypto/mimc7" | ||
) | ||
|
||
type testMiMCCircuit struct { | ||
Hash emulated.Element[sw_bn254.ScalarField] `gnark:",public"` | ||
Preimage emulated.Element[sw_bn254.ScalarField] | ||
} | ||
|
||
func (circuit *testMiMCCircuit) Define(api frontend.API) error { | ||
mimc, err := NewMiMC(api) | ||
if err != nil { | ||
return err | ||
} | ||
mimc.Write(circuit.Preimage) | ||
mimc.AssertSumIsEqual(circuit.Hash) | ||
return nil | ||
} | ||
|
||
func TestMiMC(t *testing.T) { | ||
c := qt.New(t) | ||
// generate a random input and hash it | ||
input := new(big.Int).SetInt64(12) | ||
hash, err := mimc7.Hash([]*big.Int{input}, nil) | ||
c.Assert(err, qt.IsNil) | ||
// create a witness | ||
witness := testMiMCCircuit{ | ||
Preimage: emulated.ValueOf[sw_bn254.ScalarField](input), | ||
Hash: emulated.ValueOf[sw_bn254.ScalarField](hash), | ||
} | ||
// run the test | ||
assert := test.NewAssert(t) | ||
assert.SolvingSucceeded(&testMiMCCircuit{}, &witness, test.WithCurves(ecc.BLS12_377), test.WithBackends(backend.GROTH16)) | ||
} |