From 4eb49b87d611504e52b762b953ab443515636c26 Mon Sep 17 00:00:00 2001 From: kelvin Date: Fri, 4 Aug 2017 11:25:47 +0800 Subject: [PATCH 1/3] paillier and log fix 1. pailler modify to paillier; 2. dfs init waiting log print only once --- doc/manual/manual.md | 16 +- {libpailler => libpaillier}/CMakeLists.txt | 12 +- {libpailler => libpaillier}/bn.c | 452 +-- {libpailler => libpaillier}/bn.h | 82 +- {libpailler => libpaillier}/common.c | 324 +-- {libpailler => libpaillier}/common.h | 76 +- {libpailler => libpaillier}/macro.h | 70 +- {libpailler => libpaillier}/pailler.c | 100 +- {libpailler => libpaillier}/pailler.h | 40 +- {libpailler => libpaillier}/typedef.h | 54 +- libweb3jsonrpc/dfs/DfsFileInfoScanner.cpp | 5 +- tool/java/{Pailler => Paillier}/.classpath | 16 +- tool/java/{Pailler => Paillier}/.project | 34 +- .../javascript/asn1hex.js | 212 +- .../javascript/base64.js | 142 +- .../{Pailler => Paillier}/javascript/jsbn.js | 2434 ++++++++--------- .../javascript/paillierKey.js | 666 ++--- .../{Pailler => Paillier}/javascript/rng.js | 242 +- .../{Pailler => Paillier}/javascript/rsa.js | 494 ++-- .../javascript/test.html | 162 +- .../lib/bcprov-jdk15on-1.54.jar | Bin .../{Pailler => Paillier}/paillier/asn1hex.js | 212 +- .../{Pailler => Paillier}/paillier/base64.js | 136 +- .../paillier/biginteger.js | 2400 ++++++++-------- .../paillier/paillierKey.js | 816 +++--- .../paillier/seedrandom.js | 884 +++--- .../{Pailler => Paillier}/paillier/test.html | 98 +- .../src/paillier/CommonUtils.java | 220 +- .../src/paillier/PaillierCipher.java | 228 +- .../src/paillier/PaillierKeyPair.java | 210 +- .../src/paillier/PaillierTest.java | 264 +- 31 files changed, 5546 insertions(+), 5555 deletions(-) rename {libpailler => libpaillier}/CMakeLists.txt (97%) rename {libpailler => libpaillier}/bn.c (95%) rename {libpailler => libpaillier}/bn.h (96%) rename {libpailler => libpaillier}/common.c (93%) rename {libpailler => libpaillier}/common.h (96%) rename {libpailler => libpaillier}/macro.h (95%) rename {libpailler => libpaillier}/pailler.c (96%) rename {libpailler => libpaillier}/pailler.h (93%) rename {libpailler => libpaillier}/typedef.h (93%) rename tool/java/{Pailler => Paillier}/.classpath (97%) rename tool/java/{Pailler => Paillier}/.project (95%) rename tool/java/{Pailler => Paillier}/javascript/asn1hex.js (96%) rename tool/java/{Pailler => Paillier}/javascript/base64.js (95%) rename tool/java/{Pailler => Paillier}/javascript/jsbn.js (96%) rename tool/java/{Pailler => Paillier}/javascript/paillierKey.js (97%) rename tool/java/{Pailler => Paillier}/javascript/rng.js (96%) rename tool/java/{Pailler => Paillier}/javascript/rsa.js (96%) rename tool/java/{Pailler => Paillier}/javascript/test.html (97%) rename tool/java/{Pailler => Paillier}/lib/bcprov-jdk15on-1.54.jar (100%) rename tool/java/{Pailler => Paillier}/paillier/asn1hex.js (96%) rename tool/java/{Pailler => Paillier}/paillier/base64.js (96%) rename tool/java/{Pailler => Paillier}/paillier/biginteger.js (96%) rename tool/java/{Pailler => Paillier}/paillier/paillierKey.js (97%) rename tool/java/{Pailler => Paillier}/paillier/seedrandom.js (97%) rename tool/java/{Pailler => Paillier}/paillier/test.html (97%) rename tool/java/{Pailler => Paillier}/src/paillier/CommonUtils.java (96%) rename tool/java/{Pailler => Paillier}/src/paillier/PaillierCipher.java (97%) rename tool/java/{Pailler => Paillier}/src/paillier/PaillierKeyPair.java (97%) rename tool/java/{Pailler => Paillier}/src/paillier/PaillierTest.java (97%) diff --git a/doc/manual/manual.md b/doc/manual/manual.md index d6df0ace80..b05eeb5f85 100644 --- a/doc/manual/manual.md +++ b/doc/manual/manual.md @@ -481,18 +481,6 @@ JAVA SDK提供的接口功能包括文件上传,文件删除,文件下载, |**输出参数**|**参数类型**|**参数说明**| |NA|NA|NA| - -- 接口名称:addServer -- 接口功能说明:添加文件服务器节点 -- 参数说明 - -|输入参数|参数类型|参数说明| -|:-----|:-----|:-----| -|server|FileServer|文件服务节点信息| -|ret|int|返回值| -|**输出参数**|**参数类型**|**参数说明**| -|NA|NA|NA| - ###### b. 删除文件服务器节点 - 接口名称:deleteServer @@ -630,11 +618,11 @@ uploadFile(fileInfo, file);//上传文件,等待回调upload_file_back ## 3.3 加法同态接口使用说明 对本版本所提供的加法同态运算功能,提供如下使用说明: -1.Java的API实现的同态加密算法,可以完成对需要运算的数据完成加解密操作,相关的代码工程路径为:{git_root}\tool\java\Pailler; +1.Java的API实现的同态加密算法,可以完成对需要运算的数据完成加解密操作,相关的代码工程路径为:{git_root}\tool\java\Paillier; 2.Solidity合约语言提供一个Library,实现对两个加密后数据实现加法同态运算,相关的合约路径为:{git_root}\systemcontractv2\LibPaillier.sol; -3.提供C语言同态加法算法实现,最终开放接口为智能合约同态加法运算API,相关代码路径为:{git_root}\libpailler; +3.提供C语言同态加法算法实现,最终开放接口为智能合约同态加法运算API,相关代码路径为:{git_root}\libpaillier; 4.扩展VM中的sha3指令用以支持合约与C代码底层能力的桥接和适配,相关代码路径为:{git_root}\libevm. diff --git a/libpailler/CMakeLists.txt b/libpaillier/CMakeLists.txt similarity index 97% rename from libpailler/CMakeLists.txt rename to libpaillier/CMakeLists.txt index 6afaf48e6a..aad7f522f0 100644 --- a/libpailler/CMakeLists.txt +++ b/libpaillier/CMakeLists.txt @@ -1,7 +1,7 @@ -aux_source_directory(. SRC_LIST) - -file(GLOB HEADERS "*.h") - -add_library(pailler ${SRC_LIST} ${HEADERS}) - +aux_source_directory(. SRC_LIST) + +file(GLOB HEADERS "*.h") + +add_library(pailler ${SRC_LIST} ${HEADERS}) + install(TARGETS pailler RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) \ No newline at end of file diff --git a/libpailler/bn.c b/libpaillier/bn.c similarity index 95% rename from libpailler/bn.c rename to libpaillier/bn.c index 4d2110c7a7..5765545931 100644 --- a/libpailler/bn.c +++ b/libpaillier/bn.c @@ -1,226 +1,226 @@ -#include "bn.h" - -void BN_Print(U32 *pwBN, S32 iBNWordLen) -{ - for (S32 i = iBNWordLen - 1; i >= 0; i--) - { - printf("%08X", pwBN[i]); - } - - printf("\n"); -} - -void BN_Reset(U32 *pwBN,S32 iBNWordLen) -{ - for (S32 i = 0; i < iBNWordLen; i++) - pwBN[i] = 0x0; -} - -void BN_Assign(U32 *pwDest, U32 *pwSource, S32 iBNWordLen) -{ - for (S32 i = 0; i < iBNWordLen; i++) - pwDest[i] = pwSource[i]; -} - -S32 BN_JA(U32 *pwX, U32 *pwY, S32 iBNWordLen) -{ - for (S32 i = iBNWordLen - 1; i >= 0; i--) - { - if (pwX[i] > pwY[i]) - { - return 1; - } - else - { - if (pwX[i] < pwY[i]) - { - return 0; - } - } - } - - return 0; -} - -U32 BN_Add( U32 *pwSum, U32 *pwX, U32 *pwY,S32 iBNWordLen) -{ - U64 carry = 0; - - for (S32 i = 0; i < iBNWordLen; i++) - { - carry = (U64)pwX[i] + (U64)pwY[i] + carry; - pwSum[i] = (U32)carry; - carry = carry >> 32; - } - - return (U32)carry; -} - -U32 BN_Sub(U32 *pwDiff, U32 *pwX, U32 *pwY, S32 iBNWordLen) -{ - U64 borrow = 0; - - for (S32 i = 0; i < iBNWordLen; i++) - { - borrow = (U64)pwX[i] - (U64)pwY[i] + borrow; - pwDiff[i] = (U32)borrow; - borrow = (U64)(((S64)borrow) >> 32); - } - - return (U32)borrow; -} - -void BN_Mul(U32 *pwPro, U32 *pwX, U32 *pwY, S32 iBNWordLen) -{ - U64 carry = 0; - - S32 i = iBNWordLen << 1; - BN_Reset(pwPro, i); - - for (i = 0; i < iBNWordLen; i++) - { - carry = 0; - for (S32 j = 0; j < iBNWordLen; j++) - { - carry = (U64)pwPro[i + j] + (U64)pwX[j] * (U64)pwY[i] + carry; - pwPro[i + j] = (U32)carry; - carry >>= WordLen;; - } - pwPro[i + iBNWordLen] = (U32)(carry); - } -} - -void BN_ModAdd(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule, S32 iBNWordLen) -{ - U32 c = BN_Add(pwResult, pwX, pwY,iBNWordLen); - if (c == 0) - return; - - do - { - c = BN_Sub(pwResult, pwResult, pwModule,iBNWordLen); - } while (c==0); -} - -void BN_ModSub(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule, S32 iBNWordLen) -{ - U32 c = BN_Sub(pwResult, pwX, pwY,iBNWordLen); - if (c == 0) - return; - - do - { - c = BN_Add(pwResult, pwResult, pwModule,iBNWordLen); - } while (c == 0); -} - -U32 BN_GetMontConst(U32 nLastU32, S32 nRadix) -{ - U64 y = 1; - U64 flag_2_i = 1; - U64 flag_last_i = 1; - - for (S32 i = 2; i <= nRadix; i++ ) - { - flag_2_i = flag_2_i << 1; - flag_last_i = (flag_last_i << 1) | 0x01; - - U64 tmp = nLastU32 * y; - tmp = tmp & flag_last_i; - if ( tmp > flag_2_i) - { - y = y + flag_2_i; - } - } - flag_2_i = flag_2_i << 1; - - return (U32)(flag_2_i - y); -} - -void BN_ModMul_Mont(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule, U32 wModuleConst, S32 iBNWordLen) -{ - U32 D[BNMAXWordLen + 2]; - BN_Reset(D, BNMAXWordLen + 2); - - for (int i = 0; i < iBNWordLen; i++) - { - U64 carry = 0; - for (int j = 0; j < iBNWordLen; j++) - { - carry = (U64)D[j] + (U64)pwX[j] * (U64)pwY[i] + carry; - D[j] = (U32)carry; - carry = carry >> 32; - } - - carry = (U64)D[iBNWordLen] + carry; - D[iBNWordLen] = (U32)carry; - D[iBNWordLen + 1] = (U32)(carry >> 32); - - carry = (U64)D[0] * (U64)wModuleConst; - U32 U = (U32)carry; - carry = (U64)D[0] + (U64)U * (U64)pwModule[0]; - carry = carry >> 32; - for (int j = 1; j < iBNWordLen; j++) - { - carry = (U64)D[j] + (U64)U * (U64)pwModule[j] + carry; - D[j - 1] = (U32)carry; - carry = carry >> 32; - } - carry = (U64)D[iBNWordLen] + carry; - D[iBNWordLen - 1] = (U32)carry; - D[iBNWordLen] = D[iBNWordLen + 1] + (U32)(carry >> 32); - } - - if (D[iBNWordLen] == 0) - BN_Assign(pwResult,D, iBNWordLen); - else - BN_Sub(pwResult, D, pwModule, iBNWordLen); -} - -void BN_Random(U32 *pwBN, S32 iBNWordLen) -{ - for (S32 i = 0; i < iBNWordLen; i++) - { - U8 B0 = (U8)rand(); - U8 B1 = (U8)rand(); - U8 B2 = (U8)rand(); - U8 B3 = (U8)rand(); - pwBN[i] = ((U32)B3 << 24) | ((U32)B3 << 16) | ((U32)B3 << 8) | ((U32)B3); - } -} - -void BN_GetLastRes(U32 *pwBN, U32 *pwMod, S32 iBNWordLen) -{ - if ( BN_JA(pwMod, pwBN, iBNWordLen) == 0) - { - BN_Sub(pwBN, pwBN, pwMod, iBNWordLen); - } -} - -void BN_GetR(U32 *pwR, U32 *pwModule, S32 iBNWordLen) -{ - U32 BNT[BNMAXWordLen]; - - BN_Reset(BNT, BNMAXWordLen); - - BN_Sub(pwR, BNT, pwModule, iBNWordLen);//R = 0-N; -} - -void BN_GetR2(U32 *pwR2, U32 *pwR, U32 *pwModule, U32 wModuleConst, S32 iBNWordLen, S32 iLogLogBNWordLen) -{ - U32 BN_T1[BNMAXWordLen]; - U32 BN_T2[BNMAXWordLen]; - - BN_Reset(BN_T1, BNMAXWordLen); - BN_Reset(BN_T2, BNMAXWordLen); - - BN_ModAdd(BN_T1, pwR, pwR, pwModule, iBNWordLen);//BN_T1 = 2*R - - for (S32 i = 0; i < iLogLogBNWordLen; i ++ ) - { - BN_ModMul_Mont(BN_T2, BN_T1, BN_T1, pwModule, wModuleConst, iBNWordLen);// - BN_Assign(BN_T1, BN_T2, iBNWordLen); - } - - BN_Assign(pwR2, BN_T2, iBNWordLen); -} +#include "bn.h" + +void BN_Print(U32 *pwBN, S32 iBNWordLen) +{ + for (S32 i = iBNWordLen - 1; i >= 0; i--) + { + printf("%08X", pwBN[i]); + } + + printf("\n"); +} + +void BN_Reset(U32 *pwBN,S32 iBNWordLen) +{ + for (S32 i = 0; i < iBNWordLen; i++) + pwBN[i] = 0x0; +} + +void BN_Assign(U32 *pwDest, U32 *pwSource, S32 iBNWordLen) +{ + for (S32 i = 0; i < iBNWordLen; i++) + pwDest[i] = pwSource[i]; +} + +S32 BN_JA(U32 *pwX, U32 *pwY, S32 iBNWordLen) +{ + for (S32 i = iBNWordLen - 1; i >= 0; i--) + { + if (pwX[i] > pwY[i]) + { + return 1; + } + else + { + if (pwX[i] < pwY[i]) + { + return 0; + } + } + } + + return 0; +} + +U32 BN_Add( U32 *pwSum, U32 *pwX, U32 *pwY,S32 iBNWordLen) +{ + U64 carry = 0; + + for (S32 i = 0; i < iBNWordLen; i++) + { + carry = (U64)pwX[i] + (U64)pwY[i] + carry; + pwSum[i] = (U32)carry; + carry = carry >> 32; + } + + return (U32)carry; +} + +U32 BN_Sub(U32 *pwDiff, U32 *pwX, U32 *pwY, S32 iBNWordLen) +{ + U64 borrow = 0; + + for (S32 i = 0; i < iBNWordLen; i++) + { + borrow = (U64)pwX[i] - (U64)pwY[i] + borrow; + pwDiff[i] = (U32)borrow; + borrow = (U64)(((S64)borrow) >> 32); + } + + return (U32)borrow; +} + +void BN_Mul(U32 *pwPro, U32 *pwX, U32 *pwY, S32 iBNWordLen) +{ + U64 carry = 0; + + S32 i = iBNWordLen << 1; + BN_Reset(pwPro, i); + + for (i = 0; i < iBNWordLen; i++) + { + carry = 0; + for (S32 j = 0; j < iBNWordLen; j++) + { + carry = (U64)pwPro[i + j] + (U64)pwX[j] * (U64)pwY[i] + carry; + pwPro[i + j] = (U32)carry; + carry >>= WordLen;; + } + pwPro[i + iBNWordLen] = (U32)(carry); + } +} + +void BN_ModAdd(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule, S32 iBNWordLen) +{ + U32 c = BN_Add(pwResult, pwX, pwY,iBNWordLen); + if (c == 0) + return; + + do + { + c = BN_Sub(pwResult, pwResult, pwModule,iBNWordLen); + } while (c==0); +} + +void BN_ModSub(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule, S32 iBNWordLen) +{ + U32 c = BN_Sub(pwResult, pwX, pwY,iBNWordLen); + if (c == 0) + return; + + do + { + c = BN_Add(pwResult, pwResult, pwModule,iBNWordLen); + } while (c == 0); +} + +U32 BN_GetMontConst(U32 nLastU32, S32 nRadix) +{ + U64 y = 1; + U64 flag_2_i = 1; + U64 flag_last_i = 1; + + for (S32 i = 2; i <= nRadix; i++ ) + { + flag_2_i = flag_2_i << 1; + flag_last_i = (flag_last_i << 1) | 0x01; + + U64 tmp = nLastU32 * y; + tmp = tmp & flag_last_i; + if ( tmp > flag_2_i) + { + y = y + flag_2_i; + } + } + flag_2_i = flag_2_i << 1; + + return (U32)(flag_2_i - y); +} + +void BN_ModMul_Mont(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule, U32 wModuleConst, S32 iBNWordLen) +{ + U32 D[BNMAXWordLen + 2]; + BN_Reset(D, BNMAXWordLen + 2); + + for (int i = 0; i < iBNWordLen; i++) + { + U64 carry = 0; + for (int j = 0; j < iBNWordLen; j++) + { + carry = (U64)D[j] + (U64)pwX[j] * (U64)pwY[i] + carry; + D[j] = (U32)carry; + carry = carry >> 32; + } + + carry = (U64)D[iBNWordLen] + carry; + D[iBNWordLen] = (U32)carry; + D[iBNWordLen + 1] = (U32)(carry >> 32); + + carry = (U64)D[0] * (U64)wModuleConst; + U32 U = (U32)carry; + carry = (U64)D[0] + (U64)U * (U64)pwModule[0]; + carry = carry >> 32; + for (int j = 1; j < iBNWordLen; j++) + { + carry = (U64)D[j] + (U64)U * (U64)pwModule[j] + carry; + D[j - 1] = (U32)carry; + carry = carry >> 32; + } + carry = (U64)D[iBNWordLen] + carry; + D[iBNWordLen - 1] = (U32)carry; + D[iBNWordLen] = D[iBNWordLen + 1] + (U32)(carry >> 32); + } + + if (D[iBNWordLen] == 0) + BN_Assign(pwResult,D, iBNWordLen); + else + BN_Sub(pwResult, D, pwModule, iBNWordLen); +} + +void BN_Random(U32 *pwBN, S32 iBNWordLen) +{ + for (S32 i = 0; i < iBNWordLen; i++) + { + U8 B0 = (U8)rand(); + U8 B1 = (U8)rand(); + U8 B2 = (U8)rand(); + U8 B3 = (U8)rand(); + pwBN[i] = ((U32)B3 << 24) | ((U32)B3 << 16) | ((U32)B3 << 8) | ((U32)B3); + } +} + +void BN_GetLastRes(U32 *pwBN, U32 *pwMod, S32 iBNWordLen) +{ + if ( BN_JA(pwMod, pwBN, iBNWordLen) == 0) + { + BN_Sub(pwBN, pwBN, pwMod, iBNWordLen); + } +} + +void BN_GetR(U32 *pwR, U32 *pwModule, S32 iBNWordLen) +{ + U32 BNT[BNMAXWordLen]; + + BN_Reset(BNT, BNMAXWordLen); + + BN_Sub(pwR, BNT, pwModule, iBNWordLen);//R = 0-N; +} + +void BN_GetR2(U32 *pwR2, U32 *pwR, U32 *pwModule, U32 wModuleConst, S32 iBNWordLen, S32 iLogLogBNWordLen) +{ + U32 BN_T1[BNMAXWordLen]; + U32 BN_T2[BNMAXWordLen]; + + BN_Reset(BN_T1, BNMAXWordLen); + BN_Reset(BN_T2, BNMAXWordLen); + + BN_ModAdd(BN_T1, pwR, pwR, pwModule, iBNWordLen);//BN_T1 = 2*R + + for (S32 i = 0; i < iLogLogBNWordLen; i ++ ) + { + BN_ModMul_Mont(BN_T2, BN_T1, BN_T1, pwModule, wModuleConst, iBNWordLen);// + BN_Assign(BN_T1, BN_T2, iBNWordLen); + } + + BN_Assign(pwR2, BN_T2, iBNWordLen); +} diff --git a/libpailler/bn.h b/libpaillier/bn.h similarity index 96% rename from libpailler/bn.h rename to libpaillier/bn.h index 84df06a692..28c487db59 100644 --- a/libpailler/bn.h +++ b/libpaillier/bn.h @@ -1,41 +1,41 @@ -#ifndef __HEADER_BN_H__ -#define __HEADER_BN_H__ - -#include "typedef.h" -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void BN_Print(U32 *pwBN,S32 iBNWordLen); -void BN_Reset(U32 *pwBN,S32 iBNWordLen); -void BN_Assign(U32 *pwDest, U32 *pwSource, S32 iBNWordLen); - -S32 BN_JE(U32 *pwX, U32 *pwY, S32 iBNWordLen); -S32 BN_JA(U32 *pwX, U32 *pwY, S32 iBNWordLen); - -U32 BN_Add( U32 *pwSum, U32 *pwX, U32 *pwY,S32 iBNWordLen); -U32 BN_Sub(U32 *pwDiff, U32 *pwX, U32 *pwY, S32 iBNWordLen); -void BN_Mul(U32 *pwPro, U32 *pwX, U32 *pwY, S32 iBNWordLen); - -void BN_ModAdd(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule, S32 iBNWordLen); -void BN_ModSub(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule, S32 iBNWordLen); -void BN_ModMul_Mont(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule,U32 wModuleConst,S32 iBNWordLen); - -U32 BN_GetMontConst(U32 nLastWord, S32 nRadix); -void BN_GetR(U32 *pwR, U32 *pwX, S32 iBNWordLen); -void BN_GetR2(U32 *pwR2, U32 *pwR, U32 *pwModule, U32 wModuleConst, S32 iBNWordLen, S32 iLogLogBNWordLen); - -void BN_Random(U32 *pwBN, S32 iBNWordLen); -void BN_GetLastRes(U32 *pwBN, U32 *pwMod, S32 iBNWordLen); - - -#ifdef __cplusplus -} -#endif - - -#endif - +#ifndef __HEADER_BN_H__ +#define __HEADER_BN_H__ + +#include "typedef.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void BN_Print(U32 *pwBN,S32 iBNWordLen); +void BN_Reset(U32 *pwBN,S32 iBNWordLen); +void BN_Assign(U32 *pwDest, U32 *pwSource, S32 iBNWordLen); + +S32 BN_JE(U32 *pwX, U32 *pwY, S32 iBNWordLen); +S32 BN_JA(U32 *pwX, U32 *pwY, S32 iBNWordLen); + +U32 BN_Add( U32 *pwSum, U32 *pwX, U32 *pwY,S32 iBNWordLen); +U32 BN_Sub(U32 *pwDiff, U32 *pwX, U32 *pwY, S32 iBNWordLen); +void BN_Mul(U32 *pwPro, U32 *pwX, U32 *pwY, S32 iBNWordLen); + +void BN_ModAdd(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule, S32 iBNWordLen); +void BN_ModSub(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule, S32 iBNWordLen); +void BN_ModMul_Mont(U32 *pwResult, U32 *pwX, U32 *pwY, U32 *pwModule,U32 wModuleConst,S32 iBNWordLen); + +U32 BN_GetMontConst(U32 nLastWord, S32 nRadix); +void BN_GetR(U32 *pwR, U32 *pwX, S32 iBNWordLen); +void BN_GetR2(U32 *pwR2, U32 *pwR, U32 *pwModule, U32 wModuleConst, S32 iBNWordLen, S32 iLogLogBNWordLen); + +void BN_Random(U32 *pwBN, S32 iBNWordLen); +void BN_GetLastRes(U32 *pwBN, U32 *pwMod, S32 iBNWordLen); + + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/libpailler/common.c b/libpaillier/common.c similarity index 93% rename from libpailler/common.c rename to libpaillier/common.c index 195b32ac49..701322ccd0 100644 --- a/libpailler/common.c +++ b/libpaillier/common.c @@ -1,162 +1,162 @@ -#include "common.h" - -S32 CharToByte(const S8 *pCharBuf, S32 charlen, U8 *pByteBuf, S32 *bytelen) -{ - S32 i = 0; - U8 hdata = 0; - U8 ldata = 0; - - S32 charlen_tmp = charlen; - if (charlen_tmp & LSBOfWord) - { - charlen_tmp += 1; - *bytelen = charlen_tmp >> 1; - if (ConvertHexChar(pCharBuf[0], &ldata) == 1) - { - pByteBuf[0] = ldata; - } - for (i = 1; i < *bytelen; i++) - { - if (ConvertHexChar(pCharBuf[2 * i - 1], &hdata) == 1) - { - if (ConvertHexChar(pCharBuf[2 * i], &ldata) == 1) - { - pByteBuf[i] = (hdata << 4) | ldata; - } - else - { - return 0; - } - } - else - { - return 0; - } - } - } - else - { - *bytelen = charlen_tmp >> 1; - for (i = 0; i < *bytelen; i++) - { - if (ConvertHexChar(pCharBuf[2 * i], &hdata) == 1) - { - if (ConvertHexChar(pCharBuf[2 * i + 1], &ldata) == 1) - { - pByteBuf[i] = (hdata << 4) | ldata; - } - else - { - return 0; - } - } - else - { - return 0; - } - } - } - - return 1; -} - -S32 ConvertHexChar(S8 ch, U8 *ch_byte) -{ - if ((ch >= '0') && (ch <= '9')) - { - - *ch_byte = (U8)(ch - 0x30); - return 1; - - } - else - { - if ((ch >= 'A') && (ch <= 'F')) - { - *ch_byte = (U8)(ch - 'A' + 0x0a); - return 1; - } - else - { - if ((ch >= 'a') && (ch <= 'f')) - { - *ch_byte = (U8)(ch - 'a' + 0x0a); - return 1; - } - } - } - - return 0; -} - -S32 ByteToBN(U8 *pByteBuf, S32 bytelen, U32 *pwBN, S32 iBNWordLen) -{ - S32 ExpLen = bytelen >> 2; - S32 Rem = bytelen & 0x00000003; - - if (Rem != 0) - { - ExpLen += 1; - } - - if (ExpLen > iBNWordLen) - { - return 0; - } - - S32 i = bytelen - 1; - S32 j = 0; - while (i >= Rem) - { - pwBN[j] = ((U32)pByteBuf[i]) | ((U32)pByteBuf[i - 1] << 8) | ((U32)pByteBuf[i - 2] << 16) | ((U32)pByteBuf[i - 3] << 24); - i -= 4; - j++; - } - - i = 0; - while (i < Rem) - { - pwBN[j] = (pwBN[j] << 8) | ((U32)pByteBuf[i]); - i++; - } - - return 1; -} - -S32 BNToByte(U32 *pwBN,S32 iBNWordLen,U8 *pByteBuf,S32 *bytelen) -{ - U8 * P = pByteBuf; - - for(S32 i = iBNWordLen - 1; i >= 0; i--) - { - U32 W = pwBN[i]; - *P++=(U8) ((W & 0xFF000000) >> 24); - *P++=(U8) ((W & 0x00FF0000) >> 16); - *P++=(U8) ((W & 0x0000FF00) >> 8); - *P++=(U8) (W & 0x000000FF) ; - } - *bytelen = iBNWordLen << 2; - - return 1; -} - -void U8_Print(U8* pwSource,S32 len) -{ - for(S32 i = 0;i> 1; + if (ConvertHexChar(pCharBuf[0], &ldata) == 1) + { + pByteBuf[0] = ldata; + } + for (i = 1; i < *bytelen; i++) + { + if (ConvertHexChar(pCharBuf[2 * i - 1], &hdata) == 1) + { + if (ConvertHexChar(pCharBuf[2 * i], &ldata) == 1) + { + pByteBuf[i] = (hdata << 4) | ldata; + } + else + { + return 0; + } + } + else + { + return 0; + } + } + } + else + { + *bytelen = charlen_tmp >> 1; + for (i = 0; i < *bytelen; i++) + { + if (ConvertHexChar(pCharBuf[2 * i], &hdata) == 1) + { + if (ConvertHexChar(pCharBuf[2 * i + 1], &ldata) == 1) + { + pByteBuf[i] = (hdata << 4) | ldata; + } + else + { + return 0; + } + } + else + { + return 0; + } + } + } + + return 1; +} + +S32 ConvertHexChar(S8 ch, U8 *ch_byte) +{ + if ((ch >= '0') && (ch <= '9')) + { + + *ch_byte = (U8)(ch - 0x30); + return 1; + + } + else + { + if ((ch >= 'A') && (ch <= 'F')) + { + *ch_byte = (U8)(ch - 'A' + 0x0a); + return 1; + } + else + { + if ((ch >= 'a') && (ch <= 'f')) + { + *ch_byte = (U8)(ch - 'a' + 0x0a); + return 1; + } + } + } + + return 0; +} + +S32 ByteToBN(U8 *pByteBuf, S32 bytelen, U32 *pwBN, S32 iBNWordLen) +{ + S32 ExpLen = bytelen >> 2; + S32 Rem = bytelen & 0x00000003; + + if (Rem != 0) + { + ExpLen += 1; + } + + if (ExpLen > iBNWordLen) + { + return 0; + } + + S32 i = bytelen - 1; + S32 j = 0; + while (i >= Rem) + { + pwBN[j] = ((U32)pByteBuf[i]) | ((U32)pByteBuf[i - 1] << 8) | ((U32)pByteBuf[i - 2] << 16) | ((U32)pByteBuf[i - 3] << 24); + i -= 4; + j++; + } + + i = 0; + while (i < Rem) + { + pwBN[j] = (pwBN[j] << 8) | ((U32)pByteBuf[i]); + i++; + } + + return 1; +} + +S32 BNToByte(U32 *pwBN,S32 iBNWordLen,U8 *pByteBuf,S32 *bytelen) +{ + U8 * P = pByteBuf; + + for(S32 i = iBNWordLen - 1; i >= 0; i--) + { + U32 W = pwBN[i]; + *P++=(U8) ((W & 0xFF000000) >> 24); + *P++=(U8) ((W & 0x00FF0000) >> 16); + *P++=(U8) ((W & 0x0000FF00) >> 8); + *P++=(U8) (W & 0x000000FF) ; + } + *bytelen = iBNWordLen << 2; + + return 1; +} + +void U8_Print(U8* pwSource,S32 len) +{ + for(S32 i = 0;i> 24 ); \ - (b)[(i) + 1] = (U8) ( (n) >> 16 ); \ - (b)[(i) + 2] = (U8) ( (n) >> 8 ); \ - (b)[(i) + 3] = (U8) ( (n) ); \ -} - -#ifdef __cplusplus -extern "C" { -#endif - -S32 ConvertHexChar(S8 ch, U8 *ch_byte); -S32 CharToByte(const S8 *pCharBuf, S32 charlen, U8 *pByteBuf, S32 *bytelen); -S32 ByteToBN(U8 *pByteBuf, S32 bytelen, U32 *pwBN, S32 iBNWordLen); -S32 BNToByte(U32 *pwBN,S32 iBNWordLen,U8 *pByteBuf,S32 *bytelen); - -void U8_Print(U8* pwSource,S32 len); -S32 U8_JE(U8* pwX,U8* pwY,S32 len); - -#ifdef __cplusplus -} -#endif - -#endif +#ifndef __HEADER_COMMON_H__ +#define __HEADER_COMMON_H__ + +#include "bn.h" + +#define GET_U32(n,b,i) \ +{ \ + (n) = ( (U32) (b)[(i) ] << 24 ) \ + | ( (U32) (b)[(i) + 1] << 16 ) \ + | ( (U32) (b)[(i) + 2] << 8 ) \ + | ( (U32) (b)[(i) + 3] ); \ +} + +#define PUT_U32(n,b,i) \ +{ \ + (b)[(i) ] = (U8) ( (n) >> 24 ); \ + (b)[(i) + 1] = (U8) ( (n) >> 16 ); \ + (b)[(i) + 2] = (U8) ( (n) >> 8 ); \ + (b)[(i) + 3] = (U8) ( (n) ); \ +} + +#ifdef __cplusplus +extern "C" { +#endif + +S32 ConvertHexChar(S8 ch, U8 *ch_byte); +S32 CharToByte(const S8 *pCharBuf, S32 charlen, U8 *pByteBuf, S32 *bytelen); +S32 ByteToBN(U8 *pByteBuf, S32 bytelen, U32 *pwBN, S32 iBNWordLen); +S32 BNToByte(U32 *pwBN,S32 iBNWordLen,U8 *pByteBuf,S32 *bytelen); + +void U8_Print(U8* pwSource,S32 len); +S32 U8_JE(U8* pwX,U8* pwY,S32 len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libpailler/macro.h b/libpaillier/macro.h similarity index 95% rename from libpailler/macro.h rename to libpaillier/macro.h index f807c68ec2..8e5568976e 100644 --- a/libpailler/macro.h +++ b/libpaillier/macro.h @@ -1,35 +1,35 @@ -#ifndef __HEADER_MACRO_H__ -#define __HEADER_MACRO_H__ - -#ifdef __cplusplus -extern "C"{ -#endif - -#define WRONG 0 -#define RIGHT 1 - -//macro for common bn -#define WordLen 32 -#define ByteLen 8 -#define WordByteLen (WordLen/ByteLen) -#define LSBOfWord 0x00000001 -#define MSBOfWord 0x80000000 -#define Plus 0x00000000 -#define Minus 0x00000001 - -//macro for BN in pailler -#define PaiBNBitLen 1024 -#define PaiBNWordLen 32 -#define PaiPrimeWordLen 16 -#define MAXPrimeWordLen 32 -#define Ext_PaiBNWordLen (PaiBNWordLen + 2) -#define BNMAXWordLen (2 * PaiBNWordLen + 2) -#define LogPaiBNBitLen 10 -#define LogPaiBN2BitLen 11 - - -#ifdef __cplusplus -} -#endif - -#endif +#ifndef __HEADER_MACRO_H__ +#define __HEADER_MACRO_H__ + +#ifdef __cplusplus +extern "C"{ +#endif + +#define WRONG 0 +#define RIGHT 1 + +//macro for common bn +#define WordLen 32 +#define ByteLen 8 +#define WordByteLen (WordLen/ByteLen) +#define LSBOfWord 0x00000001 +#define MSBOfWord 0x80000000 +#define Plus 0x00000000 +#define Minus 0x00000001 + +//macro for BN in pailler +#define PaiBNBitLen 1024 +#define PaiBNWordLen 32 +#define PaiPrimeWordLen 16 +#define MAXPrimeWordLen 32 +#define Ext_PaiBNWordLen (PaiBNWordLen + 2) +#define BNMAXWordLen (2 * PaiBNWordLen + 2) +#define LogPaiBNBitLen 10 +#define LogPaiBN2BitLen 11 + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libpailler/pailler.c b/libpaillier/pailler.c similarity index 96% rename from libpailler/pailler.c rename to libpaillier/pailler.c index 0a831051f8..594ca6a8db 100644 --- a/libpailler/pailler.c +++ b/libpaillier/pailler.c @@ -1,51 +1,51 @@ -#include "pailler.h" - -void PAI_HomAdd(U8 *pbBN_Result, U8 *pbBN_c1, U8 *pbBN_c2, U8 *pbBN_n, S32 iBNWordLen) -{ - /****************************/ - U32 BN_N2[BNMAXWordLen]; - U32 BN_N[BNMAXWordLen]; - U32 BN_R[BNMAXWordLen]; - U32 BN_R2[BNMAXWordLen]; - U32 BN_C1[BNMAXWordLen]; - U32 BN_C2[BNMAXWordLen]; - U32 BN_C3[BNMAXWordLen]; - U32 BN_One[BNMAXWordLen]; - U32 wModuleConst = 0; - - U8 bBN_T[8*BNMAXWordLen] = {0}; - S32 i = 0; - S32 len = 0; - /****************************/ - - BN_Reset(BN_N2, BNMAXWordLen); - BN_Reset(BN_N, BNMAXWordLen); - BN_Reset(BN_R, BNMAXWordLen); - BN_Reset(BN_R2, BNMAXWordLen); - BN_Reset(BN_C1, BNMAXWordLen); - BN_Reset(BN_C2, BNMAXWordLen); - BN_Reset(BN_C3, BNMAXWordLen); - BN_Reset(BN_One, BNMAXWordLen); - BN_One[0] = LSBOfWord; - - ByteToBN(pbBN_n, 4*iBNWordLen, BN_N, iBNWordLen); - ByteToBN(pbBN_c1, 8*iBNWordLen, BN_C1, 2*iBNWordLen); - ByteToBN(pbBN_c2, 8*iBNWordLen, BN_C2, 2*iBNWordLen); - - //n^2 - BN_Mul(BN_N2, BN_N, BN_N, iBNWordLen); - - wModuleConst = BN_GetMontConst(BN_N2[0], 32); - BN_GetR(BN_R, BN_N2, 2*iBNWordLen); - - BN_GetR2(BN_R2, BN_R, BN_N2, wModuleConst, 2*iBNWordLen, LogPaiBN2BitLen); - BN_GetLastRes(BN_R2, BN_N2, 2*iBNWordLen); - - BN_ModMul_Mont(BN_C1, BN_C1, BN_R2, BN_N2, wModuleConst, 2*iBNWordLen); - BN_ModMul_Mont(BN_C2, BN_C2, BN_R2, BN_N2, wModuleConst, 2*iBNWordLen); - BN_ModMul_Mont(BN_C3, BN_C1, BN_C2, BN_N2, wModuleConst, 2*iBNWordLen); - BN_ModMul_Mont(BN_C3, BN_C3, BN_One, BN_N2, wModuleConst, 2*iBNWordLen); - BN_GetLastRes(BN_C3, BN_N2, 2*iBNWordLen); - - BNToByte(BN_C3, 2*iBNWordLen, pbBN_Result, &len); +#include "pailler.h" + +void PAI_HomAdd(U8 *pbBN_Result, U8 *pbBN_c1, U8 *pbBN_c2, U8 *pbBN_n, S32 iBNWordLen) +{ + /****************************/ + U32 BN_N2[BNMAXWordLen]; + U32 BN_N[BNMAXWordLen]; + U32 BN_R[BNMAXWordLen]; + U32 BN_R2[BNMAXWordLen]; + U32 BN_C1[BNMAXWordLen]; + U32 BN_C2[BNMAXWordLen]; + U32 BN_C3[BNMAXWordLen]; + U32 BN_One[BNMAXWordLen]; + U32 wModuleConst = 0; + + U8 bBN_T[8*BNMAXWordLen] = {0}; + S32 i = 0; + S32 len = 0; + /****************************/ + + BN_Reset(BN_N2, BNMAXWordLen); + BN_Reset(BN_N, BNMAXWordLen); + BN_Reset(BN_R, BNMAXWordLen); + BN_Reset(BN_R2, BNMAXWordLen); + BN_Reset(BN_C1, BNMAXWordLen); + BN_Reset(BN_C2, BNMAXWordLen); + BN_Reset(BN_C3, BNMAXWordLen); + BN_Reset(BN_One, BNMAXWordLen); + BN_One[0] = LSBOfWord; + + ByteToBN(pbBN_n, 4*iBNWordLen, BN_N, iBNWordLen); + ByteToBN(pbBN_c1, 8*iBNWordLen, BN_C1, 2*iBNWordLen); + ByteToBN(pbBN_c2, 8*iBNWordLen, BN_C2, 2*iBNWordLen); + + //n^2 + BN_Mul(BN_N2, BN_N, BN_N, iBNWordLen); + + wModuleConst = BN_GetMontConst(BN_N2[0], 32); + BN_GetR(BN_R, BN_N2, 2*iBNWordLen); + + BN_GetR2(BN_R2, BN_R, BN_N2, wModuleConst, 2*iBNWordLen, LogPaiBN2BitLen); + BN_GetLastRes(BN_R2, BN_N2, 2*iBNWordLen); + + BN_ModMul_Mont(BN_C1, BN_C1, BN_R2, BN_N2, wModuleConst, 2*iBNWordLen); + BN_ModMul_Mont(BN_C2, BN_C2, BN_R2, BN_N2, wModuleConst, 2*iBNWordLen); + BN_ModMul_Mont(BN_C3, BN_C1, BN_C2, BN_N2, wModuleConst, 2*iBNWordLen); + BN_ModMul_Mont(BN_C3, BN_C3, BN_One, BN_N2, wModuleConst, 2*iBNWordLen); + BN_GetLastRes(BN_C3, BN_N2, 2*iBNWordLen); + + BNToByte(BN_C3, 2*iBNWordLen, pbBN_Result, &len); } \ No newline at end of file diff --git a/libpailler/pailler.h b/libpaillier/pailler.h similarity index 93% rename from libpailler/pailler.h rename to libpaillier/pailler.h index d82a748d0c..8bd70b7ec2 100644 --- a/libpailler/pailler.h +++ b/libpaillier/pailler.h @@ -1,20 +1,20 @@ -#ifndef __HEADER_PAILLER_H__ -#define __HEADER_PAILLER_H__ - -#include "bn.h" -#include "common.h" -#include "macro.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void PAI_HomAdd(U8 *pbBN_Result, U8 *pbBN_c1, U8 *pbBN_c2, U8 *pbBN_n, S32 iBNWordLen); - -#ifdef __cplusplus -} -#endif - - -#endif - +#ifndef __HEADER_PAILLER_H__ +#define __HEADER_PAILLER_H__ + +#include "bn.h" +#include "common.h" +#include "macro.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void PAI_HomAdd(U8 *pbBN_Result, U8 *pbBN_c1, U8 *pbBN_c2, U8 *pbBN_n, S32 iBNWordLen); + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/libpailler/typedef.h b/libpaillier/typedef.h similarity index 93% rename from libpailler/typedef.h rename to libpaillier/typedef.h index 30001a21f1..ee89380f74 100644 --- a/libpailler/typedef.h +++ b/libpaillier/typedef.h @@ -1,27 +1,27 @@ -#ifndef __HEADER_TYPEDEF_H__ -#define __HEADER_TYPEDEF_H__ - -#include -#include "macro.h" - -#ifdef __cplusplus -extern "C"{ -#endif - - typedef unsigned char U8; - typedef unsigned short U16; - typedef uint32_t U32; - typedef uint64_t U64; - - typedef char S8; - typedef short S16; - typedef int32_t S32; - typedef int64_t S64; - -#ifdef __cplusplus -} -#endif - -#endif - - +#ifndef __HEADER_TYPEDEF_H__ +#define __HEADER_TYPEDEF_H__ + +#include +#include "macro.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + typedef unsigned char U8; + typedef unsigned short U16; + typedef uint32_t U32; + typedef uint64_t U64; + + typedef char S8; + typedef short S16; + typedef int32_t S32; + typedef int64_t S64; + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/libweb3jsonrpc/dfs/DfsFileInfoScanner.cpp b/libweb3jsonrpc/dfs/DfsFileInfoScanner.cpp index bcc70f5674..bde11d0765 100644 --- a/libweb3jsonrpc/dfs/DfsFileInfoScanner.cpp +++ b/libweb3jsonrpc/dfs/DfsFileInfoScanner.cpp @@ -103,8 +103,11 @@ void DfsFileInfoScanner::doWork() { static int tag = 0; if (tag == 0) + { + tag = 1; dfs_debug << "init state is NOT OK, waiting... !!"; - + } + usleep(1000);//1ms } } diff --git a/tool/java/Pailler/.classpath b/tool/java/Paillier/.classpath similarity index 97% rename from tool/java/Pailler/.classpath rename to tool/java/Paillier/.classpath index ca374d50b5..25b3e1ead4 100644 --- a/tool/java/Pailler/.classpath +++ b/tool/java/Paillier/.classpath @@ -1,8 +1,8 @@ - - - - - - - - + + + + + + + + diff --git a/tool/java/Pailler/.project b/tool/java/Paillier/.project similarity index 95% rename from tool/java/Pailler/.project rename to tool/java/Paillier/.project index 6bcabb7910..9774493675 100644 --- a/tool/java/Pailler/.project +++ b/tool/java/Paillier/.project @@ -1,17 +1,17 @@ - - - paillier - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - + + + paillier + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/tool/java/Pailler/javascript/asn1hex.js b/tool/java/Paillier/javascript/asn1hex.js similarity index 96% rename from tool/java/Pailler/javascript/asn1hex.js rename to tool/java/Paillier/javascript/asn1hex.js index 4237a7d40e..15987bcb7a 100644 --- a/tool/java/Pailler/javascript/asn1hex.js +++ b/tool/java/Paillier/javascript/asn1hex.js @@ -1,106 +1,106 @@ -// -// asn1hex.js - Hexadecimal represented ASN.1 string library -// -// -// version: 1.0 (2010-Jun-03) -// -// Copyright (c) 2010 Kenji Urushima (kenji.urushima@gmail.com) -// -// This software is licensed under the terms of the MIT License. -// http://www.opensource.org/licenses/mit-license.php -// -// The above copyright and license notice shall be -// included in all copies or substantial portions of the Software. -// -// -// Depends on: -// - -// MEMO: -// f('3082025b02...', 2) ... 82025b ... 3bytes -// f('020100', 2) ... 01 ... 1byte -// f('0203001...', 2) ... 03 ... 1byte -// f('02818003...', 2) ... 8180 ... 2bytes -// f('3080....0000', 2) ... 80 ... -1 -// -// Requirements: -// - ASN.1 type octet length MUST be 1. -// (i.e. ASN.1 primitives like SET, SEQUENCE, INTEGER, OCTETSTRING ...) -// - -function _asnhex_getByteLengthOfL_AtObj(s, pos) { - if (s.substring(pos + 2, pos + 3) != '8') return 1; - var i = parseInt(s.substring(pos + 3, pos + 4)); - if (i == 0) return -1; // length octet '80' indefinite length - if (0 < i && i < 10) return i + 1; // including '8?' octet; - return -2; // malformed format -} - -function _asnhex_getHexOfL_AtObj(s, pos) { - var len = _asnhex_getByteLengthOfL_AtObj(s, pos); - if (len < 1) return ''; - return s.substring(pos + 2, pos + 2 + len * 2); -} - -// -// getting ASN.1 length value at the position 'idx' of -// hexa decimal string 's'. -// -// f('3082025b02...', 0) ... 82025b ... ??? -// f('020100', 0) ... 01 ... 1 -// f('0203001...', 0) ... 03 ... 3 -// f('02818003...', 0) ... 8180 ... 128 -function _asnhex_getIntOfL_AtObj(s, pos) { - var hLength = _asnhex_getHexOfL_AtObj(s, pos); - if (hLength == '') return -1; - var bi; - if (parseInt(hLength.substring(0, 1)) < 8) { - bi = parseBigInt(hLength, 16); - } else { - bi = parseBigInt(hLength.substring(2), 16); - } - return bi.intValue(); -} - -// -// get ASN.1 value starting string position -// for ASN.1 object refered by index 'idx'. -// -function _asnhex_getStartPosOfV_AtObj(s, pos) { - var l_len = _asnhex_getByteLengthOfL_AtObj(s, pos); - if (l_len < 0) return l_len; - return pos + (l_len + 1) * 2; -} - -function _asnhex_getHexOfV_AtObj(s, pos) { - var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos); - var len = _asnhex_getIntOfL_AtObj(s, pos); - return s.substring(pos1, pos1 + len * 2); -} - -function _asnhex_getPosOfNextSibling_AtObj(s, pos) { - var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos); - var len = _asnhex_getIntOfL_AtObj(s, pos); - return pos1 + len * 2; -} - -function _asnhex_getPosArrayOfChildren_AtObj(h, pos) { - var a = new Array(); - var p0 = _asnhex_getStartPosOfV_AtObj(h, pos); - a.push(p0); - - var len = _asnhex_getIntOfL_AtObj(h, pos); - var p = p0; - var k = 0; - while (1) { - var pNext = _asnhex_getPosOfNextSibling_AtObj(h, p); - if (pNext == null || (pNext - p0 >= (len * 2))) break; - if (k >= 200) break; - - a.push(pNext); - p = pNext; - - k++; - } - - return a; -} +// +// asn1hex.js - Hexadecimal represented ASN.1 string library +// +// +// version: 1.0 (2010-Jun-03) +// +// Copyright (c) 2010 Kenji Urushima (kenji.urushima@gmail.com) +// +// This software is licensed under the terms of the MIT License. +// http://www.opensource.org/licenses/mit-license.php +// +// The above copyright and license notice shall be +// included in all copies or substantial portions of the Software. +// +// +// Depends on: +// + +// MEMO: +// f('3082025b02...', 2) ... 82025b ... 3bytes +// f('020100', 2) ... 01 ... 1byte +// f('0203001...', 2) ... 03 ... 1byte +// f('02818003...', 2) ... 8180 ... 2bytes +// f('3080....0000', 2) ... 80 ... -1 +// +// Requirements: +// - ASN.1 type octet length MUST be 1. +// (i.e. ASN.1 primitives like SET, SEQUENCE, INTEGER, OCTETSTRING ...) +// - +function _asnhex_getByteLengthOfL_AtObj(s, pos) { + if (s.substring(pos + 2, pos + 3) != '8') return 1; + var i = parseInt(s.substring(pos + 3, pos + 4)); + if (i == 0) return -1; // length octet '80' indefinite length + if (0 < i && i < 10) return i + 1; // including '8?' octet; + return -2; // malformed format +} + +function _asnhex_getHexOfL_AtObj(s, pos) { + var len = _asnhex_getByteLengthOfL_AtObj(s, pos); + if (len < 1) return ''; + return s.substring(pos + 2, pos + 2 + len * 2); +} + +// +// getting ASN.1 length value at the position 'idx' of +// hexa decimal string 's'. +// +// f('3082025b02...', 0) ... 82025b ... ??? +// f('020100', 0) ... 01 ... 1 +// f('0203001...', 0) ... 03 ... 3 +// f('02818003...', 0) ... 8180 ... 128 +function _asnhex_getIntOfL_AtObj(s, pos) { + var hLength = _asnhex_getHexOfL_AtObj(s, pos); + if (hLength == '') return -1; + var bi; + if (parseInt(hLength.substring(0, 1)) < 8) { + bi = parseBigInt(hLength, 16); + } else { + bi = parseBigInt(hLength.substring(2), 16); + } + return bi.intValue(); +} + +// +// get ASN.1 value starting string position +// for ASN.1 object refered by index 'idx'. +// +function _asnhex_getStartPosOfV_AtObj(s, pos) { + var l_len = _asnhex_getByteLengthOfL_AtObj(s, pos); + if (l_len < 0) return l_len; + return pos + (l_len + 1) * 2; +} + +function _asnhex_getHexOfV_AtObj(s, pos) { + var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos); + var len = _asnhex_getIntOfL_AtObj(s, pos); + return s.substring(pos1, pos1 + len * 2); +} + +function _asnhex_getPosOfNextSibling_AtObj(s, pos) { + var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos); + var len = _asnhex_getIntOfL_AtObj(s, pos); + return pos1 + len * 2; +} + +function _asnhex_getPosArrayOfChildren_AtObj(h, pos) { + var a = new Array(); + var p0 = _asnhex_getStartPosOfV_AtObj(h, pos); + a.push(p0); + + var len = _asnhex_getIntOfL_AtObj(h, pos); + var p = p0; + var k = 0; + while (1) { + var pNext = _asnhex_getPosOfNextSibling_AtObj(h, p); + if (pNext == null || (pNext - p0 >= (len * 2))) break; + if (k >= 200) break; + + a.push(pNext); + p = pNext; + + k++; + } + + return a; +} diff --git a/tool/java/Pailler/javascript/base64.js b/tool/java/Paillier/javascript/base64.js similarity index 95% rename from tool/java/Pailler/javascript/base64.js rename to tool/java/Paillier/javascript/base64.js index 18bc46c260..ad53bb8ed0 100644 --- a/tool/java/Pailler/javascript/base64.js +++ b/tool/java/Paillier/javascript/base64.js @@ -1,71 +1,71 @@ -var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -var b64padchar="="; - -function hex2b64(h) { - var i; - var c; - var ret = ""; - for(i = 0; i+3 <= h.length; i+=3) { - c = parseInt(h.substring(i,i+3),16); - ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); - } - if(i+1 == h.length) { - c = parseInt(h.substring(i,i+1),16); - ret += b64map.charAt(c << 2); - } - else if(i+2 == h.length) { - c = parseInt(h.substring(i,i+2),16); - ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); - } - while((ret.length & 3) > 0) ret += b64padchar; - return ret; -} - -// convert a base64 string to hex -function b64tohex(s) { - var ret = "" - var i; - var k = 0; // b64 state, 0-3 - var slop; - for(i = 0; i < s.length; ++i) { - if(s.charAt(i) == b64padchar) break; - v = b64map.indexOf(s.charAt(i)); - if(v < 0) continue; - if(k == 0) { - ret += int2char(v >> 2); - slop = v & 3; - k = 1; - } - else if(k == 1) { - ret += int2char((slop << 2) | (v >> 4)); - slop = v & 0xf; - k = 2; - } - else if(k == 2) { - ret += int2char(slop); - ret += int2char(v >> 2); - slop = v & 3; - k = 3; - } - else { - ret += int2char((slop << 2) | (v >> 4)); - ret += int2char(v & 0xf); - k = 0; - } - } - if(k == 1) - ret += int2char(slop << 2); - return ret; -} - -// convert a base64 string to a byte/number array -function b64toBA(s) { - //piggyback on b64tohex for now, optimize later - var h = b64tohex(s); - var i; - var a = new Array(); - for(i = 0; 2*i < h.length; ++i) { - a[i] = parseInt(h.substring(2*i,2*i+2),16); - } - return a; -} +var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var b64padchar="="; + +function hex2b64(h) { + var i; + var c; + var ret = ""; + for(i = 0; i+3 <= h.length; i+=3) { + c = parseInt(h.substring(i,i+3),16); + ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); + } + if(i+1 == h.length) { + c = parseInt(h.substring(i,i+1),16); + ret += b64map.charAt(c << 2); + } + else if(i+2 == h.length) { + c = parseInt(h.substring(i,i+2),16); + ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); + } + while((ret.length & 3) > 0) ret += b64padchar; + return ret; +} + +// convert a base64 string to hex +function b64tohex(s) { + var ret = "" + var i; + var k = 0; // b64 state, 0-3 + var slop; + for(i = 0; i < s.length; ++i) { + if(s.charAt(i) == b64padchar) break; + v = b64map.indexOf(s.charAt(i)); + if(v < 0) continue; + if(k == 0) { + ret += int2char(v >> 2); + slop = v & 3; + k = 1; + } + else if(k == 1) { + ret += int2char((slop << 2) | (v >> 4)); + slop = v & 0xf; + k = 2; + } + else if(k == 2) { + ret += int2char(slop); + ret += int2char(v >> 2); + slop = v & 3; + k = 3; + } + else { + ret += int2char((slop << 2) | (v >> 4)); + ret += int2char(v & 0xf); + k = 0; + } + } + if(k == 1) + ret += int2char(slop << 2); + return ret; +} + +// convert a base64 string to a byte/number array +function b64toBA(s) { + //piggyback on b64tohex for now, optimize later + var h = b64tohex(s); + var i; + var a = new Array(); + for(i = 0; 2*i < h.length; ++i) { + a[i] = parseInt(h.substring(2*i,2*i+2),16); + } + return a; +} diff --git a/tool/java/Pailler/javascript/jsbn.js b/tool/java/Paillier/javascript/jsbn.js similarity index 96% rename from tool/java/Pailler/javascript/jsbn.js rename to tool/java/Paillier/javascript/jsbn.js index e163555e5c..d1b7788b0a 100644 --- a/tool/java/Pailler/javascript/jsbn.js +++ b/tool/java/Paillier/javascript/jsbn.js @@ -1,1217 +1,1217 @@ -// Copyright (c) 2005 Tom Wu -// All Rights Reserved. -// See "LICENSE" for details. - -// Basic JavaScript BN library - subset useful for RSA encryption. - -// Bits per digit -var dbits; - -// JavaScript engine analysis -var canary = 0xdeadbeefcafe; -var j_lm = ((canary&0xffffff)==0xefcafe); - -// (public) Constructor -function BigInteger(a,b,c) { - if(a != null) - if("number" == typeof a) this.fromNumber(a,b,c); - else if(b == null && "string" != typeof a) this.fromString(a,256); - else this.fromString(a,b); -} - -// return new, unset BigInteger -function nbi() { return new BigInteger(null); } - -// am: Compute w_j += (x*this_i), propagate carries, -// c is initial carry, returns final carry. -// c < 3*dvalue, x < 2*dvalue, this_i < dvalue -// We need to select the fastest one that works in this environment. - -// am1: use a single mult and divide to get the high bits, -// max digit bits should be 26 because -// max internal value = 2*dvalue^2-2*dvalue (< 2^53) -function am1(i,x,w,j,c,n) { - while(--n >= 0) { - var v = x*this[i++]+w[j]+c; - c = Math.floor(v/0x4000000); - w[j++] = v&0x3ffffff; - } - return c; -} -// am2 avoids a big mult-and-extract completely. -// Max digit bits should be <= 30 because we do bitwise ops -// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) -function am2(i,x,w,j,c,n) { - var xl = x&0x7fff, xh = x>>15; - while(--n >= 0) { - var l = this[i]&0x7fff; - var h = this[i++]>>15; - var m = xh*l+h*xl; - l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); - c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); - w[j++] = l&0x3fffffff; - } - return c; -} -// Alternately, set max digit bits to 28 since some -// browsers slow down when dealing with 32-bit numbers. -function am3(i,x,w,j,c,n) { - var xl = x&0x3fff, xh = x>>14; - while(--n >= 0) { - var l = this[i]&0x3fff; - var h = this[i++]>>14; - var m = xh*l+h*xl; - l = xl*l+((m&0x3fff)<<14)+w[j]+c; - c = (l>>28)+(m>>14)+xh*h; - w[j++] = l&0xfffffff; - } - return c; -} -if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { - BigInteger.prototype.am = am2; - dbits = 30; -} -else if(j_lm && (navigator.appName != "Netscape")) { - BigInteger.prototype.am = am1; - dbits = 26; -} -else { // Mozilla/Netscape seems to prefer am3 - BigInteger.prototype.am = am3; - dbits = 28; -} - -BigInteger.prototype.DB = dbits; -BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; - r.t = this.t; - r.s = this.s; -} - -// (protected) set from integer value x, -DV <= x < DV -function bnpFromInt(x) { - this.t = 1; - this.s = (x<0)?-1:0; - if(x > 0) this[0] = x; - else if(x < -1) this[0] = x+this.DV; - else this.t = 0; -} - -// return bigint initialized to value -function nbv(i) { var r = nbi(); r.fromInt(i); return r; } - -// (protected) set from string and radix -function bnpFromString(s,b) { - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 256) k = 8; // byte array - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else { this.fromRadix(s,b); return; } - this.t = 0; - this.s = 0; - var i = s.length, mi = false, sh = 0; - while(--i >= 0) { - var x = (k==8)?s[i]&0xff:intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-") mi = true; - continue; - } - mi = false; - if(sh == 0) - this[this.t++] = x; - else if(sh+k > this.DB) { - this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); - } - else - this[this.t-1] |= x<= this.DB) sh -= this.DB; - } - if(k == 8 && (s[0]&0x80) != 0) { - this.s = -1; - if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; -} - -// (public) return string representation in given radix -function bnToString(b) { - if(this.s < 0) return "-"+this.negate().toString(b); - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else return this.toRadix(b); - var km = (1< 0) { - if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } - while(i >= 0) { - if(p < k) { - d = (this[i]&((1<>(p+=this.DB-k); - } - else { - d = (this[i]>>(p-=k))&km; - if(p <= 0) { p += this.DB; --i; } - } - if(d > 0) m = true; - if(m) r += int2char(d); - } - } - return m?r:"0"; -} - -// (public) -this -function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } - -// (public) |this| -function bnAbs() { return (this.s<0)?this.negate():this; } - -// (public) return + if this > a, - if this < a, 0 if equal -function bnCompareTo(a) { - var r = this.s-a.s; - if(r != 0) return r; - var i = this.t; - r = i-a.t; - if(r != 0) return (this.s<0)?-r:r; - while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; - return 0; -} - -// returns bit length of the integer x -function nbits(x) { - var r = 1, t; - if((t=x>>>16) != 0) { x = t; r += 16; } - if((t=x>>8) != 0) { x = t; r += 8; } - if((t=x>>4) != 0) { x = t; r += 4; } - if((t=x>>2) != 0) { x = t; r += 2; } - if((t=x>>1) != 0) { x = t; r += 1; } - return r; -} - -// (public) return the number of bits in "this" -function bnBitLength() { - if(this.t <= 0) return 0; - return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); -} - -// (protected) r = this << n*DB -function bnpDLShiftTo(n,r) { - var i; - for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; - for(i = n-1; i >= 0; --i) r[i] = 0; - r.t = this.t+n; - r.s = this.s; -} - -// (protected) r = this >> n*DB -function bnpDRShiftTo(n,r) { - for(var i = n; i < this.t; ++i) r[i-n] = this[i]; - r.t = Math.max(this.t-n,0); - r.s = this.s; -} - -// (protected) r = this << n -function bnpLShiftTo(n,r) { - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<= 0; --i) { - r[i+ds+1] = (this[i]>>cbs)|c; - c = (this[i]&bm)<= 0; --i) r[i] = 0; - r[ds] = c; - r.t = this.t+ds+1; - r.s = this.s; - r.clamp(); -} - -// (protected) r = this >> n -function bnpRShiftTo(n,r) { - r.s = this.s; - var ds = Math.floor(n/this.DB); - if(ds >= this.t) { r.t = 0; return; } - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<>bs; - for(var i = ds+1; i < this.t; ++i) { - r[i-ds-1] |= (this[i]&bm)<>bs; - } - if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; - } - if(a.t < this.t) { - c -= a.s; - while(i < this.t) { - c += this[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } - else { - c += this.s; - while(i < a.t) { - c -= a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c -= a.s; - } - r.s = (c<0)?-1:0; - if(c < -1) r[i++] = this.DV+c; - else if(c > 0) r[i++] = c; - r.t = i; - r.clamp(); -} - -// (protected) r = this * a, r != this,a (HAC 14.12) -// "this" should be the larger one if appropriate. -function bnpMultiplyTo(a,r) { - var x = this.abs(), y = a.abs(); - var i = x.t; - r.t = i+y.t; - while(--i >= 0) r[i] = 0; - for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); - r.s = 0; - r.clamp(); - if(this.s != a.s) BigInteger.ZERO.subTo(r,r); -} - -// (protected) r = this^2, r != this (HAC 14.16) -function bnpSquareTo(r) { - var x = this.abs(); - var i = r.t = 2*x.t; - while(--i >= 0) r[i] = 0; - for(i = 0; i < x.t-1; ++i) { - var c = x.am(i,x[i],r,2*i,0,1); - if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { - r[i+x.t] -= x.DV; - r[i+x.t+1] = 1; - } - } - if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); - r.s = 0; - r.clamp(); -} - -// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) -// r != q, this != m. q or r may be null. -function bnpDivRemTo(m,q,r) { - var pm = m.abs(); - if(pm.t <= 0) return; - var pt = this.abs(); - if(pt.t < pm.t) { - if(q != null) q.fromInt(0); - if(r != null) this.copyTo(r); - return; - } - if(r == null) r = nbi(); - var y = nbi(), ts = this.s, ms = m.s; - var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus - if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } - else { pm.copyTo(y); pt.copyTo(r); } - var ys = y.t; - var y0 = y[ys-1]; - if(y0 == 0) return; - var yt = y0*(1<1)?y[ys-2]>>this.F2:0); - var d1 = this.FV/yt, d2 = (1<= 0) { - r[r.t++] = 1; - r.subTo(t,r); - } - BigInteger.ONE.dlShiftTo(ys,t); - t.subTo(y,y); // "negative" y so we can replace sub with am later - while(y.t < ys) y[y.t++] = 0; - while(--j >= 0) { - // Estimate quotient digit - var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); - if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out - y.dlShiftTo(j,t); - r.subTo(t,r); - while(r[i] < --qd) r.subTo(t,r); - } - } - if(q != null) { - r.drShiftTo(ys,q); - if(ts != ms) BigInteger.ZERO.subTo(q,q); - } - r.t = ys; - r.clamp(); - if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder - if(ts < 0) BigInteger.ZERO.subTo(r,r); -} - -// (public) this mod a -function bnMod(a) { - var r = nbi(); - this.abs().divRemTo(a,null,r); - if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); - return r; -} - -// Modular reduction using "classic" algorithm -function Classic(m) { this.m = m; } -function cConvert(x) { - if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); - else return x; -} -function cRevert(x) { return x; } -function cReduce(x) { x.divRemTo(this.m,null,x); } -function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } -function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -Classic.prototype.convert = cConvert; -Classic.prototype.revert = cRevert; -Classic.prototype.reduce = cReduce; -Classic.prototype.mulTo = cMulTo; -Classic.prototype.sqrTo = cSqrTo; - -// (protected) return "-1/this % 2^DB"; useful for Mont. reduction -// justification: -// xy == 1 (mod m) -// xy = 1+km -// xy(2-xy) = (1+km)(1-km) -// x[y(2-xy)] = 1-k^2m^2 -// x[y(2-xy)] == 1 (mod m^2) -// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 -// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. -// JS multiply "overflows" differently from C/C++, so care is needed here. -function bnpInvDigit() { - if(this.t < 1) return 0; - var x = this[0]; - if((x&1) == 0) return 0; - var y = x&3; // y == 1/x mod 2^2 - y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 - y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 - y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 - // last step - calculate inverse mod DV directly; - // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints - y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits - // we really want the negative inverse, and -DV < y < DV - return (y>0)?this.DV-y:-y; -} - -// Montgomery reduction -function Montgomery(m) { - this.m = m; - this.mp = m.invDigit(); - this.mpl = this.mp&0x7fff; - this.mph = this.mp>>15; - this.um = (1<<(m.DB-15))-1; - this.mt2 = 2*m.t; -} - -// xR mod m -function montConvert(x) { - var r = nbi(); - x.abs().dlShiftTo(this.m.t,r); - r.divRemTo(this.m,null,r); - if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); - return r; -} - -// x/R mod m -function montRevert(x) { - var r = nbi(); - x.copyTo(r); - this.reduce(r); - return r; -} - -// x = x/R mod m (HAC 14.32) -function montReduce(x) { - while(x.t <= this.mt2) // pad x so am has enough room later - x[x.t++] = 0; - for(var i = 0; i < this.m.t; ++i) { - // faster way of calculating u0 = x[i]*mp mod DV - var j = x[i]&0x7fff; - var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; - // use am to combine the multiply-shift-add into one call - j = i+this.m.t; - x[j] += this.m.am(0,u0,x,i,0,this.m.t); - // propagate carry - while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } - } - x.clamp(); - x.drShiftTo(this.m.t,x); - if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); -} - -// r = "x^2/R mod m"; x != r -function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -// r = "xy/R mod m"; x,y != r -function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - -Montgomery.prototype.convert = montConvert; -Montgomery.prototype.revert = montRevert; -Montgomery.prototype.reduce = montReduce; -Montgomery.prototype.mulTo = montMulTo; -Montgomery.prototype.sqrTo = montSqrTo; - -// (protected) true iff this is even -function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } - -// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) -function bnpExp(e,z) { - if(e > 0xffffffff || e < 1) return BigInteger.ONE; - var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; - g.copyTo(r); - while(--i >= 0) { - z.sqrTo(r,r2); - if((e&(1< 0) z.mulTo(r2,g,r); - else { var t = r; r = r2; r2 = t; } - } - return z.revert(r); -} - -// (public) this^e % m, 0 <= e < 2^32 -function bnModPowInt(e,m) { - var z; - if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); - return this.exp(e,z); -} - -// protected -BigInteger.prototype.copyTo = bnpCopyTo; -BigInteger.prototype.fromInt = bnpFromInt; -BigInteger.prototype.fromString = bnpFromString; -BigInteger.prototype.clamp = bnpClamp; -BigInteger.prototype.dlShiftTo = bnpDLShiftTo; -BigInteger.prototype.drShiftTo = bnpDRShiftTo; -BigInteger.prototype.lShiftTo = bnpLShiftTo; -BigInteger.prototype.rShiftTo = bnpRShiftTo; -BigInteger.prototype.subTo = bnpSubTo; -BigInteger.prototype.multiplyTo = bnpMultiplyTo; -BigInteger.prototype.squareTo = bnpSquareTo; -BigInteger.prototype.divRemTo = bnpDivRemTo; -BigInteger.prototype.invDigit = bnpInvDigit; -BigInteger.prototype.isEven = bnpIsEven; -BigInteger.prototype.exp = bnpExp; - -// public -BigInteger.prototype.toString = bnToString; -BigInteger.prototype.negate = bnNegate; -BigInteger.prototype.abs = bnAbs; -BigInteger.prototype.compareTo = bnCompareTo; -BigInteger.prototype.bitLength = bnBitLength; -BigInteger.prototype.mod = bnMod; -BigInteger.prototype.modPowInt = bnModPowInt; - -// "constants" -BigInteger.ZERO = nbv(0); -BigInteger.ONE = nbv(1); - -// Copyright (c) 2005-2009 Tom Wu -// All Rights Reserved. -// See "LICENSE" for details. - -// Extended JavaScript BN functions, required for RSA private ops. - -// Version 1.1: new BigInteger("0", 10) returns "proper" zero -// Version 1.2: square() API, isProbablePrime fix - -// (public) -function bnClone() { var r = nbi(); this.copyTo(r); return r; } - -// (public) return value as integer -function bnIntValue() { - if(this.s < 0) { - if(this.t == 1) return this[0]-this.DV; - else if(this.t == 0) return -1; - } - else if(this.t == 1) return this[0]; - else if(this.t == 0) return 0; - // assumes 16 < DB < 32 - return ((this[1]&((1<<(32-this.DB))-1))<>24; } - -// (public) return value as short (assumes DB>=16) -function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } - -// (protected) return x s.t. r^x < DV -function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } - -// (public) 0 if this == 0, 1 if this > 0 -function bnSigNum() { - if(this.s < 0) return -1; - else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; - else return 1; -} - -// (protected) convert to radix string -function bnpToRadix(b) { - if(b == null) b = 10; - if(this.signum() == 0 || b < 2 || b > 36) return "0"; - var cs = this.chunkSize(b); - var a = Math.pow(b,cs); - var d = nbv(a), y = nbi(), z = nbi(), r = ""; - this.divRemTo(d,y,z); - while(y.signum() > 0) { - r = (a+z.intValue()).toString(b).substr(1) + r; - y.divRemTo(d,y,z); - } - return z.intValue().toString(b) + r; -} - -// (protected) convert from radix string -function bnpFromRadix(s,b) { - this.fromInt(0); - if(b == null) b = 10; - var cs = this.chunkSize(b); - var d = Math.pow(b,cs), mi = false, j = 0, w = 0; - for(var i = 0; i < s.length; ++i) { - var x = intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-" && this.signum() == 0) mi = true; - continue; - } - w = b*w+x; - if(++j >= cs) { - this.dMultiply(d); - this.dAddOffset(w,0); - j = 0; - w = 0; - } - } - if(j > 0) { - this.dMultiply(Math.pow(b,j)); - this.dAddOffset(w,0); - } - if(mi) BigInteger.ZERO.subTo(this,this); -} - -// (protected) alternate constructor -function bnpFromNumber(a,b,c) { - if("number" == typeof b) { - // new BigInteger(int,int,RNG) - if(a < 2) this.fromInt(1); - else { - this.fromNumber(a,c); - if(!this.testBit(a-1)) // force MSB set - this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); - if(this.isEven()) this.dAddOffset(1,0); // force odd - while(!this.isProbablePrime(b)) { - this.dAddOffset(2,0); - if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); - } - } - } - else { - // new BigInteger(int,RNG) - var x = new Array(), t = a&7; - x.length = (a>>3)+1; - b.nextBytes(x); - if(t > 0) x[0] &= ((1< 0) { - if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) - r[k++] = d|(this.s<<(this.DB-p)); - while(i >= 0) { - if(p < 8) { - d = (this[i]&((1<>(p+=this.DB-8); - } - else { - d = (this[i]>>(p-=8))&0xff; - if(p <= 0) { p += this.DB; --i; } - } - if((d&0x80) != 0) d |= -256; - if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; - if(k > 0 || d != this.s) r[k++] = d; - } - } - return r; -} - -function bnEquals(a) { return(this.compareTo(a)==0); } -function bnMin(a) { return(this.compareTo(a)<0)?this:a; } -function bnMax(a) { return(this.compareTo(a)>0)?this:a; } - -// (protected) r = this op a (bitwise) -function bnpBitwiseTo(a,op,r) { - var i, f, m = Math.min(a.t,this.t); - for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); - if(a.t < this.t) { - f = a.s&this.DM; - for(i = m; i < this.t; ++i) r[i] = op(this[i],f); - r.t = this.t; - } - else { - f = this.s&this.DM; - for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); - r.t = a.t; - } - r.s = op(this.s,a.s); - r.clamp(); -} - -// (public) this & a -function op_and(x,y) { return x&y; } -function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } - -// (public) this | a -function op_or(x,y) { return x|y; } -function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } - -// (public) this ^ a -function op_xor(x,y) { return x^y; } -function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } - -// (public) this & ~a -function op_andnot(x,y) { return x&~y; } -function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } - -// (public) ~this -function bnNot() { - var r = nbi(); - for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; - r.t = this.t; - r.s = ~this.s; - return r; -} - -// (public) this << n -function bnShiftLeft(n) { - var r = nbi(); - if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); - return r; -} - -// (public) this >> n -function bnShiftRight(n) { - var r = nbi(); - if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); - return r; -} - -// return index of lowest 1-bit in x, x < 2^31 -function lbit(x) { - if(x == 0) return -1; - var r = 0; - if((x&0xffff) == 0) { x >>= 16; r += 16; } - if((x&0xff) == 0) { x >>= 8; r += 8; } - if((x&0xf) == 0) { x >>= 4; r += 4; } - if((x&3) == 0) { x >>= 2; r += 2; } - if((x&1) == 0) ++r; - return r; -} - -// (public) returns index of lowest 1-bit (or -1 if none) -function bnGetLowestSetBit() { - for(var i = 0; i < this.t; ++i) - if(this[i] != 0) return i*this.DB+lbit(this[i]); - if(this.s < 0) return this.t*this.DB; - return -1; -} - -// return number of 1 bits in x -function cbit(x) { - var r = 0; - while(x != 0) { x &= x-1; ++r; } - return r; -} - -// (public) return number of set bits -function bnBitCount() { - var r = 0, x = this.s&this.DM; - for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); - return r; -} - -// (public) true iff nth bit is set -function bnTestBit(n) { - var j = Math.floor(n/this.DB); - if(j >= this.t) return(this.s!=0); - return((this[j]&(1<<(n%this.DB)))!=0); -} - -// (protected) this op (1<>= this.DB; - } - if(a.t < this.t) { - c += a.s; - while(i < this.t) { - c += this[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } - else { - c += this.s; - while(i < a.t) { - c += a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += a.s; - } - r.s = (c<0)?-1:0; - if(c > 0) r[i++] = c; - else if(c < -1) r[i++] = this.DV+c; - r.t = i; - r.clamp(); -} - -// (public) this + a -function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } - -// (public) this - a -function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } - -// (public) this * a -function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } - -// (public) this^2 -function bnSquare() { var r = nbi(); this.squareTo(r); return r; } - -// (public) this / a -function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } - -// (public) this % a -function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } - -// (public) [this/a,this%a] -function bnDivideAndRemainder(a) { - var q = nbi(), r = nbi(); - this.divRemTo(a,q,r); - return new Array(q,r); -} - -// (protected) this *= n, this >= 0, 1 < n < DV -function bnpDMultiply(n) { - this[this.t] = this.am(0,n-1,this,0,0,this.t); - ++this.t; - this.clamp(); -} - -// (protected) this += n << w words, this >= 0 -function bnpDAddOffset(n,w) { - if(n == 0) return; - while(this.t <= w) this[this.t++] = 0; - this[w] += n; - while(this[w] >= this.DV) { - this[w] -= this.DV; - if(++w >= this.t) this[this.t++] = 0; - ++this[w]; - } -} - -// A "null" reducer -function NullExp() {} -function nNop(x) { return x; } -function nMulTo(x,y,r) { x.multiplyTo(y,r); } -function nSqrTo(x,r) { x.squareTo(r); } - -NullExp.prototype.convert = nNop; -NullExp.prototype.revert = nNop; -NullExp.prototype.mulTo = nMulTo; -NullExp.prototype.sqrTo = nSqrTo; - -// (public) this^e -function bnPow(e) { return this.exp(e,new NullExp()); } - -// (protected) r = lower n words of "this * a", a.t <= n -// "this" should be the larger one if appropriate. -function bnpMultiplyLowerTo(a,n,r) { - var i = Math.min(this.t+a.t,n); - r.s = 0; // assumes a,this >= 0 - r.t = i; - while(i > 0) r[--i] = 0; - var j; - for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); - for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); - r.clamp(); -} - -// (protected) r = "this * a" without lower n words, n > 0 -// "this" should be the larger one if appropriate. -function bnpMultiplyUpperTo(a,n,r) { - --n; - var i = r.t = this.t+a.t-n; - r.s = 0; // assumes a,this >= 0 - while(--i >= 0) r[i] = 0; - for(i = Math.max(n-this.t,0); i < a.t; ++i) - r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); - r.clamp(); - r.drShiftTo(1,r); -} - -// Barrett modular reduction -function Barrett(m) { - // setup Barrett - this.r2 = nbi(); - this.q3 = nbi(); - BigInteger.ONE.dlShiftTo(2*m.t,this.r2); - this.mu = this.r2.divide(m); - this.m = m; -} - -function barrettConvert(x) { - if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); - else if(x.compareTo(this.m) < 0) return x; - else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } -} - -function barrettRevert(x) { return x; } - -// x = x mod m (HAC 14.42) -function barrettReduce(x) { - x.drShiftTo(this.m.t-1,this.r2); - if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } - this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); - this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); - while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); - x.subTo(this.r2,x); - while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); -} - -// r = x^2 mod m; x != r -function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -// r = x*y mod m; x,y != r -function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - -Barrett.prototype.convert = barrettConvert; -Barrett.prototype.revert = barrettRevert; -Barrett.prototype.reduce = barrettReduce; -Barrett.prototype.mulTo = barrettMulTo; -Barrett.prototype.sqrTo = barrettSqrTo; - -// (public) this^e % m (HAC 14.85) -function bnModPow(e,m) { - var i = e.bitLength(), k, r = nbv(1), z; - if(i <= 0) return r; - else if(i < 18) k = 1; - else if(i < 48) k = 3; - else if(i < 144) k = 4; - else if(i < 768) k = 5; - else k = 6; - if(i < 8) - z = new Classic(m); - else if(m.isEven()) - z = new Barrett(m); - else - z = new Montgomery(m); - - // precomputation - var g = new Array(), n = 3, k1 = k-1, km = (1< 1) { - var g2 = nbi(); - z.sqrTo(g[1],g2); - while(n <= km) { - g[n] = nbi(); - z.mulTo(g2,g[n-2],g[n]); - n += 2; - } - } - - var j = e.t-1, w, is1 = true, r2 = nbi(), t; - i = nbits(e[j])-1; - while(j >= 0) { - if(i >= k1) w = (e[j]>>(i-k1))&km; - else { - w = (e[j]&((1<<(i+1))-1))<<(k1-i); - if(j > 0) w |= e[j-1]>>(this.DB+i-k1); - } - - n = k; - while((w&1) == 0) { w >>= 1; --n; } - if((i -= n) < 0) { i += this.DB; --j; } - if(is1) { // ret == 1, don't bother squaring or multiplying it - g[w].copyTo(r); - is1 = false; - } - else { - while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } - if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } - z.mulTo(r2,g[w],r); - } - - while(j >= 0 && (e[j]&(1< 0) { - x.rShiftTo(g,x); - y.rShiftTo(g,y); - } - while(x.signum() > 0) { - if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); - if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); - if(x.compareTo(y) >= 0) { - x.subTo(y,x); - x.rShiftTo(1,x); - } - else { - y.subTo(x,y); - y.rShiftTo(1,y); - } - } - if(g > 0) y.lShiftTo(g,y); - return y; -} - -// (protected) this % n, n < 2^26 -function bnpModInt(n) { - if(n <= 0) return 0; - var d = this.DV%n, r = (this.s<0)?n-1:0; - if(this.t > 0) - if(d == 0) r = this[0]%n; - else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; - return r; -} - -// (public) 1/this % m (HAC 14.61) -function bnModInverse(m) { - var ac = m.isEven(); - if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; - var u = m.clone(), v = this.clone(); - var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); - while(u.signum() != 0) { - while(u.isEven()) { - u.rShiftTo(1,u); - if(ac) { - if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } - a.rShiftTo(1,a); - } - else if(!b.isEven()) b.subTo(m,b); - b.rShiftTo(1,b); - } - while(v.isEven()) { - v.rShiftTo(1,v); - if(ac) { - if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } - c.rShiftTo(1,c); - } - else if(!d.isEven()) d.subTo(m,d); - d.rShiftTo(1,d); - } - if(u.compareTo(v) >= 0) { - u.subTo(v,u); - if(ac) a.subTo(c,a); - b.subTo(d,b); - } - else { - v.subTo(u,v); - if(ac) c.subTo(a,c); - d.subTo(b,d); - } - } - if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; - if(d.compareTo(m) >= 0) return d.subtract(m); - if(d.signum() < 0) d.addTo(m,d); else return d; - if(d.signum() < 0) return d.add(m); else return d; -} - -var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; -var lplim = (1<<26)/lowprimes[lowprimes.length-1]; - -// (public) test primality with certainty >= 1-.5^t -function bnIsProbablePrime(t) { - var i, x = this.abs(); - if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { - for(i = 0; i < lowprimes.length; ++i) - if(x[0] == lowprimes[i]) return true; - return false; - } - if(x.isEven()) return false; - i = 1; - while(i < lowprimes.length) { - var m = lowprimes[i], j = i+1; - while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; - m = x.modInt(m); - while(i < j) if(m%lowprimes[i++] == 0) return false; - } - return x.millerRabin(t); -} - -// (protected) true if probably prime (HAC 4.24, Miller-Rabin) -function bnpMillerRabin(t) { - var n1 = this.subtract(BigInteger.ONE); - var k = n1.getLowestSetBit(); - if(k <= 0) return false; - var r = n1.shiftRight(k); - t = (t+1)>>1; - if(t > lowprimes.length) t = lowprimes.length; - var a = nbi(); - for(var i = 0; i < t; ++i) { - //Pick bases at random, instead of starting at 2 - a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]); - var y = a.modPow(r,this); - if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { - var j = 1; - while(j++ < k && y.compareTo(n1) != 0) { - y = y.modPowInt(2,this); - if(y.compareTo(BigInteger.ONE) == 0) return false; - } - if(y.compareTo(n1) != 0) return false; - } - } - return true; -} - -// protected -BigInteger.prototype.chunkSize = bnpChunkSize; -BigInteger.prototype.toRadix = bnpToRadix; -BigInteger.prototype.fromRadix = bnpFromRadix; -BigInteger.prototype.fromNumber = bnpFromNumber; -BigInteger.prototype.bitwiseTo = bnpBitwiseTo; -BigInteger.prototype.changeBit = bnpChangeBit; -BigInteger.prototype.addTo = bnpAddTo; -BigInteger.prototype.dMultiply = bnpDMultiply; -BigInteger.prototype.dAddOffset = bnpDAddOffset; -BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; -BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; -BigInteger.prototype.modInt = bnpModInt; -BigInteger.prototype.millerRabin = bnpMillerRabin; - -// public -BigInteger.prototype.clone = bnClone; -BigInteger.prototype.intValue = bnIntValue; -BigInteger.prototype.byteValue = bnByteValue; -BigInteger.prototype.shortValue = bnShortValue; -BigInteger.prototype.signum = bnSigNum; -BigInteger.prototype.toByteArray = bnToByteArray; -BigInteger.prototype.equals = bnEquals; -BigInteger.prototype.min = bnMin; -BigInteger.prototype.max = bnMax; -BigInteger.prototype.and = bnAnd; -BigInteger.prototype.or = bnOr; -BigInteger.prototype.xor = bnXor; -BigInteger.prototype.andNot = bnAndNot; -BigInteger.prototype.not = bnNot; -BigInteger.prototype.shiftLeft = bnShiftLeft; -BigInteger.prototype.shiftRight = bnShiftRight; -BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; -BigInteger.prototype.bitCount = bnBitCount; -BigInteger.prototype.testBit = bnTestBit; -BigInteger.prototype.setBit = bnSetBit; -BigInteger.prototype.clearBit = bnClearBit; -BigInteger.prototype.flipBit = bnFlipBit; -BigInteger.prototype.add = bnAdd; -BigInteger.prototype.subtract = bnSubtract; -BigInteger.prototype.multiply = bnMultiply; -BigInteger.prototype.divide = bnDivide; -BigInteger.prototype.remainder = bnRemainder; -BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; -BigInteger.prototype.modPow = bnModPow; -BigInteger.prototype.modInverse = bnModInverse; -BigInteger.prototype.pow = bnPow; -BigInteger.prototype.gcd = bnGCD; -BigInteger.prototype.isProbablePrime = bnIsProbablePrime; - -// JSBN-specific extension -BigInteger.prototype.square = bnSquare; - -// BigInteger interfaces not implemented in jsbn: - -// BigInteger(int signum, byte[] magnitude) -// double doubleValue() -// float floatValue() -// int hashCode() -// long longValue() -// static BigInteger valueOf(long val) - +// Copyright (c) 2005 Tom Wu +// All Rights Reserved. +// See "LICENSE" for details. + +// Basic JavaScript BN library - subset useful for RSA encryption. + +// Bits per digit +var dbits; + +// JavaScript engine analysis +var canary = 0xdeadbeefcafe; +var j_lm = ((canary&0xffffff)==0xefcafe); + +// (public) Constructor +function BigInteger(a,b,c) { + if(a != null) + if("number" == typeof a) this.fromNumber(a,b,c); + else if(b == null && "string" != typeof a) this.fromString(a,256); + else this.fromString(a,b); +} + +// return new, unset BigInteger +function nbi() { return new BigInteger(null); } + +// am: Compute w_j += (x*this_i), propagate carries, +// c is initial carry, returns final carry. +// c < 3*dvalue, x < 2*dvalue, this_i < dvalue +// We need to select the fastest one that works in this environment. + +// am1: use a single mult and divide to get the high bits, +// max digit bits should be 26 because +// max internal value = 2*dvalue^2-2*dvalue (< 2^53) +function am1(i,x,w,j,c,n) { + while(--n >= 0) { + var v = x*this[i++]+w[j]+c; + c = Math.floor(v/0x4000000); + w[j++] = v&0x3ffffff; + } + return c; +} +// am2 avoids a big mult-and-extract completely. +// Max digit bits should be <= 30 because we do bitwise ops +// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) +function am2(i,x,w,j,c,n) { + var xl = x&0x7fff, xh = x>>15; + while(--n >= 0) { + var l = this[i]&0x7fff; + var h = this[i++]>>15; + var m = xh*l+h*xl; + l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); + c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); + w[j++] = l&0x3fffffff; + } + return c; +} +// Alternately, set max digit bits to 28 since some +// browsers slow down when dealing with 32-bit numbers. +function am3(i,x,w,j,c,n) { + var xl = x&0x3fff, xh = x>>14; + while(--n >= 0) { + var l = this[i]&0x3fff; + var h = this[i++]>>14; + var m = xh*l+h*xl; + l = xl*l+((m&0x3fff)<<14)+w[j]+c; + c = (l>>28)+(m>>14)+xh*h; + w[j++] = l&0xfffffff; + } + return c; +} +if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; +} +else if(j_lm && (navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; +} +else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; +} + +BigInteger.prototype.DB = dbits; +BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; +} + +// (protected) set from integer value x, -DV <= x < DV +function bnpFromInt(x) { + this.t = 1; + this.s = (x<0)?-1:0; + if(x > 0) this[0] = x; + else if(x < -1) this[0] = x+this.DV; + else this.t = 0; +} + +// return bigint initialized to value +function nbv(i) { var r = nbi(); r.fromInt(i); return r; } + +// (protected) set from string and radix +function bnpFromString(s,b) { + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 256) k = 8; // byte array + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else { this.fromRadix(s,b); return; } + this.t = 0; + this.s = 0; + var i = s.length, mi = false, sh = 0; + while(--i >= 0) { + var x = (k==8)?s[i]&0xff:intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if(sh == 0) + this[this.t++] = x; + else if(sh+k > this.DB) { + this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); + } + else + this[this.t-1] |= x<= this.DB) sh -= this.DB; + } + if(k == 8 && (s[0]&0x80) != 0) { + this.s = -1; + if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; +} + +// (public) return string representation in given radix +function bnToString(b) { + if(this.s < 0) return "-"+this.negate().toString(b); + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else return this.toRadix(b); + var km = (1< 0) { + if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } + while(i >= 0) { + if(p < k) { + d = (this[i]&((1<>(p+=this.DB-k); + } + else { + d = (this[i]>>(p-=k))&km; + if(p <= 0) { p += this.DB; --i; } + } + if(d > 0) m = true; + if(m) r += int2char(d); + } + } + return m?r:"0"; +} + +// (public) -this +function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } + +// (public) |this| +function bnAbs() { return (this.s<0)?this.negate():this; } + +// (public) return + if this > a, - if this < a, 0 if equal +function bnCompareTo(a) { + var r = this.s-a.s; + if(r != 0) return r; + var i = this.t; + r = i-a.t; + if(r != 0) return (this.s<0)?-r:r; + while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; + return 0; +} + +// returns bit length of the integer x +function nbits(x) { + var r = 1, t; + if((t=x>>>16) != 0) { x = t; r += 16; } + if((t=x>>8) != 0) { x = t; r += 8; } + if((t=x>>4) != 0) { x = t; r += 4; } + if((t=x>>2) != 0) { x = t; r += 2; } + if((t=x>>1) != 0) { x = t; r += 1; } + return r; +} + +// (public) return the number of bits in "this" +function bnBitLength() { + if(this.t <= 0) return 0; + return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); +} + +// (protected) r = this << n*DB +function bnpDLShiftTo(n,r) { + var i; + for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; + for(i = n-1; i >= 0; --i) r[i] = 0; + r.t = this.t+n; + r.s = this.s; +} + +// (protected) r = this >> n*DB +function bnpDRShiftTo(n,r) { + for(var i = n; i < this.t; ++i) r[i-n] = this[i]; + r.t = Math.max(this.t-n,0); + r.s = this.s; +} + +// (protected) r = this << n +function bnpLShiftTo(n,r) { + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<= 0; --i) { + r[i+ds+1] = (this[i]>>cbs)|c; + c = (this[i]&bm)<= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t+ds+1; + r.s = this.s; + r.clamp(); +} + +// (protected) r = this >> n +function bnpRShiftTo(n,r) { + r.s = this.s; + var ds = Math.floor(n/this.DB); + if(ds >= this.t) { r.t = 0; return; } + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<>bs; + for(var i = ds+1; i < this.t; ++i) { + r[i-ds-1] |= (this[i]&bm)<>bs; + } + if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; + } + if(a.t < this.t) { + c -= a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c -= a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c<0)?-1:0; + if(c < -1) r[i++] = this.DV+c; + else if(c > 0) r[i++] = c; + r.t = i; + r.clamp(); +} + +// (protected) r = this * a, r != this,a (HAC 14.12) +// "this" should be the larger one if appropriate. +function bnpMultiplyTo(a,r) { + var x = this.abs(), y = a.abs(); + var i = x.t; + r.t = i+y.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); + r.s = 0; + r.clamp(); + if(this.s != a.s) BigInteger.ZERO.subTo(r,r); +} + +// (protected) r = this^2, r != this (HAC 14.16) +function bnpSquareTo(r) { + var x = this.abs(); + var i = r.t = 2*x.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < x.t-1; ++i) { + var c = x.am(i,x[i],r,2*i,0,1); + if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { + r[i+x.t] -= x.DV; + r[i+x.t+1] = 1; + } + } + if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); + r.s = 0; + r.clamp(); +} + +// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) +// r != q, this != m. q or r may be null. +function bnpDivRemTo(m,q,r) { + var pm = m.abs(); + if(pm.t <= 0) return; + var pt = this.abs(); + if(pt.t < pm.t) { + if(q != null) q.fromInt(0); + if(r != null) this.copyTo(r); + return; + } + if(r == null) r = nbi(); + var y = nbi(), ts = this.s, ms = m.s; + var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus + if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } + else { pm.copyTo(y); pt.copyTo(r); } + var ys = y.t; + var y0 = y[ys-1]; + if(y0 == 0) return; + var yt = y0*(1<1)?y[ys-2]>>this.F2:0); + var d1 = this.FV/yt, d2 = (1<= 0) { + r[r.t++] = 1; + r.subTo(t,r); + } + BigInteger.ONE.dlShiftTo(ys,t); + t.subTo(y,y); // "negative" y so we can replace sub with am later + while(y.t < ys) y[y.t++] = 0; + while(--j >= 0) { + // Estimate quotient digit + var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); + if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out + y.dlShiftTo(j,t); + r.subTo(t,r); + while(r[i] < --qd) r.subTo(t,r); + } + } + if(q != null) { + r.drShiftTo(ys,q); + if(ts != ms) BigInteger.ZERO.subTo(q,q); + } + r.t = ys; + r.clamp(); + if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder + if(ts < 0) BigInteger.ZERO.subTo(r,r); +} + +// (public) this mod a +function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a,null,r); + if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); + return r; +} + +// Modular reduction using "classic" algorithm +function Classic(m) { this.m = m; } +function cConvert(x) { + if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; +} +function cRevert(x) { return x; } +function cReduce(x) { x.divRemTo(this.m,null,x); } +function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } +function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +Classic.prototype.convert = cConvert; +Classic.prototype.revert = cRevert; +Classic.prototype.reduce = cReduce; +Classic.prototype.mulTo = cMulTo; +Classic.prototype.sqrTo = cSqrTo; + +// (protected) return "-1/this % 2^DB"; useful for Mont. reduction +// justification: +// xy == 1 (mod m) +// xy = 1+km +// xy(2-xy) = (1+km)(1-km) +// x[y(2-xy)] = 1-k^2m^2 +// x[y(2-xy)] == 1 (mod m^2) +// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 +// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. +// JS multiply "overflows" differently from C/C++, so care is needed here. +function bnpInvDigit() { + if(this.t < 1) return 0; + var x = this[0]; + if((x&1) == 0) return 0; + var y = x&3; // y == 1/x mod 2^2 + y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 + y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 + y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y>0)?this.DV-y:-y; +} + +// Montgomery reduction +function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp&0x7fff; + this.mph = this.mp>>15; + this.um = (1<<(m.DB-15))-1; + this.mt2 = 2*m.t; +} + +// xR mod m +function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t,r); + r.divRemTo(this.m,null,r); + if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); + return r; +} + +// x/R mod m +function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; +} + +// x = x/R mod m (HAC 14.32) +function montReduce(x) { + while(x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for(var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i]&0x7fff; + var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; + // use am to combine the multiply-shift-add into one call + j = i+this.m.t; + x[j] += this.m.am(0,u0,x,i,0,this.m.t); + // propagate carry + while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } + } + x.clamp(); + x.drShiftTo(this.m.t,x); + if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = "x^2/R mod m"; x != r +function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = "xy/R mod m"; x,y != r +function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Montgomery.prototype.convert = montConvert; +Montgomery.prototype.revert = montRevert; +Montgomery.prototype.reduce = montReduce; +Montgomery.prototype.mulTo = montMulTo; +Montgomery.prototype.sqrTo = montSqrTo; + +// (protected) true iff this is even +function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } + +// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) +function bnpExp(e,z) { + if(e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; + g.copyTo(r); + while(--i >= 0) { + z.sqrTo(r,r2); + if((e&(1< 0) z.mulTo(r2,g,r); + else { var t = r; r = r2; r2 = t; } + } + return z.revert(r); +} + +// (public) this^e % m, 0 <= e < 2^32 +function bnModPowInt(e,m) { + var z; + if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e,z); +} + +// protected +BigInteger.prototype.copyTo = bnpCopyTo; +BigInteger.prototype.fromInt = bnpFromInt; +BigInteger.prototype.fromString = bnpFromString; +BigInteger.prototype.clamp = bnpClamp; +BigInteger.prototype.dlShiftTo = bnpDLShiftTo; +BigInteger.prototype.drShiftTo = bnpDRShiftTo; +BigInteger.prototype.lShiftTo = bnpLShiftTo; +BigInteger.prototype.rShiftTo = bnpRShiftTo; +BigInteger.prototype.subTo = bnpSubTo; +BigInteger.prototype.multiplyTo = bnpMultiplyTo; +BigInteger.prototype.squareTo = bnpSquareTo; +BigInteger.prototype.divRemTo = bnpDivRemTo; +BigInteger.prototype.invDigit = bnpInvDigit; +BigInteger.prototype.isEven = bnpIsEven; +BigInteger.prototype.exp = bnpExp; + +// public +BigInteger.prototype.toString = bnToString; +BigInteger.prototype.negate = bnNegate; +BigInteger.prototype.abs = bnAbs; +BigInteger.prototype.compareTo = bnCompareTo; +BigInteger.prototype.bitLength = bnBitLength; +BigInteger.prototype.mod = bnMod; +BigInteger.prototype.modPowInt = bnModPowInt; + +// "constants" +BigInteger.ZERO = nbv(0); +BigInteger.ONE = nbv(1); + +// Copyright (c) 2005-2009 Tom Wu +// All Rights Reserved. +// See "LICENSE" for details. + +// Extended JavaScript BN functions, required for RSA private ops. + +// Version 1.1: new BigInteger("0", 10) returns "proper" zero +// Version 1.2: square() API, isProbablePrime fix + +// (public) +function bnClone() { var r = nbi(); this.copyTo(r); return r; } + +// (public) return value as integer +function bnIntValue() { + if(this.s < 0) { + if(this.t == 1) return this[0]-this.DV; + else if(this.t == 0) return -1; + } + else if(this.t == 1) return this[0]; + else if(this.t == 0) return 0; + // assumes 16 < DB < 32 + return ((this[1]&((1<<(32-this.DB))-1))<>24; } + +// (public) return value as short (assumes DB>=16) +function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } + +// (protected) return x s.t. r^x < DV +function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } + +// (public) 0 if this == 0, 1 if this > 0 +function bnSigNum() { + if(this.s < 0) return -1; + else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else return 1; +} + +// (protected) convert to radix string +function bnpToRadix(b) { + if(b == null) b = 10; + if(this.signum() == 0 || b < 2 || b > 36) return "0"; + var cs = this.chunkSize(b); + var a = Math.pow(b,cs); + var d = nbv(a), y = nbi(), z = nbi(), r = ""; + this.divRemTo(d,y,z); + while(y.signum() > 0) { + r = (a+z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d,y,z); + } + return z.intValue().toString(b) + r; +} + +// (protected) convert from radix string +function bnpFromRadix(s,b) { + this.fromInt(0); + if(b == null) b = 10; + var cs = this.chunkSize(b); + var d = Math.pow(b,cs), mi = false, j = 0, w = 0; + for(var i = 0; i < s.length; ++i) { + var x = intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-" && this.signum() == 0) mi = true; + continue; + } + w = b*w+x; + if(++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w,0); + j = 0; + w = 0; + } + } + if(j > 0) { + this.dMultiply(Math.pow(b,j)); + this.dAddOffset(w,0); + } + if(mi) BigInteger.ZERO.subTo(this,this); +} + +// (protected) alternate constructor +function bnpFromNumber(a,b,c) { + if("number" == typeof b) { + // new BigInteger(int,int,RNG) + if(a < 2) this.fromInt(1); + else { + this.fromNumber(a,c); + if(!this.testBit(a-1)) // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); + if(this.isEven()) this.dAddOffset(1,0); // force odd + while(!this.isProbablePrime(b)) { + this.dAddOffset(2,0); + if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); + } + } + } + else { + // new BigInteger(int,RNG) + var x = new Array(), t = a&7; + x.length = (a>>3)+1; + b.nextBytes(x); + if(t > 0) x[0] &= ((1< 0) { + if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) + r[k++] = d|(this.s<<(this.DB-p)); + while(i >= 0) { + if(p < 8) { + d = (this[i]&((1<>(p+=this.DB-8); + } + else { + d = (this[i]>>(p-=8))&0xff; + if(p <= 0) { p += this.DB; --i; } + } + if((d&0x80) != 0) d |= -256; + if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; + if(k > 0 || d != this.s) r[k++] = d; + } + } + return r; +} + +function bnEquals(a) { return(this.compareTo(a)==0); } +function bnMin(a) { return(this.compareTo(a)<0)?this:a; } +function bnMax(a) { return(this.compareTo(a)>0)?this:a; } + +// (protected) r = this op a (bitwise) +function bnpBitwiseTo(a,op,r) { + var i, f, m = Math.min(a.t,this.t); + for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); + if(a.t < this.t) { + f = a.s&this.DM; + for(i = m; i < this.t; ++i) r[i] = op(this[i],f); + r.t = this.t; + } + else { + f = this.s&this.DM; + for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); + r.t = a.t; + } + r.s = op(this.s,a.s); + r.clamp(); +} + +// (public) this & a +function op_and(x,y) { return x&y; } +function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } + +// (public) this | a +function op_or(x,y) { return x|y; } +function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } + +// (public) this ^ a +function op_xor(x,y) { return x^y; } +function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } + +// (public) this & ~a +function op_andnot(x,y) { return x&~y; } +function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } + +// (public) ~this +function bnNot() { + var r = nbi(); + for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; + r.t = this.t; + r.s = ~this.s; + return r; +} + +// (public) this << n +function bnShiftLeft(n) { + var r = nbi(); + if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); + return r; +} + +// (public) this >> n +function bnShiftRight(n) { + var r = nbi(); + if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); + return r; +} + +// return index of lowest 1-bit in x, x < 2^31 +function lbit(x) { + if(x == 0) return -1; + var r = 0; + if((x&0xffff) == 0) { x >>= 16; r += 16; } + if((x&0xff) == 0) { x >>= 8; r += 8; } + if((x&0xf) == 0) { x >>= 4; r += 4; } + if((x&3) == 0) { x >>= 2; r += 2; } + if((x&1) == 0) ++r; + return r; +} + +// (public) returns index of lowest 1-bit (or -1 if none) +function bnGetLowestSetBit() { + for(var i = 0; i < this.t; ++i) + if(this[i] != 0) return i*this.DB+lbit(this[i]); + if(this.s < 0) return this.t*this.DB; + return -1; +} + +// return number of 1 bits in x +function cbit(x) { + var r = 0; + while(x != 0) { x &= x-1; ++r; } + return r; +} + +// (public) return number of set bits +function bnBitCount() { + var r = 0, x = this.s&this.DM; + for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); + return r; +} + +// (public) true iff nth bit is set +function bnTestBit(n) { + var j = Math.floor(n/this.DB); + if(j >= this.t) return(this.s!=0); + return((this[j]&(1<<(n%this.DB)))!=0); +} + +// (protected) this op (1<>= this.DB; + } + if(a.t < this.t) { + c += a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c += a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = (c<0)?-1:0; + if(c > 0) r[i++] = c; + else if(c < -1) r[i++] = this.DV+c; + r.t = i; + r.clamp(); +} + +// (public) this + a +function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } + +// (public) this - a +function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } + +// (public) this * a +function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } + +// (public) this^2 +function bnSquare() { var r = nbi(); this.squareTo(r); return r; } + +// (public) this / a +function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } + +// (public) this % a +function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } + +// (public) [this/a,this%a] +function bnDivideAndRemainder(a) { + var q = nbi(), r = nbi(); + this.divRemTo(a,q,r); + return new Array(q,r); +} + +// (protected) this *= n, this >= 0, 1 < n < DV +function bnpDMultiply(n) { + this[this.t] = this.am(0,n-1,this,0,0,this.t); + ++this.t; + this.clamp(); +} + +// (protected) this += n << w words, this >= 0 +function bnpDAddOffset(n,w) { + if(n == 0) return; + while(this.t <= w) this[this.t++] = 0; + this[w] += n; + while(this[w] >= this.DV) { + this[w] -= this.DV; + if(++w >= this.t) this[this.t++] = 0; + ++this[w]; + } +} + +// A "null" reducer +function NullExp() {} +function nNop(x) { return x; } +function nMulTo(x,y,r) { x.multiplyTo(y,r); } +function nSqrTo(x,r) { x.squareTo(r); } + +NullExp.prototype.convert = nNop; +NullExp.prototype.revert = nNop; +NullExp.prototype.mulTo = nMulTo; +NullExp.prototype.sqrTo = nSqrTo; + +// (public) this^e +function bnPow(e) { return this.exp(e,new NullExp()); } + +// (protected) r = lower n words of "this * a", a.t <= n +// "this" should be the larger one if appropriate. +function bnpMultiplyLowerTo(a,n,r) { + var i = Math.min(this.t+a.t,n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while(i > 0) r[--i] = 0; + var j; + for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); + for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); + r.clamp(); +} + +// (protected) r = "this * a" without lower n words, n > 0 +// "this" should be the larger one if appropriate. +function bnpMultiplyUpperTo(a,n,r) { + --n; + var i = r.t = this.t+a.t-n; + r.s = 0; // assumes a,this >= 0 + while(--i >= 0) r[i] = 0; + for(i = Math.max(n-this.t,0); i < a.t; ++i) + r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); + r.clamp(); + r.drShiftTo(1,r); +} + +// Barrett modular reduction +function Barrett(m) { + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2*m.t,this.r2); + this.mu = this.r2.divide(m); + this.m = m; +} + +function barrettConvert(x) { + if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); + else if(x.compareTo(this.m) < 0) return x; + else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } +} + +function barrettRevert(x) { return x; } + +// x = x mod m (HAC 14.42) +function barrettReduce(x) { + x.drShiftTo(this.m.t-1,this.r2); + if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } + this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); + this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); + while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); + x.subTo(this.r2,x); + while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = x^2 mod m; x != r +function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = x*y mod m; x,y != r +function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Barrett.prototype.convert = barrettConvert; +Barrett.prototype.revert = barrettRevert; +Barrett.prototype.reduce = barrettReduce; +Barrett.prototype.mulTo = barrettMulTo; +Barrett.prototype.sqrTo = barrettSqrTo; + +// (public) this^e % m (HAC 14.85) +function bnModPow(e,m) { + var i = e.bitLength(), k, r = nbv(1), z; + if(i <= 0) return r; + else if(i < 18) k = 1; + else if(i < 48) k = 3; + else if(i < 144) k = 4; + else if(i < 768) k = 5; + else k = 6; + if(i < 8) + z = new Classic(m); + else if(m.isEven()) + z = new Barrett(m); + else + z = new Montgomery(m); + + // precomputation + var g = new Array(), n = 3, k1 = k-1, km = (1< 1) { + var g2 = nbi(); + z.sqrTo(g[1],g2); + while(n <= km) { + g[n] = nbi(); + z.mulTo(g2,g[n-2],g[n]); + n += 2; + } + } + + var j = e.t-1, w, is1 = true, r2 = nbi(), t; + i = nbits(e[j])-1; + while(j >= 0) { + if(i >= k1) w = (e[j]>>(i-k1))&km; + else { + w = (e[j]&((1<<(i+1))-1))<<(k1-i); + if(j > 0) w |= e[j-1]>>(this.DB+i-k1); + } + + n = k; + while((w&1) == 0) { w >>= 1; --n; } + if((i -= n) < 0) { i += this.DB; --j; } + if(is1) { // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } + else { + while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } + if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } + z.mulTo(r2,g[w],r); + } + + while(j >= 0 && (e[j]&(1< 0) { + x.rShiftTo(g,x); + y.rShiftTo(g,y); + } + while(x.signum() > 0) { + if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); + if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); + if(x.compareTo(y) >= 0) { + x.subTo(y,x); + x.rShiftTo(1,x); + } + else { + y.subTo(x,y); + y.rShiftTo(1,y); + } + } + if(g > 0) y.lShiftTo(g,y); + return y; +} + +// (protected) this % n, n < 2^26 +function bnpModInt(n) { + if(n <= 0) return 0; + var d = this.DV%n, r = (this.s<0)?n-1:0; + if(this.t > 0) + if(d == 0) r = this[0]%n; + else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; + return r; +} + +// (public) 1/this % m (HAC 14.61) +function bnModInverse(m) { + var ac = m.isEven(); + if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + var u = m.clone(), v = this.clone(); + var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); + while(u.signum() != 0) { + while(u.isEven()) { + u.rShiftTo(1,u); + if(ac) { + if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } + a.rShiftTo(1,a); + } + else if(!b.isEven()) b.subTo(m,b); + b.rShiftTo(1,b); + } + while(v.isEven()) { + v.rShiftTo(1,v); + if(ac) { + if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } + c.rShiftTo(1,c); + } + else if(!d.isEven()) d.subTo(m,d); + d.rShiftTo(1,d); + } + if(u.compareTo(v) >= 0) { + u.subTo(v,u); + if(ac) a.subTo(c,a); + b.subTo(d,b); + } + else { + v.subTo(u,v); + if(ac) c.subTo(a,c); + d.subTo(b,d); + } + } + if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; + if(d.compareTo(m) >= 0) return d.subtract(m); + if(d.signum() < 0) d.addTo(m,d); else return d; + if(d.signum() < 0) return d.add(m); else return d; +} + +var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; +var lplim = (1<<26)/lowprimes[lowprimes.length-1]; + +// (public) test primality with certainty >= 1-.5^t +function bnIsProbablePrime(t) { + var i, x = this.abs(); + if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { + for(i = 0; i < lowprimes.length; ++i) + if(x[0] == lowprimes[i]) return true; + return false; + } + if(x.isEven()) return false; + i = 1; + while(i < lowprimes.length) { + var m = lowprimes[i], j = i+1; + while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + m = x.modInt(m); + while(i < j) if(m%lowprimes[i++] == 0) return false; + } + return x.millerRabin(t); +} + +// (protected) true if probably prime (HAC 4.24, Miller-Rabin) +function bnpMillerRabin(t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if(k <= 0) return false; + var r = n1.shiftRight(k); + t = (t+1)>>1; + if(t > lowprimes.length) t = lowprimes.length; + var a = nbi(); + for(var i = 0; i < t; ++i) { + //Pick bases at random, instead of starting at 2 + a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]); + var y = a.modPow(r,this); + if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while(j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2,this); + if(y.compareTo(BigInteger.ONE) == 0) return false; + } + if(y.compareTo(n1) != 0) return false; + } + } + return true; +} + +// protected +BigInteger.prototype.chunkSize = bnpChunkSize; +BigInteger.prototype.toRadix = bnpToRadix; +BigInteger.prototype.fromRadix = bnpFromRadix; +BigInteger.prototype.fromNumber = bnpFromNumber; +BigInteger.prototype.bitwiseTo = bnpBitwiseTo; +BigInteger.prototype.changeBit = bnpChangeBit; +BigInteger.prototype.addTo = bnpAddTo; +BigInteger.prototype.dMultiply = bnpDMultiply; +BigInteger.prototype.dAddOffset = bnpDAddOffset; +BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; +BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; +BigInteger.prototype.modInt = bnpModInt; +BigInteger.prototype.millerRabin = bnpMillerRabin; + +// public +BigInteger.prototype.clone = bnClone; +BigInteger.prototype.intValue = bnIntValue; +BigInteger.prototype.byteValue = bnByteValue; +BigInteger.prototype.shortValue = bnShortValue; +BigInteger.prototype.signum = bnSigNum; +BigInteger.prototype.toByteArray = bnToByteArray; +BigInteger.prototype.equals = bnEquals; +BigInteger.prototype.min = bnMin; +BigInteger.prototype.max = bnMax; +BigInteger.prototype.and = bnAnd; +BigInteger.prototype.or = bnOr; +BigInteger.prototype.xor = bnXor; +BigInteger.prototype.andNot = bnAndNot; +BigInteger.prototype.not = bnNot; +BigInteger.prototype.shiftLeft = bnShiftLeft; +BigInteger.prototype.shiftRight = bnShiftRight; +BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; +BigInteger.prototype.bitCount = bnBitCount; +BigInteger.prototype.testBit = bnTestBit; +BigInteger.prototype.setBit = bnSetBit; +BigInteger.prototype.clearBit = bnClearBit; +BigInteger.prototype.flipBit = bnFlipBit; +BigInteger.prototype.add = bnAdd; +BigInteger.prototype.subtract = bnSubtract; +BigInteger.prototype.multiply = bnMultiply; +BigInteger.prototype.divide = bnDivide; +BigInteger.prototype.remainder = bnRemainder; +BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; +BigInteger.prototype.modPow = bnModPow; +BigInteger.prototype.modInverse = bnModInverse; +BigInteger.prototype.pow = bnPow; +BigInteger.prototype.gcd = bnGCD; +BigInteger.prototype.isProbablePrime = bnIsProbablePrime; + +// JSBN-specific extension +BigInteger.prototype.square = bnSquare; + +// BigInteger interfaces not implemented in jsbn: + +// BigInteger(int signum, byte[] magnitude) +// double doubleValue() +// float floatValue() +// int hashCode() +// long longValue() +// static BigInteger valueOf(long val) + diff --git a/tool/java/Pailler/javascript/paillierKey.js b/tool/java/Paillier/javascript/paillierKey.js similarity index 97% rename from tool/java/Pailler/javascript/paillierKey.js rename to tool/java/Paillier/javascript/paillierKey.js index 1fc20879f5..c376369ae4 100644 --- a/tool/java/Pailler/javascript/paillierKey.js +++ b/tool/java/Paillier/javascript/paillierKey.js @@ -1,333 +1,333 @@ - -// convert a (hex) string to a bignum object -function parseBigInt(str,r) { - return new BigInteger(str,r); -} - -function _pem_extractEncodedData(sPEMString, sHead) { - var s = sPEMString; - s = s.replace("-----BEGIN " + sHead + "-----", ""); - s = s.replace("-----END " + sHead + "-----", ""); - s = s.replace(/[ \n]+/g, ""); - return s; -} - -function _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey) { - var a = new Array(); - var v1 = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); - var n1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, v1); - var e1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, n1); - var d1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, e1); - var p1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, d1); - var q1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, p1); - var dp1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, q1); - var dq1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, dp1); - var co1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, dq1); - a.push(v1, n1, e1, d1, p1, q1, dp1, dq1, co1); - return a; -} - -function _rsapem_getHexValueArrayOfChildrenFromHex(hPrivateKey) { - var posArray = _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey); - var v = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); - var n = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); - var e = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[2]); - var d = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[3]); - var p = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[4]); - var q = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[5]); - var dp = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[6]); - var dq = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[7]); - var co = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[8]); - var a = new Array(); - a.push(v, n, e, d, p, q, dp, dq, co); - return a; -} - -function _rsapem_getPosArrayOfChildrenFromPublicKeyHex(hPrivateKey) { - var a = new Array(); - var header = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); - var keys = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, header); - a.push(header, keys); - return a; -} - -function _rsapem_getPosArrayOfChildrenFromPrivateKeyHex(hPrivateKey) { - var a = new Array(); - var integer = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); - var header = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, integer); - var keys = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, header); - a.push(integer, header, keys); - return a; -} - -function _rsapem_getHexValueArrayOfChildrenFromPublicKeyHex(hPrivateKey) { - var posArray = _rsapem_getPosArrayOfChildrenFromPublicKeyHex(hPrivateKey); - var headerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); - var keysVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); - - var keysSequence = keysVal.substring(2); - posArray = _rsapem_getPosArrayOfChildrenFromPublicKeyHex(keysSequence); - var modulus = _asnhex_getHexOfV_AtObj(keysSequence, posArray[0]); - var publicExp = _asnhex_getHexOfV_AtObj(keysSequence, posArray[1]); - - var a = new Array(); - a.push(modulus, publicExp); - return a; -} - - -function _rsapem_getHexValueArrayOfChildrenFromPrivateKeyHex(hPrivateKey) { - var posArray = _rsapem_getPosArrayOfChildrenFromPrivateKeyHex(hPrivateKey); - var integerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); - var headerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); - var keysVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[2]); - - var keysSequence = keysVal.substring(2); - return _rsapem_getHexValueArrayOfChildrenFromHex(keysSequence); -} - -function _rsapem_readPrivateKeyFromPkcs1PemString(keyPEM) { - var keyB64 = _rsapem_extractEncodedData(keyPEM); - var keyHex = b64tohex(keyB64) // depends base64.js - var a = _rsapem_getHexValueArrayOfChildrenFromHex(keyHex); - this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]); -} - -function _rsapem_readPrivateKeyFromPkcs8PemString(keyPEM) { - var keyB64 = _rsapem_extractEncodedData(keyPEM); - var keyHex = b64tohex(keyB64) // depends base64.js - var a = _rsapem_getHexValueArrayOfChildrenFromPrivateKeyHex(keyHex); - this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]); -} - -function _rsapem_readPublicKeyFromX509PemString(keyPEM) { - var keyB64 = _rsapem_extractEncodedData(keyPEM); - var keyHex = b64tohex(keyB64) // depends base64.js - var a = _rsapem_getHexValueArrayOfChildrenFromPublicKeyHex(keyHex); - this.setPublic(a[0],a[1]); -} - -/** -* Pad string with leading zeros, to use even number of bytes. -*/ -function _rsapem_padWithZero(numString) { - if (numString.length % 2 == 1) { - return "0" + numString; - } - return numString; -} - -/** -* Encode length in DER format (if length <0x80, then one byte, else first byte is 0x80 + length of length :) + n-bytes of length). -*/ -function _rsapem_encodeLength(length) { - if (length >= parseInt("80", 16)) { - var realLength = _rsapem_padWithZero(length.toString(16)); - var lengthOfLength = (realLength.length / 2); - return (parseInt("80", 16) + lengthOfLength).toString(16) + realLength; - } else { - return _rsapem_padWithZero(length.toString(16)); - } -} - -/** -* Encode number in DER encoding ("02" + length + number). -*/ -function _rsapem_derEncodeNumber(number) { - var numberString = _rsapem_padWithZero(number.toString(16)); - if (numberString[0] > '7') { - numberString = "00" + numberString; - } - var lenString = _rsapem_encodeLength(numberString.length / 2); - return "02" + lenString + numberString; -} - -/** -* Converts private & public part of given key to ASN1 Hex String. -*/ -function _rsapem_privateKeyToPkcs1HexString(rsaKey) { - var result = _rsapem_derEncodeNumber(0); - result += _rsapem_derEncodeNumber(rsaKey.n); - result += _rsapem_derEncodeNumber(rsaKey.e); - result += _rsapem_derEncodeNumber(rsaKey.d); - result += _rsapem_derEncodeNumber(rsaKey.p); - result += _rsapem_derEncodeNumber(rsaKey.q); - result += _rsapem_derEncodeNumber(rsaKey.dmp1); - result += _rsapem_derEncodeNumber(rsaKey.dmq1); - result += _rsapem_derEncodeNumber(rsaKey.coeff); - - var fullLen = _rsapem_encodeLength(result.length / 2); - return '30' + fullLen + result; -} - -/** -* Converts private & public part of given key to PKCS#8 Hex String. -*/ -function _rsapem_privateKeyToPkcs8HexString(rsaKey) { - var zeroInteger = "020100"; - var encodedIdentifier = "06092A864886F70D010101"; - var encodedNull = "0500"; - var headerSequence = "300D" + encodedIdentifier + encodedNull; - var keySequence = _rsapem_privateKeyToPkcs1HexString(rsaKey); - - var keyOctetString = "04" + _rsapem_encodeLength(keySequence.length / 2) + keySequence; - - var mainSequence = zeroInteger + headerSequence + keyOctetString; - return "30" + _rsapem_encodeLength(mainSequence.length / 2) + mainSequence; -} - -/** -* Converts public part of given key to ASN1 Hex String. -*/ -function _rsapem_publicKeyToX509HexString(rsaKey) { - var encodedIdentifier = "06092A864886F70D010101"; - var encodedNull = "0500"; - var headerSequence = "300D" + encodedIdentifier + encodedNull; - - var keys = _rsapem_derEncodeNumber(rsaKey.n); - keys += _rsapem_derEncodeNumber(rsaKey.e); - - var keySequence = "0030" + _rsapem_encodeLength(keys.length / 2) + keys; - var bitstring = "03" + _rsapem_encodeLength(keySequence.length / 2) + keySequence; - - var mainSequence = headerSequence + bitstring; - - return "30" + _rsapem_encodeLength(mainSequence.length / 2) + mainSequence; -} - -/** -* Output private & public part of the key in PKCS#1 PEM format. -*/ -function _rsapem_privateKeyToPkcs1PemString() { - var b64Cert = hex2b64(_rsapem_privateKeyToPkcs1HexString(this)); - var s = "-----BEGIN RSA PRIVATE KEY-----\n"; - s = s + _rsa_splitKey(b64Cert, 64); - s = s + "\n-----END RSA PRIVATE KEY-----"; - return s; -} - -/** -* Output private & public part of the key in PKCS#8 PEM format. -*/ -function _rsapem_privateKeyToPkcs8PemString() { - var b64Cert = hex2b64(_rsapem_privateKeyToPkcs8HexString(this)); - var s = "-----BEGIN RSA PRIVATE KEY-----\n"; - s = s + _rsa_splitKey(b64Cert, 64); - s = s + "\n-----END RSA PRIVATE KEY-----"; - return s; -} - -/** -* Output public part of the key in x509 PKCS#1 PEM format. -*/ -function _rsapem_publicKeyToX509PemString() { - var b64Cert = hex2b64(_rsapem_publicKeyToX509HexString(this)); - var s = "-----BEGIN PUBLIC KEY-----\n"; - s = s + _rsa_splitKey(b64Cert, 64); - s = s + "\n-----END PUBLIC KEY-----"; - return s; -} - -function _rsa_splitKey(key, line) { - var splitKey = ""; - for (var i = 0; i < key.length; i++) { - if (i % line == 0 && i != 0 && i != (key.length - 1)) { - splitKey += "\n"; - } - splitKey += key[i]; - } - - return splitKey; -} - -function _paillier_padHex(s, n) { - var slen = s.length; - if(slen < n) { - for(var i = 0; i < n - slen; i++) { - s = "0" + s; - } - } - return s; -} - -function _paillier_encrypt(m) { - var rng = new SecureRandom(); - var random = null; - for (;;) - { - for (;;) - { - random = new BigInteger(this.n.bitLength(), 1, rng); - if (random.isProbablePrime(64)) break; - } - if(random.signum() == 1) break; - } - - if(m.signum() == -1) { - m = m.mod(this.n); - } - - var nsquare = this.n.multiply(this.n); - var g = this.n.add(BigInteger.ONE); - var cipher = g.modPow(m, nsquare).multiply(random.modPow(this.n, nsquare)).mod(nsquare); - var nstr = this.n.toString(16); - var nlen = Math.ceil(this.n.bitLength() / 8); - return _paillier_padHex(nlen.toString(16), 4) + nstr + _paillier_padHex(cipher.toString(16), nlen * 4); -} - -function _paillier_decrypt(ciphertext) { - var nlen = parseInt("0x" + c1.substr(0,4)) * 2; - var nstr = ciphertext.substr(4, nlen); - var cstr = ciphertext.substr(nlen + 4); - var n1 = parseBigInt(nstr, 16); - var intCiphertext = parseBigInt(cstr, 16); - if(n1.compareTo(this.n) != 0) return null; - - var lambda = this.p.subtract(BigInteger.ONE).multiply(this.q.subtract(BigInteger.ONE)); - var mu = lambda.modInverse(this.n); - var nsquare = this.n.multiply(this.n); - var message = intCiphertext.modPow(lambda, nsquare).subtract(BigInteger.ONE).divide(this.n).multiply(mu).mod(this.n); - var maxValue = BigInteger.ONE.shiftLeft(this.n.bitLength() / 2); - if(message.bitLength() > this.n.bitLength() / 2) { - return message.subtract(this.n); - } - else { - return message; - } -} - -function _paillier_add(c1, c2) { - var nlen1 = parseInt("0x" + c1.substr(0,4)) * 2; - var nstr1 = c1.substr(4, nlen1); - var cstr1 = c1.substr(nlen1 + 4); - var nlen2 = parseInt("0x" + c2.substr(0,4)) * 2; - var nstr2 = c2.substr(4, nlen2); - var cstr2 = c2.substr(nlen2 + 4); - var n1 = parseBigInt(nstr1, 16); - var n2 = parseBigInt(nstr2, 16); - - if(n2.compareTo(n1) != 0) { - return null; - } - - var ct1 = parseBigInt(cstr1, 16); - var ct2 = parseBigInt(cstr2, 16); - var nsquare = n1.multiply(n1); - var ct = ct1.multiply(ct2).mod(nsquare); - return _paillier_padHex(nlen1.toString(16), 4) + nstr1 + _paillier_padHex(ct.toString(16), nlen1 * 2); -} - -RSAKey.prototype.readPrivateKeyFromPkcs1PemString = _rsapem_readPrivateKeyFromPkcs1PemString; -RSAKey.prototype.privateKeyToPkcs1PemString = _rsapem_privateKeyToPkcs1PemString; - -RSAKey.prototype.readPrivateKeyFromPkcs8PemString = _rsapem_readPrivateKeyFromPkcs8PemString; -RSAKey.prototype.privateKeyToPkcs8PemString = _rsapem_privateKeyToPkcs8PemString; - -RSAKey.prototype.readPublicKeyFromX509PEMString = _rsapem_readPublicKeyFromX509PemString; -RSAKey.prototype.publicKeyToX509PemString = _rsapem_publicKeyToX509PemString; - -RSAKey.prototype.paillierEncrypt = _paillier_encrypt; -RSAKey.prototype.paillierDecrypt = _paillier_decrypt; -RSAKey.prototype.paillierAdd = _paillier_add; -RSAKey.prototype.splitKey = _rsa_splitKey; - + +// convert a (hex) string to a bignum object +function parseBigInt(str,r) { + return new BigInteger(str,r); +} + +function _pem_extractEncodedData(sPEMString, sHead) { + var s = sPEMString; + s = s.replace("-----BEGIN " + sHead + "-----", ""); + s = s.replace("-----END " + sHead + "-----", ""); + s = s.replace(/[ \n]+/g, ""); + return s; +} + +function _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey) { + var a = new Array(); + var v1 = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); + var n1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, v1); + var e1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, n1); + var d1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, e1); + var p1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, d1); + var q1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, p1); + var dp1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, q1); + var dq1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, dp1); + var co1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, dq1); + a.push(v1, n1, e1, d1, p1, q1, dp1, dq1, co1); + return a; +} + +function _rsapem_getHexValueArrayOfChildrenFromHex(hPrivateKey) { + var posArray = _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey); + var v = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); + var n = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); + var e = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[2]); + var d = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[3]); + var p = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[4]); + var q = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[5]); + var dp = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[6]); + var dq = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[7]); + var co = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[8]); + var a = new Array(); + a.push(v, n, e, d, p, q, dp, dq, co); + return a; +} + +function _rsapem_getPosArrayOfChildrenFromPublicKeyHex(hPrivateKey) { + var a = new Array(); + var header = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); + var keys = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, header); + a.push(header, keys); + return a; +} + +function _rsapem_getPosArrayOfChildrenFromPrivateKeyHex(hPrivateKey) { + var a = new Array(); + var integer = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); + var header = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, integer); + var keys = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, header); + a.push(integer, header, keys); + return a; +} + +function _rsapem_getHexValueArrayOfChildrenFromPublicKeyHex(hPrivateKey) { + var posArray = _rsapem_getPosArrayOfChildrenFromPublicKeyHex(hPrivateKey); + var headerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); + var keysVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); + + var keysSequence = keysVal.substring(2); + posArray = _rsapem_getPosArrayOfChildrenFromPublicKeyHex(keysSequence); + var modulus = _asnhex_getHexOfV_AtObj(keysSequence, posArray[0]); + var publicExp = _asnhex_getHexOfV_AtObj(keysSequence, posArray[1]); + + var a = new Array(); + a.push(modulus, publicExp); + return a; +} + + +function _rsapem_getHexValueArrayOfChildrenFromPrivateKeyHex(hPrivateKey) { + var posArray = _rsapem_getPosArrayOfChildrenFromPrivateKeyHex(hPrivateKey); + var integerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); + var headerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); + var keysVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[2]); + + var keysSequence = keysVal.substring(2); + return _rsapem_getHexValueArrayOfChildrenFromHex(keysSequence); +} + +function _rsapem_readPrivateKeyFromPkcs1PemString(keyPEM) { + var keyB64 = _rsapem_extractEncodedData(keyPEM); + var keyHex = b64tohex(keyB64) // depends base64.js + var a = _rsapem_getHexValueArrayOfChildrenFromHex(keyHex); + this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]); +} + +function _rsapem_readPrivateKeyFromPkcs8PemString(keyPEM) { + var keyB64 = _rsapem_extractEncodedData(keyPEM); + var keyHex = b64tohex(keyB64) // depends base64.js + var a = _rsapem_getHexValueArrayOfChildrenFromPrivateKeyHex(keyHex); + this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]); +} + +function _rsapem_readPublicKeyFromX509PemString(keyPEM) { + var keyB64 = _rsapem_extractEncodedData(keyPEM); + var keyHex = b64tohex(keyB64) // depends base64.js + var a = _rsapem_getHexValueArrayOfChildrenFromPublicKeyHex(keyHex); + this.setPublic(a[0],a[1]); +} + +/** +* Pad string with leading zeros, to use even number of bytes. +*/ +function _rsapem_padWithZero(numString) { + if (numString.length % 2 == 1) { + return "0" + numString; + } + return numString; +} + +/** +* Encode length in DER format (if length <0x80, then one byte, else first byte is 0x80 + length of length :) + n-bytes of length). +*/ +function _rsapem_encodeLength(length) { + if (length >= parseInt("80", 16)) { + var realLength = _rsapem_padWithZero(length.toString(16)); + var lengthOfLength = (realLength.length / 2); + return (parseInt("80", 16) + lengthOfLength).toString(16) + realLength; + } else { + return _rsapem_padWithZero(length.toString(16)); + } +} + +/** +* Encode number in DER encoding ("02" + length + number). +*/ +function _rsapem_derEncodeNumber(number) { + var numberString = _rsapem_padWithZero(number.toString(16)); + if (numberString[0] > '7') { + numberString = "00" + numberString; + } + var lenString = _rsapem_encodeLength(numberString.length / 2); + return "02" + lenString + numberString; +} + +/** +* Converts private & public part of given key to ASN1 Hex String. +*/ +function _rsapem_privateKeyToPkcs1HexString(rsaKey) { + var result = _rsapem_derEncodeNumber(0); + result += _rsapem_derEncodeNumber(rsaKey.n); + result += _rsapem_derEncodeNumber(rsaKey.e); + result += _rsapem_derEncodeNumber(rsaKey.d); + result += _rsapem_derEncodeNumber(rsaKey.p); + result += _rsapem_derEncodeNumber(rsaKey.q); + result += _rsapem_derEncodeNumber(rsaKey.dmp1); + result += _rsapem_derEncodeNumber(rsaKey.dmq1); + result += _rsapem_derEncodeNumber(rsaKey.coeff); + + var fullLen = _rsapem_encodeLength(result.length / 2); + return '30' + fullLen + result; +} + +/** +* Converts private & public part of given key to PKCS#8 Hex String. +*/ +function _rsapem_privateKeyToPkcs8HexString(rsaKey) { + var zeroInteger = "020100"; + var encodedIdentifier = "06092A864886F70D010101"; + var encodedNull = "0500"; + var headerSequence = "300D" + encodedIdentifier + encodedNull; + var keySequence = _rsapem_privateKeyToPkcs1HexString(rsaKey); + + var keyOctetString = "04" + _rsapem_encodeLength(keySequence.length / 2) + keySequence; + + var mainSequence = zeroInteger + headerSequence + keyOctetString; + return "30" + _rsapem_encodeLength(mainSequence.length / 2) + mainSequence; +} + +/** +* Converts public part of given key to ASN1 Hex String. +*/ +function _rsapem_publicKeyToX509HexString(rsaKey) { + var encodedIdentifier = "06092A864886F70D010101"; + var encodedNull = "0500"; + var headerSequence = "300D" + encodedIdentifier + encodedNull; + + var keys = _rsapem_derEncodeNumber(rsaKey.n); + keys += _rsapem_derEncodeNumber(rsaKey.e); + + var keySequence = "0030" + _rsapem_encodeLength(keys.length / 2) + keys; + var bitstring = "03" + _rsapem_encodeLength(keySequence.length / 2) + keySequence; + + var mainSequence = headerSequence + bitstring; + + return "30" + _rsapem_encodeLength(mainSequence.length / 2) + mainSequence; +} + +/** +* Output private & public part of the key in PKCS#1 PEM format. +*/ +function _rsapem_privateKeyToPkcs1PemString() { + var b64Cert = hex2b64(_rsapem_privateKeyToPkcs1HexString(this)); + var s = "-----BEGIN RSA PRIVATE KEY-----\n"; + s = s + _rsa_splitKey(b64Cert, 64); + s = s + "\n-----END RSA PRIVATE KEY-----"; + return s; +} + +/** +* Output private & public part of the key in PKCS#8 PEM format. +*/ +function _rsapem_privateKeyToPkcs8PemString() { + var b64Cert = hex2b64(_rsapem_privateKeyToPkcs8HexString(this)); + var s = "-----BEGIN RSA PRIVATE KEY-----\n"; + s = s + _rsa_splitKey(b64Cert, 64); + s = s + "\n-----END RSA PRIVATE KEY-----"; + return s; +} + +/** +* Output public part of the key in x509 PKCS#1 PEM format. +*/ +function _rsapem_publicKeyToX509PemString() { + var b64Cert = hex2b64(_rsapem_publicKeyToX509HexString(this)); + var s = "-----BEGIN PUBLIC KEY-----\n"; + s = s + _rsa_splitKey(b64Cert, 64); + s = s + "\n-----END PUBLIC KEY-----"; + return s; +} + +function _rsa_splitKey(key, line) { + var splitKey = ""; + for (var i = 0; i < key.length; i++) { + if (i % line == 0 && i != 0 && i != (key.length - 1)) { + splitKey += "\n"; + } + splitKey += key[i]; + } + + return splitKey; +} + +function _paillier_padHex(s, n) { + var slen = s.length; + if(slen < n) { + for(var i = 0; i < n - slen; i++) { + s = "0" + s; + } + } + return s; +} + +function _paillier_encrypt(m) { + var rng = new SecureRandom(); + var random = null; + for (;;) + { + for (;;) + { + random = new BigInteger(this.n.bitLength(), 1, rng); + if (random.isProbablePrime(64)) break; + } + if(random.signum() == 1) break; + } + + if(m.signum() == -1) { + m = m.mod(this.n); + } + + var nsquare = this.n.multiply(this.n); + var g = this.n.add(BigInteger.ONE); + var cipher = g.modPow(m, nsquare).multiply(random.modPow(this.n, nsquare)).mod(nsquare); + var nstr = this.n.toString(16); + var nlen = Math.ceil(this.n.bitLength() / 8); + return _paillier_padHex(nlen.toString(16), 4) + nstr + _paillier_padHex(cipher.toString(16), nlen * 4); +} + +function _paillier_decrypt(ciphertext) { + var nlen = parseInt("0x" + c1.substr(0,4)) * 2; + var nstr = ciphertext.substr(4, nlen); + var cstr = ciphertext.substr(nlen + 4); + var n1 = parseBigInt(nstr, 16); + var intCiphertext = parseBigInt(cstr, 16); + if(n1.compareTo(this.n) != 0) return null; + + var lambda = this.p.subtract(BigInteger.ONE).multiply(this.q.subtract(BigInteger.ONE)); + var mu = lambda.modInverse(this.n); + var nsquare = this.n.multiply(this.n); + var message = intCiphertext.modPow(lambda, nsquare).subtract(BigInteger.ONE).divide(this.n).multiply(mu).mod(this.n); + var maxValue = BigInteger.ONE.shiftLeft(this.n.bitLength() / 2); + if(message.bitLength() > this.n.bitLength() / 2) { + return message.subtract(this.n); + } + else { + return message; + } +} + +function _paillier_add(c1, c2) { + var nlen1 = parseInt("0x" + c1.substr(0,4)) * 2; + var nstr1 = c1.substr(4, nlen1); + var cstr1 = c1.substr(nlen1 + 4); + var nlen2 = parseInt("0x" + c2.substr(0,4)) * 2; + var nstr2 = c2.substr(4, nlen2); + var cstr2 = c2.substr(nlen2 + 4); + var n1 = parseBigInt(nstr1, 16); + var n2 = parseBigInt(nstr2, 16); + + if(n2.compareTo(n1) != 0) { + return null; + } + + var ct1 = parseBigInt(cstr1, 16); + var ct2 = parseBigInt(cstr2, 16); + var nsquare = n1.multiply(n1); + var ct = ct1.multiply(ct2).mod(nsquare); + return _paillier_padHex(nlen1.toString(16), 4) + nstr1 + _paillier_padHex(ct.toString(16), nlen1 * 2); +} + +RSAKey.prototype.readPrivateKeyFromPkcs1PemString = _rsapem_readPrivateKeyFromPkcs1PemString; +RSAKey.prototype.privateKeyToPkcs1PemString = _rsapem_privateKeyToPkcs1PemString; + +RSAKey.prototype.readPrivateKeyFromPkcs8PemString = _rsapem_readPrivateKeyFromPkcs8PemString; +RSAKey.prototype.privateKeyToPkcs8PemString = _rsapem_privateKeyToPkcs8PemString; + +RSAKey.prototype.readPublicKeyFromX509PEMString = _rsapem_readPublicKeyFromX509PemString; +RSAKey.prototype.publicKeyToX509PemString = _rsapem_publicKeyToX509PemString; + +RSAKey.prototype.paillierEncrypt = _paillier_encrypt; +RSAKey.prototype.paillierDecrypt = _paillier_decrypt; +RSAKey.prototype.paillierAdd = _paillier_add; +RSAKey.prototype.splitKey = _rsa_splitKey; + diff --git a/tool/java/Pailler/javascript/rng.js b/tool/java/Paillier/javascript/rng.js similarity index 96% rename from tool/java/Pailler/javascript/rng.js rename to tool/java/Paillier/javascript/rng.js index ff5b2f3d45..197db89332 100644 --- a/tool/java/Pailler/javascript/rng.js +++ b/tool/java/Paillier/javascript/rng.js @@ -1,121 +1,121 @@ -// prng4.js - uses Arcfour as a PRNG - -function Arcfour() { - this.i = 0; - this.j = 0; - this.S = new Array(); -} - -// Initialize arcfour context from key, an array of ints, each from [0..255] -function ARC4init(key) { - var i, j, t; - for(i = 0; i < 256; ++i) - this.S[i] = i; - j = 0; - for(i = 0; i < 256; ++i) { - j = (j + this.S[i] + key[i % key.length]) & 255; - t = this.S[i]; - this.S[i] = this.S[j]; - this.S[j] = t; - } - this.i = 0; - this.j = 0; -} - -function ARC4next() { - var t; - this.i = (this.i + 1) & 255; - this.j = (this.j + this.S[this.i]) & 255; - t = this.S[this.i]; - this.S[this.i] = this.S[this.j]; - this.S[this.j] = t; - return this.S[(t + this.S[this.i]) & 255]; -} - -Arcfour.prototype.init = ARC4init; -Arcfour.prototype.next = ARC4next; - -// Plug in your RNG constructor here -function prng_newstate() { - return new Arcfour(); -} - -// Pool size must be a multiple of 4 and greater than 32. -// An array of bytes the size of the pool will be passed to init() -var rng_psize = 256; - -// Random number generator - requires a PRNG backend, e.g. prng4.js - -// For best results, put code like -// -// in your main HTML document. - -var rng_state; -var rng_pool; -var rng_pptr; - -// Mix in a 32-bit integer into the pool -function rng_seed_int(x) { - rng_pool[rng_pptr++] ^= x & 255; - rng_pool[rng_pptr++] ^= (x >> 8) & 255; - rng_pool[rng_pptr++] ^= (x >> 16) & 255; - rng_pool[rng_pptr++] ^= (x >> 24) & 255; - if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; -} - -// Mix in the current time (w/milliseconds) into the pool -function rng_seed_time() { - rng_seed_int(new Date().getTime()); -} - -// Initialize the pool with junk if needed. -if(rng_pool == null) { - rng_pool = new Array(); - rng_pptr = 0; - var t; - if(window.crypto && window.crypto.getRandomValues) { - // Use webcrypto if available - var ua = new Uint8Array(32); - window.crypto.getRandomValues(ua); - for(t = 0; t < 32; ++t) - rng_pool[rng_pptr++] = ua[t]; - } - if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { - // Extract entropy (256 bits) from NS4 RNG if available - var z = window.crypto.random(32); - for(t = 0; t < z.length; ++t) - rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; - } - while(rng_pptr < rng_psize) { // extract some randomness from Math.random() - t = Math.floor(65536 * Math.random()); - rng_pool[rng_pptr++] = t >>> 8; - rng_pool[rng_pptr++] = t & 255; - } - rng_pptr = 0; - rng_seed_time(); - //rng_seed_int(window.screenX); - //rng_seed_int(window.screenY); -} - -function rng_get_byte() { - if(rng_state == null) { - rng_seed_time(); - rng_state = prng_newstate(); - rng_state.init(rng_pool); - for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) - rng_pool[rng_pptr] = 0; - rng_pptr = 0; - //rng_pool = null; - } - // TODO: allow reseeding after first request - return rng_state.next(); -} - -function rng_get_bytes(ba) { - var i; - for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); -} - -function SecureRandom() {} - -SecureRandom.prototype.nextBytes = rng_get_bytes; +// prng4.js - uses Arcfour as a PRNG + +function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); +} + +// Initialize arcfour context from key, an array of ints, each from [0..255] +function ARC4init(key) { + var i, j, t; + for(i = 0; i < 256; ++i) + this.S[i] = i; + j = 0; + for(i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; +} + +function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; +} + +Arcfour.prototype.init = ARC4init; +Arcfour.prototype.next = ARC4next; + +// Plug in your RNG constructor here +function prng_newstate() { + return new Arcfour(); +} + +// Pool size must be a multiple of 4 and greater than 32. +// An array of bytes the size of the pool will be passed to init() +var rng_psize = 256; + +// Random number generator - requires a PRNG backend, e.g. prng4.js + +// For best results, put code like +// +// in your main HTML document. + +var rng_state; +var rng_pool; +var rng_pptr; + +// Mix in a 32-bit integer into the pool +function rng_seed_int(x) { + rng_pool[rng_pptr++] ^= x & 255; + rng_pool[rng_pptr++] ^= (x >> 8) & 255; + rng_pool[rng_pptr++] ^= (x >> 16) & 255; + rng_pool[rng_pptr++] ^= (x >> 24) & 255; + if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; +} + +// Mix in the current time (w/milliseconds) into the pool +function rng_seed_time() { + rng_seed_int(new Date().getTime()); +} + +// Initialize the pool with junk if needed. +if(rng_pool == null) { + rng_pool = new Array(); + rng_pptr = 0; + var t; + if(window.crypto && window.crypto.getRandomValues) { + // Use webcrypto if available + var ua = new Uint8Array(32); + window.crypto.getRandomValues(ua); + for(t = 0; t < 32; ++t) + rng_pool[rng_pptr++] = ua[t]; + } + if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { + // Extract entropy (256 bits) from NS4 RNG if available + var z = window.crypto.random(32); + for(t = 0; t < z.length; ++t) + rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; + } + while(rng_pptr < rng_psize) { // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + rng_pool[rng_pptr++] = t >>> 8; + rng_pool[rng_pptr++] = t & 255; + } + rng_pptr = 0; + rng_seed_time(); + //rng_seed_int(window.screenX); + //rng_seed_int(window.screenY); +} + +function rng_get_byte() { + if(rng_state == null) { + rng_seed_time(); + rng_state = prng_newstate(); + rng_state.init(rng_pool); + for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) + rng_pool[rng_pptr] = 0; + rng_pptr = 0; + //rng_pool = null; + } + // TODO: allow reseeding after first request + return rng_state.next(); +} + +function rng_get_bytes(ba) { + var i; + for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); +} + +function SecureRandom() {} + +SecureRandom.prototype.nextBytes = rng_get_bytes; diff --git a/tool/java/Pailler/javascript/rsa.js b/tool/java/Paillier/javascript/rsa.js similarity index 96% rename from tool/java/Pailler/javascript/rsa.js rename to tool/java/Paillier/javascript/rsa.js index 36fb7f5d33..2b36f49ea2 100644 --- a/tool/java/Pailler/javascript/rsa.js +++ b/tool/java/Paillier/javascript/rsa.js @@ -1,247 +1,247 @@ -// Depends on jsbn.js and rng.js - -// Version 1.1: support utf-8 encoding in pkcs1pad2 - -// convert a (hex) string to a bignum object -function parseBigInt(str,r) { - return new BigInteger(str,r); -} - -function linebrk(s,n) { - var ret = ""; - var i = 0; - while(i + n < s.length) { - ret += s.substring(i,i+n) + "\n"; - i += n; - } - return ret + s.substring(i,s.length); -} - -function byte2Hex(b) { - if(b < 0x10) - return "0" + b.toString(16); - else - return b.toString(16); -} - -// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint -function pkcs1pad2(s,n) { - if(n < s.length + 11) { // TODO: fix for utf-8 - alert("Message too long for RSA"); - return null; - } - var ba = new Array(); - var i = s.length - 1; - while(i >= 0 && n > 0) { - var c = s.charCodeAt(i--); - if(c < 128) { // encode using utf-8 - ba[--n] = c; - } - else if((c > 127) && (c < 2048)) { - ba[--n] = (c & 63) | 128; - ba[--n] = (c >> 6) | 192; - } - else { - ba[--n] = (c & 63) | 128; - ba[--n] = ((c >> 6) & 63) | 128; - ba[--n] = (c >> 12) | 224; - } - } - ba[--n] = 0; - var rng = new SecureRandom(); - var x = new Array(); - while(n > 2) { // random non-zero pad - x[0] = 0; - while(x[0] == 0) rng.nextBytes(x); - ba[--n] = x[0]; - } - ba[--n] = 2; - ba[--n] = 0; - return new BigInteger(ba); -} - -// "empty" RSA key constructor -function RSAKey() { - this.n = null; - this.e = 0; - this.d = null; - this.p = null; - this.q = null; - this.dmp1 = null; - this.dmq1 = null; - this.coeff = null; -} - -// Set the public key fields N and e from hex strings -function RSASetPublic(N,E) { - if(N != null && E != null && N.length > 0 && E.length > 0) { - this.n = parseBigInt(N,16); - this.e = parseInt(E,16); - } - else - alert("Invalid RSA public key"); -} - -// Perform raw public operation on "x": return x^e (mod n) -function RSADoPublic(x) { - return x.modPowInt(this.e, this.n); -} - -// Return the PKCS#1 RSA encryption of "text" as an even-length hex string -function RSAEncrypt(text) { - var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3); - if(m == null) return null; - var c = this.doPublic(m); - if(c == null) return null; - var h = c.toString(16); - if((h.length & 1) == 0) return h; else return "0" + h; -} - -// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string -//function RSAEncryptB64(text) { -// var h = this.encrypt(text); -// if(h) return hex2b64(h); else return null; -//} - -// protected -RSAKey.prototype.doPublic = RSADoPublic; - -// public -RSAKey.prototype.setPublic = RSASetPublic; -RSAKey.prototype.encrypt = RSAEncrypt; -//RSAKey.prototype.encrypt_b64 = RSAEncryptB64; - - -// Depends on rsa.js and jsbn2.js - -// Version 1.1: support utf-8 decoding in pkcs1unpad2 - -// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext -function pkcs1unpad2(d,n) { - var b = d.toByteArray(); - var i = 0; - while(i < b.length && b[i] == 0) ++i; - if(b.length-i != n-1 || b[i] != 2) - return null; - ++i; - while(b[i] != 0) - if(++i >= b.length) return null; - var ret = ""; - while(++i < b.length) { - var c = b[i] & 255; - if(c < 128) { // utf-8 decode - ret += String.fromCharCode(c); - } - else if((c > 191) && (c < 224)) { - ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63)); - ++i; - } - else { - ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63)); - i += 2; - } - } - return ret; -} - -// Set the private key fields N, e, and d from hex strings -function RSASetPrivate(N,E,D) { - if(N != null && E != null && N.length > 0 && E.length > 0) { - this.n = parseBigInt(N,16); - this.e = parseInt(E,16); - this.d = parseBigInt(D,16); - } - else - alert("Invalid RSA private key"); -} - -// Set the private key fields N, e, d and CRT params from hex strings -function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) { - if(N != null && E != null && N.length > 0 && E.length > 0) { - this.n = parseBigInt(N,16); - this.e = parseInt(E,16); - this.d = parseBigInt(D,16); - this.p = parseBigInt(P,16); - this.q = parseBigInt(Q,16); - this.dmp1 = parseBigInt(DP,16); - this.dmq1 = parseBigInt(DQ,16); - this.coeff = parseBigInt(C,16); - } - else - alert("Invalid RSA private key"); -} - -// Generate a new random private key B bits long, using public expt E -function RSAGenerate(B) { - var rng = new SecureRandom(); - var qs = B>>1; - this.e = 65537; - var ee = new BigInteger("10001", 16); - for(;;) { - for(;;) { - this.p = new BigInteger(B-qs,1,rng); - if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(64)) break; - } - for(;;) { - this.q = new BigInteger(qs,1,rng); - if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(64)) break; - } - if(this.p.compareTo(this.q) <= 0) { - var t = this.p; - this.p = this.q; - this.q = t; - } - var p1 = this.p.subtract(BigInteger.ONE); - var q1 = this.q.subtract(BigInteger.ONE); - var phi = p1.multiply(q1); - if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) { - this.n = this.p.multiply(this.q); - this.d = ee.modInverse(phi); - this.dmp1 = this.d.mod(p1); - this.dmq1 = this.d.mod(q1); - this.coeff = this.q.modInverse(this.p); - break; - } - } -} - -// Perform raw private operation on "x": return x^d (mod n) -function RSADoPrivate(x) { - if(this.p == null || this.q == null) - return x.modPow(this.d, this.n); - - // TODO: re-calculate any missing CRT params - var xp = x.mod(this.p).modPow(this.dmp1, this.p); - var xq = x.mod(this.q).modPow(this.dmq1, this.q); - - while(xp.compareTo(xq) < 0) - xp = xp.add(this.p); - return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq); -} - -// Return the PKCS#1 RSA decryption of "ctext". -// "ctext" is an even-length hex string and the output is a plain string. -function RSADecrypt(ctext) { - var c = parseBigInt(ctext, 16); - var m = this.doPrivate(c); - if(m == null) return null; - return pkcs1unpad2(m, (this.n.bitLength()+7)>>3); -} - -// Return the PKCS#1 RSA decryption of "ctext". -// "ctext" is a Base64-encoded string and the output is a plain string. -//function RSAB64Decrypt(ctext) { -// var h = b64tohex(ctext); -// if(h) return this.decrypt(h); else return null; -//} - -// protected -RSAKey.prototype.doPrivate = RSADoPrivate; - -// public -RSAKey.prototype.setPrivate = RSASetPrivate; -RSAKey.prototype.setPrivateEx = RSASetPrivateEx; -RSAKey.prototype.generate = RSAGenerate; -RSAKey.prototype.decrypt = RSADecrypt; -//RSAKey.prototype.b64_decrypt = RSAB64Decrypt; - +// Depends on jsbn.js and rng.js + +// Version 1.1: support utf-8 encoding in pkcs1pad2 + +// convert a (hex) string to a bignum object +function parseBigInt(str,r) { + return new BigInteger(str,r); +} + +function linebrk(s,n) { + var ret = ""; + var i = 0; + while(i + n < s.length) { + ret += s.substring(i,i+n) + "\n"; + i += n; + } + return ret + s.substring(i,s.length); +} + +function byte2Hex(b) { + if(b < 0x10) + return "0" + b.toString(16); + else + return b.toString(16); +} + +// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint +function pkcs1pad2(s,n) { + if(n < s.length + 11) { // TODO: fix for utf-8 + alert("Message too long for RSA"); + return null; + } + var ba = new Array(); + var i = s.length - 1; + while(i >= 0 && n > 0) { + var c = s.charCodeAt(i--); + if(c < 128) { // encode using utf-8 + ba[--n] = c; + } + else if((c > 127) && (c < 2048)) { + ba[--n] = (c & 63) | 128; + ba[--n] = (c >> 6) | 192; + } + else { + ba[--n] = (c & 63) | 128; + ba[--n] = ((c >> 6) & 63) | 128; + ba[--n] = (c >> 12) | 224; + } + } + ba[--n] = 0; + var rng = new SecureRandom(); + var x = new Array(); + while(n > 2) { // random non-zero pad + x[0] = 0; + while(x[0] == 0) rng.nextBytes(x); + ba[--n] = x[0]; + } + ba[--n] = 2; + ba[--n] = 0; + return new BigInteger(ba); +} + +// "empty" RSA key constructor +function RSAKey() { + this.n = null; + this.e = 0; + this.d = null; + this.p = null; + this.q = null; + this.dmp1 = null; + this.dmq1 = null; + this.coeff = null; +} + +// Set the public key fields N and e from hex strings +function RSASetPublic(N,E) { + if(N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N,16); + this.e = parseInt(E,16); + } + else + alert("Invalid RSA public key"); +} + +// Perform raw public operation on "x": return x^e (mod n) +function RSADoPublic(x) { + return x.modPowInt(this.e, this.n); +} + +// Return the PKCS#1 RSA encryption of "text" as an even-length hex string +function RSAEncrypt(text) { + var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3); + if(m == null) return null; + var c = this.doPublic(m); + if(c == null) return null; + var h = c.toString(16); + if((h.length & 1) == 0) return h; else return "0" + h; +} + +// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string +//function RSAEncryptB64(text) { +// var h = this.encrypt(text); +// if(h) return hex2b64(h); else return null; +//} + +// protected +RSAKey.prototype.doPublic = RSADoPublic; + +// public +RSAKey.prototype.setPublic = RSASetPublic; +RSAKey.prototype.encrypt = RSAEncrypt; +//RSAKey.prototype.encrypt_b64 = RSAEncryptB64; + + +// Depends on rsa.js and jsbn2.js + +// Version 1.1: support utf-8 decoding in pkcs1unpad2 + +// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext +function pkcs1unpad2(d,n) { + var b = d.toByteArray(); + var i = 0; + while(i < b.length && b[i] == 0) ++i; + if(b.length-i != n-1 || b[i] != 2) + return null; + ++i; + while(b[i] != 0) + if(++i >= b.length) return null; + var ret = ""; + while(++i < b.length) { + var c = b[i] & 255; + if(c < 128) { // utf-8 decode + ret += String.fromCharCode(c); + } + else if((c > 191) && (c < 224)) { + ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63)); + ++i; + } + else { + ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63)); + i += 2; + } + } + return ret; +} + +// Set the private key fields N, e, and d from hex strings +function RSASetPrivate(N,E,D) { + if(N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N,16); + this.e = parseInt(E,16); + this.d = parseBigInt(D,16); + } + else + alert("Invalid RSA private key"); +} + +// Set the private key fields N, e, d and CRT params from hex strings +function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) { + if(N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N,16); + this.e = parseInt(E,16); + this.d = parseBigInt(D,16); + this.p = parseBigInt(P,16); + this.q = parseBigInt(Q,16); + this.dmp1 = parseBigInt(DP,16); + this.dmq1 = parseBigInt(DQ,16); + this.coeff = parseBigInt(C,16); + } + else + alert("Invalid RSA private key"); +} + +// Generate a new random private key B bits long, using public expt E +function RSAGenerate(B) { + var rng = new SecureRandom(); + var qs = B>>1; + this.e = 65537; + var ee = new BigInteger("10001", 16); + for(;;) { + for(;;) { + this.p = new BigInteger(B-qs,1,rng); + if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(64)) break; + } + for(;;) { + this.q = new BigInteger(qs,1,rng); + if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(64)) break; + } + if(this.p.compareTo(this.q) <= 0) { + var t = this.p; + this.p = this.q; + this.q = t; + } + var p1 = this.p.subtract(BigInteger.ONE); + var q1 = this.q.subtract(BigInteger.ONE); + var phi = p1.multiply(q1); + if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) { + this.n = this.p.multiply(this.q); + this.d = ee.modInverse(phi); + this.dmp1 = this.d.mod(p1); + this.dmq1 = this.d.mod(q1); + this.coeff = this.q.modInverse(this.p); + break; + } + } +} + +// Perform raw private operation on "x": return x^d (mod n) +function RSADoPrivate(x) { + if(this.p == null || this.q == null) + return x.modPow(this.d, this.n); + + // TODO: re-calculate any missing CRT params + var xp = x.mod(this.p).modPow(this.dmp1, this.p); + var xq = x.mod(this.q).modPow(this.dmq1, this.q); + + while(xp.compareTo(xq) < 0) + xp = xp.add(this.p); + return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq); +} + +// Return the PKCS#1 RSA decryption of "ctext". +// "ctext" is an even-length hex string and the output is a plain string. +function RSADecrypt(ctext) { + var c = parseBigInt(ctext, 16); + var m = this.doPrivate(c); + if(m == null) return null; + return pkcs1unpad2(m, (this.n.bitLength()+7)>>3); +} + +// Return the PKCS#1 RSA decryption of "ctext". +// "ctext" is a Base64-encoded string and the output is a plain string. +//function RSAB64Decrypt(ctext) { +// var h = b64tohex(ctext); +// if(h) return this.decrypt(h); else return null; +//} + +// protected +RSAKey.prototype.doPrivate = RSADoPrivate; + +// public +RSAKey.prototype.setPrivate = RSASetPrivate; +RSAKey.prototype.setPrivateEx = RSASetPrivateEx; +RSAKey.prototype.generate = RSAGenerate; +RSAKey.prototype.decrypt = RSADecrypt; +//RSAKey.prototype.b64_decrypt = RSAB64Decrypt; + diff --git a/tool/java/Pailler/javascript/test.html b/tool/java/Paillier/javascript/test.html similarity index 97% rename from tool/java/Pailler/javascript/test.html rename to tool/java/Paillier/javascript/test.html index 45170ed700..ea27e83834 100644 --- a/tool/java/Pailler/javascript/test.html +++ b/tool/java/Paillier/javascript/test.html @@ -1,81 +1,81 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/tool/java/Pailler/lib/bcprov-jdk15on-1.54.jar b/tool/java/Paillier/lib/bcprov-jdk15on-1.54.jar similarity index 100% rename from tool/java/Pailler/lib/bcprov-jdk15on-1.54.jar rename to tool/java/Paillier/lib/bcprov-jdk15on-1.54.jar diff --git a/tool/java/Pailler/paillier/asn1hex.js b/tool/java/Paillier/paillier/asn1hex.js similarity index 96% rename from tool/java/Pailler/paillier/asn1hex.js rename to tool/java/Paillier/paillier/asn1hex.js index 4237a7d40e..15987bcb7a 100644 --- a/tool/java/Pailler/paillier/asn1hex.js +++ b/tool/java/Paillier/paillier/asn1hex.js @@ -1,106 +1,106 @@ -// -// asn1hex.js - Hexadecimal represented ASN.1 string library -// -// -// version: 1.0 (2010-Jun-03) -// -// Copyright (c) 2010 Kenji Urushima (kenji.urushima@gmail.com) -// -// This software is licensed under the terms of the MIT License. -// http://www.opensource.org/licenses/mit-license.php -// -// The above copyright and license notice shall be -// included in all copies or substantial portions of the Software. -// -// -// Depends on: -// - -// MEMO: -// f('3082025b02...', 2) ... 82025b ... 3bytes -// f('020100', 2) ... 01 ... 1byte -// f('0203001...', 2) ... 03 ... 1byte -// f('02818003...', 2) ... 8180 ... 2bytes -// f('3080....0000', 2) ... 80 ... -1 -// -// Requirements: -// - ASN.1 type octet length MUST be 1. -// (i.e. ASN.1 primitives like SET, SEQUENCE, INTEGER, OCTETSTRING ...) -// - -function _asnhex_getByteLengthOfL_AtObj(s, pos) { - if (s.substring(pos + 2, pos + 3) != '8') return 1; - var i = parseInt(s.substring(pos + 3, pos + 4)); - if (i == 0) return -1; // length octet '80' indefinite length - if (0 < i && i < 10) return i + 1; // including '8?' octet; - return -2; // malformed format -} - -function _asnhex_getHexOfL_AtObj(s, pos) { - var len = _asnhex_getByteLengthOfL_AtObj(s, pos); - if (len < 1) return ''; - return s.substring(pos + 2, pos + 2 + len * 2); -} - -// -// getting ASN.1 length value at the position 'idx' of -// hexa decimal string 's'. -// -// f('3082025b02...', 0) ... 82025b ... ??? -// f('020100', 0) ... 01 ... 1 -// f('0203001...', 0) ... 03 ... 3 -// f('02818003...', 0) ... 8180 ... 128 -function _asnhex_getIntOfL_AtObj(s, pos) { - var hLength = _asnhex_getHexOfL_AtObj(s, pos); - if (hLength == '') return -1; - var bi; - if (parseInt(hLength.substring(0, 1)) < 8) { - bi = parseBigInt(hLength, 16); - } else { - bi = parseBigInt(hLength.substring(2), 16); - } - return bi.intValue(); -} - -// -// get ASN.1 value starting string position -// for ASN.1 object refered by index 'idx'. -// -function _asnhex_getStartPosOfV_AtObj(s, pos) { - var l_len = _asnhex_getByteLengthOfL_AtObj(s, pos); - if (l_len < 0) return l_len; - return pos + (l_len + 1) * 2; -} - -function _asnhex_getHexOfV_AtObj(s, pos) { - var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos); - var len = _asnhex_getIntOfL_AtObj(s, pos); - return s.substring(pos1, pos1 + len * 2); -} - -function _asnhex_getPosOfNextSibling_AtObj(s, pos) { - var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos); - var len = _asnhex_getIntOfL_AtObj(s, pos); - return pos1 + len * 2; -} - -function _asnhex_getPosArrayOfChildren_AtObj(h, pos) { - var a = new Array(); - var p0 = _asnhex_getStartPosOfV_AtObj(h, pos); - a.push(p0); - - var len = _asnhex_getIntOfL_AtObj(h, pos); - var p = p0; - var k = 0; - while (1) { - var pNext = _asnhex_getPosOfNextSibling_AtObj(h, p); - if (pNext == null || (pNext - p0 >= (len * 2))) break; - if (k >= 200) break; - - a.push(pNext); - p = pNext; - - k++; - } - - return a; -} +// +// asn1hex.js - Hexadecimal represented ASN.1 string library +// +// +// version: 1.0 (2010-Jun-03) +// +// Copyright (c) 2010 Kenji Urushima (kenji.urushima@gmail.com) +// +// This software is licensed under the terms of the MIT License. +// http://www.opensource.org/licenses/mit-license.php +// +// The above copyright and license notice shall be +// included in all copies or substantial portions of the Software. +// +// +// Depends on: +// + +// MEMO: +// f('3082025b02...', 2) ... 82025b ... 3bytes +// f('020100', 2) ... 01 ... 1byte +// f('0203001...', 2) ... 03 ... 1byte +// f('02818003...', 2) ... 8180 ... 2bytes +// f('3080....0000', 2) ... 80 ... -1 +// +// Requirements: +// - ASN.1 type octet length MUST be 1. +// (i.e. ASN.1 primitives like SET, SEQUENCE, INTEGER, OCTETSTRING ...) +// - +function _asnhex_getByteLengthOfL_AtObj(s, pos) { + if (s.substring(pos + 2, pos + 3) != '8') return 1; + var i = parseInt(s.substring(pos + 3, pos + 4)); + if (i == 0) return -1; // length octet '80' indefinite length + if (0 < i && i < 10) return i + 1; // including '8?' octet; + return -2; // malformed format +} + +function _asnhex_getHexOfL_AtObj(s, pos) { + var len = _asnhex_getByteLengthOfL_AtObj(s, pos); + if (len < 1) return ''; + return s.substring(pos + 2, pos + 2 + len * 2); +} + +// +// getting ASN.1 length value at the position 'idx' of +// hexa decimal string 's'. +// +// f('3082025b02...', 0) ... 82025b ... ??? +// f('020100', 0) ... 01 ... 1 +// f('0203001...', 0) ... 03 ... 3 +// f('02818003...', 0) ... 8180 ... 128 +function _asnhex_getIntOfL_AtObj(s, pos) { + var hLength = _asnhex_getHexOfL_AtObj(s, pos); + if (hLength == '') return -1; + var bi; + if (parseInt(hLength.substring(0, 1)) < 8) { + bi = parseBigInt(hLength, 16); + } else { + bi = parseBigInt(hLength.substring(2), 16); + } + return bi.intValue(); +} + +// +// get ASN.1 value starting string position +// for ASN.1 object refered by index 'idx'. +// +function _asnhex_getStartPosOfV_AtObj(s, pos) { + var l_len = _asnhex_getByteLengthOfL_AtObj(s, pos); + if (l_len < 0) return l_len; + return pos + (l_len + 1) * 2; +} + +function _asnhex_getHexOfV_AtObj(s, pos) { + var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos); + var len = _asnhex_getIntOfL_AtObj(s, pos); + return s.substring(pos1, pos1 + len * 2); +} + +function _asnhex_getPosOfNextSibling_AtObj(s, pos) { + var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos); + var len = _asnhex_getIntOfL_AtObj(s, pos); + return pos1 + len * 2; +} + +function _asnhex_getPosArrayOfChildren_AtObj(h, pos) { + var a = new Array(); + var p0 = _asnhex_getStartPosOfV_AtObj(h, pos); + a.push(p0); + + var len = _asnhex_getIntOfL_AtObj(h, pos); + var p = p0; + var k = 0; + while (1) { + var pNext = _asnhex_getPosOfNextSibling_AtObj(h, p); + if (pNext == null || (pNext - p0 >= (len * 2))) break; + if (k >= 200) break; + + a.push(pNext); + p = pNext; + + k++; + } + + return a; +} diff --git a/tool/java/Pailler/paillier/base64.js b/tool/java/Paillier/paillier/base64.js similarity index 96% rename from tool/java/Pailler/paillier/base64.js rename to tool/java/Paillier/paillier/base64.js index 2eda5af8e4..56840ae699 100644 --- a/tool/java/Pailler/paillier/base64.js +++ b/tool/java/Paillier/paillier/base64.js @@ -1,68 +1,68 @@ -var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -var b64pad="="; -function hex2b64(h) { - var i; - var c; - var ret = ""; - for(i = 0; i+3 <= h.length; i+=3) { - c = parseInt(h.substring(i,i+3),16); - ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); - } - if(i+1 == h.length) { - c = parseInt(h.substring(i,i+1),16); - ret += b64map.charAt(c << 2); - } - else if(i+2 == h.length) { - c = parseInt(h.substring(i,i+2),16); - ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); - } - while((ret.length & 3) > 0) ret += b64pad; - return ret; -} -// convert a base64 string to hex -function b64tohex(s) { - var ret = "" - var i; - var k = 0; // b64 state, 0-3 - var slop; - for(i = 0; i < s.length; ++i) { - if(s.charAt(i) == b64pad) break; - v = b64map.indexOf(s.charAt(i)); - if(v < 0) continue; - if(k == 0) { - ret += int2char(v >> 2); - slop = v & 3; - k = 1; - } - else if(k == 1) { - ret += int2char((slop << 2) | (v >> 4)); - slop = v & 0xf; - k = 2; - } - else if(k == 2) { - ret += int2char(slop); - ret += int2char(v >> 2); - slop = v & 3; - k = 3; - } - else { - ret += int2char((slop << 2) | (v >> 4)); - ret += int2char(v & 0xf); - k = 0; - } - } - if(k == 1) - ret += int2char(slop << 2); - return ret; -} -// convert a base64 string to a byte/number array -function b64toBA(s) { - //piggyback on b64tohex for now, optimize later - var h = b64tohex(s); - var i; - var a = new Array(); - for(i = 0; 2*i < h.length; ++i) { - a[i] = parseInt(h.substring(2*i,2*i+2),16); - } - return a; -} +var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var b64pad="="; +function hex2b64(h) { + var i; + var c; + var ret = ""; + for(i = 0; i+3 <= h.length; i+=3) { + c = parseInt(h.substring(i,i+3),16); + ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); + } + if(i+1 == h.length) { + c = parseInt(h.substring(i,i+1),16); + ret += b64map.charAt(c << 2); + } + else if(i+2 == h.length) { + c = parseInt(h.substring(i,i+2),16); + ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); + } + while((ret.length & 3) > 0) ret += b64pad; + return ret; +} +// convert a base64 string to hex +function b64tohex(s) { + var ret = "" + var i; + var k = 0; // b64 state, 0-3 + var slop; + for(i = 0; i < s.length; ++i) { + if(s.charAt(i) == b64pad) break; + v = b64map.indexOf(s.charAt(i)); + if(v < 0) continue; + if(k == 0) { + ret += int2char(v >> 2); + slop = v & 3; + k = 1; + } + else if(k == 1) { + ret += int2char((slop << 2) | (v >> 4)); + slop = v & 0xf; + k = 2; + } + else if(k == 2) { + ret += int2char(slop); + ret += int2char(v >> 2); + slop = v & 3; + k = 3; + } + else { + ret += int2char((slop << 2) | (v >> 4)); + ret += int2char(v & 0xf); + k = 0; + } + } + if(k == 1) + ret += int2char(slop << 2); + return ret; +} +// convert a base64 string to a byte/number array +function b64toBA(s) { + //piggyback on b64tohex for now, optimize later + var h = b64tohex(s); + var i; + var a = new Array(); + for(i = 0; 2*i < h.length; ++i) { + a[i] = parseInt(h.substring(2*i,2*i+2),16); + } + return a; +} diff --git a/tool/java/Pailler/paillier/biginteger.js b/tool/java/Paillier/paillier/biginteger.js similarity index 96% rename from tool/java/Pailler/paillier/biginteger.js rename to tool/java/Paillier/paillier/biginteger.js index d660917314..21e1ce85fb 100644 --- a/tool/java/Pailler/paillier/biginteger.js +++ b/tool/java/Paillier/paillier/biginteger.js @@ -1,1200 +1,1200 @@ - -var dbits; - -// JavaScript engine analysis -var canary = 0xdeadbeefcafe; -var j_lm = ((canary&0xffffff)==0xefcafe); - -// (public) Constructor -function BigInteger(a,b,c) { - if(a != null) - if("number" == typeof a) this.fromNumber(a,b,c); - else if(b == null && "string" != typeof a) this.fromString(a,256); - else this.fromString(a,b); -} - -// return new, unset BigInteger -function nbi() { return new BigInteger(null); } - -// am: Compute w_j += (x*this_i), propagate carries, -// c is initial carry, returns final carry. -// c < 3*dvalue, x < 2*dvalue, this_i < dvalue -// We need to select the fastest one that works in this environment. - -// am1: use a single mult and divide to get the high bits, -// max digit bits should be 26 because -// max internal value = 2*dvalue^2-2*dvalue (< 2^53) -function am1(i,x,w,j,c,n) { - while(--n >= 0) { - var v = x*this[i++]+w[j]+c; - c = Math.floor(v/0x4000000); - w[j++] = v&0x3ffffff; - } - return c; -} -// am2 avoids a big mult-and-extract completely. -// Max digit bits should be <= 30 because we do bitwise ops -// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) -function am2(i,x,w,j,c,n) { - var xl = x&0x7fff, xh = x>>15; - while(--n >= 0) { - var l = this[i]&0x7fff; - var h = this[i++]>>15; - var m = xh*l+h*xl; - l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); - c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); - w[j++] = l&0x3fffffff; - } - return c; -} -// Alternately, set max digit bits to 28 since some -// browsers slow down when dealing with 32-bit numbers. -function am3(i,x,w,j,c,n) { - var xl = x&0x3fff, xh = x>>14; - while(--n >= 0) { - var l = this[i]&0x3fff; - var h = this[i++]>>14; - var m = xh*l+h*xl; - l = xl*l+((m&0x3fff)<<14)+w[j]+c; - c = (l>>28)+(m>>14)+xh*h; - w[j++] = l&0xfffffff; - } - return c; -} -if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { - BigInteger.prototype.am = am2; - dbits = 30; -} -else if(j_lm && (navigator.appName != "Netscape")) { - BigInteger.prototype.am = am1; - dbits = 26; -} -else { // Mozilla/Netscape seems to prefer am3 - BigInteger.prototype.am = am3; - dbits = 28; -} - -BigInteger.prototype.DB = dbits; -BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; - r.t = this.t; - r.s = this.s; -} - -// (protected) set from integer value x, -DV <= x < DV -function bnpFromInt(x) { - this.t = 1; - this.s = (x<0)?-1:0; - if(x > 0) this[0] = x; - else if(x < -1) this[0] = x+this.DV; - else this.t = 0; -} - -// return bigint initialized to value -function nbv(i) { var r = nbi(); r.fromInt(i); return r; } - -// (protected) set from string and radix -function bnpFromString(s,b) { - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 256) k = 8; // byte array - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else { this.fromRadix(s,b); return; } - this.t = 0; - this.s = 0; - var i = s.length, mi = false, sh = 0; - while(--i >= 0) { - var x = (k==8)?s[i]&0xff:intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-") mi = true; - continue; - } - mi = false; - if(sh == 0) - this[this.t++] = x; - else if(sh+k > this.DB) { - this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); - } - else - this[this.t-1] |= x<= this.DB) sh -= this.DB; - } - if(k == 8 && (s[0]&0x80) != 0) { - this.s = -1; - if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; -} - -// (public) return string representation in given radix -function bnToString(b) { - if(this.s < 0) return "-"+this.negate().toString(b); - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else return this.toRadix(b); - var km = (1< 0) { - if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } - while(i >= 0) { - if(p < k) { - d = (this[i]&((1<>(p+=this.DB-k); - } - else { - d = (this[i]>>(p-=k))&km; - if(p <= 0) { p += this.DB; --i; } - } - if(d > 0) m = true; - if(m) r += int2char(d); - } - } - return m?r:"0"; -} - -// (public) -this -function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } - -// (public) |this| -function bnAbs() { return (this.s<0)?this.negate():this; } - -// (public) return + if this > a, - if this < a, 0 if equal -function bnCompareTo(a) { - var r = this.s-a.s; - if(r != 0) return r; - var i = this.t; - r = i-a.t; - if(r != 0) return (this.s<0)?-r:r; - while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; - return 0; -} - -// returns bit length of the integer x -function nbits(x) { - var r = 1, t; - if((t=x>>>16) != 0) { x = t; r += 16; } - if((t=x>>8) != 0) { x = t; r += 8; } - if((t=x>>4) != 0) { x = t; r += 4; } - if((t=x>>2) != 0) { x = t; r += 2; } - if((t=x>>1) != 0) { x = t; r += 1; } - return r; -} - -// (public) return the number of bits in "this" -function bnBitLength() { - if(this.t <= 0) return 0; - return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); -} - -// (protected) r = this << n*DB -function bnpDLShiftTo(n,r) { - var i; - for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; - for(i = n-1; i >= 0; --i) r[i] = 0; - r.t = this.t+n; - r.s = this.s; -} - -// (protected) r = this >> n*DB -function bnpDRShiftTo(n,r) { - for(var i = n; i < this.t; ++i) r[i-n] = this[i]; - r.t = Math.max(this.t-n,0); - r.s = this.s; -} - -// (protected) r = this << n -function bnpLShiftTo(n,r) { - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<= 0; --i) { - r[i+ds+1] = (this[i]>>cbs)|c; - c = (this[i]&bm)<= 0; --i) r[i] = 0; - r[ds] = c; - r.t = this.t+ds+1; - r.s = this.s; - r.clamp(); -} - -// (protected) r = this >> n -function bnpRShiftTo(n,r) { - r.s = this.s; - var ds = Math.floor(n/this.DB); - if(ds >= this.t) { r.t = 0; return; } - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<>bs; - for(var i = ds+1; i < this.t; ++i) { - r[i-ds-1] |= (this[i]&bm)<>bs; - } - if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; - } - if(a.t < this.t) { - c -= a.s; - while(i < this.t) { - c += this[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } - else { - c += this.s; - while(i < a.t) { - c -= a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c -= a.s; - } - r.s = (c<0)?-1:0; - if(c < -1) r[i++] = this.DV+c; - else if(c > 0) r[i++] = c; - r.t = i; - r.clamp(); -} - -// (protected) r = this * a, r != this,a (HAC 14.12) -// "this" should be the larger one if appropriate. -function bnpMultiplyTo(a,r) { - var x = this.abs(), y = a.abs(); - var i = x.t; - r.t = i+y.t; - while(--i >= 0) r[i] = 0; - for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); - r.s = 0; - r.clamp(); - if(this.s != a.s) BigInteger.ZERO.subTo(r,r); -} - -// (protected) r = this^2, r != this (HAC 14.16) -function bnpSquareTo(r) { - var x = this.abs(); - var i = r.t = 2*x.t; - while(--i >= 0) r[i] = 0; - for(i = 0; i < x.t-1; ++i) { - var c = x.am(i,x[i],r,2*i,0,1); - if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { - r[i+x.t] -= x.DV; - r[i+x.t+1] = 1; - } - } - if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); - r.s = 0; - r.clamp(); -} - -// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) -// r != q, this != m. q or r may be null. -function bnpDivRemTo(m,q,r) { - var pm = m.abs(); - if(pm.t <= 0) return; - var pt = this.abs(); - if(pt.t < pm.t) { - if(q != null) q.fromInt(0); - if(r != null) this.copyTo(r); - return; - } - if(r == null) r = nbi(); - var y = nbi(), ts = this.s, ms = m.s; - var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus - if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } - else { pm.copyTo(y); pt.copyTo(r); } - var ys = y.t; - var y0 = y[ys-1]; - if(y0 == 0) return; - var yt = y0*(1<1)?y[ys-2]>>this.F2:0); - var d1 = this.FV/yt, d2 = (1<= 0) { - r[r.t++] = 1; - r.subTo(t,r); - } - BigInteger.ONE.dlShiftTo(ys,t); - t.subTo(y,y); // "negative" y so we can replace sub with am later - while(y.t < ys) y[y.t++] = 0; - while(--j >= 0) { - // Estimate quotient digit - var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); - if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out - y.dlShiftTo(j,t); - r.subTo(t,r); - while(r[i] < --qd) r.subTo(t,r); - } - } - if(q != null) { - r.drShiftTo(ys,q); - if(ts != ms) BigInteger.ZERO.subTo(q,q); - } - r.t = ys; - r.clamp(); - if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder - if(ts < 0) BigInteger.ZERO.subTo(r,r); -} - -// (public) this mod a -function bnMod(a) { - var r = nbi(); - this.abs().divRemTo(a,null,r); - if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); - return r; -} - -// Modular reduction using "classic" algorithm -function Classic(m) { this.m = m; } -function cConvert(x) { - if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); - else return x; -} -function cRevert(x) { return x; } -function cReduce(x) { x.divRemTo(this.m,null,x); } -function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } -function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -Classic.prototype.convert = cConvert; -Classic.prototype.revert = cRevert; -Classic.prototype.reduce = cReduce; -Classic.prototype.mulTo = cMulTo; -Classic.prototype.sqrTo = cSqrTo; - -// (protected) return "-1/this % 2^DB"; useful for Mont. reduction -// justification: -// xy == 1 (mod m) -// xy = 1+km -// xy(2-xy) = (1+km)(1-km) -// x[y(2-xy)] = 1-k^2m^2 -// x[y(2-xy)] == 1 (mod m^2) -// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 -// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. -// JS multiply "overflows" differently from C/C++, so care is needed here. -function bnpInvDigit() { - if(this.t < 1) return 0; - var x = this[0]; - if((x&1) == 0) return 0; - var y = x&3; // y == 1/x mod 2^2 - y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 - y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 - y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 - // last step - calculate inverse mod DV directly; - // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints - y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits - // we really want the negative inverse, and -DV < y < DV - return (y>0)?this.DV-y:-y; -} - -// Montgomery reduction -function Montgomery(m) { - this.m = m; - this.mp = m.invDigit(); - this.mpl = this.mp&0x7fff; - this.mph = this.mp>>15; - this.um = (1<<(m.DB-15))-1; - this.mt2 = 2*m.t; -} - -// xR mod m -function montConvert(x) { - var r = nbi(); - x.abs().dlShiftTo(this.m.t,r); - r.divRemTo(this.m,null,r); - if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); - return r; -} - -// x/R mod m -function montRevert(x) { - var r = nbi(); - x.copyTo(r); - this.reduce(r); - return r; -} - -// x = x/R mod m (HAC 14.32) -function montReduce(x) { - while(x.t <= this.mt2) // pad x so am has enough room later - x[x.t++] = 0; - for(var i = 0; i < this.m.t; ++i) { - // faster way of calculating u0 = x[i]*mp mod DV - var j = x[i]&0x7fff; - var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; - // use am to combine the multiply-shift-add into one call - j = i+this.m.t; - x[j] += this.m.am(0,u0,x,i,0,this.m.t); - // propagate carry - while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } - } - x.clamp(); - x.drShiftTo(this.m.t,x); - if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); -} - -// r = "x^2/R mod m"; x != r -function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -// r = "xy/R mod m"; x,y != r -function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - -Montgomery.prototype.convert = montConvert; -Montgomery.prototype.revert = montRevert; -Montgomery.prototype.reduce = montReduce; -Montgomery.prototype.mulTo = montMulTo; -Montgomery.prototype.sqrTo = montSqrTo; - -// (protected) true iff this is even -function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } - -// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) -function bnpExp(e,z) { - if(e > 0xffffffff || e < 1) return BigInteger.ONE; - var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; - g.copyTo(r); - while(--i >= 0) { - z.sqrTo(r,r2); - if((e&(1< 0) z.mulTo(r2,g,r); - else { var t = r; r = r2; r2 = t; } - } - return z.revert(r); -} - -// (public) this^e % m, 0 <= e < 2^32 -function bnModPowInt(e,m) { - var z; - if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); - return this.exp(e,z); -} - -// protected -BigInteger.prototype.copyTo = bnpCopyTo; -BigInteger.prototype.fromInt = bnpFromInt; -BigInteger.prototype.fromString = bnpFromString; -BigInteger.prototype.clamp = bnpClamp; -BigInteger.prototype.dlShiftTo = bnpDLShiftTo; -BigInteger.prototype.drShiftTo = bnpDRShiftTo; -BigInteger.prototype.lShiftTo = bnpLShiftTo; -BigInteger.prototype.rShiftTo = bnpRShiftTo; -BigInteger.prototype.subTo = bnpSubTo; -BigInteger.prototype.multiplyTo = bnpMultiplyTo; -BigInteger.prototype.squareTo = bnpSquareTo; -BigInteger.prototype.divRemTo = bnpDivRemTo; -BigInteger.prototype.invDigit = bnpInvDigit; -BigInteger.prototype.isEven = bnpIsEven; -BigInteger.prototype.exp = bnpExp; - -// public -BigInteger.prototype.toString = bnToString; -BigInteger.prototype.negate = bnNegate; -BigInteger.prototype.abs = bnAbs; -BigInteger.prototype.compareTo = bnCompareTo; -BigInteger.prototype.bitLength = bnBitLength; -BigInteger.prototype.mod = bnMod; -BigInteger.prototype.modPowInt = bnModPowInt; - -// "constants" -BigInteger.ZERO = nbv(0); -BigInteger.ONE = nbv(1); - -function bnClone() { var r = nbi(); this.copyTo(r); return r; } - -// (public) return value as integer -function bnIntValue() { - if(this.s < 0) { - if(this.t == 1) return this[0]-this.DV; - else if(this.t == 0) return -1; - } - else if(this.t == 1) return this[0]; - else if(this.t == 0) return 0; - // assumes 16 < DB < 32 - return ((this[1]&((1<<(32-this.DB))-1))<>24; } - -// (public) return value as short (assumes DB>=16) -function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } - -// (protected) return x s.t. r^x < DV -function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } - -// (public) 0 if this == 0, 1 if this > 0 -function bnSigNum() { - if(this.s < 0) return -1; - else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; - else return 1; -} - -// (protected) convert to radix string -function bnpToRadix(b) { - if(b == null) b = 10; - if(this.signum() == 0 || b < 2 || b > 36) return "0"; - var cs = this.chunkSize(b); - var a = Math.pow(b,cs); - var d = nbv(a), y = nbi(), z = nbi(), r = ""; - this.divRemTo(d,y,z); - while(y.signum() > 0) { - r = (a+z.intValue()).toString(b).substr(1) + r; - y.divRemTo(d,y,z); - } - return z.intValue().toString(b) + r; -} - -// (protected) convert from radix string -function bnpFromRadix(s,b) { - this.fromInt(0); - if(b == null) b = 10; - var cs = this.chunkSize(b); - var d = Math.pow(b,cs), mi = false, j = 0, w = 0; - for(var i = 0; i < s.length; ++i) { - var x = intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-" && this.signum() == 0) mi = true; - continue; - } - w = b*w+x; - if(++j >= cs) { - this.dMultiply(d); - this.dAddOffset(w,0); - j = 0; - w = 0; - } - } - if(j > 0) { - this.dMultiply(Math.pow(b,j)); - this.dAddOffset(w,0); - } - if(mi) BigInteger.ZERO.subTo(this,this); -} - -// (protected) alternate constructor -function bnpFromNumber(a,b,c) { - if("number" == typeof b) { - // new BigInteger(int,int,RNG) - if(a < 2) this.fromInt(1); - else { - this.fromNumber(a,c); - if(!this.testBit(a-1)) // force MSB set - this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); - if(this.isEven()) this.dAddOffset(1,0); // force odd - while(!this.isProbablePrime(b)) { - this.dAddOffset(2,0); - if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); - } - } - } - else { - // new BigInteger(int,RNG) - var x = new Array(), t = a&7; - x.length = (a>>3)+1; - b.nextBytes(x); - if(t > 0) x[0] &= ((1< 0) { - if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) - r[k++] = d|(this.s<<(this.DB-p)); - while(i >= 0) { - if(p < 8) { - d = (this[i]&((1<>(p+=this.DB-8); - } - else { - d = (this[i]>>(p-=8))&0xff; - if(p <= 0) { p += this.DB; --i; } - } - if((d&0x80) != 0) d |= -256; - if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; - if(k > 0 || d != this.s) r[k++] = d; - } - } - return r; -} - -function bnEquals(a) { return(this.compareTo(a)==0); } -function bnMin(a) { return(this.compareTo(a)<0)?this:a; } -function bnMax(a) { return(this.compareTo(a)>0)?this:a; } - -// (protected) r = this op a (bitwise) -function bnpBitwiseTo(a,op,r) { - var i, f, m = Math.min(a.t,this.t); - for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); - if(a.t < this.t) { - f = a.s&this.DM; - for(i = m; i < this.t; ++i) r[i] = op(this[i],f); - r.t = this.t; - } - else { - f = this.s&this.DM; - for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); - r.t = a.t; - } - r.s = op(this.s,a.s); - r.clamp(); -} - -// (public) this & a -function op_and(x,y) { return x&y; } -function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } - -// (public) this | a -function op_or(x,y) { return x|y; } -function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } - -// (public) this ^ a -function op_xor(x,y) { return x^y; } -function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } - -// (public) this & ~a -function op_andnot(x,y) { return x&~y; } -function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } - -// (public) ~this -function bnNot() { - var r = nbi(); - for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; - r.t = this.t; - r.s = ~this.s; - return r; -} - -// (public) this << n -function bnShiftLeft(n) { - var r = nbi(); - if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); - return r; -} - -// (public) this >> n -function bnShiftRight(n) { - var r = nbi(); - if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); - return r; -} - -// return index of lowest 1-bit in x, x < 2^31 -function lbit(x) { - if(x == 0) return -1; - var r = 0; - if((x&0xffff) == 0) { x >>= 16; r += 16; } - if((x&0xff) == 0) { x >>= 8; r += 8; } - if((x&0xf) == 0) { x >>= 4; r += 4; } - if((x&3) == 0) { x >>= 2; r += 2; } - if((x&1) == 0) ++r; - return r; -} - -// (public) returns index of lowest 1-bit (or -1 if none) -function bnGetLowestSetBit() { - for(var i = 0; i < this.t; ++i) - if(this[i] != 0) return i*this.DB+lbit(this[i]); - if(this.s < 0) return this.t*this.DB; - return -1; -} - -// return number of 1 bits in x -function cbit(x) { - var r = 0; - while(x != 0) { x &= x-1; ++r; } - return r; -} - -// (public) return number of set bits -function bnBitCount() { - var r = 0, x = this.s&this.DM; - for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); - return r; -} - -// (public) true iff nth bit is set -function bnTestBit(n) { - var j = Math.floor(n/this.DB); - if(j >= this.t) return(this.s!=0); - return((this[j]&(1<<(n%this.DB)))!=0); -} - -// (protected) this op (1<>= this.DB; - } - if(a.t < this.t) { - c += a.s; - while(i < this.t) { - c += this[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } - else { - c += this.s; - while(i < a.t) { - c += a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += a.s; - } - r.s = (c<0)?-1:0; - if(c > 0) r[i++] = c; - else if(c < -1) r[i++] = this.DV+c; - r.t = i; - r.clamp(); -} - -// (public) this + a -function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } - -// (public) this - a -function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } - -// (public) this * a -function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } - -// (public) this^2 -function bnSquare() { var r = nbi(); this.squareTo(r); return r; } - -// (public) this / a -function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } - -// (public) this % a -function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } - -// (public) [this/a,this%a] -function bnDivideAndRemainder(a) { - var q = nbi(), r = nbi(); - this.divRemTo(a,q,r); - return new Array(q,r); -} - -// (protected) this *= n, this >= 0, 1 < n < DV -function bnpDMultiply(n) { - this[this.t] = this.am(0,n-1,this,0,0,this.t); - ++this.t; - this.clamp(); -} - -// (protected) this += n << w words, this >= 0 -function bnpDAddOffset(n,w) { - if(n == 0) return; - while(this.t <= w) this[this.t++] = 0; - this[w] += n; - while(this[w] >= this.DV) { - this[w] -= this.DV; - if(++w >= this.t) this[this.t++] = 0; - ++this[w]; - } -} - -// A "null" reducer -function NullExp() {} -function nNop(x) { return x; } -function nMulTo(x,y,r) { x.multiplyTo(y,r); } -function nSqrTo(x,r) { x.squareTo(r); } - -NullExp.prototype.convert = nNop; -NullExp.prototype.revert = nNop; -NullExp.prototype.mulTo = nMulTo; -NullExp.prototype.sqrTo = nSqrTo; - -// (public) this^e -function bnPow(e) { return this.exp(e,new NullExp()); } - -// (protected) r = lower n words of "this * a", a.t <= n -// "this" should be the larger one if appropriate. -function bnpMultiplyLowerTo(a,n,r) { - var i = Math.min(this.t+a.t,n); - r.s = 0; // assumes a,this >= 0 - r.t = i; - while(i > 0) r[--i] = 0; - var j; - for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); - for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); - r.clamp(); -} - -// (protected) r = "this * a" without lower n words, n > 0 -// "this" should be the larger one if appropriate. -function bnpMultiplyUpperTo(a,n,r) { - --n; - var i = r.t = this.t+a.t-n; - r.s = 0; // assumes a,this >= 0 - while(--i >= 0) r[i] = 0; - for(i = Math.max(n-this.t,0); i < a.t; ++i) - r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); - r.clamp(); - r.drShiftTo(1,r); -} - -// Barrett modular reduction -function Barrett(m) { - // setup Barrett - this.r2 = nbi(); - this.q3 = nbi(); - BigInteger.ONE.dlShiftTo(2*m.t,this.r2); - this.mu = this.r2.divide(m); - this.m = m; -} - -function barrettConvert(x) { - if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); - else if(x.compareTo(this.m) < 0) return x; - else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } -} - -function barrettRevert(x) { return x; } - -// x = x mod m (HAC 14.42) -function barrettReduce(x) { - x.drShiftTo(this.m.t-1,this.r2); - if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } - this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); - this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); - while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); - x.subTo(this.r2,x); - while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); -} - -// r = x^2 mod m; x != r -function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - -// r = x*y mod m; x,y != r -function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - -Barrett.prototype.convert = barrettConvert; -Barrett.prototype.revert = barrettRevert; -Barrett.prototype.reduce = barrettReduce; -Barrett.prototype.mulTo = barrettMulTo; -Barrett.prototype.sqrTo = barrettSqrTo; - -// (public) this^e % m (HAC 14.85) -function bnModPow(e,m) { - var i = e.bitLength(), k, r = nbv(1), z; - if(i <= 0) return r; - else if(i < 18) k = 1; - else if(i < 48) k = 3; - else if(i < 144) k = 4; - else if(i < 768) k = 5; - else k = 6; - if(i < 8) - z = new Classic(m); - else if(m.isEven()) - z = new Barrett(m); - else - z = new Montgomery(m); - - // precomputation - var g = new Array(), n = 3, k1 = k-1, km = (1< 1) { - var g2 = nbi(); - z.sqrTo(g[1],g2); - while(n <= km) { - g[n] = nbi(); - z.mulTo(g2,g[n-2],g[n]); - n += 2; - } - } - - var j = e.t-1, w, is1 = true, r2 = nbi(), t; - i = nbits(e[j])-1; - while(j >= 0) { - if(i >= k1) w = (e[j]>>(i-k1))&km; - else { - w = (e[j]&((1<<(i+1))-1))<<(k1-i); - if(j > 0) w |= e[j-1]>>(this.DB+i-k1); - } - - n = k; - while((w&1) == 0) { w >>= 1; --n; } - if((i -= n) < 0) { i += this.DB; --j; } - if(is1) { // ret == 1, don't bother squaring or multiplying it - g[w].copyTo(r); - is1 = false; - } - else { - while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } - if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } - z.mulTo(r2,g[w],r); - } - - while(j >= 0 && (e[j]&(1< 0) { - x.rShiftTo(g,x); - y.rShiftTo(g,y); - } - while(x.signum() > 0) { - if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); - if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); - if(x.compareTo(y) >= 0) { - x.subTo(y,x); - x.rShiftTo(1,x); - } - else { - y.subTo(x,y); - y.rShiftTo(1,y); - } - } - if(g > 0) y.lShiftTo(g,y); - return y; -} - -// (protected) this % n, n < 2^26 -function bnpModInt(n) { - if(n <= 0) return 0; - var d = this.DV%n, r = (this.s<0)?n-1:0; - if(this.t > 0) - if(d == 0) r = this[0]%n; - else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; - return r; -} - -// (public) 1/this % m (HAC 14.61) -function bnModInverse(m) { - var ac = m.isEven(); - if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; - var u = m.clone(), v = this.clone(); - var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); - while(u.signum() != 0) { - while(u.isEven()) { - u.rShiftTo(1,u); - if(ac) { - if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } - a.rShiftTo(1,a); - } - else if(!b.isEven()) b.subTo(m,b); - b.rShiftTo(1,b); - } - while(v.isEven()) { - v.rShiftTo(1,v); - if(ac) { - if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } - c.rShiftTo(1,c); - } - else if(!d.isEven()) d.subTo(m,d); - d.rShiftTo(1,d); - } - if(u.compareTo(v) >= 0) { - u.subTo(v,u); - if(ac) a.subTo(c,a); - b.subTo(d,b); - } - else { - v.subTo(u,v); - if(ac) c.subTo(a,c); - d.subTo(b,d); - } - } - if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; - if(d.compareTo(m) >= 0) return d.subtract(m); - if(d.signum() < 0) d.addTo(m,d); else return d; - if(d.signum() < 0) return d.add(m); else return d; -} - -var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; -var lplim = (1<<26)/lowprimes[lowprimes.length-1]; - -// (public) test primality with certainty >= 1-.5^t -function bnIsProbablePrime(t) { - var i, x = this.abs(); - if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { - for(i = 0; i < lowprimes.length; ++i) - if(x[0] == lowprimes[i]) return true; - return false; - } - if(x.isEven()) return false; - i = 1; - while(i < lowprimes.length) { - var m = lowprimes[i], j = i+1; - while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; - m = x.modInt(m); - while(i < j) if(m%lowprimes[i++] == 0) return false; - } - return x.millerRabin(t); -} - -// (protected) true if probably prime (HAC 4.24, Miller-Rabin) -function bnpMillerRabin(t) { - var n1 = this.subtract(BigInteger.ONE); - var k = n1.getLowestSetBit(); - if(k <= 0) return false; - var r = n1.shiftRight(k); - t = (t+1)>>1; - if(t > lowprimes.length) t = lowprimes.length; - var a = nbi(); - for(var i = 0; i < t; ++i) { - //Pick bases at random, instead of starting at 2 - a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]); - var y = a.modPow(r,this); - if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { - var j = 1; - while(j++ < k && y.compareTo(n1) != 0) { - y = y.modPowInt(2,this); - if(y.compareTo(BigInteger.ONE) == 0) return false; - } - if(y.compareTo(n1) != 0) return false; - } - } - return true; -} - -// protected -BigInteger.prototype.chunkSize = bnpChunkSize; -BigInteger.prototype.toRadix = bnpToRadix; -BigInteger.prototype.fromRadix = bnpFromRadix; -BigInteger.prototype.fromNumber = bnpFromNumber; -BigInteger.prototype.bitwiseTo = bnpBitwiseTo; -BigInteger.prototype.changeBit = bnpChangeBit; -BigInteger.prototype.addTo = bnpAddTo; -BigInteger.prototype.dMultiply = bnpDMultiply; -BigInteger.prototype.dAddOffset = bnpDAddOffset; -BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; -BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; -BigInteger.prototype.modInt = bnpModInt; -BigInteger.prototype.millerRabin = bnpMillerRabin; - -// public -BigInteger.prototype.clone = bnClone; -BigInteger.prototype.intValue = bnIntValue; -BigInteger.prototype.byteValue = bnByteValue; -BigInteger.prototype.shortValue = bnShortValue; -BigInteger.prototype.signum = bnSigNum; -BigInteger.prototype.toByteArray = bnToByteArray; -BigInteger.prototype.equals = bnEquals; -BigInteger.prototype.min = bnMin; -BigInteger.prototype.max = bnMax; -BigInteger.prototype.and = bnAnd; -BigInteger.prototype.or = bnOr; -BigInteger.prototype.xor = bnXor; -BigInteger.prototype.andNot = bnAndNot; -BigInteger.prototype.not = bnNot; -BigInteger.prototype.shiftLeft = bnShiftLeft; -BigInteger.prototype.shiftRight = bnShiftRight; -BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; -BigInteger.prototype.bitCount = bnBitCount; -BigInteger.prototype.testBit = bnTestBit; -BigInteger.prototype.setBit = bnSetBit; -BigInteger.prototype.clearBit = bnClearBit; -BigInteger.prototype.flipBit = bnFlipBit; -BigInteger.prototype.add = bnAdd; -BigInteger.prototype.subtract = bnSubtract; -BigInteger.prototype.multiply = bnMultiply; -BigInteger.prototype.divide = bnDivide; -BigInteger.prototype.remainder = bnRemainder; -BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; -BigInteger.prototype.modPow = bnModPow; -BigInteger.prototype.modInverse = bnModInverse; -BigInteger.prototype.pow = bnPow; -BigInteger.prototype.gcd = bnGCD; -BigInteger.prototype.isProbablePrime = bnIsProbablePrime; - -// JSBN-specific extension -BigInteger.prototype.square = bnSquare; - -// BigInteger interfaces not implemented in jsbn: - -// BigInteger(int signum, byte[] magnitude) -// double doubleValue() -// float floatValue() -// int hashCode() -// long longValue() -// static BigInteger valueOf(long val) + +var dbits; + +// JavaScript engine analysis +var canary = 0xdeadbeefcafe; +var j_lm = ((canary&0xffffff)==0xefcafe); + +// (public) Constructor +function BigInteger(a,b,c) { + if(a != null) + if("number" == typeof a) this.fromNumber(a,b,c); + else if(b == null && "string" != typeof a) this.fromString(a,256); + else this.fromString(a,b); +} + +// return new, unset BigInteger +function nbi() { return new BigInteger(null); } + +// am: Compute w_j += (x*this_i), propagate carries, +// c is initial carry, returns final carry. +// c < 3*dvalue, x < 2*dvalue, this_i < dvalue +// We need to select the fastest one that works in this environment. + +// am1: use a single mult and divide to get the high bits, +// max digit bits should be 26 because +// max internal value = 2*dvalue^2-2*dvalue (< 2^53) +function am1(i,x,w,j,c,n) { + while(--n >= 0) { + var v = x*this[i++]+w[j]+c; + c = Math.floor(v/0x4000000); + w[j++] = v&0x3ffffff; + } + return c; +} +// am2 avoids a big mult-and-extract completely. +// Max digit bits should be <= 30 because we do bitwise ops +// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) +function am2(i,x,w,j,c,n) { + var xl = x&0x7fff, xh = x>>15; + while(--n >= 0) { + var l = this[i]&0x7fff; + var h = this[i++]>>15; + var m = xh*l+h*xl; + l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); + c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); + w[j++] = l&0x3fffffff; + } + return c; +} +// Alternately, set max digit bits to 28 since some +// browsers slow down when dealing with 32-bit numbers. +function am3(i,x,w,j,c,n) { + var xl = x&0x3fff, xh = x>>14; + while(--n >= 0) { + var l = this[i]&0x3fff; + var h = this[i++]>>14; + var m = xh*l+h*xl; + l = xl*l+((m&0x3fff)<<14)+w[j]+c; + c = (l>>28)+(m>>14)+xh*h; + w[j++] = l&0xfffffff; + } + return c; +} +if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; +} +else if(j_lm && (navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; +} +else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; +} + +BigInteger.prototype.DB = dbits; +BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; +} + +// (protected) set from integer value x, -DV <= x < DV +function bnpFromInt(x) { + this.t = 1; + this.s = (x<0)?-1:0; + if(x > 0) this[0] = x; + else if(x < -1) this[0] = x+this.DV; + else this.t = 0; +} + +// return bigint initialized to value +function nbv(i) { var r = nbi(); r.fromInt(i); return r; } + +// (protected) set from string and radix +function bnpFromString(s,b) { + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 256) k = 8; // byte array + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else { this.fromRadix(s,b); return; } + this.t = 0; + this.s = 0; + var i = s.length, mi = false, sh = 0; + while(--i >= 0) { + var x = (k==8)?s[i]&0xff:intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if(sh == 0) + this[this.t++] = x; + else if(sh+k > this.DB) { + this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); + } + else + this[this.t-1] |= x<= this.DB) sh -= this.DB; + } + if(k == 8 && (s[0]&0x80) != 0) { + this.s = -1; + if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; +} + +// (public) return string representation in given radix +function bnToString(b) { + if(this.s < 0) return "-"+this.negate().toString(b); + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else return this.toRadix(b); + var km = (1< 0) { + if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } + while(i >= 0) { + if(p < k) { + d = (this[i]&((1<>(p+=this.DB-k); + } + else { + d = (this[i]>>(p-=k))&km; + if(p <= 0) { p += this.DB; --i; } + } + if(d > 0) m = true; + if(m) r += int2char(d); + } + } + return m?r:"0"; +} + +// (public) -this +function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } + +// (public) |this| +function bnAbs() { return (this.s<0)?this.negate():this; } + +// (public) return + if this > a, - if this < a, 0 if equal +function bnCompareTo(a) { + var r = this.s-a.s; + if(r != 0) return r; + var i = this.t; + r = i-a.t; + if(r != 0) return (this.s<0)?-r:r; + while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; + return 0; +} + +// returns bit length of the integer x +function nbits(x) { + var r = 1, t; + if((t=x>>>16) != 0) { x = t; r += 16; } + if((t=x>>8) != 0) { x = t; r += 8; } + if((t=x>>4) != 0) { x = t; r += 4; } + if((t=x>>2) != 0) { x = t; r += 2; } + if((t=x>>1) != 0) { x = t; r += 1; } + return r; +} + +// (public) return the number of bits in "this" +function bnBitLength() { + if(this.t <= 0) return 0; + return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); +} + +// (protected) r = this << n*DB +function bnpDLShiftTo(n,r) { + var i; + for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; + for(i = n-1; i >= 0; --i) r[i] = 0; + r.t = this.t+n; + r.s = this.s; +} + +// (protected) r = this >> n*DB +function bnpDRShiftTo(n,r) { + for(var i = n; i < this.t; ++i) r[i-n] = this[i]; + r.t = Math.max(this.t-n,0); + r.s = this.s; +} + +// (protected) r = this << n +function bnpLShiftTo(n,r) { + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<= 0; --i) { + r[i+ds+1] = (this[i]>>cbs)|c; + c = (this[i]&bm)<= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t+ds+1; + r.s = this.s; + r.clamp(); +} + +// (protected) r = this >> n +function bnpRShiftTo(n,r) { + r.s = this.s; + var ds = Math.floor(n/this.DB); + if(ds >= this.t) { r.t = 0; return; } + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<>bs; + for(var i = ds+1; i < this.t; ++i) { + r[i-ds-1] |= (this[i]&bm)<>bs; + } + if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; + } + if(a.t < this.t) { + c -= a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c -= a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c<0)?-1:0; + if(c < -1) r[i++] = this.DV+c; + else if(c > 0) r[i++] = c; + r.t = i; + r.clamp(); +} + +// (protected) r = this * a, r != this,a (HAC 14.12) +// "this" should be the larger one if appropriate. +function bnpMultiplyTo(a,r) { + var x = this.abs(), y = a.abs(); + var i = x.t; + r.t = i+y.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); + r.s = 0; + r.clamp(); + if(this.s != a.s) BigInteger.ZERO.subTo(r,r); +} + +// (protected) r = this^2, r != this (HAC 14.16) +function bnpSquareTo(r) { + var x = this.abs(); + var i = r.t = 2*x.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < x.t-1; ++i) { + var c = x.am(i,x[i],r,2*i,0,1); + if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { + r[i+x.t] -= x.DV; + r[i+x.t+1] = 1; + } + } + if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); + r.s = 0; + r.clamp(); +} + +// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) +// r != q, this != m. q or r may be null. +function bnpDivRemTo(m,q,r) { + var pm = m.abs(); + if(pm.t <= 0) return; + var pt = this.abs(); + if(pt.t < pm.t) { + if(q != null) q.fromInt(0); + if(r != null) this.copyTo(r); + return; + } + if(r == null) r = nbi(); + var y = nbi(), ts = this.s, ms = m.s; + var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus + if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } + else { pm.copyTo(y); pt.copyTo(r); } + var ys = y.t; + var y0 = y[ys-1]; + if(y0 == 0) return; + var yt = y0*(1<1)?y[ys-2]>>this.F2:0); + var d1 = this.FV/yt, d2 = (1<= 0) { + r[r.t++] = 1; + r.subTo(t,r); + } + BigInteger.ONE.dlShiftTo(ys,t); + t.subTo(y,y); // "negative" y so we can replace sub with am later + while(y.t < ys) y[y.t++] = 0; + while(--j >= 0) { + // Estimate quotient digit + var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); + if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out + y.dlShiftTo(j,t); + r.subTo(t,r); + while(r[i] < --qd) r.subTo(t,r); + } + } + if(q != null) { + r.drShiftTo(ys,q); + if(ts != ms) BigInteger.ZERO.subTo(q,q); + } + r.t = ys; + r.clamp(); + if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder + if(ts < 0) BigInteger.ZERO.subTo(r,r); +} + +// (public) this mod a +function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a,null,r); + if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); + return r; +} + +// Modular reduction using "classic" algorithm +function Classic(m) { this.m = m; } +function cConvert(x) { + if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; +} +function cRevert(x) { return x; } +function cReduce(x) { x.divRemTo(this.m,null,x); } +function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } +function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +Classic.prototype.convert = cConvert; +Classic.prototype.revert = cRevert; +Classic.prototype.reduce = cReduce; +Classic.prototype.mulTo = cMulTo; +Classic.prototype.sqrTo = cSqrTo; + +// (protected) return "-1/this % 2^DB"; useful for Mont. reduction +// justification: +// xy == 1 (mod m) +// xy = 1+km +// xy(2-xy) = (1+km)(1-km) +// x[y(2-xy)] = 1-k^2m^2 +// x[y(2-xy)] == 1 (mod m^2) +// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 +// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. +// JS multiply "overflows" differently from C/C++, so care is needed here. +function bnpInvDigit() { + if(this.t < 1) return 0; + var x = this[0]; + if((x&1) == 0) return 0; + var y = x&3; // y == 1/x mod 2^2 + y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 + y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 + y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y>0)?this.DV-y:-y; +} + +// Montgomery reduction +function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp&0x7fff; + this.mph = this.mp>>15; + this.um = (1<<(m.DB-15))-1; + this.mt2 = 2*m.t; +} + +// xR mod m +function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t,r); + r.divRemTo(this.m,null,r); + if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); + return r; +} + +// x/R mod m +function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; +} + +// x = x/R mod m (HAC 14.32) +function montReduce(x) { + while(x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for(var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i]&0x7fff; + var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; + // use am to combine the multiply-shift-add into one call + j = i+this.m.t; + x[j] += this.m.am(0,u0,x,i,0,this.m.t); + // propagate carry + while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } + } + x.clamp(); + x.drShiftTo(this.m.t,x); + if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = "x^2/R mod m"; x != r +function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = "xy/R mod m"; x,y != r +function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Montgomery.prototype.convert = montConvert; +Montgomery.prototype.revert = montRevert; +Montgomery.prototype.reduce = montReduce; +Montgomery.prototype.mulTo = montMulTo; +Montgomery.prototype.sqrTo = montSqrTo; + +// (protected) true iff this is even +function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } + +// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) +function bnpExp(e,z) { + if(e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; + g.copyTo(r); + while(--i >= 0) { + z.sqrTo(r,r2); + if((e&(1< 0) z.mulTo(r2,g,r); + else { var t = r; r = r2; r2 = t; } + } + return z.revert(r); +} + +// (public) this^e % m, 0 <= e < 2^32 +function bnModPowInt(e,m) { + var z; + if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e,z); +} + +// protected +BigInteger.prototype.copyTo = bnpCopyTo; +BigInteger.prototype.fromInt = bnpFromInt; +BigInteger.prototype.fromString = bnpFromString; +BigInteger.prototype.clamp = bnpClamp; +BigInteger.prototype.dlShiftTo = bnpDLShiftTo; +BigInteger.prototype.drShiftTo = bnpDRShiftTo; +BigInteger.prototype.lShiftTo = bnpLShiftTo; +BigInteger.prototype.rShiftTo = bnpRShiftTo; +BigInteger.prototype.subTo = bnpSubTo; +BigInteger.prototype.multiplyTo = bnpMultiplyTo; +BigInteger.prototype.squareTo = bnpSquareTo; +BigInteger.prototype.divRemTo = bnpDivRemTo; +BigInteger.prototype.invDigit = bnpInvDigit; +BigInteger.prototype.isEven = bnpIsEven; +BigInteger.prototype.exp = bnpExp; + +// public +BigInteger.prototype.toString = bnToString; +BigInteger.prototype.negate = bnNegate; +BigInteger.prototype.abs = bnAbs; +BigInteger.prototype.compareTo = bnCompareTo; +BigInteger.prototype.bitLength = bnBitLength; +BigInteger.prototype.mod = bnMod; +BigInteger.prototype.modPowInt = bnModPowInt; + +// "constants" +BigInteger.ZERO = nbv(0); +BigInteger.ONE = nbv(1); + +function bnClone() { var r = nbi(); this.copyTo(r); return r; } + +// (public) return value as integer +function bnIntValue() { + if(this.s < 0) { + if(this.t == 1) return this[0]-this.DV; + else if(this.t == 0) return -1; + } + else if(this.t == 1) return this[0]; + else if(this.t == 0) return 0; + // assumes 16 < DB < 32 + return ((this[1]&((1<<(32-this.DB))-1))<>24; } + +// (public) return value as short (assumes DB>=16) +function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } + +// (protected) return x s.t. r^x < DV +function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } + +// (public) 0 if this == 0, 1 if this > 0 +function bnSigNum() { + if(this.s < 0) return -1; + else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else return 1; +} + +// (protected) convert to radix string +function bnpToRadix(b) { + if(b == null) b = 10; + if(this.signum() == 0 || b < 2 || b > 36) return "0"; + var cs = this.chunkSize(b); + var a = Math.pow(b,cs); + var d = nbv(a), y = nbi(), z = nbi(), r = ""; + this.divRemTo(d,y,z); + while(y.signum() > 0) { + r = (a+z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d,y,z); + } + return z.intValue().toString(b) + r; +} + +// (protected) convert from radix string +function bnpFromRadix(s,b) { + this.fromInt(0); + if(b == null) b = 10; + var cs = this.chunkSize(b); + var d = Math.pow(b,cs), mi = false, j = 0, w = 0; + for(var i = 0; i < s.length; ++i) { + var x = intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-" && this.signum() == 0) mi = true; + continue; + } + w = b*w+x; + if(++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w,0); + j = 0; + w = 0; + } + } + if(j > 0) { + this.dMultiply(Math.pow(b,j)); + this.dAddOffset(w,0); + } + if(mi) BigInteger.ZERO.subTo(this,this); +} + +// (protected) alternate constructor +function bnpFromNumber(a,b,c) { + if("number" == typeof b) { + // new BigInteger(int,int,RNG) + if(a < 2) this.fromInt(1); + else { + this.fromNumber(a,c); + if(!this.testBit(a-1)) // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); + if(this.isEven()) this.dAddOffset(1,0); // force odd + while(!this.isProbablePrime(b)) { + this.dAddOffset(2,0); + if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); + } + } + } + else { + // new BigInteger(int,RNG) + var x = new Array(), t = a&7; + x.length = (a>>3)+1; + b.nextBytes(x); + if(t > 0) x[0] &= ((1< 0) { + if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) + r[k++] = d|(this.s<<(this.DB-p)); + while(i >= 0) { + if(p < 8) { + d = (this[i]&((1<>(p+=this.DB-8); + } + else { + d = (this[i]>>(p-=8))&0xff; + if(p <= 0) { p += this.DB; --i; } + } + if((d&0x80) != 0) d |= -256; + if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; + if(k > 0 || d != this.s) r[k++] = d; + } + } + return r; +} + +function bnEquals(a) { return(this.compareTo(a)==0); } +function bnMin(a) { return(this.compareTo(a)<0)?this:a; } +function bnMax(a) { return(this.compareTo(a)>0)?this:a; } + +// (protected) r = this op a (bitwise) +function bnpBitwiseTo(a,op,r) { + var i, f, m = Math.min(a.t,this.t); + for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); + if(a.t < this.t) { + f = a.s&this.DM; + for(i = m; i < this.t; ++i) r[i] = op(this[i],f); + r.t = this.t; + } + else { + f = this.s&this.DM; + for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); + r.t = a.t; + } + r.s = op(this.s,a.s); + r.clamp(); +} + +// (public) this & a +function op_and(x,y) { return x&y; } +function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } + +// (public) this | a +function op_or(x,y) { return x|y; } +function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } + +// (public) this ^ a +function op_xor(x,y) { return x^y; } +function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } + +// (public) this & ~a +function op_andnot(x,y) { return x&~y; } +function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } + +// (public) ~this +function bnNot() { + var r = nbi(); + for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; + r.t = this.t; + r.s = ~this.s; + return r; +} + +// (public) this << n +function bnShiftLeft(n) { + var r = nbi(); + if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); + return r; +} + +// (public) this >> n +function bnShiftRight(n) { + var r = nbi(); + if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); + return r; +} + +// return index of lowest 1-bit in x, x < 2^31 +function lbit(x) { + if(x == 0) return -1; + var r = 0; + if((x&0xffff) == 0) { x >>= 16; r += 16; } + if((x&0xff) == 0) { x >>= 8; r += 8; } + if((x&0xf) == 0) { x >>= 4; r += 4; } + if((x&3) == 0) { x >>= 2; r += 2; } + if((x&1) == 0) ++r; + return r; +} + +// (public) returns index of lowest 1-bit (or -1 if none) +function bnGetLowestSetBit() { + for(var i = 0; i < this.t; ++i) + if(this[i] != 0) return i*this.DB+lbit(this[i]); + if(this.s < 0) return this.t*this.DB; + return -1; +} + +// return number of 1 bits in x +function cbit(x) { + var r = 0; + while(x != 0) { x &= x-1; ++r; } + return r; +} + +// (public) return number of set bits +function bnBitCount() { + var r = 0, x = this.s&this.DM; + for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); + return r; +} + +// (public) true iff nth bit is set +function bnTestBit(n) { + var j = Math.floor(n/this.DB); + if(j >= this.t) return(this.s!=0); + return((this[j]&(1<<(n%this.DB)))!=0); +} + +// (protected) this op (1<>= this.DB; + } + if(a.t < this.t) { + c += a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c += a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = (c<0)?-1:0; + if(c > 0) r[i++] = c; + else if(c < -1) r[i++] = this.DV+c; + r.t = i; + r.clamp(); +} + +// (public) this + a +function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } + +// (public) this - a +function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } + +// (public) this * a +function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } + +// (public) this^2 +function bnSquare() { var r = nbi(); this.squareTo(r); return r; } + +// (public) this / a +function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } + +// (public) this % a +function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } + +// (public) [this/a,this%a] +function bnDivideAndRemainder(a) { + var q = nbi(), r = nbi(); + this.divRemTo(a,q,r); + return new Array(q,r); +} + +// (protected) this *= n, this >= 0, 1 < n < DV +function bnpDMultiply(n) { + this[this.t] = this.am(0,n-1,this,0,0,this.t); + ++this.t; + this.clamp(); +} + +// (protected) this += n << w words, this >= 0 +function bnpDAddOffset(n,w) { + if(n == 0) return; + while(this.t <= w) this[this.t++] = 0; + this[w] += n; + while(this[w] >= this.DV) { + this[w] -= this.DV; + if(++w >= this.t) this[this.t++] = 0; + ++this[w]; + } +} + +// A "null" reducer +function NullExp() {} +function nNop(x) { return x; } +function nMulTo(x,y,r) { x.multiplyTo(y,r); } +function nSqrTo(x,r) { x.squareTo(r); } + +NullExp.prototype.convert = nNop; +NullExp.prototype.revert = nNop; +NullExp.prototype.mulTo = nMulTo; +NullExp.prototype.sqrTo = nSqrTo; + +// (public) this^e +function bnPow(e) { return this.exp(e,new NullExp()); } + +// (protected) r = lower n words of "this * a", a.t <= n +// "this" should be the larger one if appropriate. +function bnpMultiplyLowerTo(a,n,r) { + var i = Math.min(this.t+a.t,n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while(i > 0) r[--i] = 0; + var j; + for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); + for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); + r.clamp(); +} + +// (protected) r = "this * a" without lower n words, n > 0 +// "this" should be the larger one if appropriate. +function bnpMultiplyUpperTo(a,n,r) { + --n; + var i = r.t = this.t+a.t-n; + r.s = 0; // assumes a,this >= 0 + while(--i >= 0) r[i] = 0; + for(i = Math.max(n-this.t,0); i < a.t; ++i) + r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); + r.clamp(); + r.drShiftTo(1,r); +} + +// Barrett modular reduction +function Barrett(m) { + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2*m.t,this.r2); + this.mu = this.r2.divide(m); + this.m = m; +} + +function barrettConvert(x) { + if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); + else if(x.compareTo(this.m) < 0) return x; + else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } +} + +function barrettRevert(x) { return x; } + +// x = x mod m (HAC 14.42) +function barrettReduce(x) { + x.drShiftTo(this.m.t-1,this.r2); + if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } + this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); + this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); + while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); + x.subTo(this.r2,x); + while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = x^2 mod m; x != r +function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = x*y mod m; x,y != r +function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Barrett.prototype.convert = barrettConvert; +Barrett.prototype.revert = barrettRevert; +Barrett.prototype.reduce = barrettReduce; +Barrett.prototype.mulTo = barrettMulTo; +Barrett.prototype.sqrTo = barrettSqrTo; + +// (public) this^e % m (HAC 14.85) +function bnModPow(e,m) { + var i = e.bitLength(), k, r = nbv(1), z; + if(i <= 0) return r; + else if(i < 18) k = 1; + else if(i < 48) k = 3; + else if(i < 144) k = 4; + else if(i < 768) k = 5; + else k = 6; + if(i < 8) + z = new Classic(m); + else if(m.isEven()) + z = new Barrett(m); + else + z = new Montgomery(m); + + // precomputation + var g = new Array(), n = 3, k1 = k-1, km = (1< 1) { + var g2 = nbi(); + z.sqrTo(g[1],g2); + while(n <= km) { + g[n] = nbi(); + z.mulTo(g2,g[n-2],g[n]); + n += 2; + } + } + + var j = e.t-1, w, is1 = true, r2 = nbi(), t; + i = nbits(e[j])-1; + while(j >= 0) { + if(i >= k1) w = (e[j]>>(i-k1))&km; + else { + w = (e[j]&((1<<(i+1))-1))<<(k1-i); + if(j > 0) w |= e[j-1]>>(this.DB+i-k1); + } + + n = k; + while((w&1) == 0) { w >>= 1; --n; } + if((i -= n) < 0) { i += this.DB; --j; } + if(is1) { // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } + else { + while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } + if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } + z.mulTo(r2,g[w],r); + } + + while(j >= 0 && (e[j]&(1< 0) { + x.rShiftTo(g,x); + y.rShiftTo(g,y); + } + while(x.signum() > 0) { + if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); + if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); + if(x.compareTo(y) >= 0) { + x.subTo(y,x); + x.rShiftTo(1,x); + } + else { + y.subTo(x,y); + y.rShiftTo(1,y); + } + } + if(g > 0) y.lShiftTo(g,y); + return y; +} + +// (protected) this % n, n < 2^26 +function bnpModInt(n) { + if(n <= 0) return 0; + var d = this.DV%n, r = (this.s<0)?n-1:0; + if(this.t > 0) + if(d == 0) r = this[0]%n; + else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; + return r; +} + +// (public) 1/this % m (HAC 14.61) +function bnModInverse(m) { + var ac = m.isEven(); + if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + var u = m.clone(), v = this.clone(); + var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); + while(u.signum() != 0) { + while(u.isEven()) { + u.rShiftTo(1,u); + if(ac) { + if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } + a.rShiftTo(1,a); + } + else if(!b.isEven()) b.subTo(m,b); + b.rShiftTo(1,b); + } + while(v.isEven()) { + v.rShiftTo(1,v); + if(ac) { + if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } + c.rShiftTo(1,c); + } + else if(!d.isEven()) d.subTo(m,d); + d.rShiftTo(1,d); + } + if(u.compareTo(v) >= 0) { + u.subTo(v,u); + if(ac) a.subTo(c,a); + b.subTo(d,b); + } + else { + v.subTo(u,v); + if(ac) c.subTo(a,c); + d.subTo(b,d); + } + } + if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; + if(d.compareTo(m) >= 0) return d.subtract(m); + if(d.signum() < 0) d.addTo(m,d); else return d; + if(d.signum() < 0) return d.add(m); else return d; +} + +var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; +var lplim = (1<<26)/lowprimes[lowprimes.length-1]; + +// (public) test primality with certainty >= 1-.5^t +function bnIsProbablePrime(t) { + var i, x = this.abs(); + if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { + for(i = 0; i < lowprimes.length; ++i) + if(x[0] == lowprimes[i]) return true; + return false; + } + if(x.isEven()) return false; + i = 1; + while(i < lowprimes.length) { + var m = lowprimes[i], j = i+1; + while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + m = x.modInt(m); + while(i < j) if(m%lowprimes[i++] == 0) return false; + } + return x.millerRabin(t); +} + +// (protected) true if probably prime (HAC 4.24, Miller-Rabin) +function bnpMillerRabin(t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if(k <= 0) return false; + var r = n1.shiftRight(k); + t = (t+1)>>1; + if(t > lowprimes.length) t = lowprimes.length; + var a = nbi(); + for(var i = 0; i < t; ++i) { + //Pick bases at random, instead of starting at 2 + a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]); + var y = a.modPow(r,this); + if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while(j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2,this); + if(y.compareTo(BigInteger.ONE) == 0) return false; + } + if(y.compareTo(n1) != 0) return false; + } + } + return true; +} + +// protected +BigInteger.prototype.chunkSize = bnpChunkSize; +BigInteger.prototype.toRadix = bnpToRadix; +BigInteger.prototype.fromRadix = bnpFromRadix; +BigInteger.prototype.fromNumber = bnpFromNumber; +BigInteger.prototype.bitwiseTo = bnpBitwiseTo; +BigInteger.prototype.changeBit = bnpChangeBit; +BigInteger.prototype.addTo = bnpAddTo; +BigInteger.prototype.dMultiply = bnpDMultiply; +BigInteger.prototype.dAddOffset = bnpDAddOffset; +BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; +BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; +BigInteger.prototype.modInt = bnpModInt; +BigInteger.prototype.millerRabin = bnpMillerRabin; + +// public +BigInteger.prototype.clone = bnClone; +BigInteger.prototype.intValue = bnIntValue; +BigInteger.prototype.byteValue = bnByteValue; +BigInteger.prototype.shortValue = bnShortValue; +BigInteger.prototype.signum = bnSigNum; +BigInteger.prototype.toByteArray = bnToByteArray; +BigInteger.prototype.equals = bnEquals; +BigInteger.prototype.min = bnMin; +BigInteger.prototype.max = bnMax; +BigInteger.prototype.and = bnAnd; +BigInteger.prototype.or = bnOr; +BigInteger.prototype.xor = bnXor; +BigInteger.prototype.andNot = bnAndNot; +BigInteger.prototype.not = bnNot; +BigInteger.prototype.shiftLeft = bnShiftLeft; +BigInteger.prototype.shiftRight = bnShiftRight; +BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; +BigInteger.prototype.bitCount = bnBitCount; +BigInteger.prototype.testBit = bnTestBit; +BigInteger.prototype.setBit = bnSetBit; +BigInteger.prototype.clearBit = bnClearBit; +BigInteger.prototype.flipBit = bnFlipBit; +BigInteger.prototype.add = bnAdd; +BigInteger.prototype.subtract = bnSubtract; +BigInteger.prototype.multiply = bnMultiply; +BigInteger.prototype.divide = bnDivide; +BigInteger.prototype.remainder = bnRemainder; +BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; +BigInteger.prototype.modPow = bnModPow; +BigInteger.prototype.modInverse = bnModInverse; +BigInteger.prototype.pow = bnPow; +BigInteger.prototype.gcd = bnGCD; +BigInteger.prototype.isProbablePrime = bnIsProbablePrime; + +// JSBN-specific extension +BigInteger.prototype.square = bnSquare; + +// BigInteger interfaces not implemented in jsbn: + +// BigInteger(int signum, byte[] magnitude) +// double doubleValue() +// float floatValue() +// int hashCode() +// long longValue() +// static BigInteger valueOf(long val) diff --git a/tool/java/Pailler/paillier/paillierKey.js b/tool/java/Paillier/paillier/paillierKey.js similarity index 97% rename from tool/java/Pailler/paillier/paillierKey.js rename to tool/java/Paillier/paillier/paillierKey.js index dc4f846182..ff0c90f83e 100644 --- a/tool/java/Pailler/paillier/paillierKey.js +++ b/tool/java/Paillier/paillier/paillierKey.js @@ -1,408 +1,408 @@ - -// convert a (hex) string to a bignum object -function parseBigInt(str,r) { - return new BigInteger(str,r); -} - -function _pem_extractEncodedData(sPEMString, sHead) { - var s = sPEMString; - s = s.replace("-----BEGIN " + sHead + "-----", ""); - s = s.replace("-----END " + sHead + "-----", ""); - s = s.replace(/[ \n]+/g, ""); - return s; -} - -function _pem_getPosArrayOfChildrenFromHex(hPrivateKey) { - var a = new Array(); - var v1 = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); - var n1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, v1); - var e1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, n1); - var d1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, e1); - var p1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, d1); - var q1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, p1); - var dp1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, q1); - var dq1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, dp1); - var co1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, dq1); - a.push(v1, n1, e1, d1, p1, q1, dp1, dq1, co1); - return a; -} - -function _pem_getHexValueArrayOfChildrenFromHex(hPrivateKey) { - var posArray = _pem_getPosArrayOfChildrenFromHex(hPrivateKey); - var v = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); - var n = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); - var e = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[2]); - var d = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[3]); - var p = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[4]); - var q = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[5]); - var dp = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[6]); - var dq = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[7]); - var co = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[8]); - var a = new Array(); - a.push(v, n, e, d, p, q, dp, dq, co); - return a; -} - -function _pem_getPosArrayOfChildrenFromPublicKeyHex(hPrivateKey) { - var a = new Array(); - var header = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); - var keys = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, header); - a.push(header, keys); - return a; -} - -function _pem_getPosArrayOfChildrenFromPrivateKeyHex(hPrivateKey) { - var a = new Array(); - var integer = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); - var header = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, integer); - var keys = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, header); - a.push(integer, header, keys); - return a; -} - -function _pem_getHexValueArrayOfChildrenFromPublicKeyHex(hPrivateKey) { - var posArray = _pem_getPosArrayOfChildrenFromPublicKeyHex(hPrivateKey); - var headerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); - var keysVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); - - var keysSequence = keysVal.substring(2); - posArray = _pem_getPosArrayOfChildrenFromPublicKeyHex(keysSequence); - var modulus = _asnhex_getHexOfV_AtObj(keysSequence, posArray[0]); - var publicExp = _asnhex_getHexOfV_AtObj(keysSequence, posArray[1]); - - var a = new Array(); - a.push(modulus, publicExp); - return a; -} - - -function _pem_getHexValueArrayOfChildrenFromPrivateKeyHex(hPrivateKey) { - var posArray = _pem_getPosArrayOfChildrenFromPrivateKeyHex(hPrivateKey); - var integerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); - var headerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); - var keysVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[2]); - - var keysSequence = keysVal.substring(2); - return _pem_getHexValueArrayOfChildrenFromHex(keysSequence); -} - -function _pem_readPrivateKeyFromPkcs1PemString(keyPEM) { - var keyB64 = _pem_extractEncodedData(keyPEM); - var keyHex = b64tohex(keyB64) // depends base64.js - var a = _pem_getHexValueArrayOfChildrenFromHex(keyHex); - this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]); -} - -function _pem_readPrivateKeyFromPkcs8PemString(keyPEM) { - var keyB64 = _pem_extractEncodedData(keyPEM); - var keyHex = b64tohex(keyB64) // depends base64.js - var a = _pem_getHexValueArrayOfChildrenFromPrivateKeyHex(keyHex); - this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]); -} - -function _pem_readPublicKeyFromX509PemString(keyPEM) { - var keyB64 = _pem_extractEncodedData(keyPEM); - var keyHex = b64tohex(keyB64) // depends base64.js - var a = _pem_getHexValueArrayOfChildrenFromPublicKeyHex(keyHex); - this.setPublic(a[0],a[1]); -} - -/** -* Pad string with leading zeros, to use even number of bytes. -*/ -function _pem_padWithZero(numString) { - if (numString.length % 2 == 1) { - return "0" + numString; - } - return numString; -} - -/** -* Encode length in DER format (if length <0x80, then one byte, else first byte is 0x80 + length of length :) + n-bytes of length). -*/ -function _pem_encodeLength(length) { - if (length >= parseInt("80", 16)) { - var realLength = _pem_padWithZero(length.toString(16)); - var lengthOfLength = (realLength.length / 2); - return (parseInt("80", 16) + lengthOfLength).toString(16) + realLength; - } else { - return _pem_padWithZero(length.toString(16)); - } -} - -/** -* Encode number in DER encoding ("02" + length + number). -*/ -function _pem_derEncodeNumber(number) { - var numberString = _pem_padWithZero(number.toString(16)); - if (numberString[0] > '7') { - numberString = "00" + numberString; - } - var lenString = _pem_encodeLength(numberString.length / 2); - return "02" + lenString + numberString; -} - -/** -* Converts private & public part of given key to ASN1 Hex String. -*/ -function _pem_privateKeyToPkcs1HexString(paillierKey) { - var result = _pem_derEncodeNumber(0); - result += _pem_derEncodeNumber(paillierKey.n); - result += _pem_derEncodeNumber(paillierKey.e); - result += _pem_derEncodeNumber(paillierKey.d); - result += _pem_derEncodeNumber(paillierKey.p); - result += _pem_derEncodeNumber(paillierKey.q); - result += _pem_derEncodeNumber(paillierKey.dmp1); - result += _pem_derEncodeNumber(paillierKey.dmq1); - result += _pem_derEncodeNumber(paillierKey.coeff); - - var fullLen = _pem_encodeLength(result.length / 2); - return '30' + fullLen + result; -} - -/** -* Converts private & public part of given key to PKCS#8 Hex String. -*/ -function _pem_privateKeyToPkcs8HexString(paillierKey) { - var zeroInteger = "020100"; - var encodedIdentifier = "06092A864886F70D010101"; - var encodedNull = "0500"; - var headerSequence = "300D" + encodedIdentifier + encodedNull; - var keySequence = _pem_privateKeyToPkcs1HexString(paillierKey); - - var keyOctetString = "04" + _pem_encodeLength(keySequence.length / 2) + keySequence; - - var mainSequence = zeroInteger + headerSequence + keyOctetString; - return "30" + _pem_encodeLength(mainSequence.length / 2) + mainSequence; -} - -/** -* Converts public part of given key to ASN1 Hex String. -*/ -function _pem_publicKeyToX509HexString(paillierKey) { - var encodedIdentifier = "06092A864886F70D010101"; - var encodedNull = "0500"; - var headerSequence = "300D" + encodedIdentifier + encodedNull; - - var keys = _pem_derEncodeNumber(paillierKey.n); - keys += _pem_derEncodeNumber(paillierKey.g); - - var keySequence = "0030" + _pem_encodeLength(keys.length / 2) + keys; - var bitstring = "03" + _pem_encodeLength(keySequence.length / 2) + keySequence; - - var mainSequence = headerSequence + bitstring; - - return "30" + _pem_encodeLength(mainSequence.length / 2) + mainSequence; -} - -/** -* Output private & public part of the key in PKCS#1 PEM format. -*/ -function _pem_privateKeyToPkcs1PemString() { - var b64Cert = hex2b64(_pem_privateKeyToPkcs1HexString(this)); - var s = "-----BEGIN PRIVATE KEY-----\n"; - s = s + _paillier_splitKey(b64Cert, 64); - s = s + "\n-----END PRIVATE KEY-----"; - return s; -} - -/** -* Output private & public part of the key in PKCS#8 PEM format. -*/ -function _pem_privateKeyToPkcs8PemString() { - var b64Cert = hex2b64(_pem_privateKeyToPkcs8HexString(this)); - var s = "-----BEGIN PRIVATE KEY-----\n"; - s = s + _paillier_splitKey(b64Cert, 64); - s = s + "\n-----END PRIVATE KEY-----"; - return s; -} - -/** -* Output public part of the key in x509 PKCS#1 PEM format. -*/ -function _pem_publicKeyToX509PemString() { - var b64Cert = hex2b64(_pem_publicKeyToX509HexString(this)); - var s = "-----BEGIN PUBLIC KEY-----\n"; - s = s + _paillier_splitKey(b64Cert, 64); - s = s + "\n-----END PUBLIC KEY-----"; - return s; -} - -function _paillier_splitKey(key, line) { - var splitKey = ""; - for (var i = 0; i < key.length; i++) { - if (i % line == 0 && i != 0 && i != (key.length - 1)) { - splitKey += "\n"; - } - splitKey += key[i]; - } - - return splitKey; -} - -function _paillier_setPublic(N,G) { - if(N != null && G != null && N.length > 0 && G.length > 0) { - this.n = parseBigInt(N,16); - this.g = parseBigInt(G,16); - } - else - alert("Invalid Paillier public key"); -} - -// Set the private key fields N, e, and d from hex strings -function _paillier_setPrivate(N,E,D) { - if(N != null && E != null && N.length > 0 && E.length > 0) { - this.n = parseBigInt(N,16); - this.e = parseInt(E,16); - this.d = parseBigInt(D,16); - } - else - alert("Invalid Paillier private key"); -} - -// Set the private key fields N, e, d and CRT params from hex strings -function _paillier_setPrivateEx(N,E,D,P,Q,DP,DQ,C) { - if(N != null && E != null && N.length > 0 && E.length > 0) { - this.n = parseBigInt(N,16); - this.e = parseInt(E,16); - this.d = parseBigInt(D,16); - this.p = parseBigInt(P,16); - this.q = parseBigInt(Q,16); - this.dmp1 = parseBigInt(DP,16); - this.dmq1 = parseBigInt(DQ,16); - this.coeff = parseBigInt(C,16); - } - else - alert("Invalid Paillier private key"); -} - -function _paillier_genKeyPair(B) { - var rng = new SecureRandom(); - var qs = B>>1; - for(;;) { - for(;;) { - this.p = new BigInteger(B-qs,1,rng); - if(this.p.isProbablePrime(64)) break; - } - for(;;) { - this.q = new BigInteger(qs,1,rng); - if(this.q.isProbablePrime(64)) break; - } - var p1 = this.p.subtract(BigInteger.ONE); - var q1 = this.q.subtract(BigInteger.ONE); - this.n = this.p.multiply(this.q); - if(this.n.bitLength() != B) continue; - var nsquare = this.n.multiply(this.n); - this.d = this.p.subtract(BigInteger.ONE).multiply(this.q.subtract(BigInteger.ONE)); - this.g = this.n.add(BigInteger.ONE); - if (this.g.modPow(this.d, nsquare).subtract(BigInteger.ONE).divide(this.n).gcd(this.n).intValue() == 1) { - this.dmp1 = this.d.mod(p1); - this.dmq1 = this.d.mod(q1); - this.coeff = this.q.modInverse(this.p); - break; - } - } -} - -function _paillier_padHex(s, n) { - var slen = s.length; - if(slen < n) { - for(var i = 0; i < n - slen; i++) { - s = "0" + s; - } - } - return s; -} - -function _paillier_encrypt(m) { - var rng = new SeededRandom(); - var random = null; - for (;;) - { - for (;;) - { - random = new BigInteger(this.n.bitLength(), 1, rng); - if (random.isProbablePrime(64)) break; - } - if(random.signum() == 1) break; - } - - if(m.signum() == -1) { - m = m.mod(this.n); - } - - var nsquare = this.n.multiply(this.n); - var cipher = this.g.modPow(m, nsquare).multiply(random.modPow(this.n, nsquare)).mod(nsquare); - var nstr = this.n.toString(16); - var nlen = Math.ceil(this.n.bitLength() / 8); - return _paillier_padHex(nlen.toString(16), 4) + nstr + _paillier_padHex(cipher.toString(16), nlen * 4); -} - -function _paillier_decrypt(ciphertext) { - var nlen = parseInt("0x" + c1.substr(0,4)) * 2; - var nstr = ciphertext.substr(4, nlen); - var cstr = ciphertext.substr(nlen + 4); - var n1 = parseBigInt(nstr, 16); - var intCiphertext = parseBigInt(cstr, 16); - if(n1.compareTo(this.n) != 0) return null; - - var mu = this.d.modInverse(this.n); - var nsquare = this.n.multiply(this.n); - var message = intCiphertext.modPow(this.d, nsquare).subtract(BigInteger.ONE).divide(this.n).multiply(mu).mod(this.n); - var maxValue = BigInteger.ONE.shiftLeft(this.n.bitLength() / 2); - if(message.bitLength() > this.n.bitLength() / 2) { - return message.subtract(this.n); - } - else { - return message; - } -} - -function _paillier_add(c1, c2) { - var nlen1 = parseInt("0x" + c1.substr(0,4)) * 2; - var nstr1 = c1.substr(4, nlen1); - var cstr1 = c1.substr(nlen1 + 4); - var nlen2 = parseInt("0x" + c2.substr(0,4)) * 2; - var nstr2 = c2.substr(4, nlen2); - var cstr2 = c2.substr(nlen2 + 4); - var n1 = parseBigInt(nstr1, 16); - var n2 = parseBigInt(nstr2, 16); - - if(n2.compareTo(n1) != 0) { - return null; - } - - var ct1 = parseBigInt(cstr1, 16); - var ct2 = parseBigInt(cstr2, 16); - var nsquare = n1.multiply(n1); - var ct = ct1.multiply(ct2).mod(nsquare); - return _paillier_padHex(nlen1.toString(16), 4) + nstr1 + _paillier_padHex(ct.toString(16), nlen1 * 2); -} - -function PaillierKey() { - this.n = null; - this.e = 0; - this.g = null; - this.d = null; - this.p = null; - this.q = null; - this.dmp1 = null; - this.dmq1 = null; - this.coeff = null; - -} - -PaillierKey.prototype.readPublicKeyFromX509PEMString = _pem_readPublicKeyFromX509PemString; -PaillierKey.prototype.publicKeyToX509PemString = _pem_publicKeyToX509PemString; -PaillierKey.prototype.readPrivateKeyFromPkcs1PemString = _pem_readPrivateKeyFromPkcs1PemString; -PaillierKey.prototype.privateKeyToPkcs1PemString = _pem_privateKeyToPkcs1PemString; -PaillierKey.prototype.readPrivateKeyFromPkcs8PemString = _pem_readPrivateKeyFromPkcs8PemString; -PaillierKey.prototype.privateKeyToPkcs8PemString = _pem_privateKeyToPkcs8PemString; -PaillierKey.prototype.setPublic = _paillier_setPublic; -PaillierKey.prototype.setPrivate = _paillier_setPrivate; -PaillierKey.prototype.setPrivateEx = _paillier_setPrivateEx; -PaillierKey.prototype.genKeyPair = _paillier_genKeyPair; -PaillierKey.prototype.encrypt = _paillier_encrypt; -PaillierKey.prototype.decrypt = _paillier_decrypt; -PaillierKey.prototype.add = _paillier_add; - + +// convert a (hex) string to a bignum object +function parseBigInt(str,r) { + return new BigInteger(str,r); +} + +function _pem_extractEncodedData(sPEMString, sHead) { + var s = sPEMString; + s = s.replace("-----BEGIN " + sHead + "-----", ""); + s = s.replace("-----END " + sHead + "-----", ""); + s = s.replace(/[ \n]+/g, ""); + return s; +} + +function _pem_getPosArrayOfChildrenFromHex(hPrivateKey) { + var a = new Array(); + var v1 = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); + var n1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, v1); + var e1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, n1); + var d1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, e1); + var p1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, d1); + var q1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, p1); + var dp1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, q1); + var dq1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, dp1); + var co1 = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, dq1); + a.push(v1, n1, e1, d1, p1, q1, dp1, dq1, co1); + return a; +} + +function _pem_getHexValueArrayOfChildrenFromHex(hPrivateKey) { + var posArray = _pem_getPosArrayOfChildrenFromHex(hPrivateKey); + var v = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); + var n = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); + var e = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[2]); + var d = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[3]); + var p = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[4]); + var q = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[5]); + var dp = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[6]); + var dq = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[7]); + var co = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[8]); + var a = new Array(); + a.push(v, n, e, d, p, q, dp, dq, co); + return a; +} + +function _pem_getPosArrayOfChildrenFromPublicKeyHex(hPrivateKey) { + var a = new Array(); + var header = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); + var keys = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, header); + a.push(header, keys); + return a; +} + +function _pem_getPosArrayOfChildrenFromPrivateKeyHex(hPrivateKey) { + var a = new Array(); + var integer = _asnhex_getStartPosOfV_AtObj(hPrivateKey, 0); + var header = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, integer); + var keys = _asnhex_getPosOfNextSibling_AtObj(hPrivateKey, header); + a.push(integer, header, keys); + return a; +} + +function _pem_getHexValueArrayOfChildrenFromPublicKeyHex(hPrivateKey) { + var posArray = _pem_getPosArrayOfChildrenFromPublicKeyHex(hPrivateKey); + var headerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); + var keysVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); + + var keysSequence = keysVal.substring(2); + posArray = _pem_getPosArrayOfChildrenFromPublicKeyHex(keysSequence); + var modulus = _asnhex_getHexOfV_AtObj(keysSequence, posArray[0]); + var publicExp = _asnhex_getHexOfV_AtObj(keysSequence, posArray[1]); + + var a = new Array(); + a.push(modulus, publicExp); + return a; +} + + +function _pem_getHexValueArrayOfChildrenFromPrivateKeyHex(hPrivateKey) { + var posArray = _pem_getPosArrayOfChildrenFromPrivateKeyHex(hPrivateKey); + var integerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[0]); + var headerVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[1]); + var keysVal = _asnhex_getHexOfV_AtObj(hPrivateKey, posArray[2]); + + var keysSequence = keysVal.substring(2); + return _pem_getHexValueArrayOfChildrenFromHex(keysSequence); +} + +function _pem_readPrivateKeyFromPkcs1PemString(keyPEM) { + var keyB64 = _pem_extractEncodedData(keyPEM); + var keyHex = b64tohex(keyB64) // depends base64.js + var a = _pem_getHexValueArrayOfChildrenFromHex(keyHex); + this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]); +} + +function _pem_readPrivateKeyFromPkcs8PemString(keyPEM) { + var keyB64 = _pem_extractEncodedData(keyPEM); + var keyHex = b64tohex(keyB64) // depends base64.js + var a = _pem_getHexValueArrayOfChildrenFromPrivateKeyHex(keyHex); + this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]); +} + +function _pem_readPublicKeyFromX509PemString(keyPEM) { + var keyB64 = _pem_extractEncodedData(keyPEM); + var keyHex = b64tohex(keyB64) // depends base64.js + var a = _pem_getHexValueArrayOfChildrenFromPublicKeyHex(keyHex); + this.setPublic(a[0],a[1]); +} + +/** +* Pad string with leading zeros, to use even number of bytes. +*/ +function _pem_padWithZero(numString) { + if (numString.length % 2 == 1) { + return "0" + numString; + } + return numString; +} + +/** +* Encode length in DER format (if length <0x80, then one byte, else first byte is 0x80 + length of length :) + n-bytes of length). +*/ +function _pem_encodeLength(length) { + if (length >= parseInt("80", 16)) { + var realLength = _pem_padWithZero(length.toString(16)); + var lengthOfLength = (realLength.length / 2); + return (parseInt("80", 16) + lengthOfLength).toString(16) + realLength; + } else { + return _pem_padWithZero(length.toString(16)); + } +} + +/** +* Encode number in DER encoding ("02" + length + number). +*/ +function _pem_derEncodeNumber(number) { + var numberString = _pem_padWithZero(number.toString(16)); + if (numberString[0] > '7') { + numberString = "00" + numberString; + } + var lenString = _pem_encodeLength(numberString.length / 2); + return "02" + lenString + numberString; +} + +/** +* Converts private & public part of given key to ASN1 Hex String. +*/ +function _pem_privateKeyToPkcs1HexString(paillierKey) { + var result = _pem_derEncodeNumber(0); + result += _pem_derEncodeNumber(paillierKey.n); + result += _pem_derEncodeNumber(paillierKey.e); + result += _pem_derEncodeNumber(paillierKey.d); + result += _pem_derEncodeNumber(paillierKey.p); + result += _pem_derEncodeNumber(paillierKey.q); + result += _pem_derEncodeNumber(paillierKey.dmp1); + result += _pem_derEncodeNumber(paillierKey.dmq1); + result += _pem_derEncodeNumber(paillierKey.coeff); + + var fullLen = _pem_encodeLength(result.length / 2); + return '30' + fullLen + result; +} + +/** +* Converts private & public part of given key to PKCS#8 Hex String. +*/ +function _pem_privateKeyToPkcs8HexString(paillierKey) { + var zeroInteger = "020100"; + var encodedIdentifier = "06092A864886F70D010101"; + var encodedNull = "0500"; + var headerSequence = "300D" + encodedIdentifier + encodedNull; + var keySequence = _pem_privateKeyToPkcs1HexString(paillierKey); + + var keyOctetString = "04" + _pem_encodeLength(keySequence.length / 2) + keySequence; + + var mainSequence = zeroInteger + headerSequence + keyOctetString; + return "30" + _pem_encodeLength(mainSequence.length / 2) + mainSequence; +} + +/** +* Converts public part of given key to ASN1 Hex String. +*/ +function _pem_publicKeyToX509HexString(paillierKey) { + var encodedIdentifier = "06092A864886F70D010101"; + var encodedNull = "0500"; + var headerSequence = "300D" + encodedIdentifier + encodedNull; + + var keys = _pem_derEncodeNumber(paillierKey.n); + keys += _pem_derEncodeNumber(paillierKey.g); + + var keySequence = "0030" + _pem_encodeLength(keys.length / 2) + keys; + var bitstring = "03" + _pem_encodeLength(keySequence.length / 2) + keySequence; + + var mainSequence = headerSequence + bitstring; + + return "30" + _pem_encodeLength(mainSequence.length / 2) + mainSequence; +} + +/** +* Output private & public part of the key in PKCS#1 PEM format. +*/ +function _pem_privateKeyToPkcs1PemString() { + var b64Cert = hex2b64(_pem_privateKeyToPkcs1HexString(this)); + var s = "-----BEGIN PRIVATE KEY-----\n"; + s = s + _paillier_splitKey(b64Cert, 64); + s = s + "\n-----END PRIVATE KEY-----"; + return s; +} + +/** +* Output private & public part of the key in PKCS#8 PEM format. +*/ +function _pem_privateKeyToPkcs8PemString() { + var b64Cert = hex2b64(_pem_privateKeyToPkcs8HexString(this)); + var s = "-----BEGIN PRIVATE KEY-----\n"; + s = s + _paillier_splitKey(b64Cert, 64); + s = s + "\n-----END PRIVATE KEY-----"; + return s; +} + +/** +* Output public part of the key in x509 PKCS#1 PEM format. +*/ +function _pem_publicKeyToX509PemString() { + var b64Cert = hex2b64(_pem_publicKeyToX509HexString(this)); + var s = "-----BEGIN PUBLIC KEY-----\n"; + s = s + _paillier_splitKey(b64Cert, 64); + s = s + "\n-----END PUBLIC KEY-----"; + return s; +} + +function _paillier_splitKey(key, line) { + var splitKey = ""; + for (var i = 0; i < key.length; i++) { + if (i % line == 0 && i != 0 && i != (key.length - 1)) { + splitKey += "\n"; + } + splitKey += key[i]; + } + + return splitKey; +} + +function _paillier_setPublic(N,G) { + if(N != null && G != null && N.length > 0 && G.length > 0) { + this.n = parseBigInt(N,16); + this.g = parseBigInt(G,16); + } + else + alert("Invalid Paillier public key"); +} + +// Set the private key fields N, e, and d from hex strings +function _paillier_setPrivate(N,E,D) { + if(N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N,16); + this.e = parseInt(E,16); + this.d = parseBigInt(D,16); + } + else + alert("Invalid Paillier private key"); +} + +// Set the private key fields N, e, d and CRT params from hex strings +function _paillier_setPrivateEx(N,E,D,P,Q,DP,DQ,C) { + if(N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N,16); + this.e = parseInt(E,16); + this.d = parseBigInt(D,16); + this.p = parseBigInt(P,16); + this.q = parseBigInt(Q,16); + this.dmp1 = parseBigInt(DP,16); + this.dmq1 = parseBigInt(DQ,16); + this.coeff = parseBigInt(C,16); + } + else + alert("Invalid Paillier private key"); +} + +function _paillier_genKeyPair(B) { + var rng = new SecureRandom(); + var qs = B>>1; + for(;;) { + for(;;) { + this.p = new BigInteger(B-qs,1,rng); + if(this.p.isProbablePrime(64)) break; + } + for(;;) { + this.q = new BigInteger(qs,1,rng); + if(this.q.isProbablePrime(64)) break; + } + var p1 = this.p.subtract(BigInteger.ONE); + var q1 = this.q.subtract(BigInteger.ONE); + this.n = this.p.multiply(this.q); + if(this.n.bitLength() != B) continue; + var nsquare = this.n.multiply(this.n); + this.d = this.p.subtract(BigInteger.ONE).multiply(this.q.subtract(BigInteger.ONE)); + this.g = this.n.add(BigInteger.ONE); + if (this.g.modPow(this.d, nsquare).subtract(BigInteger.ONE).divide(this.n).gcd(this.n).intValue() == 1) { + this.dmp1 = this.d.mod(p1); + this.dmq1 = this.d.mod(q1); + this.coeff = this.q.modInverse(this.p); + break; + } + } +} + +function _paillier_padHex(s, n) { + var slen = s.length; + if(slen < n) { + for(var i = 0; i < n - slen; i++) { + s = "0" + s; + } + } + return s; +} + +function _paillier_encrypt(m) { + var rng = new SeededRandom(); + var random = null; + for (;;) + { + for (;;) + { + random = new BigInteger(this.n.bitLength(), 1, rng); + if (random.isProbablePrime(64)) break; + } + if(random.signum() == 1) break; + } + + if(m.signum() == -1) { + m = m.mod(this.n); + } + + var nsquare = this.n.multiply(this.n); + var cipher = this.g.modPow(m, nsquare).multiply(random.modPow(this.n, nsquare)).mod(nsquare); + var nstr = this.n.toString(16); + var nlen = Math.ceil(this.n.bitLength() / 8); + return _paillier_padHex(nlen.toString(16), 4) + nstr + _paillier_padHex(cipher.toString(16), nlen * 4); +} + +function _paillier_decrypt(ciphertext) { + var nlen = parseInt("0x" + c1.substr(0,4)) * 2; + var nstr = ciphertext.substr(4, nlen); + var cstr = ciphertext.substr(nlen + 4); + var n1 = parseBigInt(nstr, 16); + var intCiphertext = parseBigInt(cstr, 16); + if(n1.compareTo(this.n) != 0) return null; + + var mu = this.d.modInverse(this.n); + var nsquare = this.n.multiply(this.n); + var message = intCiphertext.modPow(this.d, nsquare).subtract(BigInteger.ONE).divide(this.n).multiply(mu).mod(this.n); + var maxValue = BigInteger.ONE.shiftLeft(this.n.bitLength() / 2); + if(message.bitLength() > this.n.bitLength() / 2) { + return message.subtract(this.n); + } + else { + return message; + } +} + +function _paillier_add(c1, c2) { + var nlen1 = parseInt("0x" + c1.substr(0,4)) * 2; + var nstr1 = c1.substr(4, nlen1); + var cstr1 = c1.substr(nlen1 + 4); + var nlen2 = parseInt("0x" + c2.substr(0,4)) * 2; + var nstr2 = c2.substr(4, nlen2); + var cstr2 = c2.substr(nlen2 + 4); + var n1 = parseBigInt(nstr1, 16); + var n2 = parseBigInt(nstr2, 16); + + if(n2.compareTo(n1) != 0) { + return null; + } + + var ct1 = parseBigInt(cstr1, 16); + var ct2 = parseBigInt(cstr2, 16); + var nsquare = n1.multiply(n1); + var ct = ct1.multiply(ct2).mod(nsquare); + return _paillier_padHex(nlen1.toString(16), 4) + nstr1 + _paillier_padHex(ct.toString(16), nlen1 * 2); +} + +function PaillierKey() { + this.n = null; + this.e = 0; + this.g = null; + this.d = null; + this.p = null; + this.q = null; + this.dmp1 = null; + this.dmq1 = null; + this.coeff = null; + +} + +PaillierKey.prototype.readPublicKeyFromX509PEMString = _pem_readPublicKeyFromX509PemString; +PaillierKey.prototype.publicKeyToX509PemString = _pem_publicKeyToX509PemString; +PaillierKey.prototype.readPrivateKeyFromPkcs1PemString = _pem_readPrivateKeyFromPkcs1PemString; +PaillierKey.prototype.privateKeyToPkcs1PemString = _pem_privateKeyToPkcs1PemString; +PaillierKey.prototype.readPrivateKeyFromPkcs8PemString = _pem_readPrivateKeyFromPkcs8PemString; +PaillierKey.prototype.privateKeyToPkcs8PemString = _pem_privateKeyToPkcs8PemString; +PaillierKey.prototype.setPublic = _paillier_setPublic; +PaillierKey.prototype.setPrivate = _paillier_setPrivate; +PaillierKey.prototype.setPrivateEx = _paillier_setPrivateEx; +PaillierKey.prototype.genKeyPair = _paillier_genKeyPair; +PaillierKey.prototype.encrypt = _paillier_encrypt; +PaillierKey.prototype.decrypt = _paillier_decrypt; +PaillierKey.prototype.add = _paillier_add; + diff --git a/tool/java/Pailler/paillier/seedrandom.js b/tool/java/Paillier/paillier/seedrandom.js similarity index 97% rename from tool/java/Pailler/paillier/seedrandom.js rename to tool/java/Paillier/paillier/seedrandom.js index 7beacdb4c0..ffaa4dcd00 100644 --- a/tool/java/Pailler/paillier/seedrandom.js +++ b/tool/java/Paillier/paillier/seedrandom.js @@ -1,442 +1,442 @@ -// seedrandom.js version 2.0. -// Author: David Bau 4/2/2011 -// -// Defines a method Math.seedrandom() that, when called, substitutes -// an explicitly seeded RC4-based algorithm for Math.random(). Also -// supports automatic seeding from local or network sources of entropy. -// -// Usage: -// -// -// -// Math.seedrandom('yipee'); Sets Math.random to a function that is -// initialized using the given explicit seed. -// -// Math.seedrandom(); Sets Math.random to a function that is -// seeded using the current time, dom state, -// and other accumulated local entropy. -// The generated seed string is returned. -// -// Math.seedrandom('yowza', true); -// Seeds using the given explicit seed mixed -// together with accumulated entropy. -// -// -// Seeds using physical random bits downloaded -// from random.org. -// -// Seeds using urandom bits from call.jsonlib.com, -// which is faster than random.org. -// -// Examples: -// -// Math.seedrandom("hello"); // Use "hello" as the seed. -// document.write(Math.random()); // Always 0.5463663768140734 -// document.write(Math.random()); // Always 0.43973793770592234 -// var rng1 = Math.random; // Remember the current prng. -// -// var autoseed = Math.seedrandom(); // New prng with an automatic seed. -// document.write(Math.random()); // Pretty much unpredictable. -// -// Math.random = rng1; // Continue "hello" prng sequence. -// document.write(Math.random()); // Always 0.554769432473455 -// -// Math.seedrandom(autoseed); // Restart at the previous seed. -// document.write(Math.random()); // Repeat the 'unpredictable' value. -// -// Notes: -// -// Each time seedrandom('arg') is called, entropy from the passed seed -// is accumulated in a pool to help generate future seeds for the -// zero-argument form of Math.seedrandom, so entropy can be injected over -// time by calling seedrandom with explicit data repeatedly. -// -// On speed - This javascript implementation of Math.random() is about -// 3-10x slower than the built-in Math.random() because it is not native -// code, but this is typically fast enough anyway. Seeding is more expensive, -// especially if you use auto-seeding. Some details (timings on Chrome 4): -// -// Our Math.random() - avg less than 0.002 milliseconds per call -// seedrandom('explicit') - avg less than 0.5 milliseconds per call -// seedrandom('explicit', true) - avg less than 2 milliseconds per call -// seedrandom() - avg about 38 milliseconds per call -// -// LICENSE (BSD): -// -// Copyright 2010 David Bau, all rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of this module nor the names of its contributors may -// be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/** - * All code is in an anonymous closure to keep the global namespace clean. - * - * @param {number=} overflow - * @param {number=} startdenom - */ -(function (pool, math, width, chunks, significance, overflow, startdenom) -{ - - - // - // seedrandom() - // This is the seedrandom function described above. - // - math['seedrandom'] = function seedrandom(seed, use_entropy) - { - var key = []; - var arc4; - - // Flatten the seed string or build one from local entropy if needed. - seed = mixkey(flatten( - use_entropy ? [seed, pool] : arguments.length ? seed : [new Date().getTime(), pool, window], 3), key); - - // Use the seed to initialize an ARC4 generator. - arc4 = new ARC4(key); - - // Mix the randomness into accumulated entropy. - mixkey(arc4.S, pool); - - // Override Math.random - // This function returns a random double in [0, 1) that contains - // randomness in every bit of the mantissa of the IEEE 754 value. - math['random'] = function random() - { // Closure to return a random double: - var n = arc4.g(chunks); // Start with a numerator n < 2 ^ 48 - var d = startdenom; // and denominator d = 2 ^ 48. - var x = 0; // and no 'extra last byte'. - while (n < significance) - { // Fill up all significant digits by - n = (n + x) * width; // shifting numerator and - d *= width; // denominator and generating a - x = arc4.g(1); // new least-significant-byte. - } - while (n >= overflow) - { // To avoid rounding up, before adding - n /= 2; // last byte, shift everything - d /= 2; // right using integer math until - x >>>= 1; // we have exactly the desired bits. - } - return (n + x) / d; // Form the number within [0, 1). - }; - - // Return the seed that was used - return seed; - }; - - // - // ARC4 - // - // An ARC4 implementation. The constructor takes a key in the form of - // an array of at most (width) integers that should be 0 <= x < (width). - // - // The g(count) method returns a pseudorandom integer that concatenates - // the next (count) outputs from ARC4. Its return value is a number x - // that is in the range 0 <= x < (width ^ count). - // - /** @constructor */ - - function ARC4(key) - { - var t, u, me = this, - keylen = key.length; - var i = 0, - j = me.i = me.j = me.m = 0; - me.S = []; - me.c = []; - - // The empty key [] is treated as [0]. - if (!keylen) - { - key = [keylen++]; - } - - // Set up S using the standard key scheduling algorithm. - while (i < width) - { - me.S[i] = i++; - } - for (i = 0; i < width; i++) - { - t = me.S[i]; - j = lowbits(j + t + key[i % keylen]); - u = me.S[j]; - me.S[i] = u; - me.S[j] = t; - } - - // The "g" method returns the next (count) outputs as one number. - me.g = function getnext(count) - { - var s = me.S; - var i = lowbits(me.i + 1); - var t = s[i]; - var j = lowbits(me.j + t); - var u = s[j]; - s[i] = u; - s[j] = t; - var r = s[lowbits(t + u)]; - while (--count) - { - i = lowbits(i + 1); - t = s[i]; - j = lowbits(j + t); - u = s[j]; - s[i] = u; - s[j] = t; - r = r * width + s[lowbits(t + u)]; - } - me.i = i; - me.j = j; - return r; - }; - // For robust unpredictability discard an initial batch of values. - // See http://www.rsa.com/rsalabs/node.asp?id=2009 - me.g(width); - } - - // - // flatten() - // Converts an object tree to nested arrays of strings. - // - /** @param {Object=} result - * @param {string=} prop - * @param {string=} typ */ - - function flatten(obj, depth, result, prop, typ) - { - result = []; - typ = typeof (obj); - if (depth && typ == 'object') - { - for (prop in obj) - { - if (prop.indexOf('S') < 5) - { // Avoid FF3 bug (local/sessionStorage) - try - { - result.push(flatten(obj[prop], depth - 1)); - } - catch (e) - {} - } - } - } - return (result.length ? result : obj + (typ != 'string' ? '\0' : '')); - } - - // - // mixkey() - // Mixes a string seed into a key that is an array of integers, and - // returns a shortened string seed that is equivalent to the result key. - // - /** @param {number=} smear - * @param {number=} j */ - - function mixkey(seed, key, smear, j) - { - seed += ''; // Ensure the seed is a string - smear = 0; - for (j = 0; j < seed.length; j++) - { - key[lowbits(j)] = lowbits((smear ^= key[lowbits(j)] * 19) + seed.charCodeAt(j)); - } - seed = ''; - for (j in key) - { - seed += String.fromCharCode(key[j]); - } - return seed; - } - - // - // lowbits() - // A quick "n mod width" for width a power of 2. - // - - - function lowbits(n) - { - return n & (width - 1); - } - - // - // The following constants are related to IEEE 754 limits. - // - startdenom = math.pow(width, chunks); - significance = math.pow(2, significance); - overflow = significance * 2; - - // - // When seedrandom.js is loaded, we immediately mix a few bits - // from the built-in RNG into the entropy pool. Because we do - // not want to intefere with determinstic PRNG state later, - // seedrandom will not call math.random on its own again after - // initialization. - // - mixkey(math.random(), pool); - - // End anonymous scope, and pass initial values. -})([], // pool: entropy pool starts empty -Math, // math: package containing random, pow, and seedrandom -256, // width: each RC4 output is 0 <= x < 256 -6, // chunks: at least six RC4 outputs for each double -52 // significance: there are 52 significant digits in a double -); - - -// This is not really a random number generator object, and two SeededRandom -// objects will conflict with one another, but it's good enough for generating -// the rsa key. -function SeededRandom(){} - -function SRnextBytes(ba) -{ - var i; - for(i = 0; i < ba.length; i++) - { - ba[i] = Math.floor(Math.random() * 256); - } -} - -SeededRandom.prototype.nextBytes = SRnextBytes; - -// prng4.js - uses Arcfour as a PRNG - -function Arcfour() { - this.i = 0; - this.j = 0; - this.S = new Array(); -} - -// Initialize arcfour context from key, an array of ints, each from [0..255] -function ARC4init(key) { - var i, j, t; - for(i = 0; i < 256; ++i) - this.S[i] = i; - j = 0; - for(i = 0; i < 256; ++i) { - j = (j + this.S[i] + key[i % key.length]) & 255; - t = this.S[i]; - this.S[i] = this.S[j]; - this.S[j] = t; - } - this.i = 0; - this.j = 0; -} - -function ARC4next() { - var t; - this.i = (this.i + 1) & 255; - this.j = (this.j + this.S[this.i]) & 255; - t = this.S[this.i]; - this.S[this.i] = this.S[this.j]; - this.S[this.j] = t; - return this.S[(t + this.S[this.i]) & 255]; -} - -Arcfour.prototype.init = ARC4init; -Arcfour.prototype.next = ARC4next; - -// Plug in your RNG constructor here -function prng_newstate() { - return new Arcfour(); -} - -// Pool size must be a multiple of 4 and greater than 32. -// An array of bytes the size of the pool will be passed to init() -var rng_psize = 256; - -// Random number generator - requires a PRNG backend, e.g. prng4.js - -// For best results, put code like -// -// in your main HTML document. - -var rng_state; -var rng_pool; -var rng_pptr; - -// Mix in a 32-bit integer into the pool -function rng_seed_int(x) { - rng_pool[rng_pptr++] ^= x & 255; - rng_pool[rng_pptr++] ^= (x >> 8) & 255; - rng_pool[rng_pptr++] ^= (x >> 16) & 255; - rng_pool[rng_pptr++] ^= (x >> 24) & 255; - if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; -} - -// Mix in the current time (w/milliseconds) into the pool -function rng_seed_time() { - rng_seed_int(new Date().getTime()); -} - -// Initialize the pool with junk if needed. -if(rng_pool == null) { - rng_pool = new Array(); - rng_pptr = 0; - var t; - if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { - // Extract entropy (256 bits) from NS4 RNG if available - var z = window.crypto.random(32); - for(t = 0; t < z.length; ++t) - rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; - } - while(rng_pptr < rng_psize) { // extract some randomness from Math.random() - t = Math.floor(65536 * Math.random()); - rng_pool[rng_pptr++] = t >>> 8; - rng_pool[rng_pptr++] = t & 255; - } - rng_pptr = 0; - rng_seed_time(); - //rng_seed_int(window.screenX); - //rng_seed_int(window.screenY); -} - -function rng_get_byte() { - if(rng_state == null) { - rng_seed_time(); - rng_state = prng_newstate(); - rng_state.init(rng_pool); - for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) - rng_pool[rng_pptr] = 0; - rng_pptr = 0; - //rng_pool = null; - } - // TODO: allow reseeding after first request - return rng_state.next(); -} - -function rng_get_bytes(ba) { - var i; - for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); -} - -function SecureRandom() {} - -SecureRandom.prototype.nextBytes = rng_get_bytes; - +// seedrandom.js version 2.0. +// Author: David Bau 4/2/2011 +// +// Defines a method Math.seedrandom() that, when called, substitutes +// an explicitly seeded RC4-based algorithm for Math.random(). Also +// supports automatic seeding from local or network sources of entropy. +// +// Usage: +// +// +// +// Math.seedrandom('yipee'); Sets Math.random to a function that is +// initialized using the given explicit seed. +// +// Math.seedrandom(); Sets Math.random to a function that is +// seeded using the current time, dom state, +// and other accumulated local entropy. +// The generated seed string is returned. +// +// Math.seedrandom('yowza', true); +// Seeds using the given explicit seed mixed +// together with accumulated entropy. +// +// +// Seeds using physical random bits downloaded +// from random.org. +// +// Seeds using urandom bits from call.jsonlib.com, +// which is faster than random.org. +// +// Examples: +// +// Math.seedrandom("hello"); // Use "hello" as the seed. +// document.write(Math.random()); // Always 0.5463663768140734 +// document.write(Math.random()); // Always 0.43973793770592234 +// var rng1 = Math.random; // Remember the current prng. +// +// var autoseed = Math.seedrandom(); // New prng with an automatic seed. +// document.write(Math.random()); // Pretty much unpredictable. +// +// Math.random = rng1; // Continue "hello" prng sequence. +// document.write(Math.random()); // Always 0.554769432473455 +// +// Math.seedrandom(autoseed); // Restart at the previous seed. +// document.write(Math.random()); // Repeat the 'unpredictable' value. +// +// Notes: +// +// Each time seedrandom('arg') is called, entropy from the passed seed +// is accumulated in a pool to help generate future seeds for the +// zero-argument form of Math.seedrandom, so entropy can be injected over +// time by calling seedrandom with explicit data repeatedly. +// +// On speed - This javascript implementation of Math.random() is about +// 3-10x slower than the built-in Math.random() because it is not native +// code, but this is typically fast enough anyway. Seeding is more expensive, +// especially if you use auto-seeding. Some details (timings on Chrome 4): +// +// Our Math.random() - avg less than 0.002 milliseconds per call +// seedrandom('explicit') - avg less than 0.5 milliseconds per call +// seedrandom('explicit', true) - avg less than 2 milliseconds per call +// seedrandom() - avg about 38 milliseconds per call +// +// LICENSE (BSD): +// +// Copyright 2010 David Bau, all rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of this module nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/** + * All code is in an anonymous closure to keep the global namespace clean. + * + * @param {number=} overflow + * @param {number=} startdenom + */ +(function (pool, math, width, chunks, significance, overflow, startdenom) +{ + + + // + // seedrandom() + // This is the seedrandom function described above. + // + math['seedrandom'] = function seedrandom(seed, use_entropy) + { + var key = []; + var arc4; + + // Flatten the seed string or build one from local entropy if needed. + seed = mixkey(flatten( + use_entropy ? [seed, pool] : arguments.length ? seed : [new Date().getTime(), pool, window], 3), key); + + // Use the seed to initialize an ARC4 generator. + arc4 = new ARC4(key); + + // Mix the randomness into accumulated entropy. + mixkey(arc4.S, pool); + + // Override Math.random + // This function returns a random double in [0, 1) that contains + // randomness in every bit of the mantissa of the IEEE 754 value. + math['random'] = function random() + { // Closure to return a random double: + var n = arc4.g(chunks); // Start with a numerator n < 2 ^ 48 + var d = startdenom; // and denominator d = 2 ^ 48. + var x = 0; // and no 'extra last byte'. + while (n < significance) + { // Fill up all significant digits by + n = (n + x) * width; // shifting numerator and + d *= width; // denominator and generating a + x = arc4.g(1); // new least-significant-byte. + } + while (n >= overflow) + { // To avoid rounding up, before adding + n /= 2; // last byte, shift everything + d /= 2; // right using integer math until + x >>>= 1; // we have exactly the desired bits. + } + return (n + x) / d; // Form the number within [0, 1). + }; + + // Return the seed that was used + return seed; + }; + + // + // ARC4 + // + // An ARC4 implementation. The constructor takes a key in the form of + // an array of at most (width) integers that should be 0 <= x < (width). + // + // The g(count) method returns a pseudorandom integer that concatenates + // the next (count) outputs from ARC4. Its return value is a number x + // that is in the range 0 <= x < (width ^ count). + // + /** @constructor */ + + function ARC4(key) + { + var t, u, me = this, + keylen = key.length; + var i = 0, + j = me.i = me.j = me.m = 0; + me.S = []; + me.c = []; + + // The empty key [] is treated as [0]. + if (!keylen) + { + key = [keylen++]; + } + + // Set up S using the standard key scheduling algorithm. + while (i < width) + { + me.S[i] = i++; + } + for (i = 0; i < width; i++) + { + t = me.S[i]; + j = lowbits(j + t + key[i % keylen]); + u = me.S[j]; + me.S[i] = u; + me.S[j] = t; + } + + // The "g" method returns the next (count) outputs as one number. + me.g = function getnext(count) + { + var s = me.S; + var i = lowbits(me.i + 1); + var t = s[i]; + var j = lowbits(me.j + t); + var u = s[j]; + s[i] = u; + s[j] = t; + var r = s[lowbits(t + u)]; + while (--count) + { + i = lowbits(i + 1); + t = s[i]; + j = lowbits(j + t); + u = s[j]; + s[i] = u; + s[j] = t; + r = r * width + s[lowbits(t + u)]; + } + me.i = i; + me.j = j; + return r; + }; + // For robust unpredictability discard an initial batch of values. + // See http://www.rsa.com/rsalabs/node.asp?id=2009 + me.g(width); + } + + // + // flatten() + // Converts an object tree to nested arrays of strings. + // + /** @param {Object=} result + * @param {string=} prop + * @param {string=} typ */ + + function flatten(obj, depth, result, prop, typ) + { + result = []; + typ = typeof (obj); + if (depth && typ == 'object') + { + for (prop in obj) + { + if (prop.indexOf('S') < 5) + { // Avoid FF3 bug (local/sessionStorage) + try + { + result.push(flatten(obj[prop], depth - 1)); + } + catch (e) + {} + } + } + } + return (result.length ? result : obj + (typ != 'string' ? '\0' : '')); + } + + // + // mixkey() + // Mixes a string seed into a key that is an array of integers, and + // returns a shortened string seed that is equivalent to the result key. + // + /** @param {number=} smear + * @param {number=} j */ + + function mixkey(seed, key, smear, j) + { + seed += ''; // Ensure the seed is a string + smear = 0; + for (j = 0; j < seed.length; j++) + { + key[lowbits(j)] = lowbits((smear ^= key[lowbits(j)] * 19) + seed.charCodeAt(j)); + } + seed = ''; + for (j in key) + { + seed += String.fromCharCode(key[j]); + } + return seed; + } + + // + // lowbits() + // A quick "n mod width" for width a power of 2. + // + + + function lowbits(n) + { + return n & (width - 1); + } + + // + // The following constants are related to IEEE 754 limits. + // + startdenom = math.pow(width, chunks); + significance = math.pow(2, significance); + overflow = significance * 2; + + // + // When seedrandom.js is loaded, we immediately mix a few bits + // from the built-in RNG into the entropy pool. Because we do + // not want to intefere with determinstic PRNG state later, + // seedrandom will not call math.random on its own again after + // initialization. + // + mixkey(math.random(), pool); + + // End anonymous scope, and pass initial values. +})([], // pool: entropy pool starts empty +Math, // math: package containing random, pow, and seedrandom +256, // width: each RC4 output is 0 <= x < 256 +6, // chunks: at least six RC4 outputs for each double +52 // significance: there are 52 significant digits in a double +); + + +// This is not really a random number generator object, and two SeededRandom +// objects will conflict with one another, but it's good enough for generating +// the rsa key. +function SeededRandom(){} + +function SRnextBytes(ba) +{ + var i; + for(i = 0; i < ba.length; i++) + { + ba[i] = Math.floor(Math.random() * 256); + } +} + +SeededRandom.prototype.nextBytes = SRnextBytes; + +// prng4.js - uses Arcfour as a PRNG + +function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); +} + +// Initialize arcfour context from key, an array of ints, each from [0..255] +function ARC4init(key) { + var i, j, t; + for(i = 0; i < 256; ++i) + this.S[i] = i; + j = 0; + for(i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; +} + +function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; +} + +Arcfour.prototype.init = ARC4init; +Arcfour.prototype.next = ARC4next; + +// Plug in your RNG constructor here +function prng_newstate() { + return new Arcfour(); +} + +// Pool size must be a multiple of 4 and greater than 32. +// An array of bytes the size of the pool will be passed to init() +var rng_psize = 256; + +// Random number generator - requires a PRNG backend, e.g. prng4.js + +// For best results, put code like +// +// in your main HTML document. + +var rng_state; +var rng_pool; +var rng_pptr; + +// Mix in a 32-bit integer into the pool +function rng_seed_int(x) { + rng_pool[rng_pptr++] ^= x & 255; + rng_pool[rng_pptr++] ^= (x >> 8) & 255; + rng_pool[rng_pptr++] ^= (x >> 16) & 255; + rng_pool[rng_pptr++] ^= (x >> 24) & 255; + if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; +} + +// Mix in the current time (w/milliseconds) into the pool +function rng_seed_time() { + rng_seed_int(new Date().getTime()); +} + +// Initialize the pool with junk if needed. +if(rng_pool == null) { + rng_pool = new Array(); + rng_pptr = 0; + var t; + if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { + // Extract entropy (256 bits) from NS4 RNG if available + var z = window.crypto.random(32); + for(t = 0; t < z.length; ++t) + rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; + } + while(rng_pptr < rng_psize) { // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + rng_pool[rng_pptr++] = t >>> 8; + rng_pool[rng_pptr++] = t & 255; + } + rng_pptr = 0; + rng_seed_time(); + //rng_seed_int(window.screenX); + //rng_seed_int(window.screenY); +} + +function rng_get_byte() { + if(rng_state == null) { + rng_seed_time(); + rng_state = prng_newstate(); + rng_state.init(rng_pool); + for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) + rng_pool[rng_pptr] = 0; + rng_pptr = 0; + //rng_pool = null; + } + // TODO: allow reseeding after first request + return rng_state.next(); +} + +function rng_get_bytes(ba) { + var i; + for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); +} + +function SecureRandom() {} + +SecureRandom.prototype.nextBytes = rng_get_bytes; + diff --git a/tool/java/Pailler/paillier/test.html b/tool/java/Paillier/paillier/test.html similarity index 97% rename from tool/java/Pailler/paillier/test.html rename to tool/java/Paillier/paillier/test.html index be5d9aeed4..cf72b2f78e 100644 --- a/tool/java/Pailler/paillier/test.html +++ b/tool/java/Paillier/paillier/test.html @@ -1,49 +1,49 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/tool/java/Pailler/src/paillier/CommonUtils.java b/tool/java/Paillier/src/paillier/CommonUtils.java similarity index 96% rename from tool/java/Pailler/src/paillier/CommonUtils.java rename to tool/java/Paillier/src/paillier/CommonUtils.java index c7a9218a35..d8200fb1ac 100644 --- a/tool/java/Pailler/src/paillier/CommonUtils.java +++ b/tool/java/Paillier/src/paillier/CommonUtils.java @@ -1,110 +1,110 @@ -package paillier; - -import java.math.BigInteger; - -public class CommonUtils { - public CommonUtils() { - } - - public static byte[] intToByte4(int i) { - byte[] targets = new byte[4]; - targets[3] = (byte) (i & 0xFF); - targets[2] = (byte) (i >> 8 & 0xFF); - targets[1] = (byte) (i >> 16 & 0xFF); - targets[0] = (byte) (i >> 24 & 0xFF); - return targets; - } - - public static byte[] longToByte8(long lo) { - byte[] targets = new byte[8]; - for (int i = 0; i < 8; i++) { - int offset = (targets.length - 1 - i) * 8; - targets[i] = (byte) ((lo >>> offset) & 0xFF); - } - return targets; - } - - public static byte[] unsignedShortToByte2(int s) { - byte[] targets = new byte[2]; - targets[0] = (byte) (s >> 8 & 0xFF); - targets[1] = (byte) (s & 0xFF); - return targets; - } - - public static int byte2ToUnsignedShort(byte[] bytes) { - return byte2ToUnsignedShort(bytes, 0); - } - - public static int byte2ToUnsignedShort(byte[] bytes, int off) { - int high = bytes[off]; - int low = bytes[off + 1]; - return (high << 8 & 0xFF00) | (low & 0xFF); - } - - public static int byte4ToInt(byte[] bytes, int off) { - int b0 = bytes[off] & 0xFF; - int b1 = bytes[off + 1] & 0xFF; - int b2 = bytes[off + 2] & 0xFF; - int b3 = bytes[off + 3] & 0xFF; - return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; - } - - public static byte[] asUnsignedByteArray(BigInteger paramBigInteger) { - byte[] arrayOfByte1 = paramBigInteger.toByteArray(); - if (arrayOfByte1[0] == 0) { - byte[] arrayOfByte2 = new byte[arrayOfByte1.length - 1]; - System.arraycopy(arrayOfByte1, 1, arrayOfByte2, 0, arrayOfByte2.length); - return arrayOfByte2; - } - return arrayOfByte1; - } - - public static byte[] asUnsignedByteArray(BigInteger paramBigInteger, int byteLength) { - byte[] arrayOfByte1 = asUnsignedByteArray(paramBigInteger); - if(arrayOfByte1.length < byteLength) { - byte[] arrayOfByte2 = new byte[byteLength]; - int offset = byteLength - arrayOfByte1.length; - for(int i=0; i> 8 & 0xFF); + targets[1] = (byte) (i >> 16 & 0xFF); + targets[0] = (byte) (i >> 24 & 0xFF); + return targets; + } + + public static byte[] longToByte8(long lo) { + byte[] targets = new byte[8]; + for (int i = 0; i < 8; i++) { + int offset = (targets.length - 1 - i) * 8; + targets[i] = (byte) ((lo >>> offset) & 0xFF); + } + return targets; + } + + public static byte[] unsignedShortToByte2(int s) { + byte[] targets = new byte[2]; + targets[0] = (byte) (s >> 8 & 0xFF); + targets[1] = (byte) (s & 0xFF); + return targets; + } + + public static int byte2ToUnsignedShort(byte[] bytes) { + return byte2ToUnsignedShort(bytes, 0); + } + + public static int byte2ToUnsignedShort(byte[] bytes, int off) { + int high = bytes[off]; + int low = bytes[off + 1]; + return (high << 8 & 0xFF00) | (low & 0xFF); + } + + public static int byte4ToInt(byte[] bytes, int off) { + int b0 = bytes[off] & 0xFF; + int b1 = bytes[off + 1] & 0xFF; + int b2 = bytes[off + 2] & 0xFF; + int b3 = bytes[off + 3] & 0xFF; + return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; + } + + public static byte[] asUnsignedByteArray(BigInteger paramBigInteger) { + byte[] arrayOfByte1 = paramBigInteger.toByteArray(); + if (arrayOfByte1[0] == 0) { + byte[] arrayOfByte2 = new byte[arrayOfByte1.length - 1]; + System.arraycopy(arrayOfByte1, 1, arrayOfByte2, 0, arrayOfByte2.length); + return arrayOfByte2; + } + return arrayOfByte1; + } + + public static byte[] asUnsignedByteArray(BigInteger paramBigInteger, int byteLength) { + byte[] arrayOfByte1 = asUnsignedByteArray(paramBigInteger); + if(arrayOfByte1.length < byteLength) { + byte[] arrayOfByte2 = new byte[byteLength]; + int offset = byteLength - arrayOfByte1.length; + for(int i=0; i Date: Fri, 4 Aug 2017 11:44:28 +0800 Subject: [PATCH 2/3] full modify the pailler to paillier --- CMakeLists.txt | 2 +- libevm/VMExtends.cpp | 2 +- libpaillier/{pailler.c => paillier.c} | 100 +++++++++++++------------- libpaillier/{pailler.h => paillier.h} | 40 +++++------ 4 files changed, 72 insertions(+), 72 deletions(-) rename libpaillier/{pailler.c => paillier.c} (96%) rename libpaillier/{pailler.h => paillier.h} (93%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 08cc4d6c3a..48cf731fe9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,7 +63,7 @@ add_subdirectory(libcontract) add_subdirectory(libsinglepoint) add_subdirectory(libpbftseal) add_subdirectory(libraftseal) -add_subdirectory(libpailler) +add_subdirectory(libpaillier) add_subdirectory(libethcore) add_subdirectory(libethereum) add_subdirectory(libevm) diff --git a/libevm/VMExtends.cpp b/libevm/VMExtends.cpp index 57cdf1d47b..0e7ae346d7 100644 --- a/libevm/VMExtends.cpp +++ b/libevm/VMExtends.cpp @@ -6,7 +6,7 @@ #include #include "VMExtends.h" #include -#include "pailler.h" +#include "paillier.h" using namespace std; using namespace dev; diff --git a/libpaillier/pailler.c b/libpaillier/paillier.c similarity index 96% rename from libpaillier/pailler.c rename to libpaillier/paillier.c index 594ca6a8db..0a831051f8 100644 --- a/libpaillier/pailler.c +++ b/libpaillier/paillier.c @@ -1,51 +1,51 @@ -#include "pailler.h" - -void PAI_HomAdd(U8 *pbBN_Result, U8 *pbBN_c1, U8 *pbBN_c2, U8 *pbBN_n, S32 iBNWordLen) -{ - /****************************/ - U32 BN_N2[BNMAXWordLen]; - U32 BN_N[BNMAXWordLen]; - U32 BN_R[BNMAXWordLen]; - U32 BN_R2[BNMAXWordLen]; - U32 BN_C1[BNMAXWordLen]; - U32 BN_C2[BNMAXWordLen]; - U32 BN_C3[BNMAXWordLen]; - U32 BN_One[BNMAXWordLen]; - U32 wModuleConst = 0; - - U8 bBN_T[8*BNMAXWordLen] = {0}; - S32 i = 0; - S32 len = 0; - /****************************/ - - BN_Reset(BN_N2, BNMAXWordLen); - BN_Reset(BN_N, BNMAXWordLen); - BN_Reset(BN_R, BNMAXWordLen); - BN_Reset(BN_R2, BNMAXWordLen); - BN_Reset(BN_C1, BNMAXWordLen); - BN_Reset(BN_C2, BNMAXWordLen); - BN_Reset(BN_C3, BNMAXWordLen); - BN_Reset(BN_One, BNMAXWordLen); - BN_One[0] = LSBOfWord; - - ByteToBN(pbBN_n, 4*iBNWordLen, BN_N, iBNWordLen); - ByteToBN(pbBN_c1, 8*iBNWordLen, BN_C1, 2*iBNWordLen); - ByteToBN(pbBN_c2, 8*iBNWordLen, BN_C2, 2*iBNWordLen); - - //n^2 - BN_Mul(BN_N2, BN_N, BN_N, iBNWordLen); - - wModuleConst = BN_GetMontConst(BN_N2[0], 32); - BN_GetR(BN_R, BN_N2, 2*iBNWordLen); - - BN_GetR2(BN_R2, BN_R, BN_N2, wModuleConst, 2*iBNWordLen, LogPaiBN2BitLen); - BN_GetLastRes(BN_R2, BN_N2, 2*iBNWordLen); - - BN_ModMul_Mont(BN_C1, BN_C1, BN_R2, BN_N2, wModuleConst, 2*iBNWordLen); - BN_ModMul_Mont(BN_C2, BN_C2, BN_R2, BN_N2, wModuleConst, 2*iBNWordLen); - BN_ModMul_Mont(BN_C3, BN_C1, BN_C2, BN_N2, wModuleConst, 2*iBNWordLen); - BN_ModMul_Mont(BN_C3, BN_C3, BN_One, BN_N2, wModuleConst, 2*iBNWordLen); - BN_GetLastRes(BN_C3, BN_N2, 2*iBNWordLen); - - BNToByte(BN_C3, 2*iBNWordLen, pbBN_Result, &len); +#include "pailler.h" + +void PAI_HomAdd(U8 *pbBN_Result, U8 *pbBN_c1, U8 *pbBN_c2, U8 *pbBN_n, S32 iBNWordLen) +{ + /****************************/ + U32 BN_N2[BNMAXWordLen]; + U32 BN_N[BNMAXWordLen]; + U32 BN_R[BNMAXWordLen]; + U32 BN_R2[BNMAXWordLen]; + U32 BN_C1[BNMAXWordLen]; + U32 BN_C2[BNMAXWordLen]; + U32 BN_C3[BNMAXWordLen]; + U32 BN_One[BNMAXWordLen]; + U32 wModuleConst = 0; + + U8 bBN_T[8*BNMAXWordLen] = {0}; + S32 i = 0; + S32 len = 0; + /****************************/ + + BN_Reset(BN_N2, BNMAXWordLen); + BN_Reset(BN_N, BNMAXWordLen); + BN_Reset(BN_R, BNMAXWordLen); + BN_Reset(BN_R2, BNMAXWordLen); + BN_Reset(BN_C1, BNMAXWordLen); + BN_Reset(BN_C2, BNMAXWordLen); + BN_Reset(BN_C3, BNMAXWordLen); + BN_Reset(BN_One, BNMAXWordLen); + BN_One[0] = LSBOfWord; + + ByteToBN(pbBN_n, 4*iBNWordLen, BN_N, iBNWordLen); + ByteToBN(pbBN_c1, 8*iBNWordLen, BN_C1, 2*iBNWordLen); + ByteToBN(pbBN_c2, 8*iBNWordLen, BN_C2, 2*iBNWordLen); + + //n^2 + BN_Mul(BN_N2, BN_N, BN_N, iBNWordLen); + + wModuleConst = BN_GetMontConst(BN_N2[0], 32); + BN_GetR(BN_R, BN_N2, 2*iBNWordLen); + + BN_GetR2(BN_R2, BN_R, BN_N2, wModuleConst, 2*iBNWordLen, LogPaiBN2BitLen); + BN_GetLastRes(BN_R2, BN_N2, 2*iBNWordLen); + + BN_ModMul_Mont(BN_C1, BN_C1, BN_R2, BN_N2, wModuleConst, 2*iBNWordLen); + BN_ModMul_Mont(BN_C2, BN_C2, BN_R2, BN_N2, wModuleConst, 2*iBNWordLen); + BN_ModMul_Mont(BN_C3, BN_C1, BN_C2, BN_N2, wModuleConst, 2*iBNWordLen); + BN_ModMul_Mont(BN_C3, BN_C3, BN_One, BN_N2, wModuleConst, 2*iBNWordLen); + BN_GetLastRes(BN_C3, BN_N2, 2*iBNWordLen); + + BNToByte(BN_C3, 2*iBNWordLen, pbBN_Result, &len); } \ No newline at end of file diff --git a/libpaillier/pailler.h b/libpaillier/paillier.h similarity index 93% rename from libpaillier/pailler.h rename to libpaillier/paillier.h index 8bd70b7ec2..d82a748d0c 100644 --- a/libpaillier/pailler.h +++ b/libpaillier/paillier.h @@ -1,20 +1,20 @@ -#ifndef __HEADER_PAILLER_H__ -#define __HEADER_PAILLER_H__ - -#include "bn.h" -#include "common.h" -#include "macro.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void PAI_HomAdd(U8 *pbBN_Result, U8 *pbBN_c1, U8 *pbBN_c2, U8 *pbBN_n, S32 iBNWordLen); - -#ifdef __cplusplus -} -#endif - - -#endif - +#ifndef __HEADER_PAILLER_H__ +#define __HEADER_PAILLER_H__ + +#include "bn.h" +#include "common.h" +#include "macro.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void PAI_HomAdd(U8 *pbBN_Result, U8 *pbBN_c1, U8 *pbBN_c2, U8 *pbBN_n, S32 iBNWordLen); + +#ifdef __cplusplus +} +#endif + + +#endif + From 7ec0db2692f3895fb41a759e314cdd8b6c90d426 Mon Sep 17 00:00:00 2001 From: ancjf Date: Fri, 4 Aug 2017 14:37:12 +0800 Subject: [PATCH 3/3] 1. revise cmakelist 2. paillier adapt to right one --- libevm/CMakeLists.txt | 2 +- libpaillier/paillier.c | 2 +- tool/LibInt.sol | 224 +++++++++ tool/LibPaillier.sol | 39 ++ tool/LibString.sol | 885 ++++++++++++++++++++++++++++++++++ tool/demoTestPaillie.js | 34 +- tool/java/Paillier/.gitignore | 1 + 7 files changed, 1162 insertions(+), 25 deletions(-) create mode 100644 tool/LibInt.sol create mode 100644 tool/LibPaillier.sol create mode 100644 tool/LibString.sol create mode 100644 tool/java/Paillier/.gitignore diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt index cc4692a36d..4d0b771eb0 100644 --- a/libevm/CMakeLists.txt +++ b/libevm/CMakeLists.txt @@ -33,7 +33,7 @@ include_directories(../libodbc/include ../libodbc/include/sqllite ../libodbc/include/ss_linux ../libodbc/include/sybase - ../libpailler) + ../libpaillier) target_link_libraries(evm ${Eth_ETHCORE_LIBRARIES}) diff --git a/libpaillier/paillier.c b/libpaillier/paillier.c index 0a831051f8..b24f9f605a 100644 --- a/libpaillier/paillier.c +++ b/libpaillier/paillier.c @@ -1,4 +1,4 @@ -#include "pailler.h" +#include "paillier.h" void PAI_HomAdd(U8 *pbBN_Result, U8 *pbBN_c1, U8 *pbBN_c2, U8 *pbBN_n, S32 iBNWordLen) { diff --git a/tool/LibInt.sol b/tool/LibInt.sol new file mode 100644 index 0000000000..00c91b1549 --- /dev/null +++ b/tool/LibInt.sol @@ -0,0 +1,224 @@ +/** +* file LibInt.sol +* author liaoyan +* time 2016-11-29 +* desc the defination of LibInt libary +*/ + +pragma solidity ^0.4.2; + +library LibInt { + using LibInt for *; + + function toString(uint _self) internal returns (string _ret) { + if (_self == 0) { + return "0"; + } + + uint8 len = 0; + uint tmp = _self; + while (tmp > 0) { + tmp /= 10; + len++; + } + + _ret = new string(len); + + uint8 i = len-1; + while (_self > 0) { + bytes(_ret)[i--] = byte(_self%10+0x30); + _self /= 10; + } + } + + function toHexString(uint _self) internal returns (string _ret) { + if (_self == 0) { + return "0x0"; + } + + uint8 len = 2; + uint tmp = _self; + while (tmp > 0) { + tmp /= 16; + len++; + } + + _ret = new string(len); + + uint8 i = len-1; + while (_self > 0) { + if (_self%16 > 9) { + bytes(_ret)[i--] = byte(_self%16+0x61-0xa); + } else { + bytes(_ret)[i--] = byte(_self%16+0x30); + } + + _self /= 16; + } + + bytes(_ret)[0] = byte(0x30); + bytes(_ret)[1] = byte(0x78); + } + + function toHexString64(uint _self) internal returns (string _ret) { + _ret = new string(66); + bytes(_ret)[0] = '0'; + bytes(_ret)[1] = 'x'; + + for (uint8 i=65; i>=2; --i) { + uint8 digit = uint8(_self&0x0F); + _self /= 16; + + if (digit < 10) + bytes(_ret)[i] = byte(digit+0x30); + else + bytes(_ret)[i] = byte(digit-10+0x61); + } + } + + function toString(int _self) internal returns (string _ret) { + if (_self == 0) { + return "0"; + } + + uint ui = uint(_self); + bool positive = true; + uint8 len = 0; + if (_self < 0) { + ui = uint(-_self); + positive = false; + len++; + } + + uint tmp = ui; + while (tmp > 0) { + tmp /= 10; + len++; + } + + _ret = new string(len); + if (!positive) { + bytes(_ret)[0] = '-'; + } + + uint8 i = len-1; + while (ui > 0) { + bytes(_ret)[i--] = byte(ui%10+0x30); + ui /= 10; + } + } + + function toAddrString(uint _self) internal returns (string _ret) { + _ret = new string(42); + bytes(_ret)[0] = '0'; + bytes(_ret)[1] = 'x'; + + for (uint8 i=41; i>=2; --i) { + uint8 digit = uint8(_self&0x0F); + _self /= 16; + + if (digit < 10) + bytes(_ret)[i] = byte(digit+0x30); + else + bytes(_ret)[i] = byte(digit-10+0x61); + } + } + + function toKeyValue(uint _self, string _key) internal returns (string _ret) { + uint len = bytes(_key).length+3; + + if (_self == 0) { + len += 1; + } else { + uint tmp = _self; + while (tmp > 0) { + tmp /= 10; + len++; + } + } + + _ret = new string(len); + + uint i = 0; + bytes(_ret)[i++] = '"'; + for (uint j=0; j < bytes(_key).length; j++) { + bytes(_ret)[i++] = bytes(_key)[j]; + } + bytes(_ret)[i++] = '"'; + + bytes(_ret)[i++] = ':'; + + i = len-1; + if (_self == 0) { + bytes(_ret)[i] = byte(0x30); + } else { + while (_self > 0) { + bytes(_ret)[i--] = byte(_self%10+0x30); + _self /= 10; + } + } + } + + function toKeyValue(int _self, string _key) internal returns (string _ret) { + uint ui = uint(_self); + bool positive = true; + uint len = bytes(_key).length+3; + if (_self < 0) { + ui = uint(-_self); + positive = false; + len++; + } + + if (_self == 0) { + len += 1; + } else { + uint tmp = ui; + while (tmp > 0) { + tmp /= 10; + len++; + } + } + + _ret = new string(len); + + uint i = 0; + bytes(_ret)[i++] = '"'; + for (uint j=0; j < bytes(_key).length; j++) { + bytes(_ret)[i++] = bytes(_key)[j]; + } + bytes(_ret)[i++] = '"'; + + bytes(_ret)[i++] = ':'; + + if (!positive) { + bytes(_ret)[i++] = '-'; + } + i = len-1; + if (_self == 0) { + bytes(_ret)[i] = byte(0x30); + } else { + while (ui > 0) { + bytes(_ret)[i--] = byte(ui%10+0x30); + ui /= 10; + } + } + } + + function recoveryToString(uint _self) internal returns (string _ret) { + uint tmp = _self; + uint len = 0; + while (tmp > 0) { + tmp /= 256; + len++; + } + + _ret = new string(len); + tmp = _self; + uint i = len-1; + while (tmp > 0) { + bytes(_ret)[i] = byte(tmp%256); + tmp /= 256; + i--; + } + } +} \ No newline at end of file diff --git a/tool/LibPaillier.sol b/tool/LibPaillier.sol new file mode 100644 index 0000000000..a76c3504de --- /dev/null +++ b/tool/LibPaillier.sol @@ -0,0 +1,39 @@ +pragma solidity ^0.4.2; + +import "LibString.sol"; +import "LibInt.sol"; + +library LibPaillier { + using LibString for *; + using LibInt for *; + + function pai_add(string d1, string d2) internal constant returns (string) { + string memory cmd = "[69d98d6a04c41b4605aacb7bd2f74bee][08paillier]"; + cmd = cmd.concat("|", d1); + cmd = cmd.concat("|", d2); + + uint rLen = bytes(d1).length; + string memory result = new string(rLen); + + uint strptr; + assembly { + strptr := add(result, 0x20) + } + cmd = cmd.concat("|", strptr.toString()); + + bytes32 hash; + uint strlen = bytes(cmd).length; + assembly { + strptr := add(cmd, 0x20) + hash := sha3(strptr, strlen) + } + + string memory errRet = ""; + uint ret = uint(hash); + if (ret != 0) { + return errRet; + } + + return result; + } +} diff --git a/tool/LibString.sol b/tool/LibString.sol new file mode 100644 index 0000000000..d85a37c34c --- /dev/null +++ b/tool/LibString.sol @@ -0,0 +1,885 @@ +/** +* file LibString.sol +* author liaoyan +* time 2016-11-29 +* desc the defination of LibString contract +*/ + +pragma solidity ^0.4.2; + +library LibString { + + using LibString for *; + + function memcpy(uint dest, uint src, uint len) private { + // Copy word-length chunks while possible + for(; len >= 32; len -= 32) { + assembly { + mstore(dest, mload(src)) + } + dest += 32; + src += 32; + } + + // Copy remaining bytes + uint mask = 256 ** (32 - len) - 1; + assembly { + let srcpart := and(mload(src), not(mask)) + let destpart := and(mload(dest), mask) + mstore(dest, or(destpart, srcpart)) + } + } + + // Returns the memory address of the first byte of the first occurrence of + // `needle` in `self`, or the first byte after `self` if not found. + function findPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private returns (uint) { + uint ptr; + uint idx; + + if (needlelen <= selflen) { + if (needlelen <= 32) { + // Optimized assembly for 68 gas per byte on short strings + assembly { + let mask := not(sub(exp(2, mul(8, sub(32, needlelen))), 1)) + let needledata := and(mload(needleptr), mask) + let end := add(selfptr, sub(selflen, needlelen)) + ptr := selfptr + loop: + jumpi(exit, eq(and(mload(ptr), mask), needledata)) + ptr := add(ptr, 1) + jumpi(loop, lt(sub(ptr, 1), end)) + ptr := add(selfptr, selflen) + exit: + } + return ptr; + } else { + // For long needles, use hashing + bytes32 hash; + assembly { hash := sha3(needleptr, needlelen) } + ptr = selfptr; + for (idx = 0; idx <= selflen - needlelen; idx++) { + bytes32 testHash; + assembly { testHash := sha3(ptr, needlelen) } + if (hash == testHash) + return ptr; + ptr += 1; + } + } + } + return selfptr + selflen; + } + + /* + function length(string _self) internal returns (uint _ret) { + _ret = bytes(_self).length; + } + */ + + function compare(string _self, string _str) internal returns (int8 _ret) { + for (uint i=0; i bytes(_str)[i]) { + return 1; + } else if (bytes(_self)[i] < bytes(_str)[i]) { + return -1; + } + } + + if (bytes(_self).length > bytes(_str).length) { + return 1; + } if (bytes(_self).length < bytes(_str).length) { + return -1; + } else { + return 0; + } + } + + function compareNoCase(string _self, string _str) internal returns (int8 _ret) { + for (uint i=0; i= 'a' && ch1 <='z' && ch2 >= 'a' && ch2 <='z') { + if (ch1 > ch2) { + return 1; + } else if (ch1 < ch2) { + return -1; + } + } else { + if (bytes(_self)[i] > bytes(_str)[i]) { + return 1; + } else if (bytes(_self)[i] < bytes(_str)[i]) { + return -1; + } + } + } + + if (bytes(_self).length > bytes(_str).length) { + return 1; + } if (bytes(_self).length < bytes(_str).length) { + return -1; + } else { + return 0; + } + } + + function equals(string _self, string _str) internal returns (bool _ret) { + if (bytes(_self).length != bytes(_str).length) { + return false; + } + + for (uint i=0; i= 'a' && ch1 <='z' && ch2 >= 'a' && ch2 <='z') { + if (ch1 != ch2) { + return false; + } + } else { + if (bytes(_self)[i] != bytes(_str)[i]) { + return false; + } + } + } + + return true; + } + + function substr(string _self, uint _start, uint _len) internal returns (string _ret) { + if (_len > bytes(_self).length-_start) { + _len = bytes(_self).length-_start; + } + + if (_len <= 0) { + _ret = ""; + return; + } + + _ret = new string(_len); + + uint selfptr; + uint retptr; + assembly { + selfptr := add(_self, 0x20) + retptr := add(_ret, 0x20) + } + + memcpy(retptr, selfptr+_start, _len); + } + + function concat(string _self, string _str) internal returns (string _ret) { + _ret = new string(bytes(_self).length + bytes(_str).length); + + uint selfptr; + uint strptr; + uint retptr; + assembly { + selfptr := add(_self, 0x20) + strptr := add(_str, 0x20) + retptr := add(_ret, 0x20) + } + + memcpy(retptr, selfptr, bytes(_self).length); + memcpy(retptr+bytes(_self).length, strptr, bytes(_str).length); + } + + function concat(string _self, string _str1, string _str2) + internal returns (string _ret) { + _ret = new string(bytes(_self).length + bytes(_str1).length + bytes(_str2).length); + + uint selfptr; + uint str1ptr; + uint str2ptr; + uint retptr; + assembly { + selfptr := add(_self, 0x20) + str1ptr := add(_str1, 0x20) + str2ptr := add(_str2, 0x20) + retptr := add(_ret, 0x20) + } + + uint pos = 0; + memcpy(retptr+pos, selfptr, bytes(_self).length); + pos += bytes(_self).length; + memcpy(retptr+pos, str1ptr, bytes(_str1).length); + pos += bytes(_str1).length; + memcpy(retptr+pos, str2ptr, bytes(_str2).length); + pos += bytes(_str2).length; + } + + function concat(string _self, string _str1, string _str2, string _str3) + internal returns (string _ret) { + _ret = new string(bytes(_self).length + bytes(_str1).length + bytes(_str2).length + + bytes(_str3).length); + + uint selfptr; + uint str1ptr; + uint str2ptr; + uint str3ptr; + uint retptr; + assembly { + selfptr := add(_self, 0x20) + str1ptr := add(_str1, 0x20) + str2ptr := add(_str2, 0x20) + str3ptr := add(_str3, 0x20) + retptr := add(_ret, 0x20) + } + + uint pos = 0; + memcpy(retptr+pos, selfptr, bytes(_self).length); + pos += bytes(_self).length; + memcpy(retptr+pos, str1ptr, bytes(_str1).length); + pos += bytes(_str1).length; + memcpy(retptr+pos, str2ptr, bytes(_str2).length); + pos += bytes(_str2).length; + memcpy(retptr+pos, str3ptr, bytes(_str3).length); + pos += bytes(_str3).length; + } + + function trim(string _self) internal returns (string _ret) { + uint i; + uint8 ch; + for (i=0; i0; --i) { + ch = uint8(bytes(_self)[i-1]); + if (!(ch == 0x20 || ch == 0x09 || ch == 0x0D || ch == 0x0A)) { + break; + } + } + uint end = i; + + _ret = new string(end-start); + + uint selfptr; + uint retptr; + assembly { + selfptr := add(_self, 0x20) + retptr := add(_ret, 0x20) + } + + memcpy(retptr, selfptr+start, end-start); + } + + function trim(string _self, string _chars) internal returns (string _ret) { + uint16 i; + uint16 j; + bool matched; + for (i=0; i0; --i) { + matched = false; + for (j=0; j 0) { + ptr = findPtr(bytes(_self).length-pos, selfptr+pos, bytes(_delim).length, delimptr) - selfptr; + + if (ptr < bytes(_self).length) { + found = true; + } else { + ptr = bytes(_self).length; + } + } else { + ptr = bytes(_self).length; + } + + string memory elem = new string(ptr-pos); + uint elemptr; + assembly { + elemptr := add(elem, 0x20) + } + memcpy(elemptr, selfptr+pos, ptr-pos); + pos = ptr + bytes(_delim).length; + _array.push(elem); + + if (!found) { + break; + } + } + } + + function indexOf(string _self, string _str) internal returns (int _ret) { + uint selfptr; + uint strptr; + assembly { + selfptr := add(_self, 0x20) + strptr := add(_str, 0x20) + } + + uint ptr = findPtr(bytes(_self).length, selfptr, bytes(_str).length, strptr) - selfptr; + if (ptr < bytes(_self).length) { + _ret = int(ptr); + } else { + _ret = -1; + } + } + + function indexOf(string _self, string _str, uint pos) internal returns (int _ret) { + uint selfptr; + uint strptr; + assembly { + selfptr := add(_self, 0x20) + strptr := add(_str, 0x20) + } + + uint ptr = findPtr(bytes(_self).length-pos, selfptr+pos, bytes(_str).length, strptr) - selfptr; + if (ptr < bytes(_self).length) { + _ret = int(ptr); + } else { + _ret = -1; + } + } + + function toInt(string _self) internal returns (int _ret) { + _ret = 0; + if (bytes(_self).length == 0) { + return; + } + + uint16 i; + uint8 digit; + for (i=0; i= 0x30 && digit <= 0x39)) { + return; + } + _ret = _ret*10 + int(digit-0x30); + } + + if (!positive) { + _ret = -_ret; + } + } + + function toAddress(string _self) internal returns (address _ret) { + uint16 i; + uint8 digit; + for (i=0; i= 0x30 && digit <= 0x39) //'0'-'9' + digit -= 0x30; + else if (digit|0x20 >= 0x61 && digit|0x20 <= 0x66) //'a'-'f' + digit = digit-0x61+10; + else + return address(0); + + addr = addr*16+digit; + } + + return address(addr); + } + + function toKeyValue(string _self, string _key) internal returns (string _ret) { + _ret = new string(bytes(_self).length + bytes(_key).length + 5); + + uint selfptr; + uint keyptr; + uint retptr; + assembly { + selfptr := add(_self, 0x20) + keyptr := add(_key, 0x20) + retptr := add(_ret, 0x20) + } + + uint pos = 0; + + bytes(_ret)[pos++] = '"'; + memcpy(retptr+pos, keyptr, bytes(_key).length); + pos += bytes(_key).length; + bytes(_ret)[pos++] = '"'; + + bytes(_ret)[pos++] = ':'; + + bytes(_ret)[pos++] = '"'; + memcpy(retptr+pos, selfptr, bytes(_self).length); + pos += bytes(_self).length; + bytes(_ret)[pos++] = '"'; + } + + function toKeyValue(string[] storage _self, string _key) internal returns (string _ret) { + uint len = bytes(_key).length+5; + for (uint i=0; i<_self.length; ++i) { + if (i < _self.length-1) + len += bytes(_self[i]).length+3; + else + len += bytes(_self[i]).length+2; + } + + _ret = new string(len); + + uint pos = 0; + + bytes(_ret)[pos++] = '"'; + for (uint j=0; j= 0x30 && digit <= 0x39)) { + if (!positive) { + _ret = -_ret; + } + return; + } + _ret = _ret*10 + int(digit-0x30); + } + + if (!positive) { + _ret = -_ret; + } + } + + function getArrayValueByKey(string _self, string _key) internal returns (string _ret) { + int pos = -1; + uint searchStart = 0; + while (true) { + pos = _self.indexOf("\"".concat(_key, "\""), searchStart); + if (pos == -1) { + pos = _self.indexOf("'".concat(_key, "'"), searchStart); + if (pos == -1) { + return; + } + } + + pos += int(bytes(_key).length+2); + + bool colon = false; + while (uint(pos) < bytes(_self).length) { + if (bytes(_self)[uint(pos)] == ' ' || bytes(_self)[uint(pos)] == '\t' + || bytes(_self)[uint(pos)] == '\r' || bytes(_self)[uint(pos)] == '\n') { + pos++; + } else if (bytes(_self)[uint(pos)] == ':') { + pos++; + colon = true; + break; + } else { + break; + } + } + + if(uint(pos) == bytes(_self).length) { + return; + } + + if (colon) { + break; + } else { + searchStart = uint(pos); + } + } + + int start = _self.indexOf("[", uint(pos)); + if (start == -1) { + return; + } + start += 1; + + int end = _self.indexOf("]", uint(pos)); + if (end == -1) { + return; + } + + _ret = _self.substr(uint(start), uint(end-start)); + } + + function getArrayValueByKey(string _self, string _key, string[] storage _array) internal { + //Why can not use delete _array? + for (uint i=0; i<_array.length; ++i) { + delete _array[i]; + } + _array.length = 0; + + int pos = -1; + uint searchStart = 0; + while (true) { + pos = _self.indexOf("\"".concat(_key, "\""), searchStart); + if (pos == -1) { + pos = _self.indexOf("'".concat(_key, "'"), searchStart); + if (pos == -1) { + return; + } + } + + pos += int(bytes(_key).length+2); + + bool colon = false; + while (uint(pos) < bytes(_self).length) { + if (bytes(_self)[uint(pos)] == ' ' || bytes(_self)[uint(pos)] == '\t' + || bytes(_self)[uint(pos)] == '\r' || bytes(_self)[uint(pos)] == '\n') { + pos++; + } else if (bytes(_self)[uint(pos)] == ':') { + pos++; + colon = true; + break; + } else { + break; + } + } + + if(uint(pos) == bytes(_self).length) { + return; + } + + if (colon) { + break; + } else { + searchStart = uint(pos); + } + } + + int start = _self.indexOf("[", uint(pos)); + if (start == -1) { + return; + } + start += 1; + + int end = _self.indexOf("]", uint(pos)); + if (end == -1) { + return; + } + + string memory vals = _self.substr(uint(start), uint(end-start)).trim(" \t\r\n"); + + if (bytes(vals).length == 0) { + return; + } + + vals.split(",", _array); + + for (i=0; i<_array.length; ++i) { + _array[i] = _array[i].trim(" \t\r\n"); + _array[i] = _array[i].trim("'\""); + } + } + + function keyExists(string _self, string _key) internal returns (bool _ret) { + int pos = _self.indexOf("\"".concat(_key, "\"")); + if (pos == -1) { + pos = _self.indexOf("'".concat(_key, "'")); + if (pos == -1) { + return false; + } + } + + return true; + } + + function storageToUint(string _self) internal returns (uint _ret) { + uint len = bytes(_self).length; + if (len > 32) { + len = 32; + } + + _ret = 0; + for(uint i=0; i= 'a' && bytes(_self)[i] <= 'z') { + bytes(_self)[i] &= ~0x20; + } + } + + _ret = _self; + } + + function toLower(string _self) internal returns (string _ret) { + for (uint i=0; i= 'A' && bytes(_self)[i] <= 'Z') { + bytes(_self)[i] |= 0x20; + } + } + + _ret = _self; + } + } \ No newline at end of file diff --git a/tool/demoTestPaillie.js b/tool/demoTestPaillie.js index ba1a8e3752..62a1572dde 100644 --- a/tool/demoTestPaillie.js +++ b/tool/demoTestPaillie.js @@ -18,8 +18,6 @@ console.log(config); var filename="TestPaillier"; var address=fs.readFileSync(config.Ouputpath+filename+'.address','utf-8'); var abi=JSON.parse(fs.readFileSync(config.Ouputpath/*+filename+".sol:"*/+filename+'.abi', 'utf-8')); -var paillierjson = fs.readFileSync('./java/Pailler/paillier.json', 'utf-8'); -var paillie=JSON.parse(fs.readFileSync('./java/Pailler/paillier.json', 'utf-8')); var contract = web3.eth.contract(abi); var instance = contract.at(address); @@ -37,27 +35,17 @@ async function sleep(timeout) { var testsucceed = 0; var testerr = 0; - - for(var key in paillie){ - //console.log("test begin paillie = ", paillie[key]); - - var c1 = paillie[key].c1; - var c2 = paillie[key].c2; - var c3 = paillie[key].c3; - - var o1 = paillie[key].o1; - var o2 = paillie[key].o2; - var o3 = paillie[key].o3; + + var c1 = "0080B3659E936164926935376D4AA81FE1A8101B4A657EFF158C5215F3F85530D1906A4449546ABB8A6B4BA628DC5A4D0F5C3BFECE19ED4AA39C2CC8F7590F5755C186C80E26882BB7BEE4917CB2559F6C64747EBD592DEEA9195E2A5E9C5A7BD4A76FBC4432FE87EE1A6092B12B16F3AD2EE0C9269886FF72161A6DE0C2A0FC86194336F5AB1896A2A52388B2A11B21F6D877822E540997E4728C74594240760C0FD0F0EC22B6B52810CF7DB5F7B0416211451A497F5118FB7F72CA5CADA1FE15A67D8A14D8D5564244C62CF94C56874F0CC3210E75E0B2A543BDC02A8AE776D29FF005BC0774C0E103B5CE79E2D7C2CC9ABBA31A4938A0A490356F357DD7328AE924B957D16B8A2C1A43A0AB5E63C85BD345F822D0DB60F64A8505767F306FCBF5D52E49DA5174EEAAD983F447F1CDB3378DE9D3301804C4BD2C3B298B332CD45A59150311214000712472585C5D2CC266CFDFBFD7F3203948F8C36F3570EAAA53310840A45AA781DCF1156235111A0DC774660DE0F1C2CE396F4B0E14CFFBD0F3"; + var c2 = "0080B3659E936164926935376D4AA81FE1A8101B4A657EFF158C5215F3F85530D1906A4449546ABB8A6B4BA628DC5A4D0F5C3BFECE19ED4AA39C2CC8F7590F5755C186C80E26882BB7BEE4917CB2559F6C64747EBD592DEEA9195E2A5E9C5A7BD4A76FBC4432FE87EE1A6092B12B16F3AD2EE0C9269886FF72161A6DE0C2A0FC86196D2097E9608551A43770B3BD8AB822B1BB9E5987725DF9BBC401F14292755DA24030ACC69ADCA7EA9B2484AEA98EE7F73C703CE4E76CDC2EF85D749993E4DE088DFCCB626CB2FE6BDA3DBAE70108FCED4CF00A5945E6C04B87A58713A62DEABDA0E6E525C75E5415D90CB59BC72A522AC948E3A1B6ADF1891C8FE973B60776A9335D0FA05DC426ED7616A6F216C9586C3D10430E881F6834691C18BEAF054CE19777E33293A89915221C7D420DB0233CA775C6C4B5D260988F23DBDA09A3D66540FD47488EB919C1DED53561B427B54E5C63BF606DBB8F6242A39B1E697F3B0FF86A7AFCB0AA5E78A77CAA47D355730B19788A6F6E7EEEEAED8633622543179E"; + var c3 = "0080B3659E936164926935376D4AA81FE1A8101B4A657EFF158C5215F3F85530D1906A4449546ABB8A6B4BA628DC5A4D0F5C3BFECE19ED4AA39C2CC8F7590F5755C186C80E26882BB7BEE4917CB2559F6C64747EBD592DEEA9195E2A5E9C5A7BD4A76FBC4432FE87EE1A6092B12B16F3AD2EE0C9269886FF72161A6DE0C2A0FC8619679C04E3C5A73439B3BA5CAEFB666357912294740E6D0ABD4E5B78B2796BDAB158DA9A9ED0708EA41EDD4EB1B04B8F52E1FED7BC5EC568179A0102FC5D1A35C57AB899B86D1A93E90E12265A9395680BC7CEA47DBE07B61281548523F6A68C48BC580CDB6C26D18B7F144DE9CF9FF061AD616CE813C6232E4917835820CDC11FD59ED6A62B5E6AB297A12E782B3E8C639A3A1E68A1796E3E0449E02B4AE57869481579130FE95149B4B5238D0C9152781B810CBD85449E7EE049E4F556D4980D57751C80228D569A67B9B410C0DCAADD803513C341F354A58E04D7CACDF4F4013ABA0CD5BE3E9A14734D5BD6FE62CAD8A936E070B9337CCF5A11235F0FCE88DC"; - var result = instance.add(c1, c2); - if(c3 === result){ - testsucceed++; - console.log("test succeed key=", key, ",length=", Object.keys(paillie).length, ",o1=", o1, ",o2=", o2, ",o3=", o3); - }else{ - testerr++; - console.log("result=", result, ",c3=", c3, ",c1=", c1, ",c2=", c2); - } + var result = instance.add(c1, c2); + if(c3 === result){ + testsucceed++; + console.log("test succeed result=", result, ",c3=", c3, ",c1=", c1, ",c2=", c2); + }else{ + testerr++; + console.log("test failed result=", result, ",c3=", c3, ",c1=", c1, ",c2=", c2); } - - console.log("testsucceed=", testsucceed, ",testerr=", testerr, ",length=", Object.keys(paillie).length); })() diff --git a/tool/java/Paillier/.gitignore b/tool/java/Paillier/.gitignore new file mode 100644 index 0000000000..ae3c172604 --- /dev/null +++ b/tool/java/Paillier/.gitignore @@ -0,0 +1 @@ +/bin/