/* | |
Licensed to the Apache Software Foundation (ASF) under one | |
or more contributor license agreements. See the NOTICE file | |
distributed with this work for additional information | |
regarding copyright ownership. The ASF licenses this file | |
to you under the Apache License, Version 2.0 (the | |
"License"); you may not use this file except in compliance | |
with the License. You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, | |
software distributed under the License is distributed on an | |
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
KIND, either express or implied. See the License for the | |
specific language governing permissions and limitations | |
under the License. | |
*/ | |
/* Test FP4 ARITHMETICS - test driver and function exerciser for FP4 API Functions */ | |
var chai = require('chai'); | |
var CTX = require("../index"); | |
var expect = chai.expect; | |
var pf_curves = ['BN254', 'BN254CX', 'BLS381', 'BLS383', 'BLS461', 'FP256BN', 'FP512BN', 'BLS24', 'BLS48']; | |
var readBIG = function(string, ctx) { | |
while (string.length != ctx.BIG.MODBYTES*2){string = "00"+string;} | |
return ctx.BIG.fromBytes(Buffer.from(string, "hex")); | |
} | |
var readFP2 = function(string, ctx) { | |
string = string.split(","); | |
var cox = string[0].slice(1); | |
var coy = string[1].slice(0,-1); | |
var x = readBIG(cox,ctx); | |
var y = readBIG(coy,ctx); | |
return new ctx.FP2(x,y);; | |
} | |
var readFP4 = function(string, ctx) { | |
var X, Y; | |
string = string.split("],["); | |
var cox = string[0].slice(1) + "]"; | |
var coy = "[" + string[1].slice(0,-1); | |
X = readFP2(cox,ctx); | |
Y = readFP2(coy,ctx); | |
return new ctx.FP4(X,Y); | |
} | |
describe('TEST FP4 ARITHMETIC', function() { | |
pf_curves.forEach(function(curve){ | |
it('test '+ curve, function(done) { | |
this.timeout(0); | |
var ctx = new CTX(curve); | |
var vectors = require('../testVectors/fp4/'+curve+'.json'); | |
var i=0; | |
var a1 = new ctx.FP4(1), | |
a2 = new ctx.FP4(0), | |
one = new ctx.FP4(1), | |
zero = new ctx.FP4(0), | |
fp2one = new ctx.FP2(1), | |
fp2zero = new ctx.FP2(0); | |
// Test iszilch and isunity | |
expect(zero.iszilch()).to.be.true; | |
expect(one.iszilch()).to.be.false; | |
expect(zero.isunity()).to.be.false; | |
expect(one.isunity()).to.be.true; | |
// Test real/isreal | |
expect(one.isreal()).to.be.true; | |
expect(one.real().toString()).to.be.equal(fp2one.toString()); | |
one.times_i(); | |
expect(one.isreal()).to.be.false; | |
expect(one.real().toString()).to.be.equal(fp2zero.toString()); | |
// Test set using FP2 | |
one.set(fp2one,fp2zero); | |
expect(one.isunity()).to.be.true; | |
one.seta(fp2one); | |
expect(one.isunity()).to.be.true; | |
// Test handling sqrt 0,1 | |
a1.zero(); | |
expect(a1.sqrt()).to.be.true; | |
expect(a1.toString()).to.equal(zero.toString()); | |
a1.one(); | |
expect(a1.sqrt()).to.be.true; | |
expect(a1.toString()).to.equal(one.toString()); | |
vectors.forEach(function(vector){ | |
// test commutativity of addition | |
var fp41 = readFP4(vector.FP41,ctx); | |
var fp42 = readFP4(vector.FP42,ctx); | |
var fp4add = readFP4(vector.FP4add,ctx); | |
a1.copy(fp41); | |
a1.add(fp42); | |
expect(a1.toString()).to.equal(fp4add.toString()); | |
a2.copy(fp42); | |
a2.add(fp41); | |
expect(a2.toString()).to.equal(fp4add.toString()); | |
// test associativity of addition | |
a2.add(fp4add); | |
a1.copy(fp41); | |
a1.add(fp4add); | |
a1.add(fp42); | |
expect(a1.toString()).to.equal(a2.toString()); | |
// test subtraction | |
var fp4sub = readFP4(vector.FP4sub, ctx); | |
a1.copy(fp41); | |
a1.sub(fp42); | |
expect(a1.toString()).to.equal(fp4sub.toString()); | |
// test negative of a FP4 | |
var fp4neg = readFP4(vector.FP4neg, ctx); | |
a1.copy(fp41); | |
a1.neg(); | |
expect(a1.toString()).to.equal(fp4neg.toString()); | |
// test conjugate of a FP4 | |
var fp4conj = readFP4(vector.FP4conj, ctx); | |
a1.copy(fp41); | |
a1.conj(); | |
expect(a1.toString()).to.equal(fp4conj.toString()); | |
// test negative conjugate of a FP4 | |
var fp4nconj = readFP4(vector.FP4nconj, ctx); | |
a1.copy(fp41); | |
a1.nconj(); | |
expect(a1.toString()).to.equal(fp4nconj.toString()); | |
// test multiplication by FP2 | |
var fp4pmul = readFP4(vector.FP4pmul, ctx); | |
var fp2sc = readFP2(vector.FP2sc, ctx); | |
a1.copy(fp41); | |
a1.pmul(fp2sc); | |
expect(a1.toString()).to.equal(fp4pmul.toString()); | |
// test small scalar multiplication | |
var fp4imul = readFP4(vector.FP4imul, ctx); | |
a1.copy(fp41); | |
a1.imul(i); | |
expect(a1.toString()).to.equal(fp4imul.toString()); | |
i++; | |
// test square | |
var fp4sqr = readFP4(vector.FP4sqr, ctx); | |
a1.copy(fp41); | |
a1.sqr(); | |
expect(a1.toString()).to.equal(fp4sqr.toString()); | |
// test multiplication | |
var fp4mul = readFP4(vector.FP4mul, ctx); | |
a1.copy(fp41); | |
a1.mul(fp42); | |
expect(a1.toString()).to.equal(fp4mul.toString()); | |
// test power | |
var fp4pow = readFP4(vector.FP4pow, ctx); | |
var BIGsc1 = readBIG(vector.BIGsc1, ctx); | |
a1 = fp41.pow(BIGsc1); | |
expect(a1.toString()).to.equal(fp4pow.toString()); | |
// test inverse | |
var fp4inv = readFP4(vector.FP4inv, ctx); | |
a1.copy(fp41); | |
a1.inverse(); | |
expect(a1.toString()).to.equal(fp4inv.toString()); | |
// test multiplication by sqrt(1+sqrt(-1)) | |
var fp4mulj = readFP4(vector.FP4mulj, ctx); | |
a1.copy(fp41); | |
a1.times_i(); | |
expect(a1.toString()).to.equal(fp4mulj.toString()); | |
// // test the XTR addition function r=w*x-conj(x)*y+z | |
var fp4xtrA = readFP4(vector.FP4xtrA, ctx); | |
a1.copy(fp42); | |
a1.xtr_A(fp41,fp4add,fp4sub); | |
expect(a1.toString()).to.equal(fp4xtrA.toString()); | |
// test the XTR addition function r=w*x-conj(x)*y+z | |
var fp4xtrD = readFP4(vector.FP4xtrD, ctx); | |
a1.copy(fp41); | |
a1.xtr_D(); | |
expect(a1.toString()).to.equal(fp4xtrD.toString()); | |
// test the XTR single power r=Tr(x^e) | |
var fp4xtrpow = readFP4(vector.FP4xtrpow, ctx); | |
var fp121 = readFP4(vector.FP121, ctx); | |
a1 = fp121.xtr_pow(BIGsc1); | |
expect(a1.toString()).to.equal(fp4xtrpow.toString()); | |
// test the XTR double power r=Tr(x^e) | |
var fp4xtrpow2 = readFP4(vector.FP4xtrpow2, ctx); | |
var fp122 = readFP4(vector.FP122, ctx); | |
var fp123 = readFP4(vector.FP123, ctx); | |
var fp124 = readFP4(vector.FP124, ctx); | |
var BIGsc2 = readBIG(vector.BIGsc2, ctx); | |
a1 = fp121.xtr_pow2(fp122,fp123,fp124,BIGsc2,BIGsc1); | |
expect(a1.toString()).to.equal(fp4xtrpow2.toString()); | |
if (ctx.ECP.AESKEY > 16) { | |
// Test division by 2 | |
var fp4div2 = readFP4(vector.FP4div2, ctx); | |
a1.copy(fp41); | |
a1.div2(); | |
expect(a1.toString()).to.equal(fp4div2.toString()); | |
// Test division by i | |
var fp4divi = readFP4(vector.FP4divi, ctx); | |
a1.copy(fp41); | |
a1.div_i(); | |
expect(a1.toString()).to.equal(fp4divi.toString()) | |
// Test division by 2i | |
var fp4div2i = readFP4(vector.FP4div2i, ctx); | |
a1.copy(fp41); | |
a1.div_2i(); | |
expect(a1.toString()).to.equal(fp4div2i.toString()) | |
// Test square root | |
var fp4sqrt = readFP4(vector.FP4sqrt, ctx); | |
a1.copy(fp41); | |
expect(a1.sqrt()).to.equal(true); | |
expect(a1).to.satisfy(function(p) { | |
if(fp4sqrt.toString() === p.toString()) { | |
return true; | |
} else { | |
fp4sqrt.neg(); | |
} | |
return fp4sqrt.toString() === p.toString(); | |
}); | |
} | |
}); | |
done(); | |
}); | |
}); | |
}); |