import unittest import nimcrypto/utils import ../bncurve/fields proc randomSquaring*[T](): bool = for i in 0..100: var a = T.random() if a * a != a.squared(): return false var cur = T.zero() for i in 0..100: if cur.squared() != cur * cur: return false cur = cur + T.one() return true proc zeroTest*[T](): bool = if -T.zero() != T.zero(): return false if (-T.one() + T.one()) != T.zero(): return false if (T.zero() - T.zero()) != T.zero(): return false return true proc canInvert*[T](): bool = var a = T.one() for i in 0..100: if (a * a.inverse().get()) != T.one(): return false a = a + T.one() a = -T.one() for i in 0..100: if (a * a.inverse().get()) != T.one(): return false a = a - T.one() return true proc randomElementInverse*[T](): bool = for i in 0..100: var a = T.random() if a.inverse().get() * a != T.one(): return false var b = T.random() if a * b * a.inverse().get() != b: return false return true proc randomElementMultiplication*[T](): bool = for i in 0..250: var a = T.random() var b = T.random() var c = T.random() result = ((a * b) * c == a * (b * c)) proc randomElementEval*[T](): bool = for i in 0..100: var a = T.random() var b = T.random() var c = T.random() var d = T.random() var lhs = (a + b) * (c + d) var rhs = (a * c) + (b * c) + (a * d) + (b * d) if lhs != rhs: return false return true proc randomElementASN*[T](): bool = for i in 0..100: var a = T.random() if a + (-a) != T.zero(): return false for i in 0..10: var a = T.random() var r = T.random() var b = a + r var c = T.random() var d = c + r for m in 0..10: let r0 = T.random() a += r0 b += r0 c = c + r0 d = d + r0 let r1 = T.random() a -= r1 b -= r1 c = c - r1 d = d - r1 let r2 = T.random() a += (-(-r2)) b += (-(-r2)) c = c + (-(-r2)) d = d + (-(-r2)) let r3 = T.random() a -= r3 b += -r3 c = c - r3 d = d + (-r3) let r4 = T.random() a += -r4 b -= r4 c = c + (-r4) d = d - r4 b -= r d = d - r if a != b or c != d: return false return true proc testCyclotomicExp(): bool = var orig = FQ12( c0: FQ6( c0: FQ2( c0: FQ.fromString("2259924035228092997691937637688451143058635253053054071159756458902878894295"), c1: FQ.fromString("13145690032701362144460254305183927872683620413225364127064863863535255135244") ), c1: FQ2( c0: FQ.fromString("9910063591662383599552477067956819406417086889312288278252482503717089428441"), c1: FQ.fromString("537414042055419261990282459138081732565514913399498746664966841152381183961") ), c2: FQ2( c0: FQ.fromString("15311812409497308894370893420777496684951030254049554818293571309705780605004"), c1: FQ.fromString("13657107176064455789881282546557276003626320193974643644160350907227082365810") ) ), c1: FQ6( c0: FQ2( c0: FQ.fromString("4913017949003742946864670837361832856526234260447029873580022776602534856819"), c1: FQ.fromString("7834351480852267338070670220119081676575418514182895774094743209915633114041") ), c1: FQ2( c0: FQ.fromString("12837298223308203788092748646758194441270207338661891973231184407371206766993"), c1: FQ.fromString("12756474445699147370503225379431475413909971718057034061593007812727141391799") ), c2: FQ2( c0: FQ.fromString("9473802207170192255373153510655867502408045964296373712891954747252332944018"), c1: FQ.fromString("4583089109360519374075173304035813179013579459429335467869926761027310749713") ) ) ) var expected = FQ12( c0: FQ6( c0: FQ2( c0: FQ.fromString("14722956046055152398903846391223329501345567382234608299399030576415080188350"), c1: FQ.fromString("14280703280777926697010730619606819467080027543707671882210769811674790473417") ), c1: FQ2( c0: FQ.fromString("19969875076083990244184003223190771301761436396530543002586073549972410735411"), c1: FQ.fromString("10717335566913889643303549252432531178405520196706173198634734518494041323243") ), c2: FQ2( c0: FQ.fromString("6063612626166484870786832843320782567259894784043383626084549455432890717937"), c1: FQ.fromString("17089783040131779205038789608891431427943860868115199598200376195935079808729") ) ), c1: FQ6( c0: FQ2( c0: FQ.fromString("10029863438921507421569931792104023129735006154272482043027653425575205672906"), c1: FQ.fromString("6406252222753462799887280578845937185621081001436094637606245493619821542775") ), c1: FQ2( c0: FQ.fromString("1048245462913506652602966692378792381004227332967846949234978073448561848050"), c1: FQ.fromString("1444281375189053827455518242624554285012408033699861764136810522738182087554") ), c2: FQ2( c0: FQ.fromString("8839610992666735109106629514135300820412539620261852250193684883379364789120"), c1: FQ.fromString("11347360242067273846784836674906058940820632082713814508736182487171407730718") ) ) ) let e = orig.expByNegZ() result = (e == expected) proc fq12TestVector(): bool = let start = FQ12( c0: FQ6( c0: FQ2( c0: FQ.fromString("19797905000333868150253315089095386158892526856493194078073564469188852136946"), c1: FQ.fromString("10509658143212501778222314067134547632307419253211327938344904628569123178733") ), c1: FQ2( c0: FQ.fromString("208316612133170645758860571704540129781090973693601051684061348604461399206"), c1: FQ.fromString("12617661120538088237397060591907161689901553895660355849494983891299803248390") ), c2: FQ2( c0: FQ.fromString("2897490589776053688661991433341220818937967872052418196321943489809183508515"), c1: FQ.fromString("2730506433347642574983433139433778984782882168213690554721050571242082865799") ) ), c1: FQ6( c0: FQ2( c0: FQ.fromString("17870056122431653936196746815433147921488990391314067765563891966783088591110"), c1: FQ.fromString("14314041658607615069703576372547568077123863812415914883625850585470406221594") ), c1: FQ2( c0: FQ.fromString("10123533891707846623287020000407963680629966110211808794181173248765209982878"), c1: FQ.fromString("5062091880848845693514855272640141851746424235009114332841857306926659567101") ), c2: FQ2( c0: FQ.fromString("9839781502639936537333620974973645053542086898304697594692219798017709586567"), c1: FQ.fromString("1583892292110602864638265389721494775152090720173641072176370350017825640703") ) ) ) let expect = FQ12( c0: FQ6( c0: FQ2( c0: FQ.fromString("18388750939593263065521177085001223024106699964957029146547831509155008229833"), c1: FQ.fromString("18370529854582635460997127698388761779167953912610241447912705473964014492243") ), c1: FQ2( c0: FQ.fromString("3691824277096717481466579496401243638295254271265821828017111951446539785268"), c1: FQ.fromString("20513494218085713799072115076991457239411567892860153903443302793553884247235") ), c2: FQ2( c0: FQ.fromString("12214155472433286415803224222551966441740960297013786627326456052558698216399"), c1: FQ.fromString("10987494248070743195602580056085773610850106455323751205990078881956262496575") ) ), c1: FQ6( c0: FQ2( c0: FQ.fromString("5134522153456102954632718911439874984161223687865160221119284322136466794876"), c1: FQ.fromString("20119236909927036376726859192821071338930785378711977469360149362002019539920") ), c1: FQ2( c0: FQ.fromString("8839766648621210419302228913265679710586991805716981851373026244791934012854"), c1: FQ.fromString("9103032146464138788288547957401673544458789595252696070370942789051858719203") ), c2: FQ2( c0: FQ.fromString("10378379548636866240502412547812481928323945124508039853766409196375806029865"), c1: FQ.fromString("9021627154807648093720460686924074684389554332435186899318369174351765754041") ) ) ) var next = start for i in 0..<100: next = next * start var cpy = next for i in 0..<10: next = next.squared() for i in 0..<10: next = next + start next = next - cpy next = -next next = next.squared() result = (expect == next) proc fpSerializeTests[T](): bool = when (T is FQ) or (T is FR): var buffer: array[32, byte] elif (T is FQ2): var buffer: array[64, byte] else: {.fatal.} for i in 0..<1000: var e = T.random() zeroMem(addr buffer[0], sizeof(buffer)) if not e.toBytes(buffer): return false var a: T if not a.fromBytes(buffer): return false if a != e: return false return true proc fq2SerializeTestVectors(): bool = const vectors = [ FQ2( c0: FQ([12685471316754074400'u64, 5151117139186389981'u64, 1811926512010801501'u64, 2926027770199945729'u64]), c1: FQ([13288357145490715372'u64, 8465179270531902744'u64, 2331932027798174928'u64, 1169568334929779847'u64]) ), FQ2( c0: FQ([6571363706651148129'u64, 12259671536166748744'u64, 13297153216522874336'u64, 3368736813872212066'u64]), c1: FQ([7356918428694088001'u64, 13325610168162790738'u64, 11761401944674591087'u64, 2142266911265180485'u64]) ), FQ2( c0: FQ([12770271250542491457'u64, 5841829129088508933'u64, 5021659154182959822'u64, 765728708107386899'u64]), c1: FQ([9814770014224857768'u64, 169926129335489937'u64, 4476430648250845846'u64, 575721800450622933'u64]) ), FQ2( c0: FQ([10535443743532733005'u64, 18354663162560926093'u64, 3005889269269496788'u64, 892863378917010121'u64]), c1: FQ([9912639056721134596'u64, 6115953886839683024'u64, 4097812286267812943'u64, 1337629367136352970'u64]) ), FQ2( c0: FQ([7658679475413450244'u64, 11440992707440007515'u64, 16146061400040738154'u64, 991671862947387812'u64]), c1: FQ([2385857951922426638'u64, 6278331068203224119'u64, 8247542493832618243'u64, 2945883060694238627'u64]) ) ] const expects = [ "06b812bee59693d4f9f18dc46c55afe42fc5c18965669316117850ca22f55ffa44dda4f58baf6cdf629ecacae4a810098fc7d68a6bfcd200ca59322e37a4be3c", "00a41dd99c355e6984dedfc9c6752cd22b6d4d70283a128e4399734fbaa715724e0494d2d0cc7b0c71bda29d304a60cf6b3a69e366a3d50d80bfe441192d778d", "08f943db03ed61e8f2633740bdc071b76c27547891fe90d56776f9ef2a16de98dfd7d0a481fd5efb55374ea3762d879d226ac9bf7c0b347bae142e27f97d03ed", "068744cde0af982bff29d66a0e5799e78b350216ce53da6d828ca64d94bcd482af8816b7cad0dea041604d5b3ee5ddf2c5b65fc394e1752f6fa52133547a44bc", "09042d4acda2f2ff75073700783010461c5250f10724a0c27ecd295b2bda961245c9a740d3d8de3dbf6ed4fe142ee5480bd96a70d9a4442385718c4995b04b8b" ] var buffer: array[64, byte] for i in 0..