blob: a24c3e36f330412b8c9c64690e6c04f77661d235 [file] [log] [blame]
/*
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.
*/
/**
* @file test_fp_arithmetics.c
* @author Samuele Andreoli
* @brief Test for aritmetics with FP
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "arch.h"
#include "amcl.h"
#include "utils.h"
#include "fp24_YYY.h"
#define LINE_LEN 5000
/*
* Skips n closed brackets.
* Null terminates after the nth bracket and
* returns a pointer to the next char
*/
char* skip_cb(char* str, int n)
{
int i;
char* next=str;
for(i=0; i<n; i++)
{
next = strchr(++next,']');
if (next == NULL)
{
printf("ERROR unexpected test vector\n");
exit(EXIT_FAILURE);
}
}
*(++next) = '\0';
return next++;
}
void read_BIG_XXX(BIG_XXX A, char* string)
{
int len;
char support[LINE_LEN];
BIG_XXX_zero(A);
len = strlen(string)+1;
amcl_hex2bin(string,support,len);
len = (len-1)/2;
BIG_XXX_fromBytesLen(A,support,len);
BIG_XXX_norm(A);
}
void read_FP2_YYY(FP2_YYY *fp2, char* stringx)
{
char *stringy;
BIG_XXX x,y;
stringy = strchr(++stringx,',');
if (stringy == NULL)
{
printf("ERROR unexpected test vector\n");
exit(EXIT_FAILURE);
}
*(stringy)=0;
skip_cb(stringy++,1);
read_BIG_XXX(x,stringx);
read_BIG_XXX(y,stringy);
FP2_YYY_from_BIGs(fp2,x,y);
}
void read_FP4_YYY(FP4_YYY *fp4, char* stringx)
{
char *stringy;
FP2_YYY x,y;
stringy = skip_cb(stringx++,1);
skip_cb(stringy++,1);
read_FP2_YYY(&x,stringx);
read_FP2_YYY(&y,stringy);
FP4_YYY_from_FP2s(fp4,&x,&y);
}
void read_FP8_YYY(FP8_YYY *fp8, char* stringx)
{
char *stringy;
FP4_YYY x,y;
stringy = skip_cb(stringx++,3);
skip_cb(stringy++,3);
read_FP4_YYY(&x,stringx);
read_FP4_YYY(&y,stringy);
FP8_YYY_from_FP4s(fp8,&x,&y);
}
void read_FP24_YYY(FP24_YYY *fp24, char *stringx)
{
char *stringy, *stringz;
FP8_YYY x,y,z;
stringy = skip_cb(stringx++,7);
stringz = skip_cb(stringy++,7);
skip_cb(stringz++,7);
read_FP8_YYY(&x,stringx);
read_FP8_YYY(&y,stringy);
read_FP8_YYY(&z,stringz);
FP24_YYY_from_FP8s(fp24,&x,&y,&z);
}
int main(int argc, char** argv)
{
if (argc != 2)
{
printf("usage: ./test_fp24_arithmetics_ZZZ [path to test vector file]\n");
exit(EXIT_FAILURE);
}
int i = 0, j = 1, k, len = 0;
FILE *fp;
char line[LINE_LEN];
char * linePtr = NULL;
BIG_XXX M, Fr_a, Fr_b;
FP2_YYY Frob;
FP8_YYY FP8aux1;
FP24_YYY FP24aux1, FP24aux2;
char octaux[24*MODBYTES_XXX];
octet OCTaux = {0,sizeof(octaux),octaux};
FP24_YYY FP_24[3], FP_24_frobs[8];
const char* FP24_lines[3] =
{
"FP24_1 = ",
"FP24_2 = ",
"FP24_c = "
};
FP24_YYY FP_24_smul_y_dtype;
const char* FP24smul_y_dtypeline = "FP24smul_y_dtype = ";
FP24_YYY FP_24_smul_y_mtype;
const char* FP24smul_y_mtypeline = "FP24smul_y_mtype = ";
FP24_YYY FP24conj;
const char* FP24conjline = "FP24conj = ";
FP24_YYY FP24usquare;
const char* FP24usquareline = "FP24usquare = ";
FP24_YYY FP24square;
const char* FP24squareline = "FP24square = ";
FP24_YYY FP24mul;
const char* FP24mulline = "FP24mul = ";
FP24_YYY FP24smul_dtype;
const char* FP24smuldtypeline = "FP24smul_dtype = ";
FP24_YYY FP24smul_mtype;
const char* FP24smulmtypeline = "FP24smul_mtype = ";
FP24_YYY FP24inv;
const char* FP24invline = "FP24inv = ";
BIG_XXX BIGsc[10];
const char* BIGsclines[10] =
{
"BIGsc1 = ",
"BIGsc2 = ",
"BIGsc3 = ",
"BIGsc4 = ",
"BIGsc5 = ",
"BIGsc6 = ",
"BIGsc7 = ",
"BIGsc8 = ",
"BIGscs = ",
"BIGsco = "
};
FP24_YYY FP24pow;
const char* FP24powline = "FP24pow = ";
FP24_YYY FP24pinpow;
const char* FP24pinpowline = "FP24pinpow = ";
FP8_YYY FP24compows;
const char* FP24compowsline = "FP24compows = ";
FP8_YYY FP24compow;
const char* FP24compowline = "FP24compow = ";
FP24_YYY FP24pow8;
const char* FP24pow8line = "FP24pow8 = ";
FP24_YYY FP24frob;
const char* FP24frobline = "FP24frob = ";
FP8_YYY FP8trace;
const char* FP8traceline = "FP8trace = ";
BIG_XXX_rcopy(M,Modulus_YYY);
BIG_XXX_rcopy(Fr_a,Fra_YYY);
BIG_XXX_rcopy(Fr_b,Frb_YYY);
FP2_YYY_from_BIGs(&Frob,Fr_a,Fr_b);
// Set to one
FP24_YYY_one(&FP24aux1);
FP24_YYY_copy(&FP24aux2,&FP24aux1);
// Testing equal function
if(!FP24_YYY_equals(&FP24aux1,&FP24aux2))
{
printf("ERROR comparing equal FP24s or copying FP24\n");
exit(EXIT_FAILURE);
}
FP8_YYY_zero(&FP8aux1);
FP24_YYY_from_FP8(&FP24aux1,&FP8aux1);
if(FP24_YYY_equals(&FP24aux1,&FP24aux2))
{
printf("ERROR comparing different FP24s\n");
exit(EXIT_FAILURE);
}
if(!FP24_YYY_iszilch(&FP24aux1) || FP24_YYY_iszilch(&FP24aux2) || FP24_YYY_isunity(&FP24aux1) || !FP24_YYY_isunity(&FP24aux2))
{
printf("ERROR checking iszilch/isunity functions\n");
exit(EXIT_FAILURE);
}
fp = fopen(argv[1], "r");
if (fp == NULL)
{
printf("ERROR opening test vector file\n");
exit(EXIT_FAILURE);
}
while (fgets(line, LINE_LEN, fp) != NULL)
{
i++;
// Read first FP24 and perform some tests on it
if (!strncmp(line,FP24_lines[0], strlen(FP24_lines[0])))
{
len = strlen(FP24_lines[0]);
linePtr = line + len;
read_FP24_YYY(FP_24,linePtr);
// Test setting functions
FP24_YYY_from_FP8(&FP24aux1,&FP_24->a);
if(!FP8_YYY_equals(&FP24aux1.a,&FP_24->a) || !FP8_YYY_iszilch(&FP24aux1.b) || !FP8_YYY_iszilch(&FP24aux1.c))
{
printf("ERROR setting FP24 from a FP8, line %d\n",i);
exit(EXIT_FAILURE);
}
FP24_YYY_from_FP8s(&FP24aux1,&FP_24->a,&FP_24->b,&FP_24->c);
if(!FP24_YYY_equals(&FP24aux1,FP_24))
{
printf("ERROR setting FP24 from three FP8s, line %d\n",i);
exit(EXIT_FAILURE);
}
// Test octet conversion consistency
FP24_YYY_toOctet(&OCTaux,FP_24);
FP24_YYY_fromOctet(&FP24aux1,&OCTaux);
if(!FP24_YYY_equals(&FP24aux1,FP_24))
{
printf("ERROR octet conversion consistency, line %d\n",i);
exit(EXIT_FAILURE);
}
FP24_YYY_copy(FP_24_frobs,FP_24);
for (k=1; k<8; k++)
{
FP24_YYY_copy(FP_24_frobs+k,FP_24_frobs+k-1);
FP24_YYY_frob(FP_24_frobs+k,&Frob,1);
}
}
// Read other FP24s.
for(k = 1; k<3; k++)
{
if (!strncmp(line,FP24_lines[k], strlen(FP24_lines[k])))
{
len = strlen(FP24_lines[k]);
linePtr = line + len;
read_FP24_YYY(FP_24+k,linePtr);
}
}
// Read y for M-TYPE smul test
if (!strncmp(line,FP24smul_y_mtypeline, strlen(FP24smul_y_mtypeline)))
{
len = strlen(FP24smul_y_mtypeline);
linePtr = line + len;
read_FP24_YYY(&FP_24_smul_y_mtype,linePtr);
}
// Read y for D-TYPE smul test
if (!strncmp(line,FP24smul_y_dtypeline, strlen(FP24smul_y_dtypeline)))
{
len = strlen(FP24smul_y_dtypeline);
linePtr = line + len;
read_FP24_YYY(&FP_24_smul_y_dtype,linePtr);
}
// Test FP24_YYY_conj
if (!strncmp(line,FP24conjline, strlen(FP24conjline)))
{
len = strlen(FP24conjline);
linePtr = line + len;
read_FP24_YYY(&FP24conj,linePtr);
FP24_YYY_copy(&FP24aux1,FP_24);
FP24_YYY_conj(&FP24aux1,&FP24aux1);
if(!FP24_YYY_equals(&FP24aux1,&FP24conj))
{
printf("ERROR computing conjugate of FP24, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test multiplication and commutativity
if (!strncmp(line,FP24mulline, strlen(FP24mulline)))
{
len = strlen(FP24mulline);
linePtr = line + len;
read_FP24_YYY(&FP24mul,linePtr);
FP24_YYY_copy(&FP24aux1,FP_24);
FP24_YYY_mul(&FP24aux1,FP_24+1);
FP24_YYY_copy(&FP24aux2,FP_24+1);
FP24_YYY_mul(&FP24aux2,FP_24);
if(!FP24_YYY_equals(&FP24aux1,&FP24mul) || !FP24_YYY_equals(&FP24aux2,&FP24mul))
{
printf("ERROR computing multiplication of two FP24s, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test squaring
if (!strncmp(line,FP24squareline, strlen(FP24squareline)))
{
len = strlen(FP24squareline);
linePtr = line + len;
read_FP24_YYY(&FP24square,linePtr);
FP24_YYY_copy(&FP24aux1,FP_24);
FP24_YYY_sqr(&FP24aux1,&FP24aux1);
if(!FP24_YYY_equals(&FP24aux1,&FP24square))
{
printf("ERROR computing square of FP24, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test usquaring
if (!strncmp(line,FP24usquareline, strlen(FP24usquareline)))
{
len = strlen(FP24usquareline);
linePtr = line + len;
read_FP24_YYY(&FP24usquare,linePtr);
FP24_YYY_copy(&FP24aux1,FP_24);
FP24_YYY_usqr(&FP24aux1,&FP24aux1);
if(!FP24_YYY_equals(&FP24aux1,&FP24usquare))
{
printf("ERROR computing usquare of FP24, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test s-multiplication for D-TYPE
/*
if (!strncmp(line,FP24smuldtypeline, strlen(FP24smuldtypeline)))
{
len = strlen(FP24smuldtypeline);
linePtr = line + len;
read_FP24_YYY(&FP24smul_dtype,linePtr);
FP24_YYY_copy(&FP24aux1,FP_24);
FP24_YYY_smul(&FP24aux1,&FP_24_smul_y_dtype,D_TYPE);
if(!FP24_YYY_equals(&FP24aux1,&FP24smul_dtype))
{
printf("ERROR computing s-multiplication for D-TYPE, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test s-multiplication for M-TYPE
if (!strncmp(line,FP24smulmtypeline, strlen(FP24smulmtypeline)))
{
len = strlen(FP24smulmtypeline);
linePtr = line + len;
read_FP24_YYY(&FP24smul_mtype,linePtr);
FP24_YYY_copy(&FP24aux1,FP_24);
FP24_YYY_smul(&FP24aux1,&FP_24_smul_y_mtype,M_TYPE);
if(!FP24_YYY_equals(&FP24aux1,&FP24smul_mtype))
{
printf("ERROR computing s-multiplication for M-TYPE, line %d\n",i);
exit(EXIT_FAILURE);
}
}
*/
// Test inverse fuction
if (!strncmp(line,FP24invline, strlen(FP24invline)))
{
len = strlen(FP24invline);
linePtr = line + len;
read_FP24_YYY(&FP24inv,linePtr);
FP24_YYY_copy(&FP24aux1,FP_24);
FP24_YYY_inv(&FP24aux1,&FP24aux1);
if(!FP24_YYY_equals(&FP24aux1,&FP24inv))
{
printf("ERROR computing inverse of a FP24, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Read BIGS
for(k=0; k<10; k++)
{
if (!strncmp(line,BIGsclines[k], strlen(BIGsclines[k])))
{
len = strlen(BIGsclines[k]);
linePtr = line + len;
read_BIG_XXX(BIGsc[k],linePtr);
}
}
// Test power by a BIG
if (!strncmp(line,FP24powline, strlen(FP24powline)))
{
len = strlen(FP24powline);
linePtr = line + len;
read_FP24_YYY(&FP24pow,linePtr);
FP24_YYY_copy(&FP24aux1,FP_24);
FP24_YYY_pow(&FP24aux1,&FP24aux1,BIGsc[0]);
if(!FP24_YYY_equals(&FP24aux1,&FP24pow))
{
printf("ERROR computing power of a FP24 by a BIG, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test power by a small integer
if (!strncmp(line,FP24pinpowline, strlen(FP24pinpowline)))
{
len = strlen(FP24pinpowline);
linePtr = line + len;
read_FP24_YYY(&FP24pinpow,linePtr);
FP24_YYY_copy(&FP24aux1,FP_24);
FP24_YYY_pinpow(&FP24aux1,j,10);
if(!FP24_YYY_equals(&FP24aux1,&FP24pinpow))
{
printf("ERROR computing power of a FP24 by a small integer, line %d\n",i);
exit(EXIT_FAILURE);
}
j++;
}
// Test fucntion FP24_YYY_compow with small integer [< Modulus mod Curve_Order]
if (!strncmp(line,FP24compowsline, strlen(FP24compowsline)))
{
len = strlen(FP24compowsline);
linePtr = line + len;
read_FP8_YYY(&FP24compows,linePtr);
FP24_YYY_copy(&FP24aux1,FP_24+2);
FP24_YYY_compow(&FP8aux1,&FP24aux1,BIGsc[8],BIGsc[9]);
if(!FP8_YYY_equals(&FP8aux1,&FP24compows))
{
printf("ERROR testing function FP24_compow with small integer, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test fucntion FP24_YYY_compow with big integer [> Modulus mod Curve_Order]
if (!strncmp(line,FP24compowline, strlen(FP24compowline)))
{
len = strlen(FP24compowline);
linePtr = line + len;
read_FP8_YYY(&FP24compow,linePtr);
FP24_YYY_copy(&FP24aux1,FP_24+2);
FP24_YYY_compow(&FP8aux1,&FP24aux1,BIGsc[0],BIGsc[9]);
if(!FP8_YYY_equals(&FP8aux1,&FP24compow))
{
printf("ERROR testing function FP24_compow with big integer, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test function FP24_YYY_pow8
if (!strncmp(line,FP24pow8line, strlen(FP24pow8line)))
{
len = strlen(FP24pow8line);
linePtr = line + len;
read_FP24_YYY(&FP24pow8,linePtr);
FP24_YYY_pow8(&FP24aux1,FP_24_frobs,BIGsc);
if(!FP24_YYY_equals(&FP24aux1,&FP24pow8))
{
printf("ERROR testing function FP24pow8, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Raises an FP24 to the power of the internal modulus p, using the Frobenius constant f
if (!strncmp(line,FP24frobline, strlen(FP24frobline)))
{
len = strlen(FP24frobline);
linePtr = line + len;
read_FP24_YYY(&FP24frob,linePtr);
FP24_YYY_copy(&FP24aux1,FP_24);
FP24_YYY_frob(&FP24aux1,&Frob,1);
if(!FP24_YYY_equals(&FP24aux1,&FP24frob) || !FP24_YYY_equals(FP_24_frobs+1,&FP24frob))
{
printf("ERROR in raising FP24 by an internal modulus p, using the Frobenius constant f, line %d\n",i);
exit(EXIT_FAILURE);
}
}
// Test computing trace of FP24
if (!strncmp(line,FP8traceline, strlen(FP8traceline)))
{
len = strlen(FP8traceline);
linePtr = line + len;
read_FP8_YYY(&FP8trace,linePtr);
FP24_YYY_copy(&FP24aux1,FP_24);
FP24_YYY_trace(&FP8aux1,&FP24aux1);
if(!FP8_YYY_equals(&FP8aux1,&FP8trace))
{
printf("ERROR computing trace of FP24, line %d\n",i);
exit(EXIT_FAILURE);
}
}
}
fclose(fp);
printf("SUCCESS TEST ARITMETIC OF FP24 PASSED\n");
exit(EXIT_SUCCESS);
}