http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version22/java/AES.java ---------------------------------------------------------------------- diff --git a/version22/java/AES.java b/version22/java/AES.java new file mode 100644 index 0000000..648db7c --- /dev/null +++ b/version22/java/AES.java @@ -0,0 +1,695 @@ +/* +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. +*/ + + +/* AES Encryption */ + + +public class AES { + int Nk,Nr; + int mode; + private int[] fkey=new int[60]; + private int[] rkey=new int[60]; + public byte[] f=new byte[16]; + + + public static final int ECB=0; + public static final int CBC=1; + public static final int CFB1=2; + public static final int CFB2=3; + public static final int CFB4=5; + public static final int OFB1=14; + public static final int OFB2=15; + public static final int OFB4=17; + public static final int OFB8=21; + public static final int OFB16=29; + public static final int CTR1=30; + public static final int CTR2=31; + public static final int CTR4=33; + public static final int CTR8=37; + public static final int CTR16=45; + + private static final byte[] InCo={(byte)0xB,(byte)0xD,(byte)0x9,(byte)0xE}; /* Inverse Coefficients */ + + public static final int KS=16; /* Key Size in bytes */ + public static final int BS=16; /* Block Size */ + + private static final byte[] ptab= + {(byte)1,(byte)3,(byte)5,(byte)15,(byte)17,(byte)51,(byte)85,(byte)255,(byte)26,(byte)46,(byte)114,(byte)150,(byte)161,(byte)248,(byte)19,(byte)53, + (byte)95,(byte)225,(byte)56,(byte)72,(byte)216,(byte)115,(byte)149,(byte)164,(byte)247,(byte)2,(byte)6,(byte)10,(byte)30,(byte)34,(byte)102,(byte)170, + (byte)229,(byte)52,(byte)92,(byte)228,(byte)55,(byte)89,(byte)235,(byte)38,(byte)106,(byte)190,(byte)217,(byte)112,(byte)144,(byte)171,(byte)230,(byte)49, + (byte)83,(byte)245,(byte)4,(byte)12,(byte)20,(byte)60,(byte)68,(byte)204,(byte)79,(byte)209,(byte)104,(byte)184,(byte)211,(byte)110,(byte)178,(byte)205, + (byte)76,(byte)212,(byte)103,(byte)169,(byte)224,(byte)59,(byte)77,(byte)215,(byte)98,(byte)166,(byte)241,(byte)8,(byte)24,(byte)40,(byte)120,(byte)136, + (byte)131,(byte)158,(byte)185,(byte)208,(byte)107,(byte)189,(byte)220,(byte)127,(byte)129,(byte)152,(byte)179,(byte)206,(byte)73,(byte)219,(byte)118,(byte)154, + (byte)181,(byte)196,(byte)87,(byte)249,(byte)16,(byte)48,(byte)80,(byte)240,(byte)11,(byte)29,(byte)39,(byte)105,(byte)187,(byte)214,(byte)97,(byte)163, + (byte)254,(byte)25,(byte)43,(byte)125,(byte)135,(byte)146,(byte)173,(byte)236,(byte)47,(byte)113,(byte)147,(byte)174,(byte)233,(byte)32,(byte)96,(byte)160, + (byte)251,(byte)22,(byte)58,(byte)78,(byte)210,(byte)109,(byte)183,(byte)194,(byte)93,(byte)231,(byte)50,(byte)86,(byte)250,(byte)21,(byte)63,(byte)65, + (byte)195,(byte)94,(byte)226,(byte)61,(byte)71,(byte)201,(byte)64,(byte)192,(byte)91,(byte)237,(byte)44,(byte)116,(byte)156,(byte)191,(byte)218,(byte)117, + (byte)159,(byte)186,(byte)213,(byte)100,(byte)172,(byte)239,(byte)42,(byte)126,(byte)130,(byte)157,(byte)188,(byte)223,(byte)122,(byte)142,(byte)137,(byte)128, + (byte)155,(byte)182,(byte)193,(byte)88,(byte)232,(byte)35,(byte)101,(byte)175,(byte)234,(byte)37,(byte)111,(byte)177,(byte)200,(byte)67,(byte)197,(byte)84, + (byte)252,(byte)31,(byte)33,(byte)99,(byte)165,(byte)244,(byte)7,(byte)9,(byte)27,(byte)45,(byte)119,(byte)153,(byte)176,(byte)203,(byte)70,(byte)202, + (byte)69,(byte)207,(byte)74,(byte)222,(byte)121,(byte)139,(byte)134,(byte)145,(byte)168,(byte)227,(byte)62,(byte)66,(byte)198,(byte)81,(byte)243,(byte)14, + (byte)18,(byte)54,(byte)90,(byte)238,(byte)41,(byte)123,(byte)141,(byte)140,(byte)143,(byte)138,(byte)133,(byte)148,(byte)167,(byte)242,(byte)13,(byte)23, + (byte)57,(byte)75,(byte)221,(byte)124,(byte)132,(byte)151,(byte)162,(byte)253,(byte)28,(byte)36,(byte)108,(byte)180,(byte)199,(byte)82,(byte)246,(byte)1}; + + private static final byte[] ltab= + {(byte)0,(byte)255,(byte)25,(byte)1,(byte)50,(byte)2,(byte)26,(byte)198,(byte)75,(byte)199,(byte)27,(byte)104,(byte)51,(byte)238,(byte)223,(byte)3, + (byte)100,(byte)4,(byte)224,(byte)14,(byte)52,(byte)141,(byte)129,(byte)239,(byte)76,(byte)113,(byte)8,(byte)200,(byte)248,(byte)105,(byte)28,(byte)193, + (byte)125,(byte)194,(byte)29,(byte)181,(byte)249,(byte)185,(byte)39,(byte)106,(byte)77,(byte)228,(byte)166,(byte)114,(byte)154,(byte)201,(byte)9,(byte)120, + (byte)101,(byte)47,(byte)138,(byte)5,(byte)33,(byte)15,(byte)225,(byte)36,(byte)18,(byte)240,(byte)130,(byte)69,(byte)53,(byte)147,(byte)218,(byte)142, + (byte)150,(byte)143,(byte)219,(byte)189,(byte)54,(byte)208,(byte)206,(byte)148,(byte)19,(byte)92,(byte)210,(byte)241,(byte)64,(byte)70,(byte)131,(byte)56, + (byte)102,(byte)221,(byte)253,(byte)48,(byte)191,(byte)6,(byte)139,(byte)98,(byte)179,(byte)37,(byte)226,(byte)152,(byte)34,(byte)136,(byte)145,(byte)16, + (byte)126,(byte)110,(byte)72,(byte)195,(byte)163,(byte)182,(byte)30,(byte)66,(byte)58,(byte)107,(byte)40,(byte)84,(byte)250,(byte)133,(byte)61,(byte)186, + (byte)43,(byte)121,(byte)10,(byte)21,(byte)155,(byte)159,(byte)94,(byte)202,(byte)78,(byte)212,(byte)172,(byte)229,(byte)243,(byte)115,(byte)167,(byte)87, + (byte)175,(byte)88,(byte)168,(byte)80,(byte)244,(byte)234,(byte)214,(byte)116,(byte)79,(byte)174,(byte)233,(byte)213,(byte)231,(byte)230,(byte)173,(byte)232, + (byte)44,(byte)215,(byte)117,(byte)122,(byte)235,(byte)22,(byte)11,(byte)245,(byte)89,(byte)203,(byte)95,(byte)176,(byte)156,(byte)169,(byte)81,(byte)160, + (byte)127,(byte)12,(byte)246,(byte)111,(byte)23,(byte)196,(byte)73,(byte)236,(byte)216,(byte)67,(byte)31,(byte)45,(byte)164,(byte)118,(byte)123,(byte)183, + (byte)204,(byte)187,(byte)62,(byte)90,(byte)251,(byte)96,(byte)177,(byte)134,(byte)59,(byte)82,(byte)161,(byte)108,(byte)170,(byte)85,(byte)41,(byte)157, + (byte)151,(byte)178,(byte)135,(byte)144,(byte)97,(byte)190,(byte)220,(byte)252,(byte)188,(byte)149,(byte)207,(byte)205,(byte)55,(byte)63,(byte)91,(byte)209, + (byte)83,(byte)57,(byte)132,(byte)60,(byte)65,(byte)162,(byte)109,(byte)71,(byte)20,(byte)42,(byte)158,(byte)93,(byte)86,(byte)242,(byte)211,(byte)171, + (byte)68,(byte)17,(byte)146,(byte)217,(byte)35,(byte)32,(byte)46,(byte)137,(byte)180,(byte)124,(byte)184,(byte)38,(byte)119,(byte)153,(byte)227,(byte)165, + (byte)103,(byte)74,(byte)237,(byte)222,(byte)197,(byte)49,(byte)254,(byte)24,(byte)13,(byte)99,(byte)140,(byte)128,(byte)192,(byte)247,(byte)112,(byte)7}; + + private static final byte[] fbsub= + {(byte)99,(byte)124,(byte)119,(byte)123,(byte)242,(byte)107,(byte)111,(byte)197,(byte)48,(byte)1,(byte)103,(byte)43,(byte)254,(byte)215,(byte)171,(byte)118, + (byte)202,(byte)130,(byte)201,(byte)125,(byte)250,(byte)89,(byte)71,(byte)240,(byte)173,(byte)212,(byte)162,(byte)175,(byte)156,(byte)164,(byte)114,(byte)192, + (byte)183,(byte)253,(byte)147,(byte)38,(byte)54,(byte)63,(byte)247,(byte)204,(byte)52,(byte)165,(byte)229,(byte)241,(byte)113,(byte)216,(byte)49,(byte)21, + (byte)4,(byte)199,(byte)35,(byte)195,(byte)24,(byte)150,(byte)5,(byte)154,(byte)7,(byte)18,(byte)128,(byte)226,(byte)235,(byte)39,(byte)178,(byte)117, + (byte)9,(byte)131,(byte)44,(byte)26,(byte)27,(byte)110,(byte)90,(byte)160,(byte)82,(byte)59,(byte)214,(byte)179,(byte)41,(byte)227,(byte)47,(byte)132, + (byte)83,(byte)209,(byte)0,(byte)237,(byte)32,(byte)252,(byte)177,(byte)91,(byte)106,(byte)203,(byte)190,(byte)57,(byte)74,(byte)76,(byte)88,(byte)207, + (byte)208,(byte)239,(byte)170,(byte)251,(byte)67,(byte)77,(byte)51,(byte)133,(byte)69,(byte)249,(byte)2,(byte)127,(byte)80,(byte)60,(byte)159,(byte)168, + (byte)81,(byte)163,(byte)64,(byte)143,(byte)146,(byte)157,(byte)56,(byte)245,(byte)188,(byte)182,(byte)218,(byte)33,(byte)16,(byte)255,(byte)243,(byte)210, + (byte)205,(byte)12,(byte)19,(byte)236,(byte)95,(byte)151,(byte)68,(byte)23,(byte)196,(byte)167,(byte)126,(byte)61,(byte)100,(byte)93,(byte)25,(byte)115, + (byte)96,(byte)129,(byte)79,(byte)220,(byte)34,(byte)42,(byte)144,(byte)136,(byte)70,(byte)238,(byte)184,(byte)20,(byte)222,(byte)94,(byte)11,(byte)219, + (byte)224,(byte)50,(byte)58,(byte)10,(byte)73,(byte)6,(byte)36,(byte)92,(byte)194,(byte)211,(byte)172,(byte)98,(byte)145,(byte)149,(byte)228,(byte)121, + (byte)231,(byte)200,(byte)55,(byte)109,(byte)141,(byte)213,(byte)78,(byte)169,(byte)108,(byte)86,(byte)244,(byte)234,(byte)101,(byte)122,(byte)174,(byte)8, + (byte)186,(byte)120,(byte)37,(byte)46,(byte)28,(byte)166,(byte)180,(byte)198,(byte)232,(byte)221,(byte)116,(byte)31,(byte)75,(byte)189,(byte)139,(byte)138, + (byte)112,(byte)62,(byte)181,(byte)102,(byte)72,(byte)3,(byte)246,(byte)14,(byte)97,(byte)53,(byte)87,(byte)185,(byte)134,(byte)193,(byte)29,(byte)158, + (byte)225,(byte)248,(byte)152,(byte)17,(byte)105,(byte)217,(byte)142,(byte)148,(byte)155,(byte)30,(byte)135,(byte)233,(byte)206,(byte)85,(byte)40,(byte)223, + (byte)140,(byte)161,(byte)137,(byte)13,(byte)191,(byte)230,(byte)66,(byte)104,(byte)65,(byte)153,(byte)45,(byte)15,(byte)176,(byte)84,(byte)187,(byte)22}; + + private static final byte[] rbsub= + {(byte)82,(byte)9,(byte)106,(byte)213,(byte)48,(byte)54,(byte)165,(byte)56,(byte)191,(byte)64,(byte)163,(byte)158,(byte)129,(byte)243,(byte)215,(byte)251, + (byte)124,(byte)227,(byte)57,(byte)130,(byte)155,(byte)47,(byte)255,(byte)135,(byte)52,(byte)142,(byte)67,(byte)68,(byte)196,(byte)222,(byte)233,(byte)203, + (byte)84,(byte)123,(byte)148,(byte)50,(byte)166,(byte)194,(byte)35,(byte)61,(byte)238,(byte)76,(byte)149,(byte)11,(byte)66,(byte)250,(byte)195,(byte)78, + (byte)8,(byte)46,(byte)161,(byte)102,(byte)40,(byte)217,(byte)36,(byte)178,(byte)118,(byte)91,(byte)162,(byte)73,(byte)109,(byte)139,(byte)209,(byte)37, + (byte)114,(byte)248,(byte)246,(byte)100,(byte)134,(byte)104,(byte)152,(byte)22,(byte)212,(byte)164,(byte)92,(byte)204,(byte)93,(byte)101,(byte)182,(byte)146, + (byte)108,(byte)112,(byte)72,(byte)80,(byte)253,(byte)237,(byte)185,(byte)218,(byte)94,(byte)21,(byte)70,(byte)87,(byte)167,(byte)141,(byte)157,(byte)132, + (byte)144,(byte)216,(byte)171,(byte)0,(byte)140,(byte)188,(byte)211,(byte)10,(byte)247,(byte)228,(byte)88,(byte)5,(byte)184,(byte)179,(byte)69,(byte)6, + (byte)208,(byte)44,(byte)30,(byte)143,(byte)202,(byte)63,(byte)15,(byte)2,(byte)193,(byte)175,(byte)189,(byte)3,(byte)1,(byte)19,(byte)138,(byte)107, + (byte)58,(byte)145,(byte)17,(byte)65,(byte)79,(byte)103,(byte)220,(byte)234,(byte)151,(byte)242,(byte)207,(byte)206,(byte)240,(byte)180,(byte)230,(byte)115, + (byte)150,(byte)172,(byte)116,(byte)34,(byte)231,(byte)173,(byte)53,(byte)133,(byte)226,(byte)249,(byte)55,(byte)232,(byte)28,(byte)117,(byte)223,(byte)110, + (byte)71,(byte)241,(byte)26,(byte)113,(byte)29,(byte)41,(byte)197,(byte)137,(byte)111,(byte)183,(byte)98,(byte)14,(byte)170,(byte)24,(byte)190,(byte)27, + (byte)252,(byte)86,(byte)62,(byte)75,(byte)198,(byte)210,(byte)121,(byte)32,(byte)154,(byte)219,(byte)192,(byte)254,(byte)120,(byte)205,(byte)90,(byte)244, + (byte)31,(byte)221,(byte)168,(byte)51,(byte)136,(byte)7,(byte)199,(byte)49,(byte)177,(byte)18,(byte)16,(byte)89,(byte)39,(byte)128,(byte)236,(byte)95, + (byte)96,(byte)81,(byte)127,(byte)169,(byte)25,(byte)181,(byte)74,(byte)13,(byte)45,(byte)229,(byte)122,(byte)159,(byte)147,(byte)201,(byte)156,(byte)239, + (byte)160,(byte)224,(byte)59,(byte)77,(byte)174,(byte)42,(byte)245,(byte)176,(byte)200,(byte)235,(byte)187,(byte)60,(byte)131,(byte)83,(byte)153,(byte)97, + (byte)23,(byte)43,(byte)4,(byte)126,(byte)186,(byte)119,(byte)214,(byte)38,(byte)225,(byte)105,(byte)20,(byte)99,(byte)85,(byte)33,(byte)12,(byte)125}; + + private static final byte[] rco= + {(byte)1,(byte)2,(byte)4,(byte)8,(byte)16,(byte)32,(byte)64,(byte)128,(byte)27,(byte)54,(byte)108,(byte)216,(byte)171,(byte)77,(byte)154,(byte)47}; + + private static final int[] ftable= + {0xa56363c6,0x847c7cf8,0x997777ee,0x8d7b7bf6,0xdf2f2ff,0xbd6b6bd6, + 0xb16f6fde,0x54c5c591,0x50303060,0x3010102,0xa96767ce,0x7d2b2b56, + 0x19fefee7,0x62d7d7b5,0xe6abab4d,0x9a7676ec,0x45caca8f,0x9d82821f, + 0x40c9c989,0x877d7dfa,0x15fafaef,0xeb5959b2,0xc947478e,0xbf0f0fb, + 0xecadad41,0x67d4d4b3,0xfda2a25f,0xeaafaf45,0xbf9c9c23,0xf7a4a453, + 0x967272e4,0x5bc0c09b,0xc2b7b775,0x1cfdfde1,0xae93933d,0x6a26264c, + 0x5a36366c,0x413f3f7e,0x2f7f7f5,0x4fcccc83,0x5c343468,0xf4a5a551, + 0x34e5e5d1,0x8f1f1f9,0x937171e2,0x73d8d8ab,0x53313162,0x3f15152a, + 0xc040408,0x52c7c795,0x65232346,0x5ec3c39d,0x28181830,0xa1969637, + 0xf05050a,0xb59a9a2f,0x907070e,0x36121224,0x9b80801b,0x3de2e2df, + 0x26ebebcd,0x6927274e,0xcdb2b27f,0x9f7575ea,0x1b090912,0x9e83831d, + 0x742c2c58,0x2e1a1a34,0x2d1b1b36,0xb26e6edc,0xee5a5ab4,0xfba0a05b, + 0xf65252a4,0x4d3b3b76,0x61d6d6b7,0xceb3b37d,0x7b292952,0x3ee3e3dd, + 0x712f2f5e,0x97848413,0xf55353a6,0x68d1d1b9,0x0,0x2cededc1, + 0x60202040,0x1ffcfce3,0xc8b1b179,0xed5b5bb6,0xbe6a6ad4,0x46cbcb8d, + 0xd9bebe67,0x4b393972,0xde4a4a94,0xd44c4c98,0xe85858b0,0x4acfcf85, + 0x6bd0d0bb,0x2aefefc5,0xe5aaaa4f,0x16fbfbed,0xc5434386,0xd74d4d9a, + 0x55333366,0x94858511,0xcf45458a,0x10f9f9e9,0x6020204,0x817f7ffe, + 0xf05050a0,0x443c3c78,0xba9f9f25,0xe3a8a84b,0xf35151a2,0xfea3a35d, + 0xc0404080,0x8a8f8f05,0xad92923f,0xbc9d9d21,0x48383870,0x4f5f5f1, + 0xdfbcbc63,0xc1b6b677,0x75dadaaf,0x63212142,0x30101020,0x1affffe5, + 0xef3f3fd,0x6dd2d2bf,0x4ccdcd81,0x140c0c18,0x35131326,0x2fececc3, + 0xe15f5fbe,0xa2979735,0xcc444488,0x3917172e,0x57c4c493,0xf2a7a755, + 0x827e7efc,0x473d3d7a,0xac6464c8,0xe75d5dba,0x2b191932,0x957373e6, + 0xa06060c0,0x98818119,0xd14f4f9e,0x7fdcdca3,0x66222244,0x7e2a2a54, + 0xab90903b,0x8388880b,0xca46468c,0x29eeeec7,0xd3b8b86b,0x3c141428, + 0x79dedea7,0xe25e5ebc,0x1d0b0b16,0x76dbdbad,0x3be0e0db,0x56323264, + 0x4e3a3a74,0x1e0a0a14,0xdb494992,0xa06060c,0x6c242448,0xe45c5cb8, + 0x5dc2c29f,0x6ed3d3bd,0xefacac43,0xa66262c4,0xa8919139,0xa4959531, + 0x37e4e4d3,0x8b7979f2,0x32e7e7d5,0x43c8c88b,0x5937376e,0xb76d6dda, + 0x8c8d8d01,0x64d5d5b1,0xd24e4e9c,0xe0a9a949,0xb46c6cd8,0xfa5656ac, + 0x7f4f4f3,0x25eaeacf,0xaf6565ca,0x8e7a7af4,0xe9aeae47,0x18080810, + 0xd5baba6f,0x887878f0,0x6f25254a,0x722e2e5c,0x241c1c38,0xf1a6a657, + 0xc7b4b473,0x51c6c697,0x23e8e8cb,0x7cdddda1,0x9c7474e8,0x211f1f3e, + 0xdd4b4b96,0xdcbdbd61,0x868b8b0d,0x858a8a0f,0x907070e0,0x423e3e7c, + 0xc4b5b571,0xaa6666cc,0xd8484890,0x5030306,0x1f6f6f7,0x120e0e1c, + 0xa36161c2,0x5f35356a,0xf95757ae,0xd0b9b969,0x91868617,0x58c1c199, + 0x271d1d3a,0xb99e9e27,0x38e1e1d9,0x13f8f8eb,0xb398982b,0x33111122, + 0xbb6969d2,0x70d9d9a9,0x898e8e07,0xa7949433,0xb69b9b2d,0x221e1e3c, + 0x92878715,0x20e9e9c9,0x49cece87,0xff5555aa,0x78282850,0x7adfdfa5, + 0x8f8c8c03,0xf8a1a159,0x80898909,0x170d0d1a,0xdabfbf65,0x31e6e6d7, + 0xc6424284,0xb86868d0,0xc3414182,0xb0999929,0x772d2d5a,0x110f0f1e, + 0xcbb0b07b,0xfc5454a8,0xd6bbbb6d,0x3a16162c}; + + private static final int[] rtable= + {0x50a7f451,0x5365417e,0xc3a4171a,0x965e273a,0xcb6bab3b,0xf1459d1f, + 0xab58faac,0x9303e34b,0x55fa3020,0xf66d76ad,0x9176cc88,0x254c02f5, + 0xfcd7e54f,0xd7cb2ac5,0x80443526,0x8fa362b5,0x495ab1de,0x671bba25, + 0x980eea45,0xe1c0fe5d,0x2752fc3,0x12f04c81,0xa397468d,0xc6f9d36b, + 0xe75f8f03,0x959c9215,0xeb7a6dbf,0xda595295,0x2d83bed4,0xd3217458, + 0x2969e049,0x44c8c98e,0x6a89c275,0x78798ef4,0x6b3e5899,0xdd71b927, + 0xb64fe1be,0x17ad88f0,0x66ac20c9,0xb43ace7d,0x184adf63,0x82311ae5, + 0x60335197,0x457f5362,0xe07764b1,0x84ae6bbb,0x1ca081fe,0x942b08f9, + 0x58684870,0x19fd458f,0x876cde94,0xb7f87b52,0x23d373ab,0xe2024b72, + 0x578f1fe3,0x2aab5566,0x728ebb2,0x3c2b52f,0x9a7bc586,0xa50837d3, + 0xf2872830,0xb2a5bf23,0xba6a0302,0x5c8216ed,0x2b1ccf8a,0x92b479a7, + 0xf0f207f3,0xa1e2694e,0xcdf4da65,0xd5be0506,0x1f6234d1,0x8afea6c4, + 0x9d532e34,0xa055f3a2,0x32e18a05,0x75ebf6a4,0x39ec830b,0xaaef6040, + 0x69f715e,0x51106ebd,0xf98a213e,0x3d06dd96,0xae053edd,0x46bde64d, + 0xb58d5491,0x55dc471,0x6fd40604,0xff155060,0x24fb9819,0x97e9bdd6, + 0xcc434089,0x779ed967,0xbd42e8b0,0x888b8907,0x385b19e7,0xdbeec879, + 0x470a7ca1,0xe90f427c,0xc91e84f8,0x0,0x83868009,0x48ed2b32, + 0xac70111e,0x4e725a6c,0xfbff0efd,0x5638850f,0x1ed5ae3d,0x27392d36, + 0x64d90f0a,0x21a65c68,0xd1545b9b,0x3a2e3624,0xb1670a0c,0xfe75793, + 0xd296eeb4,0x9e919b1b,0x4fc5c080,0xa220dc61,0x694b775a,0x161a121c, + 0xaba93e2,0xe52aa0c0,0x43e0223c,0x1d171b12,0xb0d090e,0xadc78bf2, + 0xb9a8b62d,0xc8a91e14,0x8519f157,0x4c0775af,0xbbdd99ee,0xfd607fa3, + 0x9f2601f7,0xbcf5725c,0xc53b6644,0x347efb5b,0x7629438b,0xdcc623cb, + 0x68fcedb6,0x63f1e4b8,0xcadc31d7,0x10856342,0x40229713,0x2011c684, + 0x7d244a85,0xf83dbbd2,0x1132f9ae,0x6da129c7,0x4b2f9e1d,0xf330b2dc, + 0xec52860d,0xd0e3c177,0x6c16b32b,0x99b970a9,0xfa489411,0x2264e947, + 0xc48cfca8,0x1a3ff0a0,0xd82c7d56,0xef903322,0xc74e4987,0xc1d138d9, + 0xfea2ca8c,0x360bd498,0xcf81f5a6,0x28de7aa5,0x268eb7da,0xa4bfad3f, + 0xe49d3a2c,0xd927850,0x9bcc5f6a,0x62467e54,0xc2138df6,0xe8b8d890, + 0x5ef7392e,0xf5afc382,0xbe805d9f,0x7c93d069,0xa92dd56f,0xb31225cf, + 0x3b99acc8,0xa77d1810,0x6e639ce8,0x7bbb3bdb,0x97826cd,0xf418596e, + 0x1b79aec,0xa89a4f83,0x656e95e6,0x7ee6ffaa,0x8cfbc21,0xe6e815ef, + 0xd99be7ba,0xce366f4a,0xd4099fea,0xd67cb029,0xafb2a431,0x31233f2a, + 0x3094a5c6,0xc066a235,0x37bc4e74,0xa6ca82fc,0xb0d090e0,0x15d8a733, + 0x4a9804f1,0xf7daec41,0xe50cd7f,0x2ff69117,0x8dd64d76,0x4db0ef43, + 0x544daacc,0xdf0496e4,0xe3b5d19e,0x1b886a4c,0xb81f2cc1,0x7f516546, + 0x4ea5e9d,0x5d358c01,0x737487fa,0x2e410bfb,0x5a1d67b3,0x52d2db92, + 0x335610e9,0x1347d66d,0x8c61d79a,0x7a0ca137,0x8e14f859,0x893c13eb, + 0xee27a9ce,0x35c961b7,0xede51ce1,0x3cb1477a,0x59dfd29c,0x3f73f255, + 0x79ce1418,0xbf37c773,0xeacdf753,0x5baafd5f,0x146f3ddf,0x86db4478, + 0x81f3afca,0x3ec468b9,0x2c342438,0x5f40a3c2,0x72c31d16,0xc25e2bc, + 0x8b493c28,0x41950dff,0x7101a839,0xdeb30c08,0x9ce4b4d8,0x90c15664, + 0x6184cb7b,0x70b632d5,0x745c6c48,0x4257b8d0}; + + +/* Rotates 32-bit word left by 1, 2 or 3 byte */ + + private static int ROTL8(int x) + { + return (((x)<<8)|((x)>>>24)); + } + + private static int ROTL16(int x) + { + return (((x)<<16)|((x)>>>16)); + } + + private static int ROTL24(int x) + { + return (((x)<<24)|((x)>>>8)); + } + + private static int pack(byte[] b) + { /* pack bytes into a 32-bit Word */ + return ((((int)b[3])&0xff)<<24)|(((int)b[2]&0xff)<<16)|(((int)b[1]&0xff)<<8)|((int)b[0]&0xff); + } + + private static byte[] unpack(int a) + { /* unpack bytes from a word */ + byte [] b=new byte[4]; + b[0]=(byte)(a); + b[1]=(byte)(a>>>8); + b[2]=(byte)(a>>>16); + b[3]=(byte)(a>>>24); + return b; + } + + private static byte bmul(byte x,byte y) + { /* x.y= AntiLog(Log(x) + Log(y)) */ + + int ix=((int)x)&0xff; + int iy=((int)y)&0xff; + int lx=((int)ltab[ix])&0xff; + int ly=((int)ltab[iy])&0xff; + if (x!=0 && y!=0) return ptab[(lx+ly)%255]; + else return (byte)0; + } + + // if (x && y) + + private static int SubByte(int a) + { + byte [] b=unpack(a); + b[0]=fbsub[(int)b[0]&0xff]; + b[1]=fbsub[(int)b[1]&0xff]; + b[2]=fbsub[(int)b[2]&0xff]; + b[3]=fbsub[(int)b[3]&0xff]; + return pack(b); + } + + private static byte product(int x,int y) + { /* dot product of two 4-byte arrays */ + byte [] xb;//=new byte[4]; + byte [] yb;//=new byte[4]; + xb=unpack(x); + yb=unpack(y); + + return (byte)(bmul(xb[0],yb[0])^bmul(xb[1],yb[1])^bmul(xb[2],yb[2])^bmul(xb[3],yb[3])); + } + + private static int InvMixCol(int x) + { /* matrix Multiplication */ + int y,m; + byte [] b=new byte[4]; + + m=pack(InCo); + b[3]=product(m,x); + m=ROTL24(m); + b[2]=product(m,x); + m=ROTL24(m); + b[1]=product(m,x); + m=ROTL24(m); + b[0]=product(m,x); + y=pack(b); + return y; + } + + private static void increment(byte [] f) + { + int i; + for (i=0;i<16;i++) + { + f[i]++; + if (f[i]!=0) break; + } + } + +/* reset cipher */ + public void reset(int m,byte[] iv) + { /* reset mode, or reset iv */ + mode=m; + for (int i=0;i<16;i++) + f[i]=0; + if (mode!=ECB && iv!=null) + for (int i=0;i<16;i++) + f[i]=iv[i]; + } + + public byte[] getreg() + { + byte [] ir=new byte[16]; + for (int i=0;i<16;i++) ir[i]=f[i]; + return ir; + } + +/* Initialise cipher */ + public boolean init(int m,int nk,byte[] key,byte[] iv) + { /* Key=16 bytes */ + /* Key Scheduler. Create expanded encryption key */ + int i,j,k,N,nr; + int [] CipherKey=new int[8]; + byte [] b=new byte[4]; + nk/=4; + + if (nk!=4 && nk!=6 && nk!=8) return false; + + nr=6+nk; + + Nk=nk; Nr=nr; + + reset(m,iv); + N=4*(nr+1); + + for (i=j=0;i<nk;i++,j+=4) + { + for (k=0;k<4;k++) b[k]=key[j+k]; + CipherKey[i]=pack(b); + } + for (i=0;i<nk;i++) fkey[i]=CipherKey[i]; + for (j=nk,k=0;j<N;j+=nk,k++) + { + fkey[j]=fkey[j-nk]^SubByte(ROTL24(fkey[j-1]))^((int)rco[k])&0xff; + for (i=1;i<nk && (i+j)<N;i++) + fkey[i+j]=fkey[i+j-nk]^fkey[i+j-1]; + } + + /* now for the expanded decrypt key in reverse order */ + + for (j=0;j<4;j++) rkey[j+N-4]=fkey[j]; + for (i=4;i<N-4;i+=4) + { + k=N-4-i; + for (j=0;j<4;j++) rkey[k+j]=InvMixCol(fkey[i+j]); + } + for (j=N-4;j<N;j++) rkey[j-N+4]=fkey[j]; + return true; + } + +/* Encrypt a single block */ + public void ecb_encrypt(byte[] buff) + { + int i,j,k; + int t; + byte [] b=new byte[4]; + int [] p=new int[4]; + int [] q=new int[4]; + + for (i=j=0;i<4;i++,j+=4) + { + for (k=0;k<4;k++) b[k]=buff[j+k]; + p[i]=pack(b); + p[i]^=fkey[i]; + } + + k=4; + +/* State alternates between p and q */ + for (i=1;i<Nr;i++) + { + q[0]=fkey[k]^ftable[p[0]&0xff]^ + ROTL8(ftable[(p[1]>>>8)&0xff])^ + ROTL16(ftable[(p[2]>>>16)&0xff])^ + ROTL24(ftable[(p[3]>>>24)&0xff]); + q[1]=fkey[k+1]^ftable[p[1]&0xff]^ + ROTL8(ftable[(p[2]>>>8)&0xff])^ + ROTL16(ftable[(p[3]>>>16)&0xff])^ + ROTL24(ftable[(p[0]>>>24)&0xff]); + q[2]=fkey[k+2]^ftable[p[2]&0xff]^ + ROTL8(ftable[(p[3]>>>8)&0xff])^ + ROTL16(ftable[(p[0]>>>16)&0xff])^ + ROTL24(ftable[(p[1]>>>24)&0xff]); + q[3]=fkey[k+3]^ftable[p[3]&0xff]^ + ROTL8(ftable[(p[0]>>>8)&0xff])^ + ROTL16(ftable[(p[1]>>>16)&0xff])^ + ROTL24(ftable[(p[2]>>>24)&0xff]); + + k+=4; + for (j=0;j<4;j++) + { + t=p[j]; p[j]=q[j]; q[j]=t; + } + } + +/* Last Round */ + + q[0]=fkey[k]^((int)fbsub[p[0]&0xff]&0xff)^ + ROTL8((int)fbsub[(p[1]>>>8)&0xff]&0xff)^ + ROTL16((int)fbsub[(p[2]>>>16)&0xff]&0xff)^ + ROTL24((int)fbsub[(p[3]>>>24)&0xff]&0xff); + + q[1]=fkey[k+1]^((int)fbsub[p[1]&0xff]&0xff)^ + ROTL8((int)fbsub[(p[2]>>>8)&0xff]&0xff)^ + ROTL16((int)fbsub[(p[3]>>>16)&0xff]&0xff)^ + ROTL24((int)fbsub[(p[0]>>>24)&0xff]&0xff); + + q[2]=fkey[k+2]^((int)fbsub[p[2]&0xff]&0xff)^ + ROTL8((int)fbsub[(p[3]>>>8)&0xff]&0xff)^ + ROTL16((int)fbsub[(p[0]>>>16)&0xff]&0xff)^ + ROTL24((int)fbsub[(p[1]>>>24)&0xff]&0xff); + + q[3]=fkey[k+3]^((int)fbsub[(p[3])&0xff]&0xff)^ + ROTL8((int)fbsub[(p[0]>>>8)&0xff]&0xff)^ + ROTL16((int)fbsub[(p[1]>>>16)&0xff]&0xff)^ + ROTL24((int)fbsub[(p[2]>>>24)&0xff]&0xff); + + for (i=j=0;i<4;i++,j+=4) + { + b=unpack(q[i]); + for (k=0;k<4;k++) buff[j+k]=b[k]; + } + } + +/* Decrypt a single block */ + public void ecb_decrypt(byte[] buff) + { + int i,j,k; + int t; + byte [] b=new byte[4]; + int [] p=new int[4]; + int [] q=new int[4]; + + for (i=j=0;i<4;i++,j+=4) + { + for (k=0;k<4;k++) b[k]=buff[j+k]; + p[i]=pack(b); + p[i]^=rkey[i]; + } + + k=4; + +/* State alternates between p and q */ + for (i=1;i<Nr;i++) + { + q[0]=rkey[k]^rtable[p[0]&0xff]^ + ROTL8(rtable[(p[3]>>>8)&0xff])^ + ROTL16(rtable[(p[2]>>>16)&0xff])^ + ROTL24(rtable[(p[1]>>>24)&0xff]); + q[1]=rkey[k+1]^rtable[p[1]&0xff]^ + ROTL8(rtable[(p[0]>>>8)&0xff])^ + ROTL16(rtable[(p[3]>>>16)&0xff])^ + ROTL24(rtable[(p[2]>>>24)&0xff]); + q[2]=rkey[k+2]^rtable[p[2]&0xff]^ + ROTL8(rtable[(p[1]>>>8)&0xff])^ + ROTL16(rtable[(p[0]>>>16)&0xff])^ + ROTL24(rtable[(p[3]>>>24)&0xff]); + q[3]=rkey[k+3]^rtable[p[3]&0xff]^ + ROTL8(rtable[(p[2]>>>8)&0xff])^ + ROTL16(rtable[(p[1]>>>16)&0xff])^ + ROTL24(rtable[(p[0]>>>24)&0xff]); + + k+=4; + for (j=0;j<4;j++) + { + t=p[j]; p[j]=q[j]; q[j]=t; + } + } + +/* Last Round */ + + q[0]=rkey[k]^((int)rbsub[p[0]&0xff]&0xff)^ + ROTL8((int)rbsub[(p[3]>>>8)&0xff]&0xff)^ + ROTL16((int)rbsub[(p[2]>>>16)&0xff]&0xff)^ + ROTL24((int)rbsub[(p[1]>>>24)&0xff]&0xff); + q[1]=rkey[k+1]^((int)rbsub[p[1]&0xff]&0xff)^ + ROTL8((int)rbsub[(p[0]>>>8)&0xff]&0xff)^ + ROTL16((int)rbsub[(p[3]>>>16)&0xff]&0xff)^ + ROTL24((int)rbsub[(p[2]>>>24)&0xff]&0xff); + q[2]=rkey[k+2]^((int)rbsub[p[2]&0xff]&0xff)^ + ROTL8((int)rbsub[(p[1]>>>8)&0xff]&0xff)^ + ROTL16((int)rbsub[(p[0]>>>16)&0xff]&0xff)^ + ROTL24((int)rbsub[(p[3]>>>24)&0xff]&0xff); + q[3]=rkey[k+3]^((int)rbsub[p[3]&0xff]&0xff)^ + ROTL8((int)rbsub[(p[2]>>>8)&0xff]&0xff)^ + ROTL16((int)rbsub[(p[1]>>>16)&0xff]&0xff)^ + ROTL24((int)rbsub[(p[0]>>>24)&0xff]&0xff); + + for (i=j=0;i<4;i++,j+=4) + { + b=unpack(q[i]); + for (k=0;k<4;k++) buff[j+k]=b[k]; + } + + } + +/* Encrypt using selected mode of operation */ + public int encrypt(byte[] buff) + { + int j,bytes; + byte[] st=new byte[16]; + int fell_off; + +// Supported Modes of Operation + + fell_off=0; + switch (mode) + { + case ECB: + ecb_encrypt(buff); + return 0; + case CBC: + for (j=0;j<16;j++) buff[j]^=f[j]; + ecb_encrypt(buff); + for (j=0;j<16;j++) f[j]=buff[j]; + return 0; + + case CFB1: + case CFB2: + case CFB4: + bytes=mode-CFB1+1; + for (j=0;j<bytes;j++) fell_off=(fell_off<<8)|f[j]; + for (j=0;j<16;j++) st[j]=f[j]; + for (j=bytes;j<16;j++) f[j-bytes]=f[j]; + ecb_encrypt(st); + for (j=0;j<bytes;j++) + { + buff[j]^=st[j]; + f[16-bytes+j]=buff[j]; + } + return fell_off; + + case OFB1: + case OFB2: + case OFB4: + case OFB8: + case OFB16: + + bytes=mode-OFB1+1; + ecb_encrypt(f); + for (j=0;j<bytes;j++) buff[j]^=f[j]; + return 0; + + case CTR1: + case CTR2: + case CTR4: + case CTR8: + case CTR16: + + bytes=mode-CTR1+1; + for (j=0;j<16;j++) st[j]=f[j]; + ecb_encrypt(st); + for (j=0;j<bytes;j++) buff[j]^=st[j]; + increment(f); + + default: + return 0; + } + } + +/* Decrypt using selected mode of operation */ + public int decrypt(byte[] buff) + { + int j,bytes; + byte[] st=new byte[16]; + int fell_off; + + // Supported modes of operation + fell_off=0; + switch (mode) + { + case ECB: + ecb_decrypt(buff); + return 0; + case CBC: + for (j=0;j<16;j++) + { + st[j]=f[j]; + f[j]=buff[j]; + } + ecb_decrypt(buff); + for (j=0;j<16;j++) + { + buff[j]^=st[j]; + st[j]=0; + } + return 0; + case CFB1: + case CFB2: + case CFB4: + bytes=mode-CFB1+1; + for (j=0;j<bytes;j++) fell_off=(fell_off<<8)|f[j]; + for (j=0;j<16;j++) st[j]=f[j]; + for (j=bytes;j<16;j++) f[j-bytes]=f[j]; + ecb_encrypt(st); + for (j=0;j<bytes;j++) + { + f[16-bytes+j]=buff[j]; + buff[j]^=st[j]; + } + return fell_off; + case OFB1: + case OFB2: + case OFB4: + case OFB8: + case OFB16: + bytes=mode-OFB1+1; + ecb_encrypt(f); + for (j=0;j<bytes;j++) buff[j]^=f[j]; + return 0; + + case CTR1: + case CTR2: + case CTR4: + case CTR8: + case CTR16: + + bytes=mode-CTR1+1; + for (j=0;j<16;j++) st[j]=f[j]; + ecb_encrypt(st); + for (j=0;j<bytes;j++) buff[j]^=st[j]; + increment(f); + + default: + return 0; + } + } + +/* Clean up and delete left-overs */ + public void end() + { // clean up + int i; + for (i=0;i<4*(Nr+1);i++) + fkey[i]=rkey[i]=0; + for (i=0;i<16;i++) + f[i]=0; + } + + public static void main(String[] args) { + int i; + + byte[] key=new byte[32]; + byte[] block=new byte[16]; + byte[] iv=new byte[16]; + + for (i=0;i<32;i++) key[i]=0; + key[0]=1; + for (i=0;i<16;i++) iv[i]=(byte)i; + for (i=0;i<16;i++) block[i]=(byte)i; + + AES a=new AES(); + + a.init(CTR16,32,key,iv); + System.out.println("Plain= "); + for (i=0;i<16;i++) System.out.format("%02X ", block[i]&0xff); + System.out.println(""); + + a.encrypt(block); + + System.out.println("Encrypt= "); + for (i=0;i<16;i++) System.out.format("%02X ", block[i]&0xff); + System.out.println(""); + + a.reset(CTR16,iv); + a.decrypt(block); + + System.out.println("Decrypt= "); + for (i=0;i<16;i++) System.out.format("%02X ", block[i]&0xff); + System.out.println(""); + + a.end(); + + } +}
http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version22/java/BIG32.java ---------------------------------------------------------------------- diff --git a/version22/java/BIG32.java b/version22/java/BIG32.java new file mode 100644 index 0000000..e43e7b4 --- /dev/null +++ b/version22/java/BIG32.java @@ -0,0 +1,1016 @@ +/* +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. +*/ + +/* AMCL BIG number class */ + +public class BIG { + protected int[] w=new int[ROM.NLEN]; +/* Constructors */ + + public BIG() + { + for (int i=0;i<ROM.NLEN;i++) + w[i]=0; + } + + public BIG(int x) + { + w[0]=x; + for (int i=1;i<ROM.NLEN;i++) + w[i]=0; + } + + public BIG(BIG x) + { + for (int i=0;i<ROM.NLEN;i++) + w[i]=x.w[i]; + } + + public BIG(DBIG x) + { + for (int i=0;i<ROM.NLEN;i++) + w[i]=x.w[i]; + } + + public BIG(int[] x) + { + for (int i=0;i<ROM.NLEN;i++) + w[i]=x[i]; + } + + public int get(int i) + { + return w[i]; + } + + public void set(int i,int x) + { + w[i]=x; + } + +/* calculate Field Excess */ + public static int EXCESS(BIG a) + { + return ((a.w[ROM.NLEN-1]&ROM.OMASK)>>(ROM.MODBITS%ROM.BASEBITS)); + } + +/* Check if product causes excess */ + public static boolean pexceed(BIG a,BIG b) + { + int ea,eb; + ea=EXCESS(a); + eb=EXCESS(b); + if ((long)(ea+1)*(eb+1)>ROM.FEXCESS) return true; + return false; + } + +/* Check if square causes excess */ + public static boolean sexceed(BIG a) + { + int ea,eb; + ea=EXCESS(a); + if ((long)(ea+1)*(ea+1)>ROM.FEXCESS) return true; + return false; + } + + public static int FF_EXCESS(BIG a) + { + return ((a.get(ROM.NLEN-1)&ROM.P_OMASK)>>(ROM.P_TBITS)); + } + +/* Check if product causes excess */ + public static boolean ff_pexceed(BIG a,BIG b) + { + int ea,eb; + ea=FF_EXCESS(a); + eb=FF_EXCESS(b); + if ((long)(ea+1)*(eb+1)>ROM.P_FEXCESS) return true; + return false; + } + +/* Check if square causes excess */ + public static boolean ff_sexceed(BIG a) + { + int ea; + ea=FF_EXCESS(a); + if ((long)(ea+1)*(ea+1)>ROM.P_FEXCESS) return true; + return false; + } + +/* Conditional swap of two bigs depending on d using XOR - no branches */ + public void cswap(BIG b,int d) + { + int i; + int t,c=d; + c=~(c-1); + + for (i=0;i<ROM.NLEN;i++) + { + t=c&(w[i]^b.w[i]); + w[i]^=t; + b.w[i]^=t; + } + } + + public void cmove(BIG g,int d) + { + int i; + int b=-d; + + for (i=0;i<ROM.NLEN;i++) + { + w[i]^=(w[i]^g.w[i])&b; + } + } + + public static int cast_to_chunk(int x) + { + return (int)x; + } + +/* normalise BIG - force all digits < 2^BASEBITS */ + public long norm() { + int d,carry=0; + for (int i=0;i<ROM.NLEN-1;i++) + { + d=w[i]+carry; + w[i]=d&ROM.BMASK; + carry=d>>ROM.BASEBITS; + } + w[ROM.NLEN-1]=(w[ROM.NLEN-1]+carry); + return (long)(w[ROM.NLEN-1]>>((8*ROM.MODBYTES)%ROM.BASEBITS)); + } + +/* return number of bits */ + public int nbits() { + int bts,k=ROM.NLEN-1; + int c; + norm(); + while (k>=0 && w[k]==0) k--; + if (k<0) return 0; + bts=ROM.BASEBITS*k; + c=w[k]; + while (c!=0) {c/=2; bts++;} + return bts; + } + + public String toRawString() + { + BIG b=new BIG(this); + String s="("; + for (int i=0;i<ROM.NLEN-1;i++) + { + s+=Integer.toHexString(b.w[i]); s+=","; + } + s+=Integer.toHexString(b.w[ROM.NLEN-1]); s+=")"; + return s; + } + +/* Convert to Hex String */ + public String toString() { + BIG b; + String s=""; + int len=nbits(); + + if (len%4==0) len/=4; + else {len/=4; len++;} + if (len<ROM.MODBYTES*2) len=ROM.MODBYTES*2; + + for (int i=len-1;i>=0;i--) + { + b=new BIG(this); + b.shr(i*4); + s+=Integer.toHexString(b.w[0]&15); + } + return s; + } + + public static int[] muladd(int x,int y,int c,int r) + { + int[] tb=new int[2]; + long prod=(long)x*y+c+r; + tb[1]=(int)prod&ROM.BMASK; + tb[0]=(int)(prod>>ROM.BASEBITS); + return tb; + } + +/* this*=x, where x is >NEXCESS */ + public int pmul(int c) + { + int ak,carry=0; + int[] cr=new int[2]; + + norm(); + for (int i=0;i<ROM.NLEN;i++) + { + ak=w[i]; + w[i]=0; + cr=muladd(ak,c,carry,w[i]); + carry=cr[0]; + w[i]=cr[1]; + } + return carry; + } + +/* this*=c and catch overflow in DBIG */ + public DBIG pxmul(int c) + { + DBIG m=new DBIG(0); + int[] cr=new int[2]; + int carry=0; + for (int j=0;j<ROM.NLEN;j++) + { + cr=muladd(w[j],c,carry,m.w[j]); + carry=cr[0]; + m.w[j]=cr[1]; + } + m.w[ROM.NLEN]=carry; + return m; + } + +/* divide by 3 */ + public int div3() + { + int ak,base,carry=0; + norm(); + base=((int)1<<ROM.BASEBITS); + for (int i=ROM.NLEN-1;i>=0;i--) + { + ak=(carry*base+w[i]); + w[i]=ak/3; + carry=ak%3; + } + return (int)carry; + } + +/* return a*b where result fits in a BIG */ + public static BIG smul(BIG a,BIG b) + { + int carry; + BIG c=new BIG(0); + int[] cr=new int[2]; + for (int i=0;i<ROM.NLEN;i++) + { + carry=0; + for (int j=0;j<ROM.NLEN;j++) + { + if (i+j<ROM.NLEN) + { + cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]); + carry=cr[0]; + c.w[i+j]=cr[1]; + } + } + } + return c; + } + +/* return a*b as DBIG */ + public static DBIG mul(BIG a,BIG b) + { + long t,co; + DBIG c=new DBIG(0); + // a.norm(); + // b.norm(); + + long[] d=new long[ROM.NLEN]; + long s; + int i,k; + + for (i=0;i<ROM.NLEN;i++) + d[i]=(long)a.w[i]*b.w[i]; + + s=d[0]; + t=s; c.w[0]=(int)t&ROM.BMASK; co=t>>ROM.BASEBITS; + + for (k=1;k<ROM.NLEN;k++) + { + s+=d[k]; t=co+s; for (i=k;i>=1+k/2;i--) t+=(long)(a.w[i]-a.w[k-i])*(b.w[k-i]-b.w[i]); c.w[k]=(int)t&ROM.BMASK; co=t>>ROM.BASEBITS; + } + for (k=ROM.NLEN;k<2*ROM.NLEN-1;k++) + { + s-=d[k-ROM.NLEN]; t=co+s; for (i=ROM.NLEN-1;i>=1+k/2;i--) t+=(long)(a.w[i]-a.w[k-i])*(b.w[k-i]-b.w[i]); c.w[k]=(int)t&ROM.BMASK; co=t>>ROM.BASEBITS; + } + c.w[2*ROM.NLEN-1]=(int)co; + + return c; + } + +/* return a^2 as DBIG */ + public static DBIG sqr(BIG a) + { + int i,j,last; + long t,co; + DBIG c=new DBIG(0); + // a.norm(); + + t=(long)a.w[0]*a.w[0]; + c.w[0]=(int)t&ROM.BMASK; co=t>>ROM.BASEBITS; + t=(long)a.w[1]*a.w[0]; t+=t; t+=co; + c.w[1]=(int)t&ROM.BMASK; co=t>>ROM.BASEBITS; + + last=ROM.NLEN-ROM.NLEN%2; + for (j=2;j<last;j+=2) + { + t=(long)a.w[j]*a.w[0]; for (i=1;i<(j+1)/2;i++) t+=(long)a.w[j-i]*a.w[i]; t+=t; t+=co; t+=(long)a.w[j/2]*a.w[j/2]; + c.w[j]=(int)t&ROM.BMASK; co=t>>ROM.BASEBITS; + t=(long)a.w[j+1]*a.w[0]; for (i=1;i<(j+2)/2;i++) t+=(long)a.w[j+1-i]*a.w[i]; t+=t; t+=co; + c.w[j+1]=(int)t&ROM.BMASK; co=t>>ROM.BASEBITS; + } + j=last; + if (ROM.NLEN%2==1) + { + t=(long)a.w[j]*a.w[0]; for (i=1;i<(j+1)/2;i++) t+=(long)a.w[j-i]*a.w[i]; t+=t; t+=co; t+=(long)a.w[j/2]*a.w[j/2]; + c.w[j]=(int)t&ROM.BMASK; co=t>>ROM.BASEBITS; j++; + t=(long)a.w[ROM.NLEN-1]*a.w[j-ROM.NLEN+1]; for (i=j-ROM.NLEN+2;i<(j+1)/2;i++) t+=(long)a.w[j-i]*a.w[i]; t+=t; t+=co; + c.w[j]=(int)t&ROM.BMASK; co=t>>ROM.BASEBITS; j++; + } + for (;j<ROM.DNLEN-2;j+=2) + { + t=(long)a.w[ROM.NLEN-1]*a.w[j-ROM.NLEN+1]; for (i=j-ROM.NLEN+2;i<(j+1)/2;i++) t+=(long)a.w[j-i]*a.w[i]; t+=t; t+=co; t+=(long)a.w[j/2]*a.w[j/2]; + c.w[j]=(int)t&ROM.BMASK; co=t>>ROM.BASEBITS; + t=(long)a.w[ROM.NLEN-1]*a.w[j-ROM.NLEN+2]; for (i=j-ROM.NLEN+3;i<(j+2)/2;i++) t+=(long)a.w[j+1-i]*a.w[i]; t+=t; t+=co; + c.w[j+1]=(int)t&ROM.BMASK; co=t>>ROM.BASEBITS; + } + + t=(long)a.w[ROM.NLEN-1]*a.w[ROM.NLEN-1]+co; + c.w[ROM.DNLEN-2]=(int)t&ROM.BMASK; co=t>>ROM.BASEBITS; + c.w[ROM.DNLEN-1]=(int)co; + + return c; + } + + static BIG monty(DBIG d) + { + BIG b; + long t,c,s; + int i,k; + long[] dd=new long[ROM.NLEN]; + int[] v=new int[ROM.NLEN]; + BIG m=new BIG(ROM.Modulus); + b=new BIG(0); + + t=d.w[0]; v[0]=((int)t*ROM.MConst)&ROM.BMASK; t+=(long)v[0]*m.w[0]; c=(t>>ROM.BASEBITS)+d.w[1]; s=0; + + for (k=1;k<ROM.NLEN;k++) + { + t=c+s+(long)v[0]*m.w[k]; + for (i=k-1;i>k/2;i--) t+=(long)(v[k-i]-v[i])*(m.w[i]-m.w[k-i]); + v[k]=((int)t*ROM.MConst)&ROM.BMASK; t+=(long)v[k]*m.w[0]; c=(t>>ROM.BASEBITS)+d.w[k+1]; + dd[k]=(long)v[k]*m.w[k]; s+=dd[k]; + } + for (k=ROM.NLEN;k<2*ROM.NLEN-1;k++) + { + t=c+s; + for (i=ROM.NLEN-1;i>=1+k/2;i--) t+=(long)(v[k-i]-v[i])*(m.w[i]-m.w[k-i]); + b.w[k-ROM.NLEN]=(int)t&ROM.BMASK; c=(t>>ROM.BASEBITS)+d.w[k+1]; s-=dd[k-ROM.NLEN+1]; + } + b.w[ROM.NLEN-1]=(int)c&ROM.BMASK; + b.norm(); + return b; + } + +/* reduce a DBIG to a BIG using the appropriate form of the modulus */ + public static BIG mod(DBIG d) + { + if (ROM.MODTYPE==ROM.PSEUDO_MERSENNE) + { + BIG b; + int v,tw; + BIG t=d.split(ROM.MODBITS); + b=new BIG(d); + + v=t.pmul((int)ROM.MConst); + tw=t.w[ROM.NLEN-1]; + t.w[ROM.NLEN-1]&=ROM.TMASK; + t.w[0]+=(ROM.MConst*((tw>>ROM.TBITS)+(v<<(ROM.BASEBITS-ROM.TBITS)))); + + b.add(t); + b.norm(); + return b; + } + if (ROM.MODTYPE==ROM.MONTGOMERY_FRIENDLY) + { + BIG b; + int[] cr=new int[2]; + for (int i=0;i<ROM.NLEN;i++) + { + cr=muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[ROM.NLEN+i-1]); + d.w[ROM.NLEN+i]+=cr[0]; + d.w[ROM.NLEN+i-1]=cr[1]; + } + + b=new BIG(0); + for (int i=0;i<ROM.NLEN;i++ ) + b.w[i]=d.w[ROM.NLEN+i]; + b.norm(); + return b; + } + if (ROM.MODTYPE==ROM.GENERALISED_MERSENNE) + { // GoldiLocks Only + BIG b; + BIG t=d.split(ROM.MODBITS); + b=new BIG(d); + b.add(t); + DBIG dd=new DBIG(t); + dd.shl(ROM.MODBITS/2); + + BIG tt=dd.split(ROM.MODBITS); + BIG lo=new BIG(dd); + b.add(tt); + b.add(lo); + b.norm(); + tt.shl(ROM.MODBITS/2); + b.add(tt); + + int carry=b.w[ROM.NLEN-1]>>ROM.TBITS; + b.w[ROM.NLEN-1]&=ROM.TMASK; + b.w[0]+=carry; + + b.w[224/ROM.BASEBITS]+=carry<<(224%ROM.BASEBITS); + b.norm(); + return b; + } + if (ROM.MODTYPE==ROM.NOT_SPECIAL) + { + return monty(d); + } + + return new BIG(0); + } + + + +/****************************************************************************/ + public void xortop(long x) + { + w[ROM.NLEN-1]^=x; + } + +/* set x = x mod 2^m */ + public void mod2m(int m) + { + int i,wd,bt; + wd=m/ROM.BASEBITS; + bt=m%ROM.BASEBITS; + w[wd]&=((cast_to_chunk(1)<<bt)-1); + for (i=wd+1;i<ROM.NLEN;i++) w[i]=0; + } + +/* return n-th bit */ + public int bit(int n) + { + if ((w[n/ROM.BASEBITS]&(cast_to_chunk(1)<<(n%ROM.BASEBITS)))>0) return 1; + else return 0; + } + +/* Shift right by less than a word */ + public int fshr(int k) { + int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */ + for (int i=0;i<ROM.NLEN-1;i++) + w[i]=(w[i]>>k)|((w[i+1]<<(ROM.BASEBITS-k))&ROM.BMASK); + w[ROM.NLEN-1]=w[ROM.NLEN-1]>>k; + return r; + } + +/* Shift right by less than a word */ + public int fshl(int k) { + w[ROM.NLEN-1]=((w[ROM.NLEN-1]<<k))|(w[ROM.NLEN-2]>>(ROM.BASEBITS-k)); + for (int i=ROM.NLEN-2;i>0;i--) + w[i]=((w[i]<<k)&ROM.BMASK)|(w[i-1]>>(ROM.BASEBITS-k)); + w[0]=(w[0]<<k)&ROM.BMASK; + return (int)(w[ROM.NLEN-1]>>((8*ROM.MODBYTES)%ROM.BASEBITS)); /* return excess - only used in FF.java */ + } + +/* test for zero */ + public boolean iszilch() { + for (int i=0;i<ROM.NLEN;i++) + if (w[i]!=0) return false; + return true; + } + +/* set to zero */ + public void zero() + { + for (int i=0;i<ROM.NLEN;i++) + w[i]=0; + } + +/* set to one */ + public void one() + { + w[0]=1; + for (int i=1;i<ROM.NLEN;i++) + w[i]=0; + } + +/* Test for equal to one */ + public boolean isunity() + { + for (int i=1;i<ROM.NLEN;i++) + if (w[i]!=0) return false; + if (w[0]!=1) return false; + return true; + } + +/* Copy from another BIG */ + public void copy(BIG x) + { + for (int i=0;i<ROM.NLEN;i++) + w[i]=x.w[i]; + } + + public void copy(DBIG x) + { + for (int i=0;i<ROM.NLEN;i++) + w[i]=x.w[i]; + } + +/* general shift right */ + public void shr(int k) { + int n=k%ROM.BASEBITS; + int m=k/ROM.BASEBITS; + for (int i=0;i<ROM.NLEN-m-1;i++) + w[i]=(w[m+i]>>n)|((w[m+i+1]<<(ROM.BASEBITS-n))&ROM.BMASK); + if (ROM.NLEN>m) w[ROM.NLEN-m-1]=w[ROM.NLEN-1]>>n; + for (int i=ROM.NLEN-m;i<ROM.NLEN;i++) w[i]=0; + } + +/* general shift left */ + public void shl(int k) { + int n=k%ROM.BASEBITS; + int m=k/ROM.BASEBITS; + + w[ROM.NLEN-1]=((w[ROM.NLEN-1-m]<<n)); + if (ROM.NLEN>=m+2) w[ROM.NLEN-1]|=(w[ROM.NLEN-m-2]>>(ROM.BASEBITS-n)); + + for (int i=ROM.NLEN-2;i>m;i--) + w[i]=((w[i-m]<<n)&ROM.BMASK)|(w[i-m-1]>>(ROM.BASEBITS-n)); + w[m]=(w[0]<<n)&ROM.BMASK; + for (int i=0;i<m;i++) w[i]=0; + } + +/* return this+x */ + public BIG plus(BIG x) { + BIG s=new BIG(0); + for (int i=0;i<ROM.NLEN;i++) + s.w[i]=w[i]+x.w[i]; + return s; + } + +/* this+=x */ + public void add(BIG x) { + for (int i=0;i<ROM.NLEN;i++) + w[i]+=x.w[i]; + } + +/* this+=x, where x is int */ + public void inc(int x) { + norm(); + w[0]+=x; + } + +/* this+=x, where x is long */ + public void incl(long x) { + norm(); + w[0]+=x; + } + +/* return this.x */ + public BIG minus(BIG x) { + BIG d=new BIG(0); + for (int i=0;i<ROM.NLEN;i++) + d.w[i]=w[i]-x.w[i]; + return d; + } + +/* this-=x */ + public void sub(BIG x) { + for (int i=0;i<ROM.NLEN;i++) + w[i]-=x.w[i]; + } + +/* reverse subtract this=x-this */ + public void rsub(BIG x) { + for (int i=0;i<ROM.NLEN;i++) + w[i]=x.w[i]-w[i]; + } + +/* this-=x where x is int */ + public void dec(int x) { + norm(); + w[0]-=x; + } + +/* this*=x, where x is small int<NEXCESS */ + public void imul(int c) + { + for (int i=0;i<ROM.NLEN;i++) w[i]*=c; + } + +/* convert this BIG to byte array */ + public void tobytearray(byte[] b,int n) + { + norm(); + BIG c=new BIG(this); + + for (int i=ROM.MODBYTES-1;i>=0;i--) + { + b[i+n]=(byte)c.w[0]; + c.fshr(8); + } + } + +/* convert from byte array to BIG */ + public static BIG frombytearray(byte[] b,int n) + { + BIG m=new BIG(0); + + for (int i=0;i<ROM.MODBYTES;i++) + { + m.fshl(8); m.w[0]+=(int)b[i+n]&0xff; + //m.inc((int)b[i]&0xff); + } + return m; + } + + public void toBytes(byte[] b) + { + tobytearray(b,0); + } + + public static BIG fromBytes(byte[] b) + { + return frombytearray(b,0); + } + +/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */ + public static int comp(BIG a,BIG b) + { + for (int i=ROM.NLEN-1;i>=0;i--) + { + if (a.w[i]==b.w[i]) continue; + if (a.w[i]>b.w[i]) return 1; + else return -1; + } + return 0; + } + +/* Arazi and Qi inversion mod 256 */ + public static int invmod256(int a) + { + int U,t1,t2,b,c; + t1=0; + c=(a>>1)&1; + t1+=c; + t1&=1; + t1=2-t1; + t1<<=1; + U=t1+1; + +// i=2 + b=a&3; + t1=U*b; t1>>=2; + c=(a>>2)&3; + t2=(U*c)&3; + t1+=t2; + t1*=U; t1&=3; + t1=4-t1; + t1<<=2; + U+=t1; + +// i=4 + b=a&15; + t1=U*b; t1>>=4; + c=(a>>4)&15; + t2=(U*c)&15; + t1+=t2; + t1*=U; t1&=15; + t1=16-t1; + t1<<=4; + U+=t1; + + return U; + } + +/* a=1/a mod 2^256. This is very fast! */ + public void invmod2m() + { + int i; + BIG U=new BIG(0); + BIG b=new BIG(0); + BIG c=new BIG(0); + + U.inc(invmod256(lastbits(8))); + + for (i=8;i<ROM.BIGBITS;i<<=1) + { + b.copy(this); b.mod2m(i); + BIG t1=BIG.smul(U,b); + t1.shr(i); + + c.copy(this); c.shr(i); c.mod2m(i); + BIG t2=BIG.smul(U,c); t2.mod2m(i); + t1.add(t2); + b=BIG.smul(t1,U); t1.copy(b); + t1.mod2m(i); + + t2.one(); t2.shl(i); t1.rsub(t2); t1.norm(); + + t1.shl(i); + U.add(t1); + } + U.mod2m(ROM.BIGBITS); + copy(U); + norm(); + } + +/* reduce this mod m */ + public void mod(BIG m) + { + int k=0; + BIG r=new BIG(0); + + norm(); + if (comp(this,m)<0) return; + do + { + m.fshl(1); + k++; + } while (comp(this,m)>=0); + + while (k>0) + { + m.fshr(1); + + r.copy(this); + r.sub(m); + r.norm(); + cmove(r,(int)(1-((r.w[ROM.NLEN-1]>>(ROM.CHUNK-1))&1))); +/* + if (comp(this,m)>=0) + { + sub(m); + norm(); + } */ + k--; + } + } + +/* divide this by m */ + public void div(BIG m) + { + int d,k=0; + norm(); + BIG e=new BIG(1); + BIG b=new BIG(this); + BIG r=new BIG(0); + zero(); + + while (comp(b,m)>=0) + { + e.fshl(1); + m.fshl(1); + k++; + } + + while (k>0) + { + m.fshr(1); + e.fshr(1); + + r.copy(b); + r.sub(m); + r.norm(); + d=(int)(1-((r.w[ROM.NLEN-1]>>(ROM.CHUNK-1))&1)); + b.cmove(r,d); + r.copy(this); + r.add(e); + r.norm(); + cmove(r,d); + +/* + if (comp(b,m)>=0) + { + add(e); + norm(); + b.sub(m); + b.norm(); + } */ + k--; + } + } + +/* return parity */ + public int parity() + { + return (int)(w[0]%2); + } + +/* return n last bits */ + public int lastbits(int n) + { + int msk=(1<<n)-1; + norm(); + return ((int)w[0])&msk; + } + +/* get 8*MODBYTES size random number */ + public static BIG random(RAND rng) + { + BIG m=new BIG(0); + int i,b,j=0,r=0; + +/* generate random BIG */ + for (i=0;i<8*ROM.MODBYTES;i++) + { + if (j==0) r=rng.getByte(); + else r>>=1; + + b=r&1; + m.shl(1); m.w[0]+=b;// m.inc(b); + j++; j&=7; + } + return m; + } + +/* Create random BIG in portable way, one bit at a time */ + public static BIG randomnum(BIG q,RAND rng) + { + DBIG d=new DBIG(0); + int i,b,j=0,r=0; + for (i=0;i<2*ROM.MODBITS;i++) + { + if (j==0) r=rng.getByte(); + else r>>=1; + + b=r&1; + d.shl(1); d.w[0]+=b;// m.inc(b); + j++; j&=7; + } + BIG m=d.mod(q); + return m; + } + +/* return a*b mod m */ + public static BIG modmul(BIG a,BIG b,BIG m) + { + a.mod(m); + b.mod(m); + DBIG d=mul(a,b); + return d.mod(m); + } + +/* return a^2 mod m */ + public static BIG modsqr(BIG a,BIG m) + { + a.mod(m); + DBIG d=sqr(a); + return d.mod(m); + } + +/* return -a mod m */ + public static BIG modneg(BIG a,BIG m) + { + a.mod(m); + return m.minus(a); + } + +/* return this^e mod m */ + public BIG powmod(BIG e,BIG m) + { + int bt; + norm(); + e.norm(); + BIG a=new BIG(1); + BIG z=new BIG(e); + BIG s=new BIG(this); + while (true) + { + bt=z.parity(); + z.fshr(1); + if (bt==1) a=modmul(a,s,m); + if (z.iszilch()) break; + s=modsqr(s,m); + } + return a; + } + +/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */ + public int jacobi(BIG p) + { + int n8,k,m=0; + BIG t=new BIG(0); + BIG x=new BIG(0); + BIG n=new BIG(0); + BIG zilch=new BIG(0); + BIG one=new BIG(1); + if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0; + norm(); + x.copy(this); + n.copy(p); + x.mod(p); + + while (comp(n,one)>0) + { + if (comp(x,zilch)==0) return 0; + n8=n.lastbits(3); + k=0; + while (x.parity()==0) + { + k++; + x.shr(1); + } + if (k%2==1) m+=(n8*n8-1)/8; + m+=(n8-1)*(x.lastbits(2)-1)/4; + t.copy(n); + t.mod(x); + n.copy(x); + x.copy(t); + m%=2; + + } + if (m==0) return 1; + else return -1; + } + +/* this=1/this mod p. Binary method */ + public void invmodp(BIG p) + { + mod(p); + BIG u=new BIG(this); + BIG v=new BIG(p); + BIG x1=new BIG(1); + BIG x2=new BIG(0); + BIG t=new BIG(0); + BIG one=new BIG(1); + + while (comp(u,one)!=0 && comp(v,one)!=0) + { + while (u.parity()==0) + { + u.shr(1); + if (x1.parity()!=0) + { + x1.add(p); + x1.norm(); + } + x1.shr(1); + } + while (v.parity()==0) + { + v.shr(1); + if (x2.parity()!=0) + { + x2.add(p); + x2.norm(); + } + x2.shr(1); + } + if (comp(u,v)>=0) + { + u.sub(v); + u.norm(); + if (comp(x1,x2)>=0) x1.sub(x2); + else + { + t.copy(p); + t.sub(x2); + x1.add(t); + } + x1.norm(); + } + else + { + v.sub(u); + v.norm(); + if (comp(x2,x1)>=0) x2.sub(x1); + else + { + t.copy(p); + t.sub(x1); + x2.add(t); + } + x2.norm(); + } + } + if (comp(u,one)==0) copy(x1); + else copy(x2); + } +} http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version22/java/BIG64.java ---------------------------------------------------------------------- diff --git a/version22/java/BIG64.java b/version22/java/BIG64.java new file mode 100644 index 0000000..c66b495 --- /dev/null +++ b/version22/java/BIG64.java @@ -0,0 +1,1040 @@ +/* +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. +*/ + +/* AMCL BIG number class */ + +public class BIG { + protected long[] w=new long[ROM.NLEN]; +/* Constructors */ + public BIG() + { + for (int i=0;i<ROM.NLEN;i++) + w[i]=0; + } + + public BIG(int x) + { + w[0]=x; + for (int i=1;i<ROM.NLEN;i++) + w[i]=0; + } + + public BIG(BIG x) + { + for (int i=0;i<ROM.NLEN;i++) + w[i]=x.w[i]; + } + + public BIG(DBIG x) + { + for (int i=0;i<ROM.NLEN;i++) + w[i]=x.w[i]; + } + + public BIG(long[] x) + { + for (int i=0;i<ROM.NLEN;i++) + w[i]=x[i]; + } + + public long get(int i) + { + return w[i]; + } + + public void set(int i,long x) + { + w[i]=x; + } + +/* calculate Field Excess */ + public static long EXCESS(BIG a) + { + return ((a.w[ROM.NLEN-1]&ROM.OMASK)>>(ROM.MODBITS%ROM.BASEBITS)); + } + +/* Check if product causes excess */ + public static boolean pexceed(BIG a,BIG b) + { + long ea,eb; + ea=EXCESS(a); + eb=EXCESS(b); + if ((ea+1)>ROM.FEXCESS/(eb+1)) return true; + return false; + } + +/* Check if square causes excess */ + public static boolean sexceed(BIG a) + { + long ea; + ea=EXCESS(a); + if ((ea+1)>ROM.FEXCESS/(ea+1)) return true; + return false; + } + + public static long FF_EXCESS(BIG a) + { + return ((a.get(ROM.NLEN-1)&ROM.P_OMASK)>>(ROM.P_TBITS)); + } + +/* Check if product causes excess */ + public static boolean ff_pexceed(BIG a,BIG b) + { + long ea,eb; + ea=FF_EXCESS(a); + eb=FF_EXCESS(b); + if ((ea+1)>ROM.P_FEXCESS/(eb+1)) return true; + return false; + } + +/* Check if square causes excess */ + public static boolean ff_sexceed(BIG a) + { + long ea; + ea=FF_EXCESS(a); + if ((ea+1)>ROM.P_FEXCESS/(ea+1)) return true; + return false; + } + +/* Conditional swap of two bigs depending on d using XOR - no branches */ + public void cswap(BIG b,int d) + { + int i; + long t,c=(long)d; + c=~(c-1); + + for (i=0;i<ROM.NLEN;i++) + { + t=c&(w[i]^b.w[i]); + w[i]^=t; + b.w[i]^=t; + } + } + + public void cmove(BIG g,int d) + { + int i; + long t,b=-d; + + for (i=0;i<ROM.NLEN;i++) + { + w[i]^=(w[i]^g.w[i])&b; + } + } + + public static long cast_to_chunk(int x) + { + return (long)x; + } + +/* normalise BIG - force all digits < 2^BASEBITS */ + public long norm() { + long d,carry=0; + for (int i=0;i<ROM.NLEN-1;i++) + { + d=w[i]+carry; + w[i]=d&ROM.BMASK; + carry=(d>>ROM.BASEBITS); + } + w[ROM.NLEN-1]=(w[ROM.NLEN-1]+carry); + return (long)(w[ROM.NLEN-1]>>((8*ROM.MODBYTES)%ROM.BASEBITS)); + } + +/* return number of bits */ + public int nbits() { + int bts,k=ROM.NLEN-1; + long c; + norm(); + while (k>=0 && w[k]==0) k--; + if (k<0) return 0; + bts=ROM.BASEBITS*k; + c=w[k]; + while (c!=0) {c/=2; bts++;} + return bts; + } + + public String toRawString() + { + BIG b=new BIG(this); + String s="("; + for (int i=0;i<ROM.NLEN-1;i++) + { + s+=Long.toHexString(b.w[i]); s+=","; + } + s+=Long.toHexString(b.w[ROM.NLEN-1]); s+=")"; + return s; + } + +/* Convert to Hex String */ + public String toString() { + BIG b; + String s=""; + int len=nbits(); + + if (len%4==0) len/=4; + else {len/=4; len++;} + if (len<ROM.MODBYTES*2) len=ROM.MODBYTES*2; + + for (int i=len-1;i>=0;i--) + { + b=new BIG(this); + b.shr(i*4); + s+=Long.toHexString(b.w[0]&15); + } + return s; + } + +/* set this[i]+=x*y+c, and return high part */ +/* + public long muladd(long a,long b,long c,int i) + { + long x0,x1,y0,y1; + x0=a&ROM.HMASK; + x1=(a>>ROM.HBITS); + y0=b&ROM.HMASK; + y1=(b>>ROM.HBITS); + long bot=x0*y0; + long top=x1*y1; + long mid=x0*y1+x1*y0; + + x0=mid&ROM.HMASK; + x1=(mid>>ROM.HBITS); + bot+=x0<<ROM.HBITS; bot+=c; bot+=w[i]; + + top+=x1; + long carry=bot>>ROM.BASEBITS; + bot&=ROM.BMASK; + top+=carry; + w[i]=bot; + return top; + } +*/ + + public static long[] muladd(long a,long b,long c,long r) + { + long x0,x1,y0,y1; + long[] tb=new long[2]; + x0=a&ROM.HMASK; + x1=(a>>ROM.HBITS); + y0=b&ROM.HMASK; + y1=(b>>ROM.HBITS); + long bot=x0*y0; + long top=x1*y1; + long mid=x0*y1+x1*y0; + x0=mid&ROM.HMASK; + x1=(mid>>ROM.HBITS); + bot+=x0<<ROM.HBITS; bot+=c; bot+=r; + top+=x1; + long carry=bot>>ROM.BASEBITS; + bot&=ROM.BMASK; + top+=carry; + tb[0]=top; + tb[1]=bot; + return tb; + } + + + + +/* this*=x, where x is >NEXCESS */ + public long pmul(int c) + { + long ak,carry=0; + long[] cr=new long[2]; + norm(); + for (int i=0;i<ROM.NLEN;i++) + { + ak=w[i]; + w[i]=0; + + cr=muladd(ak,(long)c,carry,w[i]); + carry=cr[0]; + w[i]=cr[1]; + + } + return carry; + } + +/* this*=c and catch overflow in DBIG */ + public DBIG pxmul(int c) + { + DBIG m=new DBIG(0); + long[] cr=new long[2]; + long carry=0; + for (int j=0;j<ROM.NLEN;j++) + { + cr=muladd(w[j],(long)c,carry,m.w[j]); + carry=cr[0]; + m.w[j]=cr[1]; + } + m.w[ROM.NLEN]=carry; + return m; + } + +/* divide by 3 */ + public int div3() + { + long ak,base,carry=0; + norm(); + base=((long)1<<ROM.BASEBITS); + for (int i=ROM.NLEN-1;i>=0;i--) + { + ak=(carry*base+w[i]); + w[i]=ak/3; + carry=ak%3; + } + return (int)carry; + } + +/* return a*b where result fits in a BIG */ + public static BIG smul(BIG a,BIG b) + { + long carry; + long[] cr=new long[2]; + BIG c=new BIG(0); + for (int i=0;i<ROM.NLEN;i++) + { + carry=0; + for (int j=0;j<ROM.NLEN;j++) + if (i+j<ROM.NLEN) + { + cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]); + carry=cr[0]; + c.w[i+j]=cr[1]; + } + } + return c; + } + +/* return a*b as DBIG */ + public static DBIG mul(BIG a,BIG b) + { + DBIG c=new DBIG(0); + long carry; + long[] cr=new long[2]; +// a.norm(); +// b.norm(); + + for (int i=0;i<ROM.NLEN;i++) + { + carry=0; + for (int j=0;j<ROM.NLEN;j++) + { + cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]); + carry=cr[0]; + c.w[i+j]=cr[1]; + //carry=c.muladd(a.w[i],b.w[j],carry,i+j); + } + c.w[ROM.NLEN+i]=carry; + } + + return c; + } + +/* return a^2 as DBIG */ + public static DBIG sqr(BIG a) + { + DBIG c=new DBIG(0); + long carry; + long[] cr=new long[2]; + // a.norm(); + for (int i=0;i<ROM.NLEN;i++) + { + carry=0; + for (int j=i+1;j<ROM.NLEN;j++) + { + cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]); + carry=cr[0]; + c.w[i+j]=cr[1]; + //carry=c.muladd(2*a.w[i],a.w[j],carry,i+j); + } + c.w[ROM.NLEN+i]=carry; + } + + for (int i=0;i<ROM.NLEN;i++) + { + cr=muladd(a.w[i],a.w[i],0,c.w[2*i]); + c.w[2*i+1]+=cr[0]; + c.w[2*i]=cr[1]; + //c.w[2*i+1]+=c.muladd(a.w[i],a.w[i],0,2*i); + } + c.norm(); + return c; + } + + static BIG monty(DBIG d) + { + BIG b; + BIG md=new BIG(ROM.Modulus); + long m,carry; + long[] cr=new long[2]; + for (int i=0;i<ROM.NLEN;i++) + { + if (ROM.MConst==-1) m=(-d.w[i])&ROM.BMASK; + else + { + if (ROM.MConst==1) m=d.w[i]; + else m=(ROM.MConst*d.w[i])&ROM.BMASK; + } + + carry=0; + for (int j=0;j<ROM.NLEN;j++) + { + cr=muladd(m,md.w[j],carry,d.w[i+j]); + carry=cr[0]; + d.w[i+j]=cr[1]; + } + d.w[ROM.NLEN+i]+=carry; + } + + b=new BIG(0); + for (int i=0;i<ROM.NLEN;i++ ) + b.w[i]=d.w[ROM.NLEN+i]; + b.norm(); + return b; + } + +/* reduce a DBIG to a BIG using the appropriate form of the modulus */ + public static BIG mod(DBIG d) + { + if (ROM.MODTYPE==ROM.PSEUDO_MERSENNE) + { + BIG b; + long v,tw; + BIG t=d.split(ROM.MODBITS); + b=new BIG(d); + + v=t.pmul((int)ROM.MConst); + tw=t.w[ROM.NLEN-1]; + t.w[ROM.NLEN-1]&=ROM.TMASK; + t.w[0]+=(ROM.MConst*((tw>>ROM.TBITS)+(v<<(ROM.BASEBITS-ROM.TBITS)))); + + b.add(t); + b.norm(); + return b; + } + if (ROM.MODTYPE==ROM.MONTGOMERY_FRIENDLY) + { + BIG b; + long[] cr=new long[2]; + for (int i=0;i<ROM.NLEN;i++) + { + cr=muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[ROM.NLEN+i-1]); + d.w[ROM.NLEN+i]+=cr[0]; + d.w[ROM.NLEN+i-1]=cr[1]; + } + + b=new BIG(0); + for (int i=0;i<ROM.NLEN;i++ ) + b.w[i]=d.w[ROM.NLEN+i]; + b.norm(); + return b; + } + if (ROM.MODTYPE==ROM.GENERALISED_MERSENNE) + { // GoldiLocks Only + BIG b; + BIG t=d.split(ROM.MODBITS); + b=new BIG(d); + b.add(t); + DBIG dd=new DBIG(t); + dd.shl(ROM.MODBITS/2); + + BIG tt=dd.split(ROM.MODBITS); + BIG lo=new BIG(dd); + b.add(tt); + b.add(lo); + b.norm(); + tt.shl(ROM.MODBITS/2); + b.add(tt); + + long carry=b.w[ROM.NLEN-1]>>ROM.TBITS; + b.w[ROM.NLEN-1]&=ROM.TMASK; + b.w[0]+=carry; + + b.w[224/ROM.BASEBITS]+=carry<<(224%ROM.BASEBITS); + b.norm(); + return b; + } + if (ROM.MODTYPE==ROM.NOT_SPECIAL) + { + return monty(d); + } + + return new BIG(0); + } + + +/****************************************************************************/ + + public void xortop(long x) + { + w[ROM.NLEN-1]^=x; + } + +/* set x = x mod 2^m */ + public void mod2m(int m) + { + int i,wd,bt; + wd=m/ROM.BASEBITS; + bt=m%ROM.BASEBITS; + w[wd]&=((cast_to_chunk(1)<<bt)-1); + for (i=wd+1;i<ROM.NLEN;i++) w[i]=0; + } + +/* return n-th bit */ + public int bit(int n) + { + if ((w[n/ROM.BASEBITS]&(cast_to_chunk(1)<<(n%ROM.BASEBITS)))>0) return 1; + else return 0; + } + +/* Shift right by less than a word */ + public int fshr(int k) { + int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */ + for (int i=0;i<ROM.NLEN-1;i++) + w[i]=(w[i]>>k)|((w[i+1]<<(ROM.BASEBITS-k))&ROM.BMASK); + w[ROM.NLEN-1]=w[ROM.NLEN-1]>>k; + return r; + } + +/* Shift right by less than a word */ + public int fshl(int k) { + w[ROM.NLEN-1]=((w[ROM.NLEN-1]<<k))|(w[ROM.NLEN-2]>>(ROM.BASEBITS-k)); + for (int i=ROM.NLEN-2;i>0;i--) + w[i]=((w[i]<<k)&ROM.BMASK)|(w[i-1]>>(ROM.BASEBITS-k)); + w[0]=(w[0]<<k)&ROM.BMASK; + return (int)(w[ROM.NLEN-1]>>((8*ROM.MODBYTES)%ROM.BASEBITS)); /* return excess - only used in FF.java */ + } + +/* test for zero */ + public boolean iszilch() { + for (int i=0;i<ROM.NLEN;i++) + if (w[i]!=0) return false; + return true; + } + +/* set to zero */ + public void zero() + { + for (int i=0;i<ROM.NLEN;i++) + w[i]=0; + } + +/* set to one */ + public void one() + { + w[0]=1; + for (int i=1;i<ROM.NLEN;i++) + w[i]=0; + } + +/* Test for equal to one */ + public boolean isunity() + { + for (int i=1;i<ROM.NLEN;i++) + if (w[i]!=0) return false; + if (w[0]!=1) return false; + return true; + } + +/* Copy from another BIG */ + public void copy(BIG x) + { + for (int i=0;i<ROM.NLEN;i++) + w[i]=x.w[i]; + } + + public void copy(DBIG x) + { + for (int i=0;i<ROM.NLEN;i++) + w[i]=x.w[i]; + } + +/* general shift right */ + public void shr(int k) { + int n=k%ROM.BASEBITS; + int m=k/ROM.BASEBITS; + for (int i=0;i<ROM.NLEN-m-1;i++) + w[i]=(w[m+i]>>n)|((w[m+i+1]<<(ROM.BASEBITS-n))&ROM.BMASK); + if (ROM.NLEN>m) w[ROM.NLEN-m-1]=w[ROM.NLEN-1]>>n; + for (int i=ROM.NLEN-m;i<ROM.NLEN;i++) w[i]=0; + } + +/* general shift left */ + public void shl(int k) { + int n=k%ROM.BASEBITS; + int m=k/ROM.BASEBITS; + + w[ROM.NLEN-1]=((w[ROM.NLEN-1-m]<<n)); + if (ROM.NLEN>=m+2) w[ROM.NLEN-1]|=(w[ROM.NLEN-m-2]>>(ROM.BASEBITS-n)); + + for (int i=ROM.NLEN-2;i>m;i--) + w[i]=((w[i-m]<<n)&ROM.BMASK)|(w[i-m-1]>>(ROM.BASEBITS-n)); + w[m]=(w[0]<<n)&ROM.BMASK; + for (int i=0;i<m;i++) w[i]=0; + } + +/* return this+x */ + public BIG plus(BIG x) { + BIG s=new BIG(0); + for (int i=0;i<ROM.NLEN;i++) + s.w[i]=w[i]+x.w[i]; + return s; + } + +/* this+=x */ + public void add(BIG x) { + for (int i=0;i<ROM.NLEN;i++) + w[i]+=x.w[i]; + } + +/* this+=x, where x is int */ + public void inc(int x) { + norm(); + w[0]+=x; + } + +/* this+=x, where x is long */ + public void incl(long x) { + norm(); + w[0]+=x; + } + +/* return this.x */ + public BIG minus(BIG x) { + BIG d=new BIG(0); + for (int i=0;i<ROM.NLEN;i++) + d.w[i]=w[i]-x.w[i]; + return d; + } + +/* this-=x */ + public void sub(BIG x) { + for (int i=0;i<ROM.NLEN;i++) + w[i]-=x.w[i]; + } + +/* reverse subtract this=x-this */ + public void rsub(BIG x) { + for (int i=0;i<ROM.NLEN;i++) + w[i]=x.w[i]-w[i]; + } + +/* this-=x where x is int */ + public void dec(int x) { + norm(); + w[0]-=x; + } + +/* this*=x, where x is small int<NEXCESS */ + public void imul(int c) + { + for (int i=0;i<ROM.NLEN;i++) w[i]*=c; + } + +/* convert this BIG to byte array */ + public void tobytearray(byte[] b,int n) + { + norm(); + BIG c=new BIG(this); + + for (int i=ROM.MODBYTES-1;i>=0;i--) + { + b[i+n]=(byte)c.w[0]; + c.fshr(8); + } + } + +/* convert from byte array to BIG */ + public static BIG frombytearray(byte[] b,int n) + { + BIG m=new BIG(0); + + for (int i=0;i<ROM.MODBYTES;i++) + { + m.fshl(8); m.w[0]+=(int)b[i+n]&0xff; + //m.inc((int)b[i]&0xff); + } + return m; + } + + public void toBytes(byte[] b) + { + tobytearray(b,0); + } + + public static BIG fromBytes(byte[] b) + { + return frombytearray(b,0); + } + +/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */ + public static int comp(BIG a,BIG b) + { + for (int i=ROM.NLEN-1;i>=0;i--) + { + if (a.w[i]==b.w[i]) continue; + if (a.w[i]>b.w[i]) return 1; + else return -1; + } + return 0; + } + +/* Arazi and Qi inversion mod 256 */ + public static int invmod256(int a) + { + int U,t1,t2,b,c; + t1=0; + c=(a>>1)&1; + t1+=c; + t1&=1; + t1=2-t1; + t1<<=1; + U=t1+1; + +// i=2 + b=a&3; + t1=U*b; t1>>=2; + c=(a>>2)&3; + t2=(U*c)&3; + t1+=t2; + t1*=U; t1&=3; + t1=4-t1; + t1<<=2; + U+=t1; + +// i=4 + b=a&15; + t1=U*b; t1>>=4; + c=(a>>4)&15; + t2=(U*c)&15; + t1+=t2; + t1*=U; t1&=15; + t1=16-t1; + t1<<=4; + U+=t1; + + return U; + } + +/* a=1/a mod 2^256. This is very fast! */ + public void invmod2m() + { + int i; + BIG U=new BIG(0); + BIG b=new BIG(0); + BIG c=new BIG(0); + + U.inc(invmod256(lastbits(8))); + + for (i=8;i<ROM.BIGBITS;i<<=1) + { + b.copy(this); b.mod2m(i); + BIG t1=BIG.smul(U,b); + t1.shr(i); + + c.copy(this); c.shr(i); c.mod2m(i); + BIG t2=BIG.smul(U,c); t2.mod2m(i); + t1.add(t2); + b=BIG.smul(t1,U); t1.copy(b); + t1.mod2m(i); + + t2.one(); t2.shl(i); t1.rsub(t2); t1.norm(); + + t1.shl(i); + U.add(t1); + } + U.mod2m(ROM.BIGBITS); + copy(U); + norm(); + } + +/* reduce this mod m */ + public void mod(BIG m) + { + int k=0; + BIG r=new BIG(0); + + norm(); + if (comp(this,m)<0) return; + do + { + m.fshl(1); + k++; + } while (comp(this,m)>=0); + + while (k>0) + { + m.fshr(1); + + r.copy(this); + r.sub(m); + r.norm(); + cmove(r,(int)(1-((r.w[ROM.NLEN-1]>>(ROM.CHUNK-1))&1))); +/* + if (comp(this,m)>=0) + { + sub(m); + norm(); + } */ + k--; + } + } + +/* divide this by m */ + public void div(BIG m) + { + int d,k=0; + norm(); + BIG e=new BIG(1); + BIG b=new BIG(this); + BIG r=new BIG(0); + zero(); + + while (comp(b,m)>=0) + { + e.fshl(1); + m.fshl(1); + k++; + } + + while (k>0) + { + m.fshr(1); + e.fshr(1); + + r.copy(b); + r.sub(m); + r.norm(); + d=(int)(1-((r.w[ROM.NLEN-1]>>(ROM.CHUNK-1))&1)); + b.cmove(r,d); + r.copy(this); + r.add(e); + r.norm(); + cmove(r,d); + +/* + if (comp(b,m)>=0) + { + add(e); + norm(); + b.sub(m); + b.norm(); + } */ + k--; + } + } + +/* return parity */ + public int parity() + { + return (int)(w[0]%2); + } + +/* return n last bits */ + public int lastbits(int n) + { + int msk=(1<<n)-1; + norm(); + return ((int)w[0])&msk; + } + +/* get 8*MODBYTES size random number */ + public static BIG random(RAND rng) + { + BIG m=new BIG(0); + int i,b,j=0,r=0; + +/* generate random BIG */ + for (i=0;i<8*ROM.MODBYTES;i++) + { + if (j==0) r=rng.getByte(); + else r>>=1; + + b=r&1; + m.shl(1); m.w[0]+=b;// m.inc(b); + j++; j&=7; + } + return m; + } + +/* Create random BIG in portable way, one bit at a time */ + public static BIG randomnum(BIG q,RAND rng) + { + DBIG d=new DBIG(0); + int i,b,j=0,r=0; + for (i=0;i<2*ROM.MODBITS;i++) + { + if (j==0) r=rng.getByte(); + else r>>=1; + + b=r&1; + d.shl(1); d.w[0]+=b;// m.inc(b); + j++; j&=7; + } + BIG m=d.mod(q); + return m; + } + +/* return a*b mod m */ + public static BIG modmul(BIG a,BIG b,BIG m) + { + a.mod(m); + b.mod(m); + DBIG d=mul(a,b); + return d.mod(m); + } + +/* return a^2 mod m */ + public static BIG modsqr(BIG a,BIG m) + { + a.mod(m); + DBIG d=sqr(a); + return d.mod(m); + } + +/* return -a mod m */ + public static BIG modneg(BIG a,BIG m) + { + a.mod(m); + return m.minus(a); + } + +/* return this^e mod m */ + public BIG powmod(BIG e,BIG m) + { + int bt; + norm(); + e.norm(); + BIG a=new BIG(1); + BIG z=new BIG(e); + BIG s=new BIG(this); + while (true) + { + bt=z.parity(); + z.fshr(1); + if (bt==1) a=modmul(a,s,m); + if (z.iszilch()) break; + s=modsqr(s,m); + } + return a; + } + +/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */ + public int jacobi(BIG p) + { + int n8,k,m=0; + BIG t=new BIG(0); + BIG x=new BIG(0); + BIG n=new BIG(0); + BIG zilch=new BIG(0); + BIG one=new BIG(1); + if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0; + norm(); + x.copy(this); + n.copy(p); + x.mod(p); + + while (comp(n,one)>0) + { + if (comp(x,zilch)==0) return 0; + n8=n.lastbits(3); + k=0; + while (x.parity()==0) + { + k++; + x.shr(1); + } + if (k%2==1) m+=(n8*n8-1)/8; + m+=(n8-1)*(x.lastbits(2)-1)/4; + t.copy(n); + t.mod(x); + n.copy(x); + x.copy(t); + m%=2; + + } + if (m==0) return 1; + else return -1; + } + +/* this=1/this mod p. Binary method */ + public void invmodp(BIG p) + { + mod(p); + BIG u=new BIG(this); + BIG v=new BIG(p); + BIG x1=new BIG(1); + BIG x2=new BIG(0); + BIG t=new BIG(0); + BIG one=new BIG(1); + + while (comp(u,one)!=0 && comp(v,one)!=0) + { + while (u.parity()==0) + { + u.shr(1); + if (x1.parity()!=0) + { + x1.add(p); + x1.norm(); + } + x1.shr(1); + } + while (v.parity()==0) + { + v.shr(1); + if (x2.parity()!=0) + { + x2.add(p); + x2.norm(); + } + x2.shr(1); + } + if (comp(u,v)>=0) + { + u.sub(v); + u.norm(); + if (comp(x1,x2)>=0) x1.sub(x2); + else + { + t.copy(p); + t.sub(x2); + x1.add(t); + } + x1.norm(); + } + else + { + v.sub(u); + v.norm(); + if (comp(x2,x1)>=0) x2.sub(x1); + else + { + t.copy(p); + t.sub(x1); + x2.add(t); + } + x2.norm(); + } + } + if (comp(u,one)==0) copy(x1); + else copy(x2); + } +} http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version22/java/BenchtestEC.java ---------------------------------------------------------------------- diff --git a/version22/java/BenchtestEC.java b/version22/java/BenchtestEC.java new file mode 100644 index 0000000..1800635 --- /dev/null +++ b/version22/java/BenchtestEC.java @@ -0,0 +1,160 @@ +/* +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 and benchmark elliptic curve and RSA functions */ + +public class BenchtestEC +{ +/* generate an RSA key pair */ + public static final int MIN_TIME=10; /* seconds */ + public static final int MIN_ITERS=10; + + public static void main(String[] args) + { + int i,iterations; + long start,elapsed; + byte[] RAW=new byte[100]; + RAND rng=new RAND(); + double dur; + rsa_public_key pub=new rsa_public_key(ROM.FFLEN); + rsa_private_key priv=new rsa_private_key(ROM.HFLEN); + byte[] P=new byte[RSA.RFS]; + byte[] M=new byte[RSA.RFS]; + byte[] C=new byte[RSA.RFS]; + + + rng.clean(); + for (i=0;i<100;i++) RAW[i]=(byte)(i); + + rng.seed(100,RAW); + if (ROM.CURVETYPE==ROM.WEIERSTRASS) + { + System.out.print("Weierstrass parameterization\n"); + } + if (ROM.CURVETYPE==ROM.EDWARDS) + { + System.out.print("Edwards parameterization\n"); + } + if (ROM.CURVETYPE==ROM.MONTGOMERY) + { + System.out.print("Montgomery parameterization\n"); + } + + if (ROM.MODTYPE==ROM.PSEUDO_MERSENNE) + { + System.out.print("Pseudo-Mersenne Modulus\n"); + } + if (ROM.MODTYPE==ROM.MONTGOMERY_FRIENDLY) + { + System.out.print("Montgomery friendly Modulus\n"); + } + if (ROM.MODTYPE==ROM.GENERALISED_MERSENNE) + { + System.out.print("Generalised-Mersenne Modulus\n"); + } + if (ROM.MODTYPE==ROM.NOT_SPECIAL) + { + System.out.print("Not special Modulus\n"); + } + + System.out.format("Modulus size %d bits\n",ROM.MODBITS); + System.out.format("%d bit build\n",ROM.CHUNK); + BIG r,gx,gy,s,wx,wy; + ECP G,WP; + + gx=new BIG(ROM.CURVE_Gx); + if (ROM.CURVETYPE!=ROM.MONTGOMERY) + { + gy=new BIG(ROM.CURVE_Gy); + G=new ECP(gx,gy); + } + else + G=new ECP(gx); + + r=new BIG(ROM.CURVE_Order); + s=BIG.randomnum(r,rng); + + WP=G.mul(r); + if (!WP.is_infinity()) + { + System.out.print("FAILURE - rG!=O\n"); + return; + } + + start = System.currentTimeMillis(); + iterations=0; + do { + WP=G.mul(s); + iterations++; + elapsed=(System.currentTimeMillis()-start); + } while (elapsed<MIN_TIME*1000 || iterations<MIN_ITERS); + dur=(double)elapsed/iterations; + System.out.format("EC mul - %8d iterations ",iterations); + System.out.format(" %8.2f ms per iteration\n",dur); + + + System.out.format("Generating %d-bit RSA public/private key pair\n",ROM.FFLEN*ROM.BIGBITS); + + iterations=0; + start=System.currentTimeMillis(); + do { + RSA.KEY_PAIR(rng,65537,priv,pub); + iterations++; + elapsed=(System.currentTimeMillis()-start); + } while (elapsed<MIN_TIME*1000 || iterations<MIN_ITERS); + dur=(double)elapsed/iterations; + System.out.format("RSA gen - %8d iterations ",iterations); + System.out.format(" %8.2f ms per iteration\n",dur); + + for (i=0;i<RSA.RFS;i++) M[i]=(byte)(i%128); + + iterations=0; + start=System.currentTimeMillis(); + do { + RSA.ENCRYPT(pub,M,C); + iterations++; + elapsed=(System.currentTimeMillis()-start); + } while (elapsed<MIN_TIME*1000 || iterations<MIN_ITERS); + dur=(double)elapsed/iterations; + System.out.format("RSA enc - %8d iterations ",iterations); + System.out.format(" %8.2f ms per iteration\n",dur); + + iterations=0; + start=System.currentTimeMillis(); + do { + RSA.DECRYPT(priv,C,P); + iterations++; + elapsed=(System.currentTimeMillis()-start); + } while (elapsed<MIN_TIME*1000 || iterations<MIN_ITERS); + dur=(double)elapsed/iterations; + System.out.format("RSA dec - %8d iterations ",iterations); + System.out.format(" %8.2f ms per iteration\n",dur); + + for (i=0;i<RSA.RFS;i++) + { + if (P[i]!=M[i]) + { + System.out.print("FAILURE - RSA decryption\n"); + return; + } + } + + System.out.print("All tests pass\n"); + } +} http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version22/java/BenchtestPAIR.java ---------------------------------------------------------------------- diff --git a/version22/java/BenchtestPAIR.java b/version22/java/BenchtestPAIR.java new file mode 100644 index 0000000..6958643 --- /dev/null +++ b/version22/java/BenchtestPAIR.java @@ -0,0 +1,208 @@ +/* +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 and benchmark pairing functions */ + +public class BenchtestPAIR +{ + public static final int MIN_TIME=10; /* seconds */ + public static final int MIN_ITERS=10; + + public static void main(String[] args) + { + int i,iterations; + long start,elapsed; + byte[] RAW=new byte[100]; + RAND rng=new RAND(); + double dur; + + rng.clean(); + for (i=0;i<100;i++) RAW[i]=(byte)(i); + rng.seed(100,RAW); + + if (ROM.CURVE_PAIRING_TYPE==ROM.BN_CURVE) + { + System.out.print("BN Pairing-Friendly Curve\n"); + } + if (ROM.CURVE_PAIRING_TYPE==ROM.BLS_CURVE) + { + System.out.print("BLS Pairing-Friendly Curve\n"); + } + + System.out.format("Modulus size %d bits\n",ROM.MODBITS); + System.out.format("%d bit build\n",ROM.CHUNK); + + ECP G=new ECP(new BIG(ROM.CURVE_Gx),new BIG(ROM.CURVE_Gy)); + + BIG r=new BIG(ROM.CURVE_Order); + BIG s=BIG.randomnum(r,rng); + + ECP P=PAIR.G1mul(G,r); + + if (!P.is_infinity()) + { + System.out.print("FAILURE - rP!=O\n"); + return; + } + + iterations=0; + start=System.currentTimeMillis(); + do { + P=PAIR.G1mul(G,s); + iterations++; + elapsed=(System.currentTimeMillis()-start); + } while (elapsed<MIN_TIME*1000 || iterations<MIN_ITERS); + dur=(double)elapsed/iterations; + System.out.format("G1 mul - %8d iterations ",iterations); + System.out.format(" %8.2f ms per iteration\n",dur); + + ECP2 Q=new ECP2(new FP2(new BIG(ROM.CURVE_Pxa),new BIG(ROM.CURVE_Pxb)),new FP2(new BIG(ROM.CURVE_Pya),new BIG(ROM.CURVE_Pyb))); + ECP2 W=PAIR.G2mul(Q,r); + + if (!W.is_infinity()) + { + System.out.print("FAILURE - rQ!=O\n"); + return; + } + + iterations=0; + start=System.currentTimeMillis(); + do { + W=PAIR.G2mul(Q,s); + iterations++; + elapsed=(System.currentTimeMillis()-start); + } while (elapsed<MIN_TIME*1000 || iterations<MIN_ITERS); + dur=(double)elapsed/iterations; + System.out.format("G2 mul - %8d iterations ",iterations); + System.out.format(" %8.2f ms per iteration\n",dur); + + FP12 w=PAIR.ate(Q,P); + w=PAIR.fexp(w); + + FP12 g=PAIR.GTpow(w,r); + + if (!g.isunity()) + { + System.out.print("FAILURE - g^r!=1\n"); + return; + } + + iterations=0; + start=System.currentTimeMillis(); + do { + g=PAIR.GTpow(w,s); + iterations++; + elapsed=(System.currentTimeMillis()-start); + } while (elapsed<MIN_TIME*1000 || iterations<MIN_ITERS); + dur=(double)elapsed/iterations; + System.out.format("GT pow - %8d iterations ",iterations); + System.out.format(" %8.2f ms per iteration\n",dur); + + FP2 f=new FP2(new BIG(ROM.CURVE_Fra),new BIG(ROM.CURVE_Frb)); + BIG q=new BIG(ROM.Modulus); + + BIG m=new BIG(q); + m.mod(r); + + BIG a=new BIG(s); + a.mod(m); + + BIG b=new BIG(s); + b.div(m); + + g.copy(w); + FP4 c=g.trace(); + + g.frob(f); + FP4 cp=g.trace(); + + w.conj(); + g.mul(w); + FP4 cpm1=g.trace(); + g.mul(w); + FP4 cpm2=g.trace(); + FP4 cr; + + iterations=0; + start=System.currentTimeMillis(); + do { + cr=c.xtr_pow2(cp,cpm1,cpm2,a,b); + iterations++; + elapsed=(System.currentTimeMillis()-start); + } while (elapsed<MIN_TIME*1000 || iterations<MIN_ITERS); + dur=(double)elapsed/iterations; + System.out.format("GT pow (compressed) - %8d iterations ",iterations); + System.out.format(" %8.2f ms per iteration\n",dur); + + iterations=0; + start=System.currentTimeMillis(); + do { + w=PAIR.ate(Q,P); + iterations++; + elapsed=(System.currentTimeMillis()-start); + } while (elapsed<MIN_TIME*1000 || iterations<MIN_ITERS); + dur=(double)elapsed/iterations; + System.out.format("PAIRing ATE - %8d iterations ",iterations); + System.out.format(" %8.2f ms per iteration\n",dur); + + iterations=0; + start=System.currentTimeMillis(); + do { + g=PAIR.fexp(w); + iterations++; + elapsed=(System.currentTimeMillis()-start); + } while (elapsed<MIN_TIME*1000 || iterations<MIN_ITERS); + dur=(double)elapsed/iterations; + System.out.format("PAIRing FEXP - %8d iterations ",iterations); + System.out.format(" %8.2f ms per iteration\n",dur); + + P.copy(G); + Q.copy(W); + + P=PAIR.G1mul(P,s); + + g=PAIR.ate(Q,P); + g=PAIR.fexp(g); + + P.copy(G); + Q=PAIR.G2mul(Q,s); + + w=PAIR.ate(Q,P); + w=PAIR.fexp(w); + + if (!g.equals(w)) + { + System.out.print("FAILURE - e(sQ,p)!=e(Q,sP) \n"); + return; + } + + Q.copy(W); + g=PAIR.ate(Q,P); + g=PAIR.fexp(g); + g=PAIR.GTpow(g,s); + + if (!g.equals(w)) + { + System.out.print("FAILURE - e(sQ,p)!=e(Q,P)^s \n"); + return; + } + + System.out.print("All tests pass\n"); + } +} http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version22/java/DBIG32.java ---------------------------------------------------------------------- diff --git a/version22/java/DBIG32.java b/version22/java/DBIG32.java new file mode 100644 index 0000000..892fcd1 --- /dev/null +++ b/version22/java/DBIG32.java @@ -0,0 +1,308 @@ +/* +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. +*/ + +/* AMCL double length DBIG number class */ + +public class DBIG { + protected int[] w=new int[ROM.DNLEN]; + +/* normalise this */ + public void norm() { + int d,carry=0; + for (int i=0;i<ROM.DNLEN-1;i++) + { + d=w[i]+carry; + carry=d>>ROM.BASEBITS; + w[i]=d&ROM.BMASK; + } + w[ROM.DNLEN-1]=(w[ROM.DNLEN-1]+carry); + } + + +/* + public String toRawString() + { + DBIG b=new DBIG(this); + String s="("; + for (int i=0;i<ROM.DNLEN-1;i++) + { + s+=Integer.toHexString(b.w[i]); s+=","; + } + s+=Integer.toHexString(b.w[ROM.DNLEN-1]); s+=")"; + return s; + } +*/ + + +/****************************************************************************/ + + +/* return number of bits in this */ + public int nbits() { + int bts,k=ROM.DNLEN-1; + long c; + norm(); + while (w[k]==0 && k>=0) k--; + if (k<0) return 0; + bts=ROM.BASEBITS*k; + c=w[k]; + while (c!=0) {c/=2; bts++;} + return bts; + } + +/* convert this to string */ + public String toString() { + DBIG b; + String s=""; + int len=nbits(); + if (len%4==0) len>>=2; //len/=4; + else {len>>=2; len++;} + + for (int i=len-1;i>=0;i--) + { + b=new DBIG(this); + b.shr(i*4); + s+=Integer.toHexString((int)(b.w[0]&15)); + } + return s; + } + + public void cmove(DBIG g,int d) + { + int i; + // int b=-d; + + for (i=0;i<ROM.DNLEN;i++) + { + w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d); + } + } + +/* Constructors */ + public DBIG(int x) + { + w[0]=x; + for (int i=1;i<ROM.DNLEN;i++) + w[i]=0; + } + + public DBIG(DBIG x) + { + for (int i=0;i<ROM.DNLEN;i++) + w[i]=x.w[i]; + } + + public DBIG(BIG x) + { + for (int i=0;i<ROM.NLEN-1;i++) + w[i]=x.w[i];//get(i); + + w[ROM.NLEN-1]=x.w[(ROM.NLEN-1)]&ROM.BMASK; /* top word normalized */ + w[ROM.NLEN]=(x.w[(ROM.NLEN-1)]>>ROM.BASEBITS); + + for (int i=ROM.NLEN+1;i<ROM.DNLEN;i++) w[i]=0; + } + +/* split DBIG at position n, return higher half, keep lower half */ + public BIG split(int n) + { + BIG t=new BIG(0); + int nw,m=n%ROM.BASEBITS; + int carry=w[ROM.DNLEN-1]<<(ROM.BASEBITS-m); + + for (int i=ROM.DNLEN-2;i>=ROM.NLEN-1;i--) + { + nw=(w[i]>>m)|carry; + carry=(w[i]<<(ROM.BASEBITS-m))&ROM.BMASK; + t.w[i-ROM.NLEN+1]=nw; + // t.set(i-ROM.NLEN+1,nw); + } + w[ROM.NLEN-1]&=(((int)1<<m)-1); + return t; + } + +/* Copy from another DBIG */ + public void copy(DBIG x) + { + for (int i=0;i<ROM.DNLEN;i++) + w[i]=x.w[i]; + } + +/* test this=0? */ + public boolean iszilch() { + for (int i=0;i<ROM.DNLEN;i++) + if (w[i]!=0) return false; + return true; + } + +/* shift this right by k bits */ + public void shr(int k) { + int n=k%ROM.BASEBITS; + int m=k/ROM.BASEBITS; + for (int i=0;i<ROM.DNLEN-m-1;i++) + w[i]=(w[m+i]>>n)|((w[m+i+1]<<(ROM.BASEBITS-n))&ROM.BMASK); + w[ROM.DNLEN-m-1]=w[ROM.DNLEN-1]>>n; + for (int i=ROM.DNLEN-m;i<ROM.DNLEN;i++) w[i]=0; + } + +/* shift this left by k bits */ + public void shl(int k) { + int n=k%ROM.BASEBITS; + int m=k/ROM.BASEBITS; + + w[ROM.DNLEN-1]=((w[ROM.DNLEN-1-m]<<n))|(w[ROM.DNLEN-m-2]>>(ROM.BASEBITS-n)); + for (int i=ROM.DNLEN-2;i>m;i--) + w[i]=((w[i-m]<<n)&ROM.BMASK)|(w[i-m-1]>>(ROM.BASEBITS-n)); + w[m]=(w[0]<<n)&ROM.BMASK; + for (int i=0;i<m;i++) w[i]=0; + } + +/* this+=x */ + public void add(DBIG x) { + for (int i=0;i<ROM.DNLEN;i++) + w[i]+=x.w[i]; + } + +/* this-=x */ + public void sub(DBIG x) { + for (int i=0;i<ROM.DNLEN;i++) + w[i]-=x.w[i]; + } + +/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */ + public static int comp(DBIG a,DBIG b) + { + for (int i=ROM.DNLEN-1;i>=0;i--) + { + if (a.w[i]==b.w[i]) continue; + if (a.w[i]>b.w[i]) return 1; + else return -1; + } + return 0; + } + +/* reduces this DBIG mod a BIG, and returns the BIG */ + public BIG mod(BIG c) + { + int k=0; + norm(); + DBIG m=new DBIG(c); + DBIG r=new DBIG(0); + + if (comp(this,m)<0) return new BIG(this); + + do + { + m.shl(1); + k++; + } + while (comp(this,m)>=0); + + while (k>0) + { + m.shr(1); + + r.copy(this); + r.sub(m); + r.norm(); + cmove(r,(int)(1-((r.w[ROM.DNLEN-1]>>(ROM.CHUNK-1))&1))); +/* + if (comp(this,m)>=0) + { + sub(m); + norm(); + } +*/ + k--; + } + return new BIG(this); + } + +/* reduces this DBIG mod a DBIG in place */ +/* public void mod(DBIG m) + { + int k=0; + if (comp(this,m)<0) return; + + do + { + m.shl(1); + k++; + } + while (comp(this,m)>=0); + + while (k>0) + { + m.shr(1); + if (comp(this,m)>=0) + { + sub(m); + norm(); + } + k--; + } + return; + + }*/ + +/* return this/c */ + public BIG div(BIG c) + { + int d,k=0; + DBIG m=new DBIG(c); + DBIG dr=new DBIG(0); + BIG r=new BIG(0); + BIG a=new BIG(0); + BIG e=new BIG(1); + norm(); + + while (comp(this,m)>=0) + { + e.fshl(1); + m.shl(1); + k++; + } + + while (k>0) + { + m.shr(1); + e.shr(1); + + dr.copy(this); + dr.sub(m); + dr.norm(); + d=(int)(1-((dr.w[ROM.DNLEN-1]>>(ROM.CHUNK-1))&1)); + cmove(dr,d); + r.copy(a); + r.add(e); + r.norm(); + a.cmove(r,d); +/* + if (comp(this,m)>0) + { + a.add(e); + a.norm(); + sub(m); + norm(); + } */ + k--; + } + return a; + } +}
