add all
This commit is contained in:
632
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/BCrypt.cs
vendored
Normal file
632
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/BCrypt.cs
vendored
Normal file
@@ -0,0 +1,632 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* Core of password hashing scheme Bcrypt,
|
||||
* designed by Niels Provos and David Mazières,
|
||||
* corresponds to the C reference implementation.
|
||||
* <p>
|
||||
* This implementation does not correspondent to the 1999 published paper
|
||||
* "A Future-Adaptable Password Scheme" of Niels Provos and David Mazières,
|
||||
* see: https://www.usenix.org/legacy/events/usenix99/provos/provos_html/node1.html.
|
||||
* In contrast to the paper, the order of key setup and salt setup is reversed:
|
||||
* state <- ExpandKey(state, 0, key)
|
||||
* state %lt;- ExpandKey(state, 0, salt)
|
||||
* This corresponds to the OpenBSD reference implementation of Bcrypt.
|
||||
* </p><p>
|
||||
* Note:
|
||||
* There is no successful cryptanalysis (status 2015), but
|
||||
* the amount of memory and the band width of Bcrypt
|
||||
* may be insufficient to effectively prevent attacks
|
||||
* with custom hardware like FPGAs, ASICs
|
||||
* </p><p>
|
||||
* This implementation uses some parts of Bouncy Castle's BlowfishEngine.
|
||||
* </p>
|
||||
*/
|
||||
public sealed class BCrypt
|
||||
{
|
||||
// magic String "OrpheanBeholderScryDoubt" is used as clear text for encryption
|
||||
private static readonly uint[] MAGIC_STRING =
|
||||
{
|
||||
0x4F727068, 0x65616E42, 0x65686F6C,
|
||||
0x64657253, 0x63727944, 0x6F756274
|
||||
};
|
||||
|
||||
internal const int MAGIC_STRING_LENGTH = 6;
|
||||
|
||||
private static readonly uint[]
|
||||
KP = {
|
||||
0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
|
||||
0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
|
||||
0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
|
||||
0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917,
|
||||
0x9216D5D9, 0x8979FB1B
|
||||
},
|
||||
|
||||
KS0 = {
|
||||
0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7,
|
||||
0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99,
|
||||
0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
|
||||
0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
|
||||
0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE,
|
||||
0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
|
||||
0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF,
|
||||
0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
|
||||
0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
|
||||
0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440,
|
||||
0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE,
|
||||
0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
|
||||
0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E,
|
||||
0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677,
|
||||
0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
|
||||
0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
|
||||
0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88,
|
||||
0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
|
||||
0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E,
|
||||
0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
|
||||
0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
|
||||
0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98,
|
||||
0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88,
|
||||
0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
|
||||
0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6,
|
||||
0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D,
|
||||
0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
|
||||
0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
|
||||
0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA,
|
||||
0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
|
||||
0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F,
|
||||
0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
|
||||
0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
|
||||
0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB,
|
||||
0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279,
|
||||
0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
|
||||
0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB,
|
||||
0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82,
|
||||
0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
|
||||
0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
|
||||
0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0,
|
||||
0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
|
||||
0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790,
|
||||
0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
|
||||
0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
|
||||
0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0,
|
||||
0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7,
|
||||
0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
|
||||
0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD,
|
||||
0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1,
|
||||
0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
|
||||
0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
|
||||
0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477,
|
||||
0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
|
||||
0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49,
|
||||
0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
|
||||
0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
|
||||
0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5,
|
||||
0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41,
|
||||
0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
|
||||
0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400,
|
||||
0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915,
|
||||
0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
|
||||
0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A
|
||||
},
|
||||
|
||||
KS1 = {
|
||||
0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623,
|
||||
0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266,
|
||||
0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
|
||||
0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
|
||||
0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6,
|
||||
0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
|
||||
0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E,
|
||||
0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
|
||||
0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
|
||||
0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8,
|
||||
0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF,
|
||||
0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
|
||||
0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701,
|
||||
0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7,
|
||||
0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
|
||||
0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
|
||||
0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF,
|
||||
0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
|
||||
0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E,
|
||||
0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
|
||||
0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
|
||||
0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2,
|
||||
0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16,
|
||||
0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
|
||||
0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B,
|
||||
0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509,
|
||||
0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
|
||||
0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
|
||||
0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F,
|
||||
0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
|
||||
0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4,
|
||||
0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
|
||||
0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
|
||||
0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28,
|
||||
0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802,
|
||||
0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
|
||||
0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510,
|
||||
0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF,
|
||||
0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
|
||||
0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
|
||||
0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50,
|
||||
0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
|
||||
0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8,
|
||||
0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
|
||||
0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
|
||||
0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696,
|
||||
0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128,
|
||||
0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
|
||||
0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0,
|
||||
0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0,
|
||||
0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
|
||||
0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
|
||||
0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3,
|
||||
0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
|
||||
0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00,
|
||||
0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
|
||||
0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
|
||||
0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E,
|
||||
0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735,
|
||||
0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
|
||||
0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9,
|
||||
0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340,
|
||||
0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
|
||||
0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7
|
||||
},
|
||||
|
||||
KS2 = {
|
||||
0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934,
|
||||
0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068,
|
||||
0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
|
||||
0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
|
||||
0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45,
|
||||
0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
|
||||
0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A,
|
||||
0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
|
||||
0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
|
||||
0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6,
|
||||
0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42,
|
||||
0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
|
||||
0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2,
|
||||
0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB,
|
||||
0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
|
||||
0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
|
||||
0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33,
|
||||
0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
|
||||
0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3,
|
||||
0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
|
||||
0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
|
||||
0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564,
|
||||
0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B,
|
||||
0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
|
||||
0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922,
|
||||
0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728,
|
||||
0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
|
||||
0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
|
||||
0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37,
|
||||
0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
|
||||
0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804,
|
||||
0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
|
||||
0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
|
||||
0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB,
|
||||
0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D,
|
||||
0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
|
||||
0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350,
|
||||
0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9,
|
||||
0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
|
||||
0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
|
||||
0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D,
|
||||
0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
|
||||
0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F,
|
||||
0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
|
||||
0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
|
||||
0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9,
|
||||
0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2,
|
||||
0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
|
||||
0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E,
|
||||
0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633,
|
||||
0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
|
||||
0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
|
||||
0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52,
|
||||
0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
|
||||
0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5,
|
||||
0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
|
||||
0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
|
||||
0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76,
|
||||
0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24,
|
||||
0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
|
||||
0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4,
|
||||
0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C,
|
||||
0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
|
||||
0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0
|
||||
},
|
||||
|
||||
KS3 = {
|
||||
0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B,
|
||||
0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE,
|
||||
0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
|
||||
0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
|
||||
0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8,
|
||||
0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
|
||||
0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304,
|
||||
0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
|
||||
0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
|
||||
0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6,
|
||||
0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9,
|
||||
0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
|
||||
0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593,
|
||||
0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51,
|
||||
0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
|
||||
0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
|
||||
0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B,
|
||||
0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
|
||||
0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C,
|
||||
0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
|
||||
0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
|
||||
0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319,
|
||||
0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB,
|
||||
0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
|
||||
0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991,
|
||||
0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32,
|
||||
0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
|
||||
0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
|
||||
0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE,
|
||||
0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
|
||||
0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5,
|
||||
0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
|
||||
0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
|
||||
0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D,
|
||||
0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84,
|
||||
0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
|
||||
0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8,
|
||||
0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD,
|
||||
0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
|
||||
0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
|
||||
0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38,
|
||||
0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
|
||||
0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C,
|
||||
0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
|
||||
0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
|
||||
0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442,
|
||||
0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964,
|
||||
0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
|
||||
0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8,
|
||||
0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D,
|
||||
0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
|
||||
0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
|
||||
0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02,
|
||||
0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
|
||||
0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614,
|
||||
0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
|
||||
0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
|
||||
0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B,
|
||||
0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0,
|
||||
0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
|
||||
0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E,
|
||||
0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9,
|
||||
0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
|
||||
0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6
|
||||
};
|
||||
|
||||
//====================================
|
||||
// Useful constants
|
||||
//====================================
|
||||
|
||||
private const int ROUNDS = 16;
|
||||
private const int SBOX_SK = 256;
|
||||
private const int SBOX_SK2 = SBOX_SK * 2;
|
||||
private const int SBOX_SK3 = SBOX_SK * 3;
|
||||
private const int P_SZ = ROUNDS + 2;
|
||||
|
||||
private readonly uint[] S; // the s-boxes
|
||||
private readonly uint[] P; // the p-array
|
||||
|
||||
private BCrypt()
|
||||
{
|
||||
S = new uint[SBOX_SK * 4];
|
||||
P = new uint[P_SZ];
|
||||
}
|
||||
|
||||
//==================================
|
||||
// Private Implementation
|
||||
//==================================
|
||||
|
||||
private uint F(uint x)
|
||||
{
|
||||
return (((S[(x >> 24)] + S[SBOX_SK + ((x >> 16) & 0xff)])
|
||||
^ S[SBOX_SK2 + ((x >> 8) & 0xff)]) + S[SBOX_SK3 + (x & 0xff)]);
|
||||
}
|
||||
|
||||
/*
|
||||
* apply the encryption cycle to each value pair in the table.
|
||||
*/
|
||||
private void ProcessTable(uint xl, uint xr, uint[] table)
|
||||
{
|
||||
int size = table.Length;
|
||||
|
||||
for (int s = 0; s < size; s += 2)
|
||||
{
|
||||
xl ^= P[0];
|
||||
|
||||
for (int i = 1; i < ROUNDS; i += 2)
|
||||
{
|
||||
xr ^= F(xl) ^ P[i];
|
||||
xl ^= F(xr) ^ P[i + 1];
|
||||
}
|
||||
|
||||
xr ^= P[ROUNDS + 1];
|
||||
|
||||
table[s] = xr;
|
||||
table[s + 1] = xl;
|
||||
|
||||
xr = xl; // end of cycle swap
|
||||
xl = table[s];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the S-boxes and the P-array, with a fixed string
|
||||
* This string contains the hexadecimal digits of pi (3.141...)
|
||||
*/
|
||||
private void InitState()
|
||||
{
|
||||
Array.Copy(KS0, 0, S, 0, SBOX_SK);
|
||||
Array.Copy(KS1, 0, S, SBOX_SK, SBOX_SK);
|
||||
Array.Copy(KS2, 0, S, SBOX_SK2, SBOX_SK);
|
||||
Array.Copy(KS3, 0, S, SBOX_SK3, SBOX_SK);
|
||||
|
||||
Array.Copy(KP, 0, P, 0, P_SZ);
|
||||
}
|
||||
|
||||
/*
|
||||
* XOR P with key cyclic.
|
||||
* This is the first part of ExpandKey function
|
||||
*/
|
||||
private void CyclicXorKey(byte[] key)
|
||||
{
|
||||
int keyLength = key.Length;
|
||||
int keyIndex = 0;
|
||||
|
||||
for (int i = 0; i < P_SZ; i++)
|
||||
{
|
||||
// get the 32 bits of the key, in 4 * 8 bit chunks
|
||||
uint data = 0x0000000;
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
// create a 32 bit block
|
||||
data = (data << 8) | key[keyIndex];
|
||||
|
||||
// wrap when we get to the end of the key
|
||||
if (++keyIndex >= keyLength)
|
||||
{
|
||||
keyIndex = 0;
|
||||
}
|
||||
}
|
||||
// XOR the newly created 32 bit chunk onto the P-array
|
||||
P[i] ^= data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* encrypt magic String 64 times in ECB
|
||||
*/
|
||||
private byte[] EncryptMagicString()
|
||||
{
|
||||
uint[] text = {
|
||||
MAGIC_STRING[0], MAGIC_STRING[1],
|
||||
MAGIC_STRING[2], MAGIC_STRING[3],
|
||||
MAGIC_STRING[4], MAGIC_STRING[5]
|
||||
};
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
for (int j = 0; j < MAGIC_STRING_LENGTH; j += 2)
|
||||
{
|
||||
uint left = text[j];
|
||||
uint right = text[j + 1];
|
||||
|
||||
left ^= P[0];
|
||||
for (int k = 1; k < ROUNDS; k += 2)
|
||||
{
|
||||
right ^= F(left) ^ P[k];
|
||||
left ^= F(right) ^ P[k + 1];
|
||||
}
|
||||
right ^= P[ROUNDS + 1];
|
||||
// swap values:
|
||||
text[j] = right;
|
||||
text[j + 1] = left;
|
||||
}
|
||||
}
|
||||
byte[] result = new byte[24]; // holds 192 bit key
|
||||
Pack.UInt32_To_BE(text, result, 0);
|
||||
Array.Clear(text, 0, text.Length);
|
||||
Array.Clear(P, 0, P.Length);
|
||||
Array.Clear(S, 0, S.Length);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a part of Eksblowfish function
|
||||
*
|
||||
* @param table: sub-keys or working key
|
||||
* @param salt32Bit: a 16 byte salt as two 32 bit words
|
||||
* @param iv1: value from last proceeded table
|
||||
* @param iv2: value from last proceeded table
|
||||
*/
|
||||
private void ProcessTableWithSalt(uint[] table, uint[] salt32Bit, uint iv1, uint iv2)
|
||||
{
|
||||
uint xl = iv1 ^ salt32Bit[0];
|
||||
uint xr = iv2 ^ salt32Bit[1];
|
||||
|
||||
uint yl;
|
||||
uint yr;
|
||||
int size = table.Length;
|
||||
|
||||
for (int s = 0; s < size; s += 4)
|
||||
{
|
||||
xl ^= P[0];
|
||||
for (int i = 1; i < ROUNDS; i += 2)
|
||||
{
|
||||
xr ^= F(xl) ^ P[i];
|
||||
xl ^= F(xr) ^ P[i + 1];
|
||||
}
|
||||
xr ^= P[ROUNDS + 1];
|
||||
|
||||
table[s] = xr;
|
||||
table[s + 1] = xl;
|
||||
|
||||
yl = salt32Bit[2] ^ xr;
|
||||
yr = salt32Bit[3] ^ xl;
|
||||
|
||||
if (s + 2 >= size) // P holds 18 values
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
yl ^= P[0];
|
||||
for (int i = 1; i < ROUNDS; i += 2)
|
||||
{
|
||||
yr ^= F(yl) ^ P[i];
|
||||
yl ^= F(yr) ^ P[i + 1];
|
||||
}
|
||||
yr ^= P[ROUNDS + 1];
|
||||
|
||||
table[s + 2] = yr;
|
||||
table[s + 3] = yl;
|
||||
|
||||
xl = salt32Bit[0] ^ yr;
|
||||
xr = salt32Bit[1] ^ yl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives a raw 192 bit Bcrypt key
|
||||
*
|
||||
* @param cost the cost factor, treated as an exponent of 2
|
||||
* @param salt a 16 byte salt
|
||||
* @param psw the password
|
||||
* @return a 192 bit key
|
||||
*/
|
||||
private byte[] DeriveRawKey(int cost, byte[] salt, byte[] psw)
|
||||
{
|
||||
if (salt.Length != 16)
|
||||
throw new DataLengthException("Invalid salt size: 16 bytes expected.");
|
||||
if (cost < 4 || cost > 31)
|
||||
throw new ArgumentException("Illegal cost factor: 4 - 31 expected.", "cost");
|
||||
|
||||
if (psw.Length == 0)
|
||||
{
|
||||
psw = new byte[4];
|
||||
}
|
||||
|
||||
// state <- InitState()
|
||||
InitState();
|
||||
|
||||
uint[] salt32Bit = new uint[4]; // holds 16 byte salt
|
||||
Pack.BE_To_UInt32(salt, 0, salt32Bit);
|
||||
|
||||
uint[] salt32Bit2 = new uint[salt.Length]; // swapped values
|
||||
salt32Bit2[0] = salt32Bit[2];
|
||||
salt32Bit2[1] = salt32Bit[3];
|
||||
salt32Bit2[2] = salt32Bit[0];
|
||||
salt32Bit2[3] = salt32Bit[1];
|
||||
|
||||
// ExpandKey( state, salt, key):
|
||||
CyclicXorKey(psw);
|
||||
ProcessTableWithSalt(P, salt32Bit, 0, 0);
|
||||
Array.Clear(salt32Bit, 0, salt32Bit.Length);
|
||||
ProcessTableWithSalt(S, salt32Bit2, P[P.Length - 2], P[P.Length - 1]);
|
||||
Array.Clear(salt32Bit2, 0, salt32Bit2.Length);
|
||||
|
||||
int rounds = 1 << cost;
|
||||
for (int i = 0; i != rounds; i++) // rounds may be negative if cost is 31
|
||||
{
|
||||
// state <- ExpandKey(state, 0, key);
|
||||
CyclicXorKey(psw);
|
||||
ProcessTable(0, 0, P);
|
||||
ProcessTable(P[P_SZ - 2], P[P_SZ - 1], S);
|
||||
|
||||
// state <- ExpandKey(state, 0, salt);
|
||||
CyclicXorKey(salt);
|
||||
ProcessTable(0, 0, P);
|
||||
ProcessTable(P[P_SZ - 2], P[P_SZ - 1], S);
|
||||
}
|
||||
|
||||
// encrypt magicString 64 times
|
||||
return EncryptMagicString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Size of the salt parameter in bytes
|
||||
*/
|
||||
internal const int SALT_SIZE_BYTES = 16;
|
||||
|
||||
/**
|
||||
* Minimum value of cost parameter, equal to log2(bytes of salt)
|
||||
*/
|
||||
internal const int MIN_COST = 4;
|
||||
|
||||
/**
|
||||
* Maximum value of cost parameter (31 == 2,147,483,648)
|
||||
*/
|
||||
internal const int MAX_COST = 31;
|
||||
|
||||
/**
|
||||
* Maximum size of password == max (unrestricted) size of Blowfish key
|
||||
*/
|
||||
// Blowfish spec limits keys to 448bit/56 bytes to ensure all bits of key affect all ciphertext
|
||||
// bits, but technically algorithm handles 72 byte keys and most implementations support this.
|
||||
internal const int MAX_PASSWORD_BYTES = 72;
|
||||
|
||||
/**
|
||||
* Converts a character password to bytes incorporating the required trailing zero byte.
|
||||
*
|
||||
* @param password the password to be encoded.
|
||||
* @return a byte representation of the password in UTF8 + trailing zero.
|
||||
*/
|
||||
public static byte[] PasswordToByteArray(char[] password)
|
||||
{
|
||||
return Arrays.Append(Strings.ToUtf8ByteArray(password), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the <b>bcrypt</b> hash of a password.
|
||||
* <p>
|
||||
* This implements the raw <b>bcrypt</b> function as defined in the bcrypt specification, not
|
||||
* the crypt encoded version implemented in OpenBSD.
|
||||
* </p>
|
||||
* @param password the password bytes (up to 72 bytes) to use for this invocation.
|
||||
* @param salt the 128 bit salt to use for this invocation.
|
||||
* @param cost the bcrypt cost parameter. The cost of the bcrypt function grows as
|
||||
* <code>2^cost</code>. Legal values are 4..31 inclusive.
|
||||
* @return the output of the raw bcrypt operation: a 192 bit (24 byte) hash.
|
||||
*/
|
||||
public static byte[] Generate(byte[] password, byte[] salt, int cost)
|
||||
{
|
||||
if (password == null)
|
||||
throw new ArgumentNullException("password");
|
||||
if (password.Length > MAX_PASSWORD_BYTES)
|
||||
throw new ArgumentException("BCrypt password must be <= 72 bytes", "password");
|
||||
if (salt == null)
|
||||
throw new ArgumentNullException("salt");
|
||||
if (salt.Length != SALT_SIZE_BYTES)
|
||||
throw new ArgumentException("BCrypt salt must be 128 bits", "salt");
|
||||
if (cost < MIN_COST || cost > MAX_COST)
|
||||
throw new ArgumentException("BCrypt cost must be from 4..31", "cost");
|
||||
|
||||
return new BCrypt().DeriveRawKey(cost, salt, password);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/BCrypt.cs.meta
vendored
Normal file
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/BCrypt.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6023682d710547a4db596e974c58e5bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,194 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* Basic KDF generator for derived keys and ivs as defined by IEEE P1363a/ISO 18033
|
||||
* <br/>
|
||||
* This implementation is based on ISO 18033/P1363a.
|
||||
*/
|
||||
public abstract class BaseKdfBytesGenerator
|
||||
: IDerivationFunction
|
||||
{
|
||||
private int counterStart;
|
||||
private IDigest digest;
|
||||
private byte[] shared;
|
||||
private byte[] iv;
|
||||
|
||||
/**
|
||||
* Construct a KDF Parameters generator.
|
||||
*
|
||||
* @param counterStart value of counter.
|
||||
* @param digest the digest to be used as the source of derived keys.
|
||||
*/
|
||||
protected BaseKdfBytesGenerator(int counterStart, IDigest digest)
|
||||
{
|
||||
this.counterStart = counterStart;
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
public void Init(IDerivationParameters parameters)
|
||||
{
|
||||
if (parameters is KdfParameters kdfParameters)
|
||||
{
|
||||
shared = kdfParameters.GetSharedSecret();
|
||||
iv = kdfParameters.GetIV();
|
||||
}
|
||||
else if (parameters is Iso18033KdfParameters iso18033KdfParameters)
|
||||
{
|
||||
shared = iso18033KdfParameters.GetSeed();
|
||||
iv = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("KDF parameters required for KDF Generator");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return the underlying digest.
|
||||
*/
|
||||
public IDigest Digest => digest;
|
||||
|
||||
/**
|
||||
* fill len bytes of the output buffer with bytes generated from
|
||||
* the derivation function.
|
||||
*
|
||||
* @throws ArgumentException if the size of the request will cause an overflow.
|
||||
* @throws DataLengthException if the out buffer is too small.
|
||||
*/
|
||||
public int GenerateBytes(byte[] output, int outOff, int length)
|
||||
{
|
||||
Check.OutputLength(output, outOff, length, "output buffer too small");
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
return GenerateBytes(output.AsSpan(outOff, length));
|
||||
#else
|
||||
long oBytes = length;
|
||||
int digestSize = digest.GetDigestSize();
|
||||
|
||||
//
|
||||
// this is at odds with the standard implementation, the
|
||||
// maximum value should be hBits * (2^32 - 1) where hBits
|
||||
// is the digest output size in bits. We can't have an
|
||||
// array with a long index at the moment...
|
||||
//
|
||||
if (oBytes > ((2L << 32) - 1))
|
||||
throw new ArgumentException("Output length too large");
|
||||
|
||||
int cThreshold = (int)((oBytes + digestSize - 1) / digestSize);
|
||||
|
||||
byte[] dig = new byte[digestSize];
|
||||
|
||||
byte[] C = new byte[4];
|
||||
Pack.UInt32_To_BE((uint)counterStart, C, 0);
|
||||
|
||||
uint counterBase = (uint)(counterStart & ~0xFF);
|
||||
|
||||
for (int i = 0; i < cThreshold; i++)
|
||||
{
|
||||
digest.BlockUpdate(shared, 0, shared.Length);
|
||||
digest.BlockUpdate(C, 0, 4);
|
||||
|
||||
if (iv != null)
|
||||
{
|
||||
digest.BlockUpdate(iv, 0, iv.Length);
|
||||
}
|
||||
|
||||
digest.DoFinal(dig, 0);
|
||||
|
||||
if (length > digestSize)
|
||||
{
|
||||
Array.Copy(dig, 0, output, outOff, digestSize);
|
||||
outOff += digestSize;
|
||||
length -= digestSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Copy(dig, 0, output, outOff, length);
|
||||
}
|
||||
|
||||
if (++C[3] == 0)
|
||||
{
|
||||
counterBase += 0x100;
|
||||
Pack.UInt32_To_BE(counterBase, C, 0);
|
||||
}
|
||||
}
|
||||
|
||||
digest.Reset();
|
||||
|
||||
return (int)oBytes;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
public int GenerateBytes(Span<byte> output)
|
||||
{
|
||||
long oBytes = output.Length;
|
||||
int digestSize = digest.GetDigestSize();
|
||||
|
||||
//
|
||||
// this is at odds with the standard implementation, the
|
||||
// maximum value should be hBits * (2^32 - 1) where hBits
|
||||
// is the digest output size in bits. We can't have an
|
||||
// array with a long index at the moment...
|
||||
//
|
||||
if (oBytes > ((2L << 32) - 1))
|
||||
throw new ArgumentException("Output length too large");
|
||||
|
||||
int cThreshold = (int)((oBytes + digestSize - 1) / digestSize);
|
||||
|
||||
Span<byte> dig = digestSize <= 128
|
||||
? stackalloc byte[digestSize]
|
||||
: new byte[digestSize];
|
||||
|
||||
Span<byte> C = stackalloc byte[4];
|
||||
Pack.UInt32_To_BE((uint)counterStart, C);
|
||||
|
||||
uint counterBase = (uint)(counterStart & ~0xFF);
|
||||
|
||||
for (int i = 0; i < cThreshold; i++)
|
||||
{
|
||||
digest.BlockUpdate(shared);
|
||||
digest.BlockUpdate(C);
|
||||
|
||||
if (iv != null)
|
||||
{
|
||||
digest.BlockUpdate(iv);
|
||||
}
|
||||
|
||||
digest.DoFinal(dig);
|
||||
|
||||
int remaining = output.Length;
|
||||
if (remaining > digestSize)
|
||||
{
|
||||
dig.CopyTo(output);
|
||||
output = output[digestSize..];
|
||||
}
|
||||
else
|
||||
{
|
||||
dig[..remaining].CopyTo(output);
|
||||
}
|
||||
|
||||
if (++C[3] == 0)
|
||||
{
|
||||
counterBase += 0x100;
|
||||
Pack.UInt32_To_BE(counterBase, C);
|
||||
}
|
||||
}
|
||||
|
||||
digest.Reset();
|
||||
|
||||
return (int)oBytes;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3439e9d02faadfd4b96c0da140cc3051
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,42 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* a basic Diffie-Hellman key pair generator.
|
||||
*
|
||||
* This generates keys consistent for use with the basic algorithm for
|
||||
* Diffie-Hellman.
|
||||
*/
|
||||
public class DHBasicKeyPairGenerator
|
||||
: IAsymmetricCipherKeyPairGenerator
|
||||
{
|
||||
private DHKeyGenerationParameters param;
|
||||
|
||||
public virtual void Init(
|
||||
KeyGenerationParameters parameters)
|
||||
{
|
||||
this.param = (DHKeyGenerationParameters)parameters;
|
||||
}
|
||||
|
||||
public virtual AsymmetricCipherKeyPair GenerateKeyPair()
|
||||
{
|
||||
DHKeyGeneratorHelper helper = DHKeyGeneratorHelper.Instance;
|
||||
DHParameters dhp = param.Parameters;
|
||||
|
||||
BigInteger x = helper.CalculatePrivate(dhp, param.Random);
|
||||
BigInteger y = helper.CalculatePublic(dhp, x);
|
||||
|
||||
return new AsymmetricCipherKeyPair(
|
||||
new DHPublicKeyParameters(y, dhp),
|
||||
new DHPrivateKeyParameters(x, dhp));
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7987a02369f45bf46be2bd071b00bd3a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,76 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Multiplier;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
class DHKeyGeneratorHelper
|
||||
{
|
||||
internal static readonly DHKeyGeneratorHelper Instance = new DHKeyGeneratorHelper();
|
||||
|
||||
private DHKeyGeneratorHelper()
|
||||
{
|
||||
}
|
||||
|
||||
internal BigInteger CalculatePrivate(
|
||||
DHParameters dhParams,
|
||||
SecureRandom random)
|
||||
{
|
||||
int limit = dhParams.L;
|
||||
|
||||
if (limit != 0)
|
||||
{
|
||||
int minWeight = limit >> 2;
|
||||
for (;;)
|
||||
{
|
||||
BigInteger x = new BigInteger(limit, random).SetBit(limit - 1);
|
||||
if (WNafUtilities.GetNafWeight(x) >= minWeight)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BigInteger min = BigInteger.Two;
|
||||
int m = dhParams.M;
|
||||
if (m != 0)
|
||||
{
|
||||
min = BigInteger.One.ShiftLeft(m - 1);
|
||||
}
|
||||
|
||||
BigInteger q = dhParams.Q;
|
||||
if (q == null)
|
||||
{
|
||||
q = dhParams.P;
|
||||
}
|
||||
BigInteger max = q.Subtract(BigInteger.Two);
|
||||
|
||||
{
|
||||
int minWeight = max.BitLength >> 2;
|
||||
for (;;)
|
||||
{
|
||||
BigInteger x = BigIntegers.CreateRandomInRange(min, max, random);
|
||||
if (WNafUtilities.GetNafWeight(x) >= minWeight)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal BigInteger CalculatePublic(
|
||||
DHParameters dhParams,
|
||||
BigInteger x)
|
||||
{
|
||||
return dhParams.G.ModPow(x, dhParams.P);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 607f394ddbca4cd458888bdefd99ead6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,42 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* a Diffie-Hellman key pair generator.
|
||||
*
|
||||
* This generates keys consistent for use in the MTI/A0 key agreement protocol
|
||||
* as described in "Handbook of Applied Cryptography", Pages 516-519.
|
||||
*/
|
||||
public class DHKeyPairGenerator
|
||||
: IAsymmetricCipherKeyPairGenerator
|
||||
{
|
||||
private DHKeyGenerationParameters param;
|
||||
|
||||
public virtual void Init(
|
||||
KeyGenerationParameters parameters)
|
||||
{
|
||||
this.param = (DHKeyGenerationParameters)parameters;
|
||||
}
|
||||
|
||||
public virtual AsymmetricCipherKeyPair GenerateKeyPair()
|
||||
{
|
||||
DHKeyGeneratorHelper helper = DHKeyGeneratorHelper.Instance;
|
||||
DHParameters dhp = param.Parameters;
|
||||
|
||||
BigInteger x = helper.CalculatePrivate(dhp, param.Random);
|
||||
BigInteger y = helper.CalculatePublic(dhp, x);
|
||||
|
||||
return new AsymmetricCipherKeyPair(
|
||||
new DHPublicKeyParameters(y, dhp),
|
||||
new DHPrivateKeyParameters(x, dhp));
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6fc29e9fe66ed4e4c9b1fc1e27d211e3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,49 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
public class DHParametersGenerator
|
||||
{
|
||||
private int size;
|
||||
private int certainty;
|
||||
private SecureRandom random;
|
||||
|
||||
public virtual void Init(
|
||||
int size,
|
||||
int certainty,
|
||||
SecureRandom random)
|
||||
{
|
||||
this.size = size;
|
||||
this.certainty = certainty;
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
/**
|
||||
* which Generates the p and g values from the given parameters,
|
||||
* returning the DHParameters object.
|
||||
* <p>
|
||||
* Note: can take a while...</p>
|
||||
*/
|
||||
public virtual DHParameters GenerateParameters()
|
||||
{
|
||||
//
|
||||
// find a safe prime p where p = 2*q + 1, where p and q are prime.
|
||||
//
|
||||
BigInteger[] safePrimes = DHParametersHelper.GenerateSafePrimes(size, certainty, random);
|
||||
|
||||
BigInteger p = safePrimes[0];
|
||||
BigInteger q = safePrimes[1];
|
||||
BigInteger g = DHParametersHelper.SelectGenerator(p, q, random);
|
||||
|
||||
return new DHParameters(p, g, q, BigInteger.Two, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 462a00ee0abde8b44abc08366c0e7cb8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
160
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/DHParametersHelper.cs
vendored
Normal file
160
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/DHParametersHelper.cs
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Multiplier;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
internal class DHParametersHelper
|
||||
{
|
||||
private static readonly BigInteger Six = BigInteger.ValueOf(6);
|
||||
|
||||
private static readonly int[][] primeLists = BigInteger.primeLists;
|
||||
private static readonly int[] primeProducts = BigInteger.primeProducts;
|
||||
private static readonly BigInteger[] BigPrimeProducts = ConstructBigPrimeProducts(primeProducts);
|
||||
|
||||
private static BigInteger[] ConstructBigPrimeProducts(int[] primeProducts)
|
||||
{
|
||||
BigInteger[] bpp = new BigInteger[primeProducts.Length];
|
||||
for (int i = 0; i < bpp.Length; ++i)
|
||||
{
|
||||
bpp[i] = BigInteger.ValueOf(primeProducts[i]);
|
||||
}
|
||||
return bpp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds a pair of prime BigInteger's {p, q: p = 2q + 1}
|
||||
*
|
||||
* (see: Handbook of Applied Cryptography 4.86)
|
||||
*/
|
||||
internal static BigInteger[] GenerateSafePrimes(int size, int certainty, SecureRandom random)
|
||||
{
|
||||
BigInteger p, q;
|
||||
int qLength = size - 1;
|
||||
int minWeight = size >> 2;
|
||||
|
||||
if (size <= 32)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
q = new BigInteger(qLength, 2, random);
|
||||
|
||||
p = q.ShiftLeft(1).Add(BigInteger.One);
|
||||
|
||||
if (!p.IsProbablePrime(certainty, true))
|
||||
continue;
|
||||
|
||||
if (certainty > 2 && !q.IsProbablePrime(certainty, true))
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Note: Modified from Java version for speed
|
||||
for (;;)
|
||||
{
|
||||
q = new BigInteger(qLength, 0, random);
|
||||
|
||||
retry:
|
||||
for (int i = 0; i < primeLists.Length; ++i)
|
||||
{
|
||||
int test = q.Remainder(BigPrimeProducts[i]).IntValue;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
int rem3 = test % 3;
|
||||
if (rem3 != 2)
|
||||
{
|
||||
int diff = 2 * rem3 + 2;
|
||||
q = q.Add(BigInteger.ValueOf(diff));
|
||||
test = (test + diff) % primeProducts[i];
|
||||
}
|
||||
}
|
||||
|
||||
int[] primeList = primeLists[i];
|
||||
for (int j = 0; j < primeList.Length; ++j)
|
||||
{
|
||||
int prime = primeList[j];
|
||||
int qRem = test % prime;
|
||||
if (qRem == 0 || qRem == (prime >> 1))
|
||||
{
|
||||
q = q.Add(Six);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (q.BitLength != qLength)
|
||||
continue;
|
||||
|
||||
if (!q.RabinMillerTest(2, random, true))
|
||||
continue;
|
||||
|
||||
p = q.ShiftLeft(1).Add(BigInteger.One);
|
||||
|
||||
if (!p.RabinMillerTest(certainty, random, true))
|
||||
continue;
|
||||
|
||||
if (certainty > 2 && !q.RabinMillerTest(certainty - 2, random, true))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Require a minimum weight of the NAF representation, since low-weight primes may be
|
||||
* weak against a version of the number-field-sieve for the discrete-logarithm-problem.
|
||||
*
|
||||
* See "The number field sieve for integers of low weight", Oliver Schirokauer.
|
||||
*/
|
||||
if (WNafUtilities.GetNafWeight(p) < minWeight)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new BigInteger[] { p, q };
|
||||
}
|
||||
|
||||
/*
|
||||
* Select a high order element of the multiplicative group Zp*
|
||||
*
|
||||
* p and q must be s.t. p = 2*q + 1, where p and q are prime (see generateSafePrimes)
|
||||
*/
|
||||
internal static BigInteger SelectGenerator(BigInteger p, BigInteger q, SecureRandom random)
|
||||
{
|
||||
BigInteger pMinusTwo = p.Subtract(BigInteger.Two);
|
||||
BigInteger g;
|
||||
|
||||
/*
|
||||
* (see: Handbook of Applied Cryptography 4.80)
|
||||
*/
|
||||
// do
|
||||
// {
|
||||
// g = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusTwo, random);
|
||||
// }
|
||||
// while (g.ModPow(BigInteger.Two, p).Equals(BigInteger.One)
|
||||
// || g.ModPow(q, p).Equals(BigInteger.One));
|
||||
|
||||
/*
|
||||
* RFC 2631 2.2.1.2 (and see: Handbook of Applied Cryptography 4.81)
|
||||
*/
|
||||
do
|
||||
{
|
||||
BigInteger h = BigIntegers.CreateRandomInRange(BigInteger.Two, pMinusTwo, random);
|
||||
|
||||
g = h.ModPow(BigInteger.Two, p);
|
||||
}
|
||||
while (g.Equals(BigInteger.One));
|
||||
|
||||
return g;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: feb64c5411c6a6944b3cbf866130ab0d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,70 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
public class DesEdeKeyGenerator
|
||||
: DesKeyGenerator
|
||||
{
|
||||
public DesEdeKeyGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
internal DesEdeKeyGenerator(
|
||||
int defaultStrength)
|
||||
: base(defaultStrength)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* initialise the key generator - if strength is set to zero
|
||||
* the key Generated will be 192 bits in size, otherwise
|
||||
* strength can be 128 or 192 (or 112 or 168 if you don't count
|
||||
* parity bits), depending on whether you wish to do 2-key or 3-key
|
||||
* triple DES.
|
||||
*
|
||||
* @param param the parameters to be used for key generation
|
||||
*/
|
||||
protected override void EngineInit(KeyGenerationParameters parameters)
|
||||
{
|
||||
this.random = parameters.Random;
|
||||
this.strength = (parameters.Strength + 7) / 8;
|
||||
|
||||
if (strength == 0 || strength == (168 / 8))
|
||||
{
|
||||
strength = DesEdeParameters.DesEdeKeyLength;
|
||||
}
|
||||
else if (strength == (112 / 8))
|
||||
{
|
||||
strength = 2 * DesEdeParameters.DesKeyLength;
|
||||
}
|
||||
else if (strength != DesEdeParameters.DesEdeKeyLength
|
||||
&& strength != (2 * DesEdeParameters.DesKeyLength))
|
||||
{
|
||||
throw new ArgumentException("DESede key must be "
|
||||
+ (DesEdeParameters.DesEdeKeyLength * 8) + " or "
|
||||
+ (2 * 8 * DesEdeParameters.DesKeyLength)
|
||||
+ " bits long.");
|
||||
}
|
||||
}
|
||||
|
||||
protected override byte[] EngineGenerateKey()
|
||||
{
|
||||
byte[] newKey = new byte[strength];
|
||||
|
||||
do
|
||||
{
|
||||
random.NextBytes(newKey);
|
||||
DesEdeParameters.SetOddParity(newKey);
|
||||
}
|
||||
while (DesEdeParameters.IsWeakKey(newKey, 0, newKey.Length) || !DesEdeParameters.IsRealEdeKey(newKey, 0));
|
||||
|
||||
return newKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd71f83ea2b09164bb2499d7f019ebf0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,60 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
public class DesKeyGenerator
|
||||
: CipherKeyGenerator
|
||||
{
|
||||
public DesKeyGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
internal DesKeyGenerator(
|
||||
int defaultStrength)
|
||||
: base(defaultStrength)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* initialise the key generator - if strength is set to zero
|
||||
* the key generated will be 64 bits in size, otherwise
|
||||
* strength can be 64 or 56 bits (if you don't count the parity bits).
|
||||
*
|
||||
* @param param the parameters to be used for key generation
|
||||
*/
|
||||
protected override void EngineInit(KeyGenerationParameters parameters)
|
||||
{
|
||||
base.EngineInit(parameters);
|
||||
|
||||
if (strength == 0 || strength == (56 / 8))
|
||||
{
|
||||
strength = DesParameters.DesKeyLength;
|
||||
}
|
||||
else if (strength != DesParameters.DesKeyLength)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"DES key must be " + (DesParameters.DesKeyLength * 8) + " bits long.");
|
||||
}
|
||||
}
|
||||
|
||||
protected override byte[] EngineGenerateKey()
|
||||
{
|
||||
byte[] newKey = new byte[DesParameters.DesKeyLength];
|
||||
|
||||
do
|
||||
{
|
||||
random.NextBytes(newKey);
|
||||
DesParameters.SetOddParity(newKey);
|
||||
}
|
||||
while (DesParameters.IsWeakKey(newKey, 0));
|
||||
|
||||
return newKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7bd86a459e7b0794c8e95b09994cb052
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,76 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Multiplier;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* a DSA key pair generator.
|
||||
*
|
||||
* This Generates DSA keys in line with the method described
|
||||
* in <i>FIPS 186-3 B.1 FFC Key Pair Generation</i>.
|
||||
*/
|
||||
public class DsaKeyPairGenerator
|
||||
: IAsymmetricCipherKeyPairGenerator
|
||||
{
|
||||
private static readonly BigInteger One = BigInteger.One;
|
||||
|
||||
private DsaKeyGenerationParameters param;
|
||||
|
||||
public void Init(
|
||||
KeyGenerationParameters parameters)
|
||||
{
|
||||
if (parameters == null)
|
||||
throw new ArgumentNullException("parameters");
|
||||
|
||||
// Note: If we start accepting instances of KeyGenerationParameters,
|
||||
// must apply constraint checking on strength (see DsaParametersGenerator.Init)
|
||||
|
||||
this.param = (DsaKeyGenerationParameters) parameters;
|
||||
}
|
||||
|
||||
public AsymmetricCipherKeyPair GenerateKeyPair()
|
||||
{
|
||||
DsaParameters dsaParams = param.Parameters;
|
||||
|
||||
BigInteger x = GeneratePrivateKey(dsaParams.Q, param.Random);
|
||||
BigInteger y = CalculatePublicKey(dsaParams.P, dsaParams.G, x);
|
||||
|
||||
return new AsymmetricCipherKeyPair(
|
||||
new DsaPublicKeyParameters(y, dsaParams),
|
||||
new DsaPrivateKeyParameters(x, dsaParams));
|
||||
}
|
||||
|
||||
private static BigInteger GeneratePrivateKey(BigInteger q, SecureRandom random)
|
||||
{
|
||||
// B.1.2 Key Pair Generation by Testing Candidates
|
||||
int minWeight = q.BitLength >> 2;
|
||||
for (;;)
|
||||
{
|
||||
// TODO Prefer this method? (change test cases that used fixed random)
|
||||
// B.1.1 Key Pair Generation Using Extra Random Bits
|
||||
//BigInteger x = new BigInteger(q.BitLength + 64, random).Mod(q.Subtract(One)).Add(One);
|
||||
|
||||
BigInteger x = BigIntegers.CreateRandomInRange(One, q.Subtract(One), random);
|
||||
if (WNafUtilities.GetNafWeight(x) >= minWeight)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static BigInteger CalculatePublicKey(BigInteger p, BigInteger g, BigInteger x)
|
||||
{
|
||||
return g.ModPow(x, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d7a9505dee25094a95be5c48c579f41
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,359 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* Generate suitable parameters for DSA, in line with FIPS 186-2, or FIPS 186-3.
|
||||
*/
|
||||
public class DsaParametersGenerator
|
||||
{
|
||||
private IDigest digest;
|
||||
private int L, N;
|
||||
private int certainty;
|
||||
private SecureRandom random;
|
||||
private bool use186_3;
|
||||
private int usageIndex;
|
||||
|
||||
public DsaParametersGenerator()
|
||||
: this(new Sha1Digest())
|
||||
{
|
||||
}
|
||||
|
||||
public DsaParametersGenerator(IDigest digest)
|
||||
{
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
/// <summary>Initialise the generator</summary>
|
||||
/// <remarks>This form can only be used for older DSA (pre-DSA2) parameters</remarks>
|
||||
/// <param name="size">the size of keys in bits (from 512 up to 1024, and a multiple of 64)</param>
|
||||
/// <param name="certainty">measure of robustness of primes (at least 80 for FIPS 186-2 compliance)</param>
|
||||
/// <param name="random">the source of randomness to use</param>
|
||||
public virtual void Init(
|
||||
int size,
|
||||
int certainty,
|
||||
SecureRandom random)
|
||||
{
|
||||
if (!IsValidDsaStrength(size))
|
||||
throw new ArgumentException("size must be from 512 - 1024 and a multiple of 64", "size");
|
||||
|
||||
this.use186_3 = false;
|
||||
this.L = size;
|
||||
this.N = GetDefaultN(size);
|
||||
this.certainty = certainty;
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
/// <summary>Initialise the generator for DSA 2</summary>
|
||||
/// <remarks>You must use this Init method if you need to generate parameters for DSA 2 keys</remarks>
|
||||
/// <param name="parameters">An instance of <c>DsaParameterGenerationParameters</c> used to configure this generator</param>
|
||||
public virtual void Init(DsaParameterGenerationParameters parameters)
|
||||
{
|
||||
// TODO Should we enforce the minimum 'certainty' values as per C.3 Table C.1?
|
||||
this.use186_3 = true;
|
||||
this.L = parameters.L;
|
||||
this.N = parameters.N;
|
||||
this.certainty = parameters.Certainty;
|
||||
this.random = parameters.Random;
|
||||
this.usageIndex = parameters.UsageIndex;
|
||||
|
||||
if ((L < 1024 || L > 3072) || L % 1024 != 0)
|
||||
throw new ArgumentException("Values must be between 1024 and 3072 and a multiple of 1024", "L");
|
||||
if (L == 1024 && N != 160)
|
||||
throw new ArgumentException("N must be 160 for L = 1024");
|
||||
if (L == 2048 && (N != 224 && N != 256))
|
||||
throw new ArgumentException("N must be 224 or 256 for L = 2048");
|
||||
if (L == 3072 && N != 256)
|
||||
throw new ArgumentException("N must be 256 for L = 3072");
|
||||
|
||||
if (digest.GetDigestSize() * 8 < N)
|
||||
throw new InvalidOperationException("Digest output size too small for value of N");
|
||||
}
|
||||
|
||||
/// <summary>Generates a set of <c>DsaParameters</c></summary>
|
||||
/// <remarks>Can take a while...</remarks>
|
||||
public virtual DsaParameters GenerateParameters()
|
||||
{
|
||||
return use186_3
|
||||
? GenerateParameters_FIPS186_3()
|
||||
: GenerateParameters_FIPS186_2();
|
||||
}
|
||||
|
||||
protected virtual DsaParameters GenerateParameters_FIPS186_2()
|
||||
{
|
||||
byte[] seed = new byte[20];
|
||||
byte[] part1 = new byte[20];
|
||||
byte[] part2 = new byte[20];
|
||||
byte[] u = new byte[20];
|
||||
int n = (L - 1) / 160;
|
||||
byte[] w = new byte[L / 8];
|
||||
|
||||
if (!(digest is Sha1Digest))
|
||||
throw new InvalidOperationException("can only use SHA-1 for generating FIPS 186-2 parameters");
|
||||
|
||||
for (;;)
|
||||
{
|
||||
random.NextBytes(seed);
|
||||
|
||||
Hash(digest, seed, part1);
|
||||
Array.Copy(seed, 0, part2, 0, seed.Length);
|
||||
Inc(part2);
|
||||
Hash(digest, part2, part2);
|
||||
|
||||
for (int i = 0; i != u.Length; i++)
|
||||
{
|
||||
u[i] = (byte)(part1[i] ^ part2[i]);
|
||||
}
|
||||
|
||||
u[0] |= (byte)0x80;
|
||||
u[19] |= (byte)0x01;
|
||||
|
||||
BigInteger q = new BigInteger(1, u);
|
||||
|
||||
if (!q.IsProbablePrime(certainty))
|
||||
continue;
|
||||
|
||||
byte[] offset = Arrays.Clone(seed);
|
||||
Inc(offset);
|
||||
|
||||
for (int counter = 0; counter < 4096; ++counter)
|
||||
{
|
||||
for (int k = 0; k < n; k++)
|
||||
{
|
||||
Inc(offset);
|
||||
Hash(digest, offset, part1);
|
||||
Array.Copy(part1, 0, w, w.Length - (k + 1) * part1.Length, part1.Length);
|
||||
}
|
||||
|
||||
Inc(offset);
|
||||
Hash(digest, offset, part1);
|
||||
Array.Copy(part1, part1.Length - ((w.Length - (n) * part1.Length)), w, 0, w.Length - n * part1.Length);
|
||||
|
||||
w[0] |= (byte)0x80;
|
||||
|
||||
BigInteger x = new BigInteger(1, w);
|
||||
|
||||
BigInteger c = x.Mod(q.ShiftLeft(1));
|
||||
|
||||
BigInteger p = x.Subtract(c.Subtract(BigInteger.One));
|
||||
|
||||
if (p.BitLength != L)
|
||||
continue;
|
||||
|
||||
if (p.IsProbablePrime(certainty))
|
||||
{
|
||||
BigInteger g = CalculateGenerator_FIPS186_2(p, q, random);
|
||||
|
||||
return new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual BigInteger CalculateGenerator_FIPS186_2(BigInteger p, BigInteger q, SecureRandom r)
|
||||
{
|
||||
BigInteger e = p.Subtract(BigInteger.One).Divide(q);
|
||||
BigInteger pSub2 = p.Subtract(BigInteger.Two);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
BigInteger h = BigIntegers.CreateRandomInRange(BigInteger.Two, pSub2, r);
|
||||
BigInteger g = h.ModPow(e, p);
|
||||
|
||||
if (g.BitLength > 1)
|
||||
return g;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* generate suitable parameters for DSA, in line with
|
||||
* <i>FIPS 186-3 A.1 Generation of the FFC Primes p and q</i>.
|
||||
*/
|
||||
protected virtual DsaParameters GenerateParameters_FIPS186_3()
|
||||
{
|
||||
// A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function
|
||||
IDigest d = digest;
|
||||
int outlen = d.GetDigestSize() * 8;
|
||||
|
||||
// 1. Check that the (L, N) pair is in the list of acceptable (L, N pairs) (see Section 4.2). If
|
||||
// the pair is not in the list, then return INVALID.
|
||||
// Note: checked at initialisation
|
||||
|
||||
// 2. If (seedlen < N), then return INVALID.
|
||||
// FIXME This should be configurable (must be >= N)
|
||||
int seedlen = N;
|
||||
byte[] seed = new byte[seedlen / 8];
|
||||
|
||||
// 3. n = ceiling(L ⁄ outlen) – 1.
|
||||
int n = (L - 1) / outlen;
|
||||
|
||||
// 4. b = L – 1 – (n ∗ outlen).
|
||||
int b = (L - 1) % outlen;
|
||||
|
||||
byte[] output = new byte[d.GetDigestSize()];
|
||||
for (;;)
|
||||
{
|
||||
// 5. Get an arbitrary sequence of seedlen bits as the domain_parameter_seed.
|
||||
random.NextBytes(seed);
|
||||
|
||||
// 6. U = Hash (domain_parameter_seed) mod 2^(N–1).
|
||||
Hash(d, seed, output);
|
||||
BigInteger U = new BigInteger(1, output).Mod(BigInteger.One.ShiftLeft(N - 1));
|
||||
|
||||
// 7. q = 2^(N–1) + U + 1 – ( U mod 2).
|
||||
BigInteger q = U.SetBit(0).SetBit(N - 1);
|
||||
|
||||
// 8. Test whether or not q is prime as specified in Appendix C.3.
|
||||
// TODO Review C.3 for primality checking
|
||||
if (!q.IsProbablePrime(certainty))
|
||||
{
|
||||
// 9. If q is not a prime, then go to step 5.
|
||||
continue;
|
||||
}
|
||||
|
||||
// 10. offset = 1.
|
||||
// Note: 'offset' value managed incrementally
|
||||
byte[] offset = Arrays.Clone(seed);
|
||||
|
||||
// 11. For counter = 0 to (4L – 1) do
|
||||
int counterLimit = 4 * L;
|
||||
for (int counter = 0; counter < counterLimit; ++counter)
|
||||
{
|
||||
// 11.1 For j = 0 to n do
|
||||
// Vj = Hash ((domain_parameter_seed + offset + j) mod 2^seedlen).
|
||||
// 11.2 W = V0 + (V1 ∗ 2^outlen) + ... + (V^(n–1) ∗ 2^((n–1) ∗ outlen)) + ((Vn mod 2^b) ∗ 2^(n ∗ outlen)).
|
||||
// TODO Assemble w as a byte array
|
||||
BigInteger W = BigInteger.Zero;
|
||||
for (int j = 0, exp = 0; j <= n; ++j, exp += outlen)
|
||||
{
|
||||
Inc(offset);
|
||||
Hash(d, offset, output);
|
||||
|
||||
BigInteger Vj = new BigInteger(1, output);
|
||||
if (j == n)
|
||||
{
|
||||
Vj = Vj.Mod(BigInteger.One.ShiftLeft(b));
|
||||
}
|
||||
|
||||
W = W.Add(Vj.ShiftLeft(exp));
|
||||
}
|
||||
|
||||
// 11.3 X = W + 2^(L–1). Comment: 0 ≤ W < 2L–1; hence, 2L–1 ≤ X < 2L.
|
||||
BigInteger X = W.Add(BigInteger.One.ShiftLeft(L - 1));
|
||||
|
||||
// 11.4 c = X mod 2q.
|
||||
BigInteger c = X.Mod(q.ShiftLeft(1));
|
||||
|
||||
// 11.5 p = X - (c - 1). Comment: p ≡ 1 (mod 2q).
|
||||
BigInteger p = X.Subtract(c.Subtract(BigInteger.One));
|
||||
|
||||
// 11.6 If (p < 2^(L - 1)), then go to step 11.9
|
||||
if (p.BitLength != L)
|
||||
continue;
|
||||
|
||||
// 11.7 Test whether or not p is prime as specified in Appendix C.3.
|
||||
// TODO Review C.3 for primality checking
|
||||
if (p.IsProbablePrime(certainty))
|
||||
{
|
||||
// 11.8 If p is determined to be prime, then return VALID and the values of p, q and
|
||||
// (optionally) the values of domain_parameter_seed and counter.
|
||||
// TODO Make configurable (8-bit unsigned)?
|
||||
|
||||
if (usageIndex >= 0)
|
||||
{
|
||||
BigInteger g = CalculateGenerator_FIPS186_3_Verifiable(d, p, q, seed, usageIndex);
|
||||
if (g != null)
|
||||
return new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter, usageIndex));
|
||||
}
|
||||
|
||||
{
|
||||
BigInteger g = CalculateGenerator_FIPS186_3_Unverifiable(p, q, random);
|
||||
|
||||
return new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter));
|
||||
}
|
||||
}
|
||||
|
||||
// 11.9 offset = offset + n + 1. Comment: Increment offset; then, as part of
|
||||
// the loop in step 11, increment counter; if
|
||||
// counter < 4L, repeat steps 11.1 through 11.8.
|
||||
// Note: 'offset' value already incremented in inner loop
|
||||
}
|
||||
// 12. Go to step 5.
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual BigInteger CalculateGenerator_FIPS186_3_Unverifiable(BigInteger p, BigInteger q,
|
||||
SecureRandom r)
|
||||
{
|
||||
return CalculateGenerator_FIPS186_2(p, q, r);
|
||||
}
|
||||
|
||||
protected virtual BigInteger CalculateGenerator_FIPS186_3_Verifiable(IDigest d, BigInteger p, BigInteger q,
|
||||
byte[] seed, int index)
|
||||
{
|
||||
// A.2.3 Verifiable Canonical Generation of the Generator g
|
||||
BigInteger e = p.Subtract(BigInteger.One).Divide(q);
|
||||
byte[] ggen = Hex.DecodeStrict("6767656E");
|
||||
|
||||
// 7. U = domain_parameter_seed || "ggen" || index || count.
|
||||
byte[] U = new byte[seed.Length + ggen.Length + 1 + 2];
|
||||
Array.Copy(seed, 0, U, 0, seed.Length);
|
||||
Array.Copy(ggen, 0, U, seed.Length, ggen.Length);
|
||||
U[U.Length - 3] = (byte)index;
|
||||
|
||||
byte[] w = new byte[d.GetDigestSize()];
|
||||
for (int count = 1; count < (1 << 16); ++count)
|
||||
{
|
||||
Inc(U);
|
||||
Hash(d, U, w);
|
||||
BigInteger W = new BigInteger(1, w);
|
||||
BigInteger g = W.ModPow(e, p);
|
||||
|
||||
if (g.CompareTo(BigInteger.Two) >= 0)
|
||||
return g;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static bool IsValidDsaStrength(
|
||||
int strength)
|
||||
{
|
||||
return strength >= 512 && strength <= 1024 && strength % 64 == 0;
|
||||
}
|
||||
|
||||
protected static void Hash(IDigest d, byte[] input, byte[] output)
|
||||
{
|
||||
d.BlockUpdate(input, 0, input.Length);
|
||||
d.DoFinal(output, 0);
|
||||
}
|
||||
|
||||
private static int GetDefaultN(int L)
|
||||
{
|
||||
return L > 1024 ? 256 : 160;
|
||||
}
|
||||
|
||||
protected static void Inc(byte[] buf)
|
||||
{
|
||||
for (int i = buf.Length - 1; i >= 0; --i)
|
||||
{
|
||||
byte b = (byte)(buf[i] + 1);
|
||||
buf[i] = b;
|
||||
|
||||
if (b != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b909747924741146803cbe3be2e7280
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
190
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/ECKeyPairGenerator.cs
vendored
Normal file
190
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/ECKeyPairGenerator.cs
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.Sec;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.X9;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.EC;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Multiplier;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
public class ECKeyPairGenerator
|
||||
: IAsymmetricCipherKeyPairGenerator
|
||||
{
|
||||
private readonly string algorithm;
|
||||
|
||||
private ECDomainParameters parameters;
|
||||
private DerObjectIdentifier publicKeyParamSet;
|
||||
private SecureRandom random;
|
||||
|
||||
public ECKeyPairGenerator()
|
||||
: this("EC")
|
||||
{
|
||||
}
|
||||
|
||||
public ECKeyPairGenerator(
|
||||
string algorithm)
|
||||
{
|
||||
if (algorithm == null)
|
||||
throw new ArgumentNullException("algorithm");
|
||||
|
||||
this.algorithm = ECKeyParameters.VerifyAlgorithmName(algorithm);
|
||||
}
|
||||
|
||||
public void Init(
|
||||
KeyGenerationParameters parameters)
|
||||
{
|
||||
if (parameters is ECKeyGenerationParameters)
|
||||
{
|
||||
ECKeyGenerationParameters ecP = (ECKeyGenerationParameters) parameters;
|
||||
|
||||
this.publicKeyParamSet = ecP.PublicKeyParamSet;
|
||||
this.parameters = ecP.DomainParameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
DerObjectIdentifier oid;
|
||||
switch (parameters.Strength)
|
||||
{
|
||||
case 192:
|
||||
oid = X9ObjectIdentifiers.Prime192v1;
|
||||
break;
|
||||
case 224:
|
||||
oid = SecObjectIdentifiers.SecP224r1;
|
||||
break;
|
||||
case 239:
|
||||
oid = X9ObjectIdentifiers.Prime239v1;
|
||||
break;
|
||||
case 256:
|
||||
oid = X9ObjectIdentifiers.Prime256v1;
|
||||
break;
|
||||
case 384:
|
||||
oid = SecObjectIdentifiers.SecP384r1;
|
||||
break;
|
||||
case 521:
|
||||
oid = SecObjectIdentifiers.SecP521r1;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidParameterException("unknown key size.");
|
||||
}
|
||||
|
||||
X9ECParameters ecps = FindECCurveByOid(oid);
|
||||
|
||||
this.publicKeyParamSet = oid;
|
||||
this.parameters = new ECDomainParameters(
|
||||
ecps.Curve, ecps.G, ecps.N, ecps.H, ecps.GetSeed());
|
||||
}
|
||||
|
||||
this.random = parameters.Random;
|
||||
|
||||
if (this.random == null)
|
||||
{
|
||||
this.random = CryptoServicesRegistrar.GetSecureRandom();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the domain parameters this routine generates an EC key
|
||||
* pair in accordance with X9.62 section 5.2.1 pages 26, 27.
|
||||
*/
|
||||
public AsymmetricCipherKeyPair GenerateKeyPair()
|
||||
{
|
||||
BigInteger n = parameters.N;
|
||||
BigInteger d;
|
||||
int minWeight = n.BitLength >> 2;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
d = new BigInteger(n.BitLength, random);
|
||||
|
||||
if (d.CompareTo(BigInteger.One) < 0 || d.CompareTo(n) >= 0)
|
||||
continue;
|
||||
|
||||
if (WNafUtilities.GetNafWeight(d) < minWeight)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
ECPoint q = CreateBasePointMultiplier().Multiply(parameters.G, d);
|
||||
|
||||
if (publicKeyParamSet != null)
|
||||
{
|
||||
return new AsymmetricCipherKeyPair(
|
||||
new ECPublicKeyParameters(algorithm, q, publicKeyParamSet),
|
||||
new ECPrivateKeyParameters(algorithm, d, publicKeyParamSet));
|
||||
}
|
||||
|
||||
return new AsymmetricCipherKeyPair(
|
||||
new ECPublicKeyParameters(algorithm, q, parameters),
|
||||
new ECPrivateKeyParameters(algorithm, d, parameters));
|
||||
}
|
||||
|
||||
protected virtual ECMultiplier CreateBasePointMultiplier()
|
||||
{
|
||||
return new FixedPointCombMultiplier();
|
||||
}
|
||||
|
||||
internal static X9ECParameters FindECCurveByName(string name)
|
||||
{
|
||||
X9ECParameters ecP = CustomNamedCurves.GetByName(name);
|
||||
if (ecP == null)
|
||||
{
|
||||
ecP = ECNamedCurveTable.GetByName(name);
|
||||
}
|
||||
return ecP;
|
||||
}
|
||||
|
||||
internal static X9ECParametersHolder FindECCurveByNameLazy(string name)
|
||||
{
|
||||
X9ECParametersHolder holder = CustomNamedCurves.GetByNameLazy(name);
|
||||
if (holder == null)
|
||||
{
|
||||
holder = ECNamedCurveTable.GetByNameLazy(name);
|
||||
}
|
||||
return holder;
|
||||
}
|
||||
|
||||
internal static X9ECParameters FindECCurveByOid(DerObjectIdentifier oid)
|
||||
{
|
||||
X9ECParameters ecP = CustomNamedCurves.GetByOid(oid);
|
||||
if (ecP == null)
|
||||
{
|
||||
ecP = ECNamedCurveTable.GetByOid(oid);
|
||||
}
|
||||
return ecP;
|
||||
}
|
||||
|
||||
internal static X9ECParametersHolder FindECCurveByOidLazy(DerObjectIdentifier oid)
|
||||
{
|
||||
X9ECParametersHolder holder = CustomNamedCurves.GetByOidLazy(oid);
|
||||
if (holder == null)
|
||||
{
|
||||
holder = ECNamedCurveTable.GetByOidLazy(oid);
|
||||
}
|
||||
return holder;
|
||||
}
|
||||
|
||||
internal static ECPublicKeyParameters GetCorrespondingPublicKey(
|
||||
ECPrivateKeyParameters privKey)
|
||||
{
|
||||
ECDomainParameters ec = privKey.Parameters;
|
||||
ECPoint q = new FixedPointCombMultiplier().Multiply(ec.G, privKey.D);
|
||||
|
||||
if (privKey.PublicKeyParamSet != null)
|
||||
{
|
||||
return new ECPublicKeyParameters(privKey.AlgorithmName, q, privKey.PublicKeyParamSet);
|
||||
}
|
||||
|
||||
return new ECPublicKeyParameters(privKey.AlgorithmName, q, ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e92a9e0fd2d687a4ab1287c7157ec5a3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
public class Ed25519KeyPairGenerator
|
||||
: IAsymmetricCipherKeyPairGenerator
|
||||
{
|
||||
private SecureRandom random;
|
||||
|
||||
public virtual void Init(KeyGenerationParameters parameters)
|
||||
{
|
||||
this.random = parameters.Random;
|
||||
}
|
||||
|
||||
public virtual AsymmetricCipherKeyPair GenerateKeyPair()
|
||||
{
|
||||
Ed25519PrivateKeyParameters privateKey = new Ed25519PrivateKeyParameters(random);
|
||||
Ed25519PublicKeyParameters publicKey = privateKey.GeneratePublicKey();
|
||||
return new AsymmetricCipherKeyPair(publicKey, privateKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05a4d5644f5c6e64f85d8825a8bb766c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
public class Ed448KeyPairGenerator
|
||||
: IAsymmetricCipherKeyPairGenerator
|
||||
{
|
||||
private SecureRandom random;
|
||||
|
||||
public virtual void Init(KeyGenerationParameters parameters)
|
||||
{
|
||||
this.random = parameters.Random;
|
||||
}
|
||||
|
||||
public virtual AsymmetricCipherKeyPair GenerateKeyPair()
|
||||
{
|
||||
Ed448PrivateKeyParameters privateKey = new Ed448PrivateKeyParameters(random);
|
||||
Ed448PublicKeyParameters publicKey = privateKey.GeneratePublicKey();
|
||||
return new AsymmetricCipherKeyPair(publicKey, privateKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 226ca45f4849c5344b748d2d66f408ff
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,44 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* a ElGamal key pair generator.
|
||||
* <p>
|
||||
* This Generates keys consistent for use with ElGamal as described in
|
||||
* page 164 of "Handbook of Applied Cryptography".</p>
|
||||
*/
|
||||
public class ElGamalKeyPairGenerator
|
||||
: IAsymmetricCipherKeyPairGenerator
|
||||
{
|
||||
private ElGamalKeyGenerationParameters param;
|
||||
|
||||
public void Init(
|
||||
KeyGenerationParameters parameters)
|
||||
{
|
||||
this.param = (ElGamalKeyGenerationParameters) parameters;
|
||||
}
|
||||
|
||||
public AsymmetricCipherKeyPair GenerateKeyPair()
|
||||
{
|
||||
DHKeyGeneratorHelper helper = DHKeyGeneratorHelper.Instance;
|
||||
ElGamalParameters egp = param.Parameters;
|
||||
DHParameters dhp = new DHParameters(egp.P, egp.G, null, 0, egp.L);
|
||||
|
||||
BigInteger x = helper.CalculatePrivate(dhp, param.Random);
|
||||
BigInteger y = helper.CalculatePublic(dhp, x);
|
||||
|
||||
return new AsymmetricCipherKeyPair(
|
||||
new ElGamalPublicKeyParameters(y, egp),
|
||||
new ElGamalPrivateKeyParameters(x, egp));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8cdb2b6491a41e14c9390d896b88a607
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,50 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
public class ElGamalParametersGenerator
|
||||
{
|
||||
private int size;
|
||||
private int certainty;
|
||||
private SecureRandom random;
|
||||
|
||||
public void Init(
|
||||
int size,
|
||||
int certainty,
|
||||
SecureRandom random)
|
||||
{
|
||||
this.size = size;
|
||||
this.certainty = certainty;
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
/**
|
||||
* which Generates the p and g values from the given parameters,
|
||||
* returning the ElGamalParameters object.
|
||||
* <p>
|
||||
* Note: can take a while...
|
||||
* </p>
|
||||
*/
|
||||
public ElGamalParameters GenerateParameters()
|
||||
{
|
||||
//
|
||||
// find a safe prime p where p = 2*q + 1, where p and q are prime.
|
||||
//
|
||||
BigInteger[] safePrimes = DHParametersHelper.GenerateSafePrimes(size, certainty, random);
|
||||
|
||||
BigInteger p = safePrimes[0];
|
||||
BigInteger q = safePrimes[1];
|
||||
BigInteger g = DHParametersHelper.SelectGenerator(p, q, random);
|
||||
|
||||
return new ElGamalParameters(p, g);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d37f120fe9417b489fddcaf24464bcf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,86 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.CryptoPro;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Multiplier;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* a GOST3410 key pair generator.
|
||||
* This generates GOST3410 keys in line with the method described
|
||||
* in GOST R 34.10-94.
|
||||
*/
|
||||
public class Gost3410KeyPairGenerator
|
||||
: IAsymmetricCipherKeyPairGenerator
|
||||
{
|
||||
private Gost3410KeyGenerationParameters param;
|
||||
|
||||
public void Init(
|
||||
KeyGenerationParameters parameters)
|
||||
{
|
||||
if (parameters is Gost3410KeyGenerationParameters)
|
||||
{
|
||||
this.param = (Gost3410KeyGenerationParameters) parameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
Gost3410KeyGenerationParameters kgp = new Gost3410KeyGenerationParameters(
|
||||
parameters.Random,
|
||||
CryptoProObjectIdentifiers.GostR3410x94CryptoProA);
|
||||
|
||||
if (parameters.Strength != kgp.Parameters.P.BitLength - 1)
|
||||
{
|
||||
// TODO Should we complain?
|
||||
}
|
||||
|
||||
this.param = kgp;
|
||||
}
|
||||
}
|
||||
|
||||
public AsymmetricCipherKeyPair GenerateKeyPair()
|
||||
{
|
||||
SecureRandom random = param.Random;
|
||||
Gost3410Parameters gost3410Params = param.Parameters;
|
||||
|
||||
BigInteger q = gost3410Params.Q, x;
|
||||
|
||||
int minWeight = 64;
|
||||
for (;;)
|
||||
{
|
||||
x = new BigInteger(256, random);
|
||||
|
||||
if (x.SignValue < 1 || x.CompareTo(q) >= 0)
|
||||
continue;
|
||||
|
||||
if (WNafUtilities.GetNafWeight(x) < minWeight)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
BigInteger p = gost3410Params.P;
|
||||
BigInteger a = gost3410Params.A;
|
||||
|
||||
// calculate the public key.
|
||||
BigInteger y = a.ModPow(x, p);
|
||||
|
||||
if (param.PublicKeyParamSet != null)
|
||||
{
|
||||
return new AsymmetricCipherKeyPair(
|
||||
new Gost3410PublicKeyParameters(y, param.PublicKeyParamSet),
|
||||
new Gost3410PrivateKeyParameters(x, param.PublicKeyParamSet));
|
||||
}
|
||||
|
||||
return new AsymmetricCipherKeyPair(
|
||||
new Gost3410PublicKeyParameters(y, gost3410Params),
|
||||
new Gost3410PrivateKeyParameters(x, gost3410Params));
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0d6deb37aecdd74681d22229adbb1f0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,534 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* generate suitable parameters for GOST3410.
|
||||
*/
|
||||
public class Gost3410ParametersGenerator
|
||||
{
|
||||
private int size;
|
||||
private int typeproc;
|
||||
private SecureRandom init_random;
|
||||
|
||||
/**
|
||||
* initialise the key generator.
|
||||
*
|
||||
* @param size size of the key
|
||||
* @param typeProcedure type procedure A,B = 1; A',B' - else
|
||||
* @param random random byte source.
|
||||
*/
|
||||
public void Init(
|
||||
int size,
|
||||
int typeProcedure,
|
||||
SecureRandom random)
|
||||
{
|
||||
this.size = size;
|
||||
this.typeproc = typeProcedure;
|
||||
this.init_random = random;
|
||||
}
|
||||
|
||||
//Procedure A
|
||||
private int procedure_A(int x0, int c, BigInteger[] pq, int size)
|
||||
{
|
||||
//Verify and perform condition: 0<x<2^16; 0<c<2^16; c - odd.
|
||||
while(x0<0 || x0>65536)
|
||||
{
|
||||
x0 = init_random.NextInt()/32768;
|
||||
}
|
||||
|
||||
while((c<0 || c>65536) || (c/2==0))
|
||||
{
|
||||
c = init_random.NextInt()/32768 + 1;
|
||||
}
|
||||
|
||||
BigInteger C = BigInteger.ValueOf(c);
|
||||
BigInteger constA16 = BigInteger.ValueOf(19381);
|
||||
|
||||
//step1
|
||||
BigInteger[] y = new BigInteger[1]; // begin length = 1
|
||||
y[0] = BigInteger.ValueOf(x0);
|
||||
|
||||
//step 2
|
||||
int[] t = new int[1]; // t - orders; begin length = 1
|
||||
t[0] = size;
|
||||
int s = 0;
|
||||
for (int i=0; t[i]>=17; i++)
|
||||
{
|
||||
// extension array t
|
||||
int[] tmp_t = new int[t.Length + 1]; ///////////////
|
||||
Array.Copy(t,0,tmp_t,0,t.Length); // extension
|
||||
t = new int[tmp_t.Length]; // array t
|
||||
Array.Copy(tmp_t, 0, t, 0, tmp_t.Length); ///////////////
|
||||
|
||||
t[i+1] = t[i]/2;
|
||||
s = i+1;
|
||||
}
|
||||
|
||||
//step3
|
||||
BigInteger[] p = new BigInteger[s+1];
|
||||
p[s] = new BigInteger("8003",16); //set min prime number length 16 bit
|
||||
|
||||
int m = s-1; //step4
|
||||
|
||||
for (int i=0; i<s; i++)
|
||||
{
|
||||
int rm = t[m]/16; //step5
|
||||
|
||||
step6: for(;;)
|
||||
{
|
||||
//step 6
|
||||
BigInteger[] tmp_y = new BigInteger[y.Length]; ////////////////
|
||||
Array.Copy(y,0,tmp_y,0,y.Length); // extension
|
||||
y = new BigInteger[rm+1]; // array y
|
||||
Array.Copy(tmp_y,0,y,0,tmp_y.Length); ////////////////
|
||||
|
||||
for (int j=0; j<rm; j++)
|
||||
{
|
||||
y[j+1] = (y[j].Multiply(constA16).Add(C)).Mod(BigInteger.Two.Pow(16));
|
||||
}
|
||||
|
||||
//step 7
|
||||
BigInteger Ym = BigInteger.Zero;
|
||||
for (int j=0; j<rm; j++)
|
||||
{
|
||||
Ym = Ym.Add(y[j].ShiftLeft(16*j));
|
||||
}
|
||||
|
||||
y[0] = y[rm]; //step 8
|
||||
|
||||
//step 9
|
||||
BigInteger N = BigInteger.One.ShiftLeft(t[m]-1).Divide(p[m+1]).Add(
|
||||
Ym.ShiftLeft(t[m]-1).Divide(p[m+1].ShiftLeft(16*rm)));
|
||||
|
||||
if (N.TestBit(0))
|
||||
{
|
||||
N = N.Add(BigInteger.One);
|
||||
}
|
||||
|
||||
//step 10
|
||||
|
||||
for(;;)
|
||||
{
|
||||
//step 11
|
||||
BigInteger NByLastP = N.Multiply(p[m+1]);
|
||||
|
||||
if (NByLastP.BitLength > t[m])
|
||||
{
|
||||
goto step6; //step 12
|
||||
}
|
||||
|
||||
p[m] = NByLastP.Add(BigInteger.One);
|
||||
|
||||
//step13
|
||||
if (BigInteger.Two.ModPow(NByLastP, p[m]).CompareTo(BigInteger.One) == 0
|
||||
&& BigInteger.Two.ModPow(N, p[m]).CompareTo(BigInteger.One) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
N = N.Add(BigInteger.Two);
|
||||
}
|
||||
|
||||
if (--m < 0)
|
||||
{
|
||||
pq[0] = p[0];
|
||||
pq[1] = p[1];
|
||||
return y[0].IntValue; //return for procedure B step 2
|
||||
}
|
||||
|
||||
break; //step 14
|
||||
}
|
||||
}
|
||||
return y[0].IntValue;
|
||||
}
|
||||
|
||||
//Procedure A'
|
||||
private long procedure_Aa(long x0, long c, BigInteger[] pq, int size)
|
||||
{
|
||||
//Verify and perform condition: 0<x<2^32; 0<c<2^32; c - odd.
|
||||
while(x0<0 || x0>4294967296L)
|
||||
{
|
||||
x0 = init_random.NextInt()*2;
|
||||
}
|
||||
|
||||
while((c<0 || c>4294967296L) || (c/2==0))
|
||||
{
|
||||
c = init_random.NextInt()*2+1;
|
||||
}
|
||||
|
||||
BigInteger C = BigInteger.ValueOf(c);
|
||||
BigInteger constA32 = BigInteger.ValueOf(97781173);
|
||||
|
||||
//step1
|
||||
BigInteger[] y = new BigInteger[1]; // begin length = 1
|
||||
y[0] = BigInteger.ValueOf(x0);
|
||||
|
||||
//step 2
|
||||
int[] t = new int[1]; // t - orders; begin length = 1
|
||||
t[0] = size;
|
||||
int s = 0;
|
||||
for (int i=0; t[i]>=33; i++)
|
||||
{
|
||||
// extension array t
|
||||
int[] tmp_t = new int[t.Length + 1]; ///////////////
|
||||
Array.Copy(t,0,tmp_t,0,t.Length); // extension
|
||||
t = new int[tmp_t.Length]; // array t
|
||||
Array.Copy(tmp_t, 0, t, 0, tmp_t.Length); ///////////////
|
||||
|
||||
t[i+1] = t[i]/2;
|
||||
s = i+1;
|
||||
}
|
||||
|
||||
//step3
|
||||
BigInteger[] p = new BigInteger[s+1];
|
||||
p[s] = new BigInteger("8000000B",16); //set min prime number length 32 bit
|
||||
|
||||
int m = s-1; //step4
|
||||
|
||||
for (int i=0; i<s; i++)
|
||||
{
|
||||
int rm = t[m]/32; //step5
|
||||
|
||||
step6: for(;;)
|
||||
{
|
||||
//step 6
|
||||
BigInteger[] tmp_y = new BigInteger[y.Length]; ////////////////
|
||||
Array.Copy(y,0,tmp_y,0,y.Length); // extension
|
||||
y = new BigInteger[rm+1]; // array y
|
||||
Array.Copy(tmp_y,0,y,0,tmp_y.Length); ////////////////
|
||||
|
||||
for (int j=0; j<rm; j++)
|
||||
{
|
||||
y[j+1] = (y[j].Multiply(constA32).Add(C)).Mod(BigInteger.Two.Pow(32));
|
||||
}
|
||||
|
||||
//step 7
|
||||
BigInteger Ym = BigInteger.Zero;
|
||||
for (int j=0; j<rm; j++)
|
||||
{
|
||||
Ym = Ym.Add(y[j].ShiftLeft(32*j));
|
||||
}
|
||||
|
||||
y[0] = y[rm]; //step 8
|
||||
|
||||
//step 9
|
||||
BigInteger N = BigInteger.One.ShiftLeft(t[m]-1).Divide(p[m+1]).Add(
|
||||
Ym.ShiftLeft(t[m]-1).Divide(p[m+1].ShiftLeft(32*rm)));
|
||||
|
||||
if (N.TestBit(0))
|
||||
{
|
||||
N = N.Add(BigInteger.One);
|
||||
}
|
||||
|
||||
//step 10
|
||||
|
||||
for(;;)
|
||||
{
|
||||
//step 11
|
||||
BigInteger NByLastP = N.Multiply(p[m+1]);
|
||||
|
||||
if (NByLastP.BitLength > t[m])
|
||||
{
|
||||
goto step6; //step 12
|
||||
}
|
||||
|
||||
p[m] = NByLastP.Add(BigInteger.One);
|
||||
|
||||
//step13
|
||||
if (BigInteger.Two.ModPow(NByLastP, p[m]).CompareTo(BigInteger.One) == 0
|
||||
&& BigInteger.Two.ModPow(N, p[m]).CompareTo(BigInteger.One) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
N = N.Add(BigInteger.Two);
|
||||
}
|
||||
|
||||
if (--m < 0)
|
||||
{
|
||||
pq[0] = p[0];
|
||||
pq[1] = p[1];
|
||||
return y[0].LongValue; //return for procedure B' step 2
|
||||
}
|
||||
|
||||
break; //step 14
|
||||
}
|
||||
}
|
||||
return y[0].LongValue;
|
||||
}
|
||||
|
||||
//Procedure B
|
||||
private void procedure_B(int x0, int c, BigInteger[] pq)
|
||||
{
|
||||
//Verify and perform condition: 0<x<2^16; 0<c<2^16; c - odd.
|
||||
while(x0<0 || x0>65536)
|
||||
{
|
||||
x0 = init_random.NextInt()/32768;
|
||||
}
|
||||
|
||||
while((c<0 || c>65536) || (c/2==0))
|
||||
{
|
||||
c = init_random.NextInt()/32768 + 1;
|
||||
}
|
||||
|
||||
BigInteger [] qp = new BigInteger[2];
|
||||
BigInteger q = null, Q = null, p = null;
|
||||
BigInteger C = BigInteger.ValueOf(c);
|
||||
BigInteger constA16 = BigInteger.ValueOf(19381);
|
||||
|
||||
//step1
|
||||
x0 = procedure_A(x0, c, qp, 256);
|
||||
q = qp[0];
|
||||
|
||||
//step2
|
||||
x0 = procedure_A(x0, c, qp, 512);
|
||||
Q = qp[0];
|
||||
|
||||
BigInteger[] y = new BigInteger[65];
|
||||
y[0] = BigInteger.ValueOf(x0);
|
||||
|
||||
const int tp = 1024;
|
||||
|
||||
BigInteger qQ = q.Multiply(Q);
|
||||
|
||||
step3:
|
||||
for(;;)
|
||||
{
|
||||
//step 3
|
||||
for (int j=0; j<64; j++)
|
||||
{
|
||||
y[j+1] = (y[j].Multiply(constA16).Add(C)).Mod(BigInteger.Two.Pow(16));
|
||||
}
|
||||
|
||||
//step 4
|
||||
BigInteger Y = BigInteger.Zero;
|
||||
|
||||
for (int j=0; j<64; j++)
|
||||
{
|
||||
Y = Y.Add(y[j].ShiftLeft(16*j));
|
||||
}
|
||||
|
||||
y[0] = y[64]; //step 5
|
||||
|
||||
//step 6
|
||||
BigInteger N = BigInteger.One.ShiftLeft(tp-1).Divide(qQ).Add(
|
||||
Y.ShiftLeft(tp-1).Divide(qQ.ShiftLeft(1024)));
|
||||
|
||||
if (N.TestBit(0))
|
||||
{
|
||||
N = N.Add(BigInteger.One);
|
||||
}
|
||||
|
||||
//step 7
|
||||
|
||||
for(;;)
|
||||
{
|
||||
//step 11
|
||||
BigInteger qQN = qQ.Multiply(N);
|
||||
|
||||
if (qQN.BitLength > tp)
|
||||
{
|
||||
goto step3; //step 9
|
||||
}
|
||||
|
||||
p = qQN.Add(BigInteger.One);
|
||||
|
||||
//step10
|
||||
if (BigInteger.Two.ModPow(qQN, p).CompareTo(BigInteger.One) == 0
|
||||
&& BigInteger.Two.ModPow(q.Multiply(N), p).CompareTo(BigInteger.One) != 0)
|
||||
{
|
||||
pq[0] = p;
|
||||
pq[1] = q;
|
||||
return;
|
||||
}
|
||||
|
||||
N = N.Add(BigInteger.Two);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Procedure B'
|
||||
private void procedure_Bb(long x0, long c, BigInteger[] pq)
|
||||
{
|
||||
//Verify and perform condition: 0<x<2^32; 0<c<2^32; c - odd.
|
||||
while(x0<0 || x0>4294967296L)
|
||||
{
|
||||
x0 = init_random.NextInt()*2;
|
||||
}
|
||||
|
||||
while((c<0 || c>4294967296L) || (c/2==0))
|
||||
{
|
||||
c = init_random.NextInt()*2+1;
|
||||
}
|
||||
|
||||
BigInteger [] qp = new BigInteger[2];
|
||||
BigInteger q = null, Q = null, p = null;
|
||||
BigInteger C = BigInteger.ValueOf(c);
|
||||
BigInteger constA32 = BigInteger.ValueOf(97781173);
|
||||
|
||||
//step1
|
||||
x0 = procedure_Aa(x0, c, qp, 256);
|
||||
q = qp[0];
|
||||
|
||||
//step2
|
||||
x0 = procedure_Aa(x0, c, qp, 512);
|
||||
Q = qp[0];
|
||||
|
||||
BigInteger[] y = new BigInteger[33];
|
||||
y[0] = BigInteger.ValueOf(x0);
|
||||
|
||||
const int tp = 1024;
|
||||
|
||||
BigInteger qQ = q.Multiply(Q);
|
||||
|
||||
step3:
|
||||
for(;;)
|
||||
{
|
||||
//step 3
|
||||
for (int j=0; j<32; j++)
|
||||
{
|
||||
y[j+1] = (y[j].Multiply(constA32).Add(C)).Mod(BigInteger.Two.Pow(32));
|
||||
}
|
||||
|
||||
//step 4
|
||||
BigInteger Y = BigInteger.Zero;
|
||||
for (int j=0; j<32; j++)
|
||||
{
|
||||
Y = Y.Add(y[j].ShiftLeft(32*j));
|
||||
}
|
||||
|
||||
y[0] = y[32]; //step 5
|
||||
|
||||
//step 6
|
||||
BigInteger N = BigInteger.One.ShiftLeft(tp-1).Divide(qQ).Add(
|
||||
Y.ShiftLeft(tp-1).Divide(qQ.ShiftLeft(1024)));
|
||||
|
||||
if (N.TestBit(0))
|
||||
{
|
||||
N = N.Add(BigInteger.One);
|
||||
}
|
||||
|
||||
//step 7
|
||||
|
||||
for(;;)
|
||||
{
|
||||
//step 11
|
||||
BigInteger qQN = qQ.Multiply(N);
|
||||
|
||||
if (qQN.BitLength > tp)
|
||||
{
|
||||
goto step3; //step 9
|
||||
}
|
||||
|
||||
p = qQN.Add(BigInteger.One);
|
||||
|
||||
//step10
|
||||
if (BigInteger.Two.ModPow(qQN, p).CompareTo(BigInteger.One) == 0
|
||||
&& BigInteger.Two.ModPow(q.Multiply(N), p).CompareTo(BigInteger.One) != 0)
|
||||
{
|
||||
pq[0] = p;
|
||||
pq[1] = q;
|
||||
return;
|
||||
}
|
||||
|
||||
N = N.Add(BigInteger.Two);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Procedure C
|
||||
* procedure generates the a value from the given p,q,
|
||||
* returning the a value.
|
||||
*/
|
||||
private BigInteger procedure_C(BigInteger p, BigInteger q)
|
||||
{
|
||||
BigInteger pSub1 = p.Subtract(BigInteger.One);
|
||||
BigInteger pSub1Divq = pSub1.Divide(q);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
BigInteger d = new BigInteger(p.BitLength, init_random);
|
||||
|
||||
// 1 < d < p-1
|
||||
if (d.CompareTo(BigInteger.One) > 0 && d.CompareTo(pSub1) < 0)
|
||||
{
|
||||
BigInteger a = d.ModPow(pSub1Divq, p);
|
||||
|
||||
if (a.CompareTo(BigInteger.One) != 0)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* which generates the p , q and a values from the given parameters,
|
||||
* returning the Gost3410Parameters object.
|
||||
*/
|
||||
public Gost3410Parameters GenerateParameters()
|
||||
{
|
||||
BigInteger [] pq = new BigInteger[2];
|
||||
BigInteger q = null, p = null, a = null;
|
||||
|
||||
int x0, c;
|
||||
long x0L, cL;
|
||||
|
||||
if (typeproc==1)
|
||||
{
|
||||
x0 = init_random.NextInt();
|
||||
c = init_random.NextInt();
|
||||
|
||||
switch(size)
|
||||
{
|
||||
case 512:
|
||||
procedure_A(x0, c, pq, 512);
|
||||
break;
|
||||
case 1024:
|
||||
procedure_B(x0, c, pq);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Ooops! key size 512 or 1024 bit.");
|
||||
}
|
||||
p = pq[0]; q = pq[1];
|
||||
a = procedure_C(p, q);
|
||||
//System.out.println("p:"+p.toString(16)+"\n"+"q:"+q.toString(16)+"\n"+"a:"+a.toString(16));
|
||||
//System.out.println("p:"+p+"\n"+"q:"+q+"\n"+"a:"+a);
|
||||
return new Gost3410Parameters(p, q, a, new Gost3410ValidationParameters(x0, c));
|
||||
}
|
||||
else
|
||||
{
|
||||
x0L = init_random.NextLong();
|
||||
cL = init_random.NextLong();
|
||||
|
||||
switch(size)
|
||||
{
|
||||
case 512:
|
||||
procedure_Aa(x0L, cL, pq, 512);
|
||||
break;
|
||||
case 1024:
|
||||
procedure_Bb(x0L, cL, pq);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("Ooops! key size 512 or 1024 bit.");
|
||||
}
|
||||
p = pq[0]; q = pq[1];
|
||||
a = procedure_C(p, q);
|
||||
//System.out.println("p:"+p.toString(16)+"\n"+"q:"+q.toString(16)+"\n"+"a:"+a.toString(16));
|
||||
//System.out.println("p:"+p+"\n"+"q:"+q+"\n"+"a:"+a);
|
||||
return new Gost3410Parameters(p, q, a, new Gost3410ValidationParameters(x0L, cL));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85de73367cf272f47b6a49d02a0536b1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
180
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/HKDFBytesGenerator.cs
vendored
Normal file
180
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/HKDFBytesGenerator.cs
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* HMAC-based Extract-and-Expand Key Derivation Function (HKDF) implemented
|
||||
* according to IETF RFC 5869, May 2010 as specified by H. Krawczyk, IBM
|
||||
* Research & P. Eronen, Nokia. It uses a HMac internally to compute de OKM
|
||||
* (output keying material) and is likely to have better security properties
|
||||
* than KDF's based on just a hash function.
|
||||
*/
|
||||
public sealed class HkdfBytesGenerator
|
||||
: IDerivationFunction
|
||||
{
|
||||
private HMac hMacHash;
|
||||
private int hashLen;
|
||||
|
||||
private byte[] info;
|
||||
private byte[] currentT;
|
||||
|
||||
private int generatedBytes;
|
||||
|
||||
/**
|
||||
* Creates a HKDFBytesGenerator based on the given hash function.
|
||||
*
|
||||
* @param hash the digest to be used as the source of generatedBytes bytes
|
||||
*/
|
||||
public HkdfBytesGenerator(IDigest hash)
|
||||
{
|
||||
this.hMacHash = new HMac(hash);
|
||||
this.hashLen = hash.GetDigestSize();
|
||||
}
|
||||
|
||||
public void Init(IDerivationParameters parameters)
|
||||
{
|
||||
if (!(parameters is HkdfParameters hkdfParameters))
|
||||
throw new ArgumentException("HKDF parameters required for HkdfBytesGenerator", "parameters");
|
||||
|
||||
if (hkdfParameters.SkipExtract)
|
||||
{
|
||||
// use IKM directly as PRK
|
||||
hMacHash.Init(new KeyParameter(hkdfParameters.GetIkm()));
|
||||
}
|
||||
else
|
||||
{
|
||||
hMacHash.Init(Extract(hkdfParameters.GetSalt(), hkdfParameters.GetIkm()));
|
||||
}
|
||||
|
||||
info = hkdfParameters.GetInfo();
|
||||
|
||||
generatedBytes = 0;
|
||||
currentT = new byte[hashLen];
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the extract part of the key derivation function.
|
||||
*
|
||||
* @param salt the salt to use
|
||||
* @param ikm the input keying material
|
||||
* @return the PRK as KeyParameter
|
||||
*/
|
||||
private KeyParameter Extract(byte[] salt, byte[] ikm)
|
||||
{
|
||||
if (salt == null)
|
||||
{
|
||||
// TODO check if hashLen is indeed same as HMAC size
|
||||
hMacHash.Init(new KeyParameter(new byte[hashLen]));
|
||||
}
|
||||
else
|
||||
{
|
||||
hMacHash.Init(new KeyParameter(salt));
|
||||
}
|
||||
|
||||
hMacHash.BlockUpdate(ikm, 0, ikm.Length);
|
||||
|
||||
byte[] prk = new byte[hashLen];
|
||||
hMacHash.DoFinal(prk, 0);
|
||||
return new KeyParameter(prk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the expand part of the key derivation function, using currentT
|
||||
* as input and output buffer.
|
||||
*
|
||||
* @throws DataLengthException if the total number of bytes generated is larger than the one
|
||||
* specified by RFC 5869 (255 * HashLen)
|
||||
*/
|
||||
private void ExpandNext()
|
||||
{
|
||||
int n = generatedBytes / hashLen + 1;
|
||||
if (n >= 256)
|
||||
{
|
||||
throw new DataLengthException(
|
||||
"HKDF cannot generate more than 255 blocks of HashLen size");
|
||||
}
|
||||
// special case for T(0): T(0) is empty, so no update
|
||||
if (generatedBytes != 0)
|
||||
{
|
||||
hMacHash.BlockUpdate(currentT, 0, hashLen);
|
||||
}
|
||||
hMacHash.BlockUpdate(info, 0, info.Length);
|
||||
hMacHash.Update((byte)n);
|
||||
hMacHash.DoFinal(currentT, 0);
|
||||
}
|
||||
|
||||
public IDigest Digest => hMacHash.GetUnderlyingDigest();
|
||||
|
||||
public int GenerateBytes(byte[] output, int outOff, int length)
|
||||
{
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
return GenerateBytes(output.AsSpan(outOff, length));
|
||||
#else
|
||||
if (generatedBytes > 255 * hashLen - length)
|
||||
throw new DataLengthException("HKDF may only be used for 255 * HashLen bytes of output");
|
||||
|
||||
int toGenerate = length;
|
||||
int posInT = generatedBytes % hashLen;
|
||||
if (posInT != 0)
|
||||
{
|
||||
// copy what is left in the currentT (1..hash
|
||||
int toCopy = System.Math.Min(hashLen - posInT, toGenerate);
|
||||
Array.Copy(currentT, posInT, output, outOff, toCopy);
|
||||
generatedBytes += toCopy;
|
||||
toGenerate -= toCopy;
|
||||
outOff += toCopy;
|
||||
}
|
||||
|
||||
while (toGenerate > 0)
|
||||
{
|
||||
ExpandNext();
|
||||
int toCopy = System.Math.Min(hashLen, toGenerate);
|
||||
Array.Copy(currentT, 0, output, outOff, toCopy);
|
||||
generatedBytes += toCopy;
|
||||
toGenerate -= toCopy;
|
||||
outOff += toCopy;
|
||||
}
|
||||
|
||||
return length;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
public int GenerateBytes(Span<byte> output)
|
||||
{
|
||||
int length = output.Length;
|
||||
if (generatedBytes > 255 * hashLen - length)
|
||||
throw new DataLengthException("HKDF may only be used for 255 * HashLen bytes of output");
|
||||
|
||||
int posInT = generatedBytes % hashLen;
|
||||
if (posInT != 0)
|
||||
{
|
||||
// copy what is left in the currentT (1..hash
|
||||
int toCopy = System.Math.Min(hashLen - posInT, output.Length);
|
||||
currentT.AsSpan(posInT, toCopy).CopyTo(output);
|
||||
generatedBytes += toCopy;
|
||||
output = output[toCopy..];
|
||||
}
|
||||
|
||||
while (!output.IsEmpty)
|
||||
{
|
||||
ExpandNext();
|
||||
int toCopy = System.Math.Min(hashLen, output.Length);
|
||||
currentT.AsSpan(0, toCopy).CopyTo(output);
|
||||
generatedBytes += toCopy;
|
||||
output = output[toCopy..];
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5dc8bb4a7ea06e64ca30ed36950729de
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,166 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
public sealed class KdfCounterBytesGenerator
|
||||
: IMacDerivationFunction
|
||||
{
|
||||
private readonly IMac prf;
|
||||
private readonly int h;
|
||||
|
||||
private byte[] fixedInputDataCtrPrefix;
|
||||
private byte[] fixedInputData_afterCtr;
|
||||
private int maxSizeExcl;
|
||||
// ios is i defined as an octet string (the binary representation)
|
||||
private byte[] ios;
|
||||
|
||||
// operational
|
||||
private int generatedBytes;
|
||||
// k is used as buffer for all K(i) values
|
||||
private byte[] k;
|
||||
|
||||
public KdfCounterBytesGenerator(IMac prf)
|
||||
{
|
||||
this.prf = prf;
|
||||
this.h = prf.GetMacSize();
|
||||
this.k = new byte[h];
|
||||
}
|
||||
|
||||
public void Init(IDerivationParameters param)
|
||||
{
|
||||
if (!(param is KdfCounterParameters kdfParams))
|
||||
throw new ArgumentException("Wrong type of arguments given");
|
||||
|
||||
// --- init mac based PRF ---
|
||||
|
||||
this.prf.Init(new KeyParameter(kdfParams.Ki));
|
||||
|
||||
// --- set arguments ---
|
||||
|
||||
this.fixedInputDataCtrPrefix = kdfParams.FixedInputDataCounterPrefix;
|
||||
this.fixedInputData_afterCtr = kdfParams.FixedInputDataCounterSuffix;
|
||||
|
||||
int r = kdfParams.R;
|
||||
this.ios = new byte[r / 8];
|
||||
|
||||
BigInteger maxSize = BigInteger.One.ShiftLeft(r).Multiply(BigInteger.ValueOf(h));
|
||||
this.maxSizeExcl = maxSize.BitLength > 31 ? int.MaxValue : maxSize.IntValueExact;
|
||||
|
||||
// --- set operational state ---
|
||||
|
||||
generatedBytes = 0;
|
||||
}
|
||||
|
||||
public IMac Mac => prf;
|
||||
|
||||
public IDigest Digest
|
||||
{
|
||||
get { return (prf as HMac)?.GetUnderlyingDigest(); }
|
||||
}
|
||||
|
||||
public int GenerateBytes(byte[] output, int outOff, int length)
|
||||
{
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
return GenerateBytes(output.AsSpan(outOff, length));
|
||||
#else
|
||||
if (generatedBytes >= maxSizeExcl - length)
|
||||
throw new DataLengthException("Current KDFCTR may only be used for " + maxSizeExcl + " bytes");
|
||||
|
||||
int toGenerate = length;
|
||||
int posInK = generatedBytes % h;
|
||||
if (posInK != 0)
|
||||
{
|
||||
// copy what is left in the currentT (1..hash
|
||||
int toCopy = System.Math.Min(h - posInK, toGenerate);
|
||||
Array.Copy(k, posInK, output, outOff, toCopy);
|
||||
generatedBytes += toCopy;
|
||||
toGenerate -= toCopy;
|
||||
outOff += toCopy;
|
||||
}
|
||||
|
||||
while (toGenerate > 0)
|
||||
{
|
||||
GenerateNext();
|
||||
int toCopy = System.Math.Min(h, toGenerate);
|
||||
Array.Copy(k, 0, output, outOff, toCopy);
|
||||
generatedBytes += toCopy;
|
||||
toGenerate -= toCopy;
|
||||
outOff += toCopy;
|
||||
}
|
||||
|
||||
return length;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
public int GenerateBytes(Span<byte> output)
|
||||
{
|
||||
int length = output.Length;
|
||||
if (generatedBytes >= maxSizeExcl - length)
|
||||
throw new DataLengthException("Current KDFCTR may only be used for " + maxSizeExcl + " bytes");
|
||||
|
||||
int posInK = generatedBytes % h;
|
||||
if (posInK != 0)
|
||||
{
|
||||
// copy what is left in the currentT (1..hash
|
||||
int toCopy = System.Math.Min(h - posInK, output.Length);
|
||||
k.AsSpan(posInK, toCopy).CopyTo(output);
|
||||
generatedBytes += toCopy;
|
||||
output = output[toCopy..];
|
||||
}
|
||||
|
||||
while (!output.IsEmpty)
|
||||
{
|
||||
GenerateNext();
|
||||
int toCopy = System.Math.Min(h, output.Length);
|
||||
k.AsSpan(0, toCopy).CopyTo(output);
|
||||
generatedBytes += toCopy;
|
||||
output = output[toCopy..];
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
#endif
|
||||
|
||||
private void GenerateNext()
|
||||
{
|
||||
int i = generatedBytes / h + 1;
|
||||
|
||||
// encode i into counter buffer
|
||||
switch (ios.Length)
|
||||
{
|
||||
case 4:
|
||||
ios[0] = (byte)(i >> 24);
|
||||
// fall through
|
||||
goto case 3;
|
||||
case 3:
|
||||
ios[ios.Length - 3] = (byte)(i >> 16);
|
||||
// fall through
|
||||
goto case 2;
|
||||
case 2:
|
||||
ios[ios.Length - 2] = (byte)(i >> 8);
|
||||
// fall through
|
||||
goto case 1;
|
||||
case 1:
|
||||
ios[ios.Length - 1] = (byte)i;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("Unsupported size of counter i");
|
||||
}
|
||||
|
||||
// special case for K(0): K(0) is empty, so no update
|
||||
prf.BlockUpdate(fixedInputDataCtrPrefix, 0, fixedInputDataCtrPrefix.Length);
|
||||
prf.BlockUpdate(ios, 0, ios.Length);
|
||||
prf.BlockUpdate(fixedInputData_afterCtr, 0, fixedInputData_afterCtr.Length);
|
||||
prf.DoFinal(k, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc39111d8cdbba34ebdc8e5e74231af5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,197 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
public sealed class KdfDoublePipelineIterationBytesGenerator
|
||||
: IMacDerivationFunction
|
||||
{
|
||||
// fields set by the constructor
|
||||
private readonly IMac prf;
|
||||
private readonly int h;
|
||||
|
||||
// fields set by init
|
||||
private byte[] fixedInputData;
|
||||
private int maxSizeExcl;
|
||||
// ios is i defined as an octet string (the binary representation)
|
||||
private byte[] ios;
|
||||
private bool useCounter;
|
||||
|
||||
// operational
|
||||
private int generatedBytes;
|
||||
// k is used as buffer for all K(i) values
|
||||
private byte[] a;
|
||||
private byte[] k;
|
||||
|
||||
public KdfDoublePipelineIterationBytesGenerator(IMac prf)
|
||||
{
|
||||
this.prf = prf;
|
||||
this.h = prf.GetMacSize();
|
||||
this.a = new byte[h];
|
||||
this.k = new byte[h];
|
||||
}
|
||||
|
||||
public void Init(IDerivationParameters parameters)
|
||||
{
|
||||
if (!(parameters is KdfDoublePipelineIterationParameters dpiParams))
|
||||
throw new ArgumentException("Wrong type of arguments given");
|
||||
|
||||
// --- init mac based PRF ---
|
||||
|
||||
this.prf.Init(new KeyParameter(dpiParams.Ki));
|
||||
|
||||
// --- set arguments ---
|
||||
|
||||
this.fixedInputData = dpiParams.FixedInputData;
|
||||
|
||||
int r = dpiParams.R;
|
||||
this.ios = new byte[r / 8];
|
||||
|
||||
if (dpiParams.UseCounter)
|
||||
{
|
||||
// this is more conservative than the spec
|
||||
BigInteger maxSize = BigInteger.One.ShiftLeft(r).Multiply(BigInteger.ValueOf(h));
|
||||
this.maxSizeExcl = maxSize.BitLength > 31 ? int.MaxValue : maxSize.IntValueExact;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.maxSizeExcl = int.MaxValue;
|
||||
}
|
||||
|
||||
this.useCounter = dpiParams.UseCounter;
|
||||
|
||||
// --- set operational state ---
|
||||
|
||||
generatedBytes = 0;
|
||||
}
|
||||
|
||||
private void GenerateNext()
|
||||
{
|
||||
if (generatedBytes == 0)
|
||||
{
|
||||
// --- step 4 ---
|
||||
prf.BlockUpdate(fixedInputData, 0, fixedInputData.Length);
|
||||
prf.DoFinal(a, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// --- step 5a ---
|
||||
prf.BlockUpdate(a, 0, a.Length);
|
||||
prf.DoFinal(a, 0);
|
||||
}
|
||||
|
||||
// --- step 5b ---
|
||||
prf.BlockUpdate(a, 0, a.Length);
|
||||
|
||||
if (useCounter)
|
||||
{
|
||||
int i = generatedBytes / h + 1;
|
||||
|
||||
// encode i into counter buffer
|
||||
switch (ios.Length)
|
||||
{
|
||||
case 4:
|
||||
ios[0] = (byte)(i >> 24);
|
||||
// fall through
|
||||
goto case 3;
|
||||
case 3:
|
||||
ios[ios.Length - 3] = (byte)(i >> 16);
|
||||
// fall through
|
||||
goto case 2;
|
||||
case 2:
|
||||
ios[ios.Length - 2] = (byte)(i >> 8);
|
||||
// fall through
|
||||
goto case 1;
|
||||
case 1:
|
||||
ios[ios.Length - 1] = (byte)i;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("Unsupported size of counter i");
|
||||
}
|
||||
prf.BlockUpdate(ios, 0, ios.Length);
|
||||
}
|
||||
|
||||
prf.BlockUpdate(fixedInputData, 0, fixedInputData.Length);
|
||||
prf.DoFinal(k, 0);
|
||||
}
|
||||
|
||||
public IDigest Digest
|
||||
{
|
||||
get { return (prf as HMac)?.GetUnderlyingDigest(); }
|
||||
}
|
||||
|
||||
public int GenerateBytes(byte[] output, int outOff, int length)
|
||||
{
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
return GenerateBytes(output.AsSpan(outOff, length));
|
||||
#else
|
||||
if (generatedBytes >= maxSizeExcl - length)
|
||||
throw new DataLengthException("Current KDFCTR may only be used for " + maxSizeExcl + " bytes");
|
||||
|
||||
int toGenerate = length;
|
||||
int posInK = generatedBytes % h;
|
||||
if (posInK != 0)
|
||||
{
|
||||
// copy what is left in the currentT (1..hash
|
||||
int toCopy = System.Math.Min(h - posInK, toGenerate);
|
||||
Array.Copy(k, posInK, output, outOff, toCopy);
|
||||
generatedBytes += toCopy;
|
||||
toGenerate -= toCopy;
|
||||
outOff += toCopy;
|
||||
}
|
||||
|
||||
while (toGenerate > 0)
|
||||
{
|
||||
GenerateNext();
|
||||
int toCopy = System.Math.Min(h, toGenerate);
|
||||
Array.Copy(k, 0, output, outOff, toCopy);
|
||||
generatedBytes += toCopy;
|
||||
toGenerate -= toCopy;
|
||||
outOff += toCopy;
|
||||
}
|
||||
|
||||
return length;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
public int GenerateBytes(Span<byte> output)
|
||||
{
|
||||
int length = output.Length;
|
||||
if (generatedBytes >= maxSizeExcl - length)
|
||||
throw new DataLengthException("Current KDFCTR may only be used for " + maxSizeExcl + " bytes");
|
||||
|
||||
int posInK = generatedBytes % h;
|
||||
if (posInK != 0)
|
||||
{
|
||||
// copy what is left in the currentT (1..hash
|
||||
GenerateNext();
|
||||
int toCopy = System.Math.Min(h - posInK, output.Length);
|
||||
k.AsSpan(posInK, toCopy).CopyTo(output);
|
||||
generatedBytes += toCopy;
|
||||
output = output[toCopy..];
|
||||
}
|
||||
|
||||
while (!output.IsEmpty)
|
||||
{
|
||||
GenerateNext();
|
||||
int toCopy = System.Math.Min(h, output.Length);
|
||||
k.AsSpan(0, toCopy).CopyTo(output);
|
||||
generatedBytes += toCopy;
|
||||
output = output[toCopy..];
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
#endif
|
||||
|
||||
public IMac Mac => prf;
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb0bf8409b479ee47a685ff2f36a07f0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,193 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
public sealed class KdfFeedbackBytesGenerator
|
||||
: IMacDerivationFunction
|
||||
{
|
||||
// please refer to the standard for the meaning of the variable names
|
||||
// all field lengths are in bytes, not in bits as specified by the standard
|
||||
|
||||
// fields set by the constructor
|
||||
private readonly IMac prf;
|
||||
private readonly int h;
|
||||
|
||||
// fields set by init
|
||||
private byte[] fixedInputData;
|
||||
private int maxSizeExcl;
|
||||
// ios is i defined as an octet string (the binary representation)
|
||||
private byte[] ios;
|
||||
private byte[] iv;
|
||||
private bool useCounter;
|
||||
|
||||
// operational
|
||||
private int generatedBytes;
|
||||
// k is used as buffer for all K(i) values
|
||||
private byte[] k;
|
||||
|
||||
public KdfFeedbackBytesGenerator(IMac prf)
|
||||
{
|
||||
this.prf = prf;
|
||||
this.h = prf.GetMacSize();
|
||||
this.k = new byte[h];
|
||||
}
|
||||
|
||||
public void Init(IDerivationParameters parameters)
|
||||
{
|
||||
if (!(parameters is KdfFeedbackParameters feedbackParams))
|
||||
throw new ArgumentException("Wrong type of arguments given");
|
||||
|
||||
// --- init mac based PRF ---
|
||||
|
||||
this.prf.Init(new KeyParameter(feedbackParams.Ki));
|
||||
|
||||
// --- set arguments ---
|
||||
|
||||
this.fixedInputData = feedbackParams.FixedInputData;
|
||||
|
||||
int r = feedbackParams.R;
|
||||
this.ios = new byte[r / 8];
|
||||
|
||||
if (feedbackParams.UseCounter)
|
||||
{
|
||||
// this is more conservative than the spec
|
||||
BigInteger maxSize = BigInteger.One.ShiftLeft(r).Multiply(BigInteger.ValueOf(h));
|
||||
this.maxSizeExcl = maxSize.BitLength > 31 ? int.MaxValue : maxSize.IntValueExact;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.maxSizeExcl = int.MaxValue;
|
||||
}
|
||||
|
||||
this.iv = feedbackParams.Iv;
|
||||
this.useCounter = feedbackParams.UseCounter;
|
||||
|
||||
// --- set operational state ---
|
||||
|
||||
generatedBytes = 0;
|
||||
}
|
||||
|
||||
public IDigest Digest
|
||||
{
|
||||
get { return (prf as HMac)?.GetUnderlyingDigest(); }
|
||||
}
|
||||
|
||||
public int GenerateBytes(byte[] output, int outOff, int length)
|
||||
{
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
return GenerateBytes(output.AsSpan(outOff, length));
|
||||
#else
|
||||
if (generatedBytes >= maxSizeExcl - length)
|
||||
throw new DataLengthException("Current KDFCTR may only be used for " + maxSizeExcl + " bytes");
|
||||
|
||||
int toGenerate = length;
|
||||
int posInK = generatedBytes % h;
|
||||
if (posInK != 0)
|
||||
{
|
||||
// copy what is left in the currentT (1..hash
|
||||
int toCopy = System.Math.Min(h - posInK, toGenerate);
|
||||
Array.Copy(k, posInK, output, outOff, toCopy);
|
||||
generatedBytes += toCopy;
|
||||
toGenerate -= toCopy;
|
||||
outOff += toCopy;
|
||||
}
|
||||
|
||||
while (toGenerate > 0)
|
||||
{
|
||||
GenerateNext();
|
||||
int toCopy = System.Math.Min(h, toGenerate);
|
||||
Array.Copy(k, 0, output, outOff, toCopy);
|
||||
generatedBytes += toCopy;
|
||||
toGenerate -= toCopy;
|
||||
outOff += toCopy;
|
||||
}
|
||||
|
||||
return length;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
public int GenerateBytes(Span<byte> output)
|
||||
{
|
||||
int length = output.Length;
|
||||
if (generatedBytes >= maxSizeExcl - length)
|
||||
throw new DataLengthException("Current KDFCTR may only be used for " + maxSizeExcl + " bytes");
|
||||
|
||||
int posInK = generatedBytes % h;
|
||||
if (posInK != 0)
|
||||
{
|
||||
// copy what is left in the currentT (1..hash
|
||||
int toCopy = System.Math.Min(h - posInK, output.Length);
|
||||
k.AsSpan(posInK, toCopy).CopyTo(output);
|
||||
generatedBytes += toCopy;
|
||||
output = output[toCopy..];
|
||||
}
|
||||
|
||||
while (!output.IsEmpty)
|
||||
{
|
||||
GenerateNext();
|
||||
int toCopy = System.Math.Min(h, output.Length);
|
||||
k.AsSpan(0, toCopy).CopyTo(output);
|
||||
generatedBytes += toCopy;
|
||||
output = output[toCopy..];
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
#endif
|
||||
|
||||
private void GenerateNext()
|
||||
{
|
||||
// TODO enable IV
|
||||
if (generatedBytes == 0)
|
||||
{
|
||||
prf.BlockUpdate(iv, 0, iv.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
prf.BlockUpdate(k, 0, k.Length);
|
||||
}
|
||||
|
||||
if (useCounter)
|
||||
{
|
||||
int i = generatedBytes / h + 1;
|
||||
|
||||
// encode i into counter buffer
|
||||
switch (ios.Length)
|
||||
{
|
||||
case 4:
|
||||
ios[0] = (byte)(i >> 24);
|
||||
// fall through
|
||||
goto case 3;
|
||||
case 3:
|
||||
ios[ios.Length - 3] = (byte)(i >> 16);
|
||||
// fall through
|
||||
goto case 2;
|
||||
case 2:
|
||||
ios[ios.Length - 2] = (byte)(i >> 8);
|
||||
// fall through
|
||||
goto case 1;
|
||||
case 1:
|
||||
ios[ios.Length - 1] = (byte)i;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("Unsupported size of counter i");
|
||||
}
|
||||
prf.BlockUpdate(ios, 0, ios.Length);
|
||||
}
|
||||
|
||||
prf.BlockUpdate(fixedInputData, 0, fixedInputData.Length);
|
||||
prf.DoFinal(k, 0);
|
||||
}
|
||||
|
||||
public IMac Mac => prf;
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 58963baccfc1e0f4fbca340b6726abb7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,25 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* KFD1 generator for derived keys and ivs as defined by IEEE P1363a/ISO 18033
|
||||
* <br/>
|
||||
* This implementation is based on IEEE P1363/ISO 18033.
|
||||
*/
|
||||
public sealed class Kdf1BytesGenerator
|
||||
: BaseKdfBytesGenerator
|
||||
{
|
||||
/**
|
||||
* Construct a KDF1 byte generator.
|
||||
*
|
||||
* @param digest the digest to be used as the source of derived keys.
|
||||
*/
|
||||
public Kdf1BytesGenerator(IDigest digest)
|
||||
: base(0, digest)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 71c746db80178644ebaf39e5b0218ead
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,26 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* KDF2 generator for derived keys and ivs as defined by IEEE P1363a/ISO 18033
|
||||
* <br/>
|
||||
* This implementation is based on IEEE P1363/ISO 18033.
|
||||
*/
|
||||
public sealed class Kdf2BytesGenerator
|
||||
: BaseKdfBytesGenerator
|
||||
{
|
||||
/**
|
||||
* Construct a KDF2 bytes generator. Generates key material
|
||||
* according to IEEE P1363 or ISO 18033 depending on the initialisation.
|
||||
*
|
||||
* @param digest the digest to be used as the source of derived keys.
|
||||
*/
|
||||
public Kdf2BytesGenerator(IDigest digest)
|
||||
: base(1, digest)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8f69934c97758b4fbbfa9b80e47aa3f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
116
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/Mgf1BytesGenerator.cs
vendored
Normal file
116
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/Mgf1BytesGenerator.cs
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/// <summary>Generator for MGF1 as defined in Pkcs 1v2</summary>
|
||||
public sealed class Mgf1BytesGenerator
|
||||
: IDerivationFunction
|
||||
{
|
||||
private readonly IDigest m_digest;
|
||||
private readonly int m_hLen;
|
||||
|
||||
private byte[] m_buffer;
|
||||
|
||||
/// <param name="digest">the digest to be used as the source of generated bytes</param>
|
||||
public Mgf1BytesGenerator(IDigest digest)
|
||||
{
|
||||
m_digest = digest;
|
||||
m_hLen = digest.GetDigestSize();
|
||||
}
|
||||
|
||||
public void Init(IDerivationParameters parameters)
|
||||
{
|
||||
if (!(parameters is MgfParameters mgfParameters))
|
||||
throw new ArgumentException("MGF parameters required for MGF1Generator");
|
||||
|
||||
m_buffer = new byte[mgfParameters.SeedLength + 4 + m_hLen];
|
||||
mgfParameters.GetSeed(m_buffer, 0);
|
||||
}
|
||||
|
||||
/// <summary>the underlying digest.</summary>
|
||||
public IDigest Digest => m_digest;
|
||||
|
||||
/// <summary>Fill <c>len</c> bytes of the output buffer with bytes generated from the derivation function.
|
||||
/// </summary>
|
||||
public int GenerateBytes(byte[] output, int outOff, int length)
|
||||
{
|
||||
Check.OutputLength(output, outOff, length, "output buffer too small");
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
return GenerateBytes(output.AsSpan(outOff, length));
|
||||
#else
|
||||
int hashPos = m_buffer.Length - m_hLen;
|
||||
int counterPos = hashPos - 4;
|
||||
uint counter = 0;
|
||||
|
||||
m_digest.Reset();
|
||||
|
||||
int end = outOff + length;
|
||||
int limit = end - m_hLen;
|
||||
|
||||
while (outOff <= limit)
|
||||
{
|
||||
Pack.UInt32_To_BE(counter++, m_buffer, counterPos);
|
||||
|
||||
m_digest.BlockUpdate(m_buffer, 0, hashPos);
|
||||
m_digest.DoFinal(output, outOff);
|
||||
|
||||
outOff += m_hLen;
|
||||
}
|
||||
|
||||
if (outOff < end)
|
||||
{
|
||||
Pack.UInt32_To_BE(counter, m_buffer, counterPos);
|
||||
|
||||
m_digest.BlockUpdate(m_buffer, 0, hashPos);
|
||||
m_digest.DoFinal(m_buffer, hashPos);
|
||||
|
||||
Array.Copy(m_buffer, hashPos, output, outOff, end - outOff);
|
||||
}
|
||||
|
||||
return length;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
public int GenerateBytes(Span<byte> output)
|
||||
{
|
||||
int hashPos = m_buffer.Length - m_hLen;
|
||||
int counterPos = hashPos - 4;
|
||||
uint counter = 0;
|
||||
|
||||
m_digest.Reset();
|
||||
|
||||
int pos = 0, length = output.Length, limit = length - m_hLen;
|
||||
|
||||
while (pos <= limit)
|
||||
{
|
||||
Pack.UInt32_To_BE(counter++, m_buffer.AsSpan(counterPos));
|
||||
|
||||
m_digest.BlockUpdate(m_buffer.AsSpan(0, hashPos));
|
||||
m_digest.DoFinal(output[pos..]);
|
||||
|
||||
pos += m_hLen;
|
||||
}
|
||||
|
||||
if (pos < length)
|
||||
{
|
||||
Pack.UInt32_To_BE(counter, m_buffer.AsSpan(counterPos));
|
||||
|
||||
m_digest.BlockUpdate(m_buffer.AsSpan(0, hashPos));
|
||||
m_digest.DoFinal(m_buffer.AsSpan(hashPos));
|
||||
m_buffer.AsSpan(hashPos, length - pos).CopyTo(output[pos..]);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7578f8928ecb36d4186cb9e9e9248c93
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,263 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* Key generation parameters for NaccacheStern cipher. For details on this cipher, please see
|
||||
*
|
||||
* http://www.gemplus.com/smart/rd/publications/pdf/NS98pkcs.pdf
|
||||
*/
|
||||
public class NaccacheSternKeyPairGenerator
|
||||
: IAsymmetricCipherKeyPairGenerator
|
||||
{
|
||||
private static readonly int[] smallPrimes =
|
||||
{
|
||||
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
|
||||
};
|
||||
|
||||
private NaccacheSternKeyGenerationParameters param;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator#init(org.bouncycastle.crypto.KeyGenerationParameters)
|
||||
*/
|
||||
public void Init(KeyGenerationParameters parameters)
|
||||
{
|
||||
this.param = (NaccacheSternKeyGenerationParameters)parameters;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator#generateKeyPair()
|
||||
*/
|
||||
public AsymmetricCipherKeyPair GenerateKeyPair()
|
||||
{
|
||||
int strength = param.Strength;
|
||||
SecureRandom rand = param.Random;
|
||||
int certainty = param.Certainty;
|
||||
|
||||
var smallPrimes = FindFirstPrimes(param.CountSmallPrimes);
|
||||
|
||||
smallPrimes = PermuteList(smallPrimes, rand);
|
||||
|
||||
BigInteger u = BigInteger.One;
|
||||
BigInteger v = BigInteger.One;
|
||||
|
||||
for (int i = 0; i < smallPrimes.Count / 2; i++)
|
||||
{
|
||||
u = u.Multiply((BigInteger)smallPrimes[i]);
|
||||
}
|
||||
for (int i = smallPrimes.Count / 2; i < smallPrimes.Count; i++)
|
||||
{
|
||||
v = v.Multiply((BigInteger)smallPrimes[i]);
|
||||
}
|
||||
|
||||
BigInteger sigma = u.Multiply(v);
|
||||
|
||||
// n = (2 a u _p + 1 ) ( 2 b v _q + 1)
|
||||
// -> |n| = strength
|
||||
// |2| = 1 in bits
|
||||
// -> |a| * |b| = |n| - |u| - |v| - |_p| - |_q| - |2| -|2|
|
||||
// remainingStrength = strength - sigma.bitLength() - _p.bitLength() -
|
||||
// _q.bitLength() - 1 -1
|
||||
int remainingStrength = strength - sigma.BitLength - 48;
|
||||
BigInteger a = GeneratePrime(remainingStrength / 2 + 1, certainty, rand);
|
||||
BigInteger b = GeneratePrime(remainingStrength / 2 + 1, certainty, rand);
|
||||
|
||||
BigInteger _p;
|
||||
BigInteger _q;
|
||||
BigInteger p;
|
||||
BigInteger q;
|
||||
|
||||
long tries = 0;
|
||||
|
||||
BigInteger _2au = a.Multiply(u).ShiftLeft(1);
|
||||
BigInteger _2bv = b.Multiply(v).ShiftLeft(1);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
tries++;
|
||||
|
||||
_p = GeneratePrime(24, certainty, rand);
|
||||
|
||||
p = _p.Multiply(_2au).Add(BigInteger.One);
|
||||
|
||||
if (!p.IsProbablePrime(certainty, true))
|
||||
continue;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
_q = GeneratePrime(24, certainty, rand);
|
||||
|
||||
if (_p.Equals(_q))
|
||||
continue;
|
||||
|
||||
q = _q.Multiply(_2bv).Add(BigInteger.One);
|
||||
|
||||
if (q.IsProbablePrime(certainty, true))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!sigma.Gcd(_p.Multiply(_q)).Equals(BigInteger.One))
|
||||
{
|
||||
//Console.WriteLine("sigma.gcd(_p.mult(_q)) != 1!\n _p: " + _p +"\n _q: "+ _q );
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p.Multiply(q).BitLength < strength)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
BigInteger n = p.Multiply(q);
|
||||
BigInteger phi_n = p.Subtract(BigInteger.One).Multiply(q.Subtract(BigInteger.One));
|
||||
BigInteger g;
|
||||
tries = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// TODO After the first loop, just regenerate one randomly-selected gPart each time?
|
||||
var gParts = new List<BigInteger>();
|
||||
for (int ind = 0; ind != smallPrimes.Count; ind++)
|
||||
{
|
||||
BigInteger i = smallPrimes[ind];
|
||||
BigInteger e = phi_n.Divide(i);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
tries++;
|
||||
|
||||
g = GeneratePrime(strength, certainty, rand);
|
||||
|
||||
if (!g.ModPow(e, n).Equals(BigInteger.One))
|
||||
{
|
||||
gParts.Add(g);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
g = BigInteger.One;
|
||||
for (int i = 0; i < smallPrimes.Count; i++)
|
||||
{
|
||||
BigInteger gPart = (BigInteger) gParts[i];
|
||||
BigInteger smallPrime = (BigInteger) smallPrimes[i];
|
||||
g = g.Multiply(gPart.ModPow(sigma.Divide(smallPrime), n)).Mod(n);
|
||||
}
|
||||
|
||||
// make sure that g is not divisible by p_i or q_i
|
||||
bool divisible = false;
|
||||
for (int i = 0; i < smallPrimes.Count; i++)
|
||||
{
|
||||
if (g.ModPow(phi_n.Divide((BigInteger)smallPrimes[i]), n).Equals(BigInteger.One))
|
||||
{
|
||||
divisible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (divisible)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// make sure that g has order > phi_n/4
|
||||
|
||||
//if (g.ModPow(phi_n.Divide(BigInteger.ValueOf(4)), n).Equals(BigInteger.One))
|
||||
if (g.ModPow(phi_n.ShiftRight(2), n).Equals(BigInteger.One))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g.ModPow(phi_n.Divide(_p), n).Equals(BigInteger.One))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (g.ModPow(phi_n.Divide(_q), n).Equals(BigInteger.One))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (g.ModPow(phi_n.Divide(a), n).Equals(BigInteger.One))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (g.ModPow(phi_n.Divide(b), n).Equals(BigInteger.One))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return new AsymmetricCipherKeyPair(new NaccacheSternKeyParameters(false, g, n, sigma.BitLength),
|
||||
new NaccacheSternPrivateKeyParameters(g, n, sigma.BitLength, smallPrimes, phi_n));
|
||||
}
|
||||
|
||||
private static BigInteger GeneratePrime(int bitLength, int certainty, SecureRandom rand)
|
||||
{
|
||||
return new BigInteger(bitLength, certainty, rand);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a permuted ArrayList from the original one. The original List
|
||||
* is not modified
|
||||
*
|
||||
* @param arr
|
||||
* the ArrayList to be permuted
|
||||
* @param rand
|
||||
* the source of Randomness for permutation
|
||||
* @return a new IList with the permuted elements.
|
||||
*/
|
||||
private static IList<T> PermuteList<T>(IList<T> arr, SecureRandom rand)
|
||||
{
|
||||
// TODO Create a utility method for generating permutation of first 'n' integers
|
||||
|
||||
var retval = new List<T>(arr.Count);
|
||||
|
||||
foreach (var element in arr)
|
||||
{
|
||||
int index = rand.Next(retval.Count + 1);
|
||||
retval.Insert(index, element);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the first 'count' primes starting with 3
|
||||
*
|
||||
* @param count
|
||||
* the number of primes to find
|
||||
* @return a vector containing the found primes as Integer
|
||||
*/
|
||||
private static IList<BigInteger> FindFirstPrimes(int count)
|
||||
{
|
||||
var primes = new List<BigInteger>(count);
|
||||
|
||||
for (int i = 0; i != count; i++)
|
||||
{
|
||||
primes.Add(BigInteger.ValueOf(smallPrimes[i]));
|
||||
}
|
||||
|
||||
return primes;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c29fa55407fbbe5459cec743e9286b87
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
305
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/OpenBsdBCrypt.cs
vendored
Normal file
305
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/OpenBsdBCrypt.cs
vendored
Normal file
@@ -0,0 +1,305 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* Password hashing scheme BCrypt,
|
||||
* designed by Niels Provos and David Mazières, using the
|
||||
* String format and the Base64 encoding
|
||||
* of the reference implementation on OpenBSD
|
||||
*/
|
||||
public class OpenBsdBCrypt
|
||||
{
|
||||
private static readonly byte[] EncodingTable = // the Bcrypts encoding table for OpenBSD
|
||||
{
|
||||
(byte)'.', (byte)'/', (byte)'A', (byte)'B', (byte)'C', (byte)'D',
|
||||
(byte)'E', (byte)'F', (byte)'G', (byte)'H', (byte)'I', (byte)'J',
|
||||
(byte)'K', (byte)'L', (byte)'M', (byte)'N', (byte)'O', (byte)'P',
|
||||
(byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', (byte)'V',
|
||||
(byte)'W', (byte)'X', (byte)'Y', (byte)'Z', (byte)'a', (byte)'b',
|
||||
(byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', (byte)'h',
|
||||
(byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
|
||||
(byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t',
|
||||
(byte)'u', (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z',
|
||||
(byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5',
|
||||
(byte)'6', (byte)'7', (byte)'8', (byte)'9'
|
||||
};
|
||||
|
||||
/*
|
||||
* set up the decoding table.
|
||||
*/
|
||||
private static readonly byte[] DecodingTable = new byte[128];
|
||||
private static readonly string DefaultVersion = "2y";
|
||||
private static readonly HashSet<string> AllowedVersions = new HashSet<string>();
|
||||
|
||||
static OpenBsdBCrypt()
|
||||
{
|
||||
// Presently just the Bcrypt versions.
|
||||
AllowedVersions.Add("2a");
|
||||
AllowedVersions.Add("2y");
|
||||
AllowedVersions.Add("2b");
|
||||
|
||||
for (int i = 0; i < DecodingTable.Length; i++)
|
||||
{
|
||||
DecodingTable[i] = (byte)0xff;
|
||||
}
|
||||
|
||||
for (int i = 0; i < EncodingTable.Length; i++)
|
||||
{
|
||||
DecodingTable[EncodingTable[i]] = (byte)i;
|
||||
}
|
||||
}
|
||||
|
||||
public OpenBsdBCrypt()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a 60 character Bcrypt String, including
|
||||
* version, cost factor, salt and hash, separated by '$'
|
||||
*
|
||||
* @param version the version, 2y,2b or 2a. (2a is not backwards compatible.)
|
||||
* @param cost the cost factor, treated as an exponent of 2
|
||||
* @param salt a 16 byte salt
|
||||
* @param password the password
|
||||
* @return a 60 character Bcrypt String
|
||||
*/
|
||||
private static string CreateBcryptString(string version, byte[] password, byte[] salt, int cost)
|
||||
{
|
||||
if (!AllowedVersions.Contains(version))
|
||||
throw new ArgumentException("Version " + version + " is not accepted by this implementation.", "version");
|
||||
|
||||
StringBuilder sb = new StringBuilder(60);
|
||||
sb.Append('$');
|
||||
sb.Append(version);
|
||||
sb.Append('$');
|
||||
sb.Append(cost < 10 ? ("0" + cost) : cost.ToString());
|
||||
sb.Append('$');
|
||||
sb.Append(EncodeData(salt));
|
||||
|
||||
byte[] key = BCrypt.Generate(password, salt, cost);
|
||||
|
||||
sb.Append(EncodeData(key));
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a 60 character Bcrypt String, including
|
||||
* version, cost factor, salt and hash, separated by '$' using version
|
||||
* '2y'.
|
||||
*
|
||||
* @param cost the cost factor, treated as an exponent of 2
|
||||
* @param salt a 16 byte salt
|
||||
* @param password the password
|
||||
* @return a 60 character Bcrypt String
|
||||
*/
|
||||
public static string Generate(char[] password, byte[] salt, int cost)
|
||||
{
|
||||
return Generate(DefaultVersion, password, salt, cost);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a 60 character Bcrypt String, including
|
||||
* version, cost factor, salt and hash, separated by '$'
|
||||
*
|
||||
* @param version the version, may be 2b, 2y or 2a. (2a is not backwards compatible.)
|
||||
* @param cost the cost factor, treated as an exponent of 2
|
||||
* @param salt a 16 byte salt
|
||||
* @param password the password
|
||||
* @return a 60 character Bcrypt String
|
||||
*/
|
||||
public static string Generate(string version, char[] password, byte[] salt, int cost)
|
||||
{
|
||||
if (!AllowedVersions.Contains(version))
|
||||
throw new ArgumentException("Version " + version + " is not accepted by this implementation.", "version");
|
||||
if (password == null)
|
||||
throw new ArgumentNullException("password");
|
||||
if (salt == null)
|
||||
throw new ArgumentNullException("salt");
|
||||
if (salt.Length != 16)
|
||||
throw new DataLengthException("16 byte salt required: " + salt.Length);
|
||||
|
||||
if (cost < 4 || cost > 31) // Minimum rounds: 16, maximum 2^31
|
||||
throw new ArgumentException("Invalid cost factor.", "cost");
|
||||
|
||||
byte[] psw = Strings.ToUtf8ByteArray(password);
|
||||
|
||||
// 0 termination:
|
||||
|
||||
byte[] tmp = new byte[psw.Length >= 72 ? 72 : psw.Length + 1];
|
||||
int copyLen = System.Math.Min(psw.Length, tmp.Length);
|
||||
Array.Copy(psw, 0, tmp, 0, copyLen);
|
||||
|
||||
Array.Clear(psw, 0, psw.Length);
|
||||
|
||||
string rv = CreateBcryptString(version, tmp, salt, cost);
|
||||
|
||||
Array.Clear(tmp, 0, tmp.Length);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a password corresponds to a 60 character Bcrypt String
|
||||
*
|
||||
* @param bcryptString a 60 character Bcrypt String, including
|
||||
* version, cost factor, salt and hash,
|
||||
* separated by '$'
|
||||
* @param password the password as an array of chars
|
||||
* @return true if the password corresponds to the
|
||||
* Bcrypt String, otherwise false
|
||||
*/
|
||||
public static bool CheckPassword(string bcryptString, char[] password)
|
||||
{
|
||||
// validate bcryptString:
|
||||
if (bcryptString.Length != 60)
|
||||
throw new DataLengthException("Bcrypt String length: " + bcryptString.Length + ", 60 required.");
|
||||
if (bcryptString[0] != '$' || bcryptString[3] != '$' || bcryptString[6] != '$')
|
||||
throw new ArgumentException("Invalid Bcrypt String format.", "bcryptString");
|
||||
|
||||
string version = bcryptString.Substring(1, 2);
|
||||
if (!AllowedVersions.Contains(version))
|
||||
throw new ArgumentException("Bcrypt version '" + version + "' is not supported by this implementation", "bcryptString");
|
||||
|
||||
int cost;
|
||||
try
|
||||
{
|
||||
cost = int.Parse(bcryptString.Substring(4, 2));
|
||||
}
|
||||
catch (Exception nfe)
|
||||
{
|
||||
throw new ArgumentException("Invalid cost factor: " + bcryptString.Substring(4, 2), "bcryptString", nfe);
|
||||
}
|
||||
if (cost < 4 || cost > 31)
|
||||
throw new ArgumentException("Invalid cost factor: " + cost + ", 4 < cost < 31 expected.");
|
||||
|
||||
// check password:
|
||||
if (password == null)
|
||||
throw new ArgumentNullException("Missing password.");
|
||||
|
||||
int start = bcryptString.LastIndexOf('$') + 1, end = bcryptString.Length - 31;
|
||||
byte[] salt = DecodeSaltString(bcryptString.Substring(start, end - start));
|
||||
|
||||
string newBcryptString = Generate(version, password, salt, cost);
|
||||
|
||||
return bcryptString.Equals(newBcryptString);
|
||||
}
|
||||
|
||||
/*
|
||||
* encode the input data producing a Bcrypt base 64 string.
|
||||
*
|
||||
* @param a byte representation of the salt or the password
|
||||
* @return the Bcrypt base64 string
|
||||
*/
|
||||
private static string EncodeData(byte[] data)
|
||||
{
|
||||
if (data.Length != 24 && data.Length != 16) // 192 bit key or 128 bit salt expected
|
||||
throw new DataLengthException("Invalid length: " + data.Length + ", 24 for key or 16 for salt expected");
|
||||
|
||||
bool salt = false;
|
||||
if (data.Length == 16)//salt
|
||||
{
|
||||
salt = true;
|
||||
byte[] tmp = new byte[18];// zero padding
|
||||
Array.Copy(data, 0, tmp, 0, data.Length);
|
||||
data = tmp;
|
||||
}
|
||||
else // key
|
||||
{
|
||||
data[data.Length - 1] = (byte)0;
|
||||
}
|
||||
|
||||
MemoryStream mOut = new MemoryStream();
|
||||
int len = data.Length;
|
||||
|
||||
uint a1, a2, a3;
|
||||
int i;
|
||||
for (i = 0; i < len; i += 3)
|
||||
{
|
||||
a1 = data[i];
|
||||
a2 = data[i + 1];
|
||||
a3 = data[i + 2];
|
||||
|
||||
mOut.WriteByte(EncodingTable[(a1 >> 2) & 0x3f]);
|
||||
mOut.WriteByte(EncodingTable[((a1 << 4) | (a2 >> 4)) & 0x3f]);
|
||||
mOut.WriteByte(EncodingTable[((a2 << 2) | (a3 >> 6)) & 0x3f]);
|
||||
mOut.WriteByte(EncodingTable[a3 & 0x3f]);
|
||||
}
|
||||
|
||||
string result = Strings.FromByteArray(mOut.ToArray());
|
||||
int resultLen = salt
|
||||
? 22 // truncate padding
|
||||
: result.Length - 1;
|
||||
|
||||
return result.Substring(0, resultLen);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* decodes the bcrypt base 64 encoded SaltString
|
||||
*
|
||||
* @param a 22 character Bcrypt base 64 encoded String
|
||||
* @return the 16 byte salt
|
||||
* @exception DataLengthException if the length
|
||||
* of parameter is not 22
|
||||
* @exception InvalidArgumentException if the parameter
|
||||
* contains a value other than from Bcrypts base 64 encoding table
|
||||
*/
|
||||
private static byte[] DecodeSaltString(string saltString)
|
||||
{
|
||||
char[] saltChars = saltString.ToCharArray();
|
||||
|
||||
MemoryStream mOut = new MemoryStream(16);
|
||||
byte b1, b2, b3, b4;
|
||||
|
||||
if (saltChars.Length != 22)// bcrypt salt must be 22 (16 bytes)
|
||||
throw new DataLengthException("Invalid base64 salt length: " + saltChars.Length + " , 22 required.");
|
||||
|
||||
// check string for invalid characters:
|
||||
for (int i = 0; i < saltChars.Length; i++)
|
||||
{
|
||||
int value = saltChars[i];
|
||||
if (value > 122 || value < 46 || (value > 57 && value < 65))
|
||||
throw new ArgumentException("Salt string contains invalid character: " + value, "saltString");
|
||||
}
|
||||
|
||||
// Padding: add two '\u0000'
|
||||
char[] tmp = new char[22 + 2];
|
||||
Array.Copy(saltChars, 0, tmp, 0, saltChars.Length);
|
||||
saltChars = tmp;
|
||||
|
||||
int len = saltChars.Length;
|
||||
|
||||
for (int i = 0; i < len; i += 4)
|
||||
{
|
||||
b1 = DecodingTable[saltChars[i]];
|
||||
b2 = DecodingTable[saltChars[i + 1]];
|
||||
b3 = DecodingTable[saltChars[i + 2]];
|
||||
b4 = DecodingTable[saltChars[i + 3]];
|
||||
|
||||
mOut.WriteByte((byte)((b1 << 2) | (b2 >> 4)));
|
||||
mOut.WriteByte((byte)((b2 << 4) | (b3 >> 2)));
|
||||
mOut.WriteByte((byte)((b3 << 6) | b4));
|
||||
}
|
||||
|
||||
byte[] saltBytes = mOut.ToArray();
|
||||
|
||||
// truncate:
|
||||
byte[] tmpSalt = new byte[16];
|
||||
Array.Copy(saltBytes, 0, tmpSalt, 0, tmpSalt.Length);
|
||||
saltBytes = tmpSalt;
|
||||
|
||||
return saltBytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2fd5c2633a8c524499774e3ee4da6c2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,144 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/// <description>
|
||||
/// Generator for PBE derived keys and IVs as usd by OpenSSL. Originally this scheme was a simple extension of
|
||||
/// PKCS 5 V2.0 Scheme 1 using MD5 with an iteration count of 1. The default digest was changed to SHA-256 with
|
||||
/// OpenSSL 1.1.0. This implementation still defaults to MD5, but the digest can now be set.
|
||||
/// </description>
|
||||
public class OpenSslPbeParametersGenerator
|
||||
: PbeParametersGenerator
|
||||
{
|
||||
private readonly IDigest digest;
|
||||
|
||||
///
|
||||
/// <description>
|
||||
/// Construct a OpenSSL Parameters generator - digest the original MD5.
|
||||
/// </description>
|
||||
///
|
||||
public OpenSslPbeParametersGenerator() : this(new MD5Digest())
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// <description>
|
||||
/// Construct a OpenSSL Parameters generator - digest as specified.
|
||||
/// </description>
|
||||
/// <param name="digest">the digest to use as the PRF.</param>
|
||||
///
|
||||
public OpenSslPbeParametersGenerator(IDigest digest)
|
||||
{
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
public override void Init(
|
||||
byte[] password,
|
||||
byte[] salt,
|
||||
int iterationCount)
|
||||
{
|
||||
// Ignore the provided iterationCount
|
||||
base.Init(password, salt, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise - note the iteration count for this algorithm is fixed at 1.
|
||||
*
|
||||
* @param password password to use.
|
||||
* @param salt salt to use.
|
||||
*/
|
||||
public virtual void Init(
|
||||
byte[] password,
|
||||
byte[] salt)
|
||||
{
|
||||
base.Init(password, salt, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* the derived key function, the ith hash of the password and the salt.
|
||||
*/
|
||||
private byte[] GenerateDerivedKey(
|
||||
int bytesNeeded)
|
||||
{
|
||||
byte[] buf = new byte[digest.GetDigestSize()];
|
||||
byte[] key = new byte[bytesNeeded];
|
||||
int offset = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
digest.BlockUpdate(mPassword, 0, mPassword.Length);
|
||||
digest.BlockUpdate(mSalt, 0, mSalt.Length);
|
||||
|
||||
digest.DoFinal(buf, 0);
|
||||
|
||||
int len = (bytesNeeded > buf.Length) ? buf.Length : bytesNeeded;
|
||||
Array.Copy(buf, 0, key, offset, len);
|
||||
offset += len;
|
||||
|
||||
// check if we need any more
|
||||
bytesNeeded -= len;
|
||||
if (bytesNeeded == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// do another round
|
||||
digest.Reset();
|
||||
digest.BlockUpdate(buf, 0, buf.Length);
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
public override ICipherParameters GenerateDerivedParameters(
|
||||
string algorithm,
|
||||
int keySize)
|
||||
{
|
||||
keySize /= 8;
|
||||
|
||||
byte[] dKey = GenerateDerivedKey(keySize);
|
||||
|
||||
return ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize);
|
||||
}
|
||||
|
||||
public override ICipherParameters GenerateDerivedParameters(
|
||||
string algorithm,
|
||||
int keySize,
|
||||
int ivSize)
|
||||
{
|
||||
keySize /= 8;
|
||||
ivSize /= 8;
|
||||
|
||||
byte[] dKey = GenerateDerivedKey(keySize + ivSize);
|
||||
KeyParameter key = ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize);
|
||||
|
||||
return new ParametersWithIV(key, dKey, keySize, ivSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a key parameter for use with a MAC derived from the password,
|
||||
* salt, and iteration count we are currently initialised with.
|
||||
*
|
||||
* @param keySize the size of the key we want (in bits)
|
||||
* @return a KeyParameter object.
|
||||
* @exception ArgumentException if the key length larger than the base hash size.
|
||||
*/
|
||||
public override ICipherParameters GenerateDerivedMacParameters(
|
||||
int keySize)
|
||||
{
|
||||
keySize = keySize / 8;
|
||||
|
||||
byte[] dKey = GenerateDerivedKey(keySize);
|
||||
|
||||
return new KeyParameter(dKey, 0, keySize);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44c24ce050670094cbeacc6ed9cc61f0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,207 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* Generator for Pbe derived keys and ivs as defined by Pkcs 12 V1.0.
|
||||
* <p>
|
||||
* The document this implementation is based on can be found at
|
||||
* <a href="http://www.rsasecurity.com/rsalabs/pkcs/pkcs-12/index.html">
|
||||
* RSA's Pkcs12 Page</a>
|
||||
* </p>
|
||||
*/
|
||||
public class Pkcs12ParametersGenerator
|
||||
: PbeParametersGenerator
|
||||
{
|
||||
public const int KeyMaterial = 1;
|
||||
public const int IVMaterial = 2;
|
||||
public const int MacMaterial = 3;
|
||||
|
||||
private readonly IDigest digest;
|
||||
|
||||
private readonly int u;
|
||||
private readonly int v;
|
||||
|
||||
/**
|
||||
* Construct a Pkcs 12 Parameters generator.
|
||||
*
|
||||
* @param digest the digest to be used as the source of derived keys.
|
||||
* @exception ArgumentException if an unknown digest is passed in.
|
||||
*/
|
||||
public Pkcs12ParametersGenerator(
|
||||
IDigest digest)
|
||||
{
|
||||
this.digest = digest;
|
||||
|
||||
u = digest.GetDigestSize();
|
||||
v = digest.GetByteLength();
|
||||
}
|
||||
|
||||
/**
|
||||
* add a + b + 1, returning the result in a. The a value is treated
|
||||
* as a BigInteger of length (b.Length * 8) bits. The result is
|
||||
* modulo 2^b.Length in case of overflow.
|
||||
*/
|
||||
private void Adjust(
|
||||
byte[] a,
|
||||
int aOff,
|
||||
byte[] b)
|
||||
{
|
||||
int x = (b[b.Length - 1] & 0xff) + (a[aOff + b.Length - 1] & 0xff) + 1;
|
||||
|
||||
a[aOff + b.Length - 1] = (byte)x;
|
||||
x = (int) ((uint) x >> 8);
|
||||
|
||||
for (int i = b.Length - 2; i >= 0; i--)
|
||||
{
|
||||
x += (b[i] & 0xff) + (a[aOff + i] & 0xff);
|
||||
a[aOff + i] = (byte)x;
|
||||
x = (int) ((uint) x >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* generation of a derived key ala Pkcs12 V1.0.
|
||||
*/
|
||||
private byte[] GenerateDerivedKey(
|
||||
int idByte,
|
||||
int n)
|
||||
{
|
||||
byte[] D = new byte[v];
|
||||
byte[] dKey = new byte[n];
|
||||
|
||||
for (int i = 0; i != D.Length; i++)
|
||||
{
|
||||
D[i] = (byte)idByte;
|
||||
}
|
||||
|
||||
byte[] S;
|
||||
|
||||
if ((mSalt != null) && (mSalt.Length != 0))
|
||||
{
|
||||
S = new byte[v * ((mSalt.Length + v - 1) / v)];
|
||||
|
||||
for (int i = 0; i != S.Length; i++)
|
||||
{
|
||||
S[i] = mSalt[i % mSalt.Length];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
S = new byte[0];
|
||||
}
|
||||
|
||||
byte[] P;
|
||||
|
||||
if ((mPassword != null) && (mPassword.Length != 0))
|
||||
{
|
||||
P = new byte[v * ((mPassword.Length + v - 1) / v)];
|
||||
|
||||
for (int i = 0; i != P.Length; i++)
|
||||
{
|
||||
P[i] = mPassword[i % mPassword.Length];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
P = new byte[0];
|
||||
}
|
||||
|
||||
byte[] I = new byte[S.Length + P.Length];
|
||||
|
||||
Array.Copy(S, 0, I, 0, S.Length);
|
||||
Array.Copy(P, 0, I, S.Length, P.Length);
|
||||
|
||||
byte[] B = new byte[v];
|
||||
int c = (n + u - 1) / u;
|
||||
byte[] A = new byte[u];
|
||||
|
||||
for (int i = 1; i <= c; i++)
|
||||
{
|
||||
digest.BlockUpdate(D, 0, D.Length);
|
||||
digest.BlockUpdate(I, 0, I.Length);
|
||||
digest.DoFinal(A, 0);
|
||||
|
||||
for (int j = 1; j != mIterationCount; j++)
|
||||
{
|
||||
digest.BlockUpdate(A, 0, A.Length);
|
||||
digest.DoFinal(A, 0);
|
||||
}
|
||||
|
||||
for (int j = 0; j != B.Length; j++)
|
||||
{
|
||||
B[j] = A[j % A.Length];
|
||||
}
|
||||
|
||||
for (int j = 0; j != I.Length / v; j++)
|
||||
{
|
||||
Adjust(I, j * v, B);
|
||||
}
|
||||
|
||||
if (i == c)
|
||||
{
|
||||
Array.Copy(A, 0, dKey, (i - 1) * u, dKey.Length - ((i - 1) * u));
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Copy(A, 0, dKey, (i - 1) * u, A.Length);
|
||||
}
|
||||
}
|
||||
|
||||
return dKey;
|
||||
}
|
||||
|
||||
public override ICipherParameters GenerateDerivedParameters(
|
||||
string algorithm,
|
||||
int keySize)
|
||||
{
|
||||
keySize /= 8;
|
||||
|
||||
byte[] dKey = GenerateDerivedKey(KeyMaterial, keySize);
|
||||
|
||||
return ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize);
|
||||
}
|
||||
|
||||
public override ICipherParameters GenerateDerivedParameters(
|
||||
string algorithm,
|
||||
int keySize,
|
||||
int ivSize)
|
||||
{
|
||||
keySize /= 8;
|
||||
ivSize /= 8;
|
||||
|
||||
byte[] dKey = GenerateDerivedKey(KeyMaterial, keySize);
|
||||
KeyParameter key = ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize);
|
||||
|
||||
byte[] iv = GenerateDerivedKey(IVMaterial, ivSize);
|
||||
|
||||
return new ParametersWithIV(key, iv, 0, ivSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a key parameter for use with a MAC derived from the password,
|
||||
* salt, and iteration count we are currently initialised with.
|
||||
*
|
||||
* @param keySize the size of the key we want (in bits)
|
||||
* @return a KeyParameter object.
|
||||
*/
|
||||
public override ICipherParameters GenerateDerivedMacParameters(
|
||||
int keySize)
|
||||
{
|
||||
keySize /= 8;
|
||||
|
||||
byte[] dKey = GenerateDerivedKey(MacMaterial, keySize);
|
||||
|
||||
return new KeyParameter(dKey, 0, keySize);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a87fe1cd419e1934eb8c093990d78809
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,122 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* Generator for Pbe derived keys and ivs as defined by Pkcs 5 V2.0 Scheme 1.
|
||||
* Note this generator is limited to the size of the hash produced by the
|
||||
* digest used to drive it.
|
||||
* <p>
|
||||
* The document this implementation is based on can be found at
|
||||
* <a href="http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html">
|
||||
* RSA's Pkcs5 Page</a>
|
||||
* </p>
|
||||
*/
|
||||
public class Pkcs5S1ParametersGenerator
|
||||
: PbeParametersGenerator
|
||||
{
|
||||
private readonly IDigest digest;
|
||||
|
||||
/**
|
||||
* Construct a Pkcs 5 Scheme 1 Parameters generator.
|
||||
*
|
||||
* @param digest the digest to be used as the source of derived keys.
|
||||
*/
|
||||
public Pkcs5S1ParametersGenerator(
|
||||
IDigest digest)
|
||||
{
|
||||
this.digest = digest;
|
||||
}
|
||||
|
||||
/**
|
||||
* the derived key function, the ith hash of the mPassword and the mSalt.
|
||||
*/
|
||||
private byte[] GenerateDerivedKey()
|
||||
{
|
||||
byte[] digestBytes = new byte[digest.GetDigestSize()];
|
||||
|
||||
digest.BlockUpdate(mPassword, 0, mPassword.Length);
|
||||
digest.BlockUpdate(mSalt, 0, mSalt.Length);
|
||||
|
||||
digest.DoFinal(digestBytes, 0);
|
||||
for (int i = 1; i < mIterationCount; i++)
|
||||
{
|
||||
digest.BlockUpdate(digestBytes, 0, digestBytes.Length);
|
||||
digest.DoFinal(digestBytes, 0);
|
||||
}
|
||||
|
||||
return digestBytes;
|
||||
}
|
||||
|
||||
public override ICipherParameters GenerateDerivedParameters(
|
||||
string algorithm,
|
||||
int keySize)
|
||||
{
|
||||
keySize /= 8;
|
||||
|
||||
if (keySize > digest.GetDigestSize())
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Can't Generate a derived key " + keySize + " bytes long.");
|
||||
}
|
||||
|
||||
byte[] dKey = GenerateDerivedKey();
|
||||
|
||||
return ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize);
|
||||
}
|
||||
|
||||
public override ICipherParameters GenerateDerivedParameters(
|
||||
string algorithm,
|
||||
int keySize,
|
||||
int ivSize)
|
||||
{
|
||||
keySize /= 8;
|
||||
ivSize /= 8;
|
||||
|
||||
if ((keySize + ivSize) > digest.GetDigestSize())
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Can't Generate a derived key " + (keySize + ivSize) + " bytes long.");
|
||||
}
|
||||
|
||||
byte[] dKey = GenerateDerivedKey();
|
||||
KeyParameter key = ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize);
|
||||
|
||||
return new ParametersWithIV(key, dKey, keySize, ivSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a key parameter for use with a MAC derived from the mPassword,
|
||||
* mSalt, and iteration count we are currently initialised with.
|
||||
*
|
||||
* @param keySize the size of the key we want (in bits)
|
||||
* @return a KeyParameter object.
|
||||
* @exception ArgumentException if the key length larger than the base hash size.
|
||||
*/
|
||||
public override ICipherParameters GenerateDerivedMacParameters(
|
||||
int keySize)
|
||||
{
|
||||
keySize /= 8;
|
||||
|
||||
if (keySize > digest.GetDigestSize())
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Can't Generate a derived key " + keySize + " bytes long.");
|
||||
}
|
||||
|
||||
byte[] dKey = GenerateDerivedKey();
|
||||
|
||||
return new KeyParameter(dKey, 0, keySize);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 879260314ed88734c969c559f2b3b846
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,148 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* Generator for Pbe derived keys and ivs as defined by Pkcs 5 V2.0 Scheme 2.
|
||||
* This generator uses a SHA-1 HMac as the calculation function.
|
||||
* <p>
|
||||
* The document this implementation is based on can be found at
|
||||
* <a href="http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html">
|
||||
* RSA's Pkcs5 Page</a></p>
|
||||
*/
|
||||
public class Pkcs5S2ParametersGenerator
|
||||
: PbeParametersGenerator
|
||||
{
|
||||
private readonly IMac hMac;
|
||||
private readonly byte[] state;
|
||||
|
||||
/**
|
||||
* construct a Pkcs5 Scheme 2 Parameters generator.
|
||||
*/
|
||||
public Pkcs5S2ParametersGenerator()
|
||||
: this(new Sha1Digest())
|
||||
{
|
||||
}
|
||||
|
||||
public Pkcs5S2ParametersGenerator(IDigest digest)
|
||||
{
|
||||
this.hMac = new HMac(digest);
|
||||
this.state = new byte[hMac.GetMacSize()];
|
||||
}
|
||||
|
||||
private void F(
|
||||
byte[] S,
|
||||
int c,
|
||||
byte[] iBuf,
|
||||
byte[] outBytes,
|
||||
int outOff)
|
||||
{
|
||||
if (c == 0)
|
||||
throw new ArgumentException("iteration count must be at least 1.");
|
||||
|
||||
if (S != null)
|
||||
{
|
||||
hMac.BlockUpdate(S, 0, S.Length);
|
||||
}
|
||||
|
||||
hMac.BlockUpdate(iBuf, 0, iBuf.Length);
|
||||
hMac.DoFinal(state, 0);
|
||||
|
||||
Array.Copy(state, 0, outBytes, outOff, state.Length);
|
||||
|
||||
for (int count = 1; count < c; ++count)
|
||||
{
|
||||
hMac.BlockUpdate(state, 0, state.Length);
|
||||
hMac.DoFinal(state, 0);
|
||||
|
||||
for (int j = 0; j < state.Length; ++j)
|
||||
{
|
||||
outBytes[outOff + j] ^= state[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] GenerateDerivedKey(
|
||||
int dkLen)
|
||||
{
|
||||
int hLen = hMac.GetMacSize();
|
||||
int l = (dkLen + hLen - 1) / hLen;
|
||||
byte[] iBuf = new byte[4];
|
||||
byte[] outBytes = new byte[l * hLen];
|
||||
int outPos = 0;
|
||||
|
||||
ICipherParameters param = new KeyParameter(mPassword);
|
||||
|
||||
hMac.Init(param);
|
||||
|
||||
for (int i = 1; i <= l; i++)
|
||||
{
|
||||
// Increment the value in 'iBuf'
|
||||
int pos = 3;
|
||||
while (++iBuf[pos] == 0)
|
||||
{
|
||||
--pos;
|
||||
}
|
||||
|
||||
F(mSalt, mIterationCount, iBuf, outBytes, outPos);
|
||||
outPos += hLen;
|
||||
}
|
||||
|
||||
return outBytes;
|
||||
}
|
||||
|
||||
public override ICipherParameters GenerateDerivedParameters(
|
||||
string algorithm,
|
||||
int keySize)
|
||||
{
|
||||
keySize /= 8;
|
||||
|
||||
byte[] dKey = GenerateDerivedKey(keySize);
|
||||
|
||||
return ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize);
|
||||
}
|
||||
|
||||
public override ICipherParameters GenerateDerivedParameters(
|
||||
string algorithm,
|
||||
int keySize,
|
||||
int ivSize)
|
||||
{
|
||||
keySize /= 8;
|
||||
ivSize /= 8;
|
||||
|
||||
byte[] dKey = GenerateDerivedKey(keySize + ivSize);
|
||||
KeyParameter key = ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize);
|
||||
|
||||
return new ParametersWithIV(key, dKey, keySize, ivSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a key parameter for use with a MAC derived from the password,
|
||||
* salt, and iteration count we are currently initialised with.
|
||||
*
|
||||
* @param keySize the size of the key we want (in bits)
|
||||
* @return a KeyParameter object.
|
||||
*/
|
||||
public override ICipherParameters GenerateDerivedMacParameters(
|
||||
int keySize)
|
||||
{
|
||||
keySize /= 8;
|
||||
|
||||
byte[] dKey = GenerateDerivedKey(keySize);
|
||||
|
||||
return new KeyParameter(dKey, 0, keySize);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1734f017d19ae4945b8c2694150c953a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,120 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates keys for the Poly1305 MAC.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Poly1305 keys are 256 bit keys consisting of a 128 bit secret key used for the underlying block
|
||||
/// cipher followed by a 128 bit {@code r} value used for the polynomial portion of the Mac. <br/>
|
||||
/// The {@code r} value has a specific format with some bits required to be cleared, resulting in an
|
||||
/// effective 106 bit key. <br/>
|
||||
/// A separately generated 256 bit key can be modified to fit the Poly1305 key format by using the
|
||||
/// {@link #clamp(byte[])} method to clear the required bits.
|
||||
/// </remarks>
|
||||
/// <seealso cref="Poly1305"/>
|
||||
public class Poly1305KeyGenerator
|
||||
: CipherKeyGenerator
|
||||
{
|
||||
private const byte R_MASK_LOW_2 = (byte)0xFC;
|
||||
private const byte R_MASK_HIGH_4 = (byte)0x0F;
|
||||
|
||||
/// <summary>
|
||||
/// Initialises the key generator.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Poly1305 keys are always 256 bits, so the key length in the provided parameters is ignored.
|
||||
/// </remarks>
|
||||
protected override void EngineInit(KeyGenerationParameters param)
|
||||
{
|
||||
// Poly1305 keys are always 256 bits
|
||||
this.random = param.Random;
|
||||
this.strength = 32;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a 256 bit key in the format required for Poly1305 - e.g.
|
||||
/// <code>k[0] ... k[15], r[0] ... r[15]</code> with the required bits in <code>r</code> cleared
|
||||
/// as per <see cref="Clamp(byte[])"/>.
|
||||
/// </summary>
|
||||
protected override byte[] EngineGenerateKey()
|
||||
{
|
||||
byte[] key = base.EngineGenerateKey();
|
||||
Clamp(key);
|
||||
return key;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modifies an existing 32 byte key value to comply with the requirements of the Poly1305 key by
|
||||
/// clearing required bits in the <code>r</code> (second 16 bytes) portion of the key.<br/>
|
||||
/// Specifically:
|
||||
/// <ul>
|
||||
/// <li>r[3], r[7], r[11], r[15] have top four bits clear (i.e., are {0, 1, . . . , 15})</li>
|
||||
/// <li>r[4], r[8], r[12] have bottom two bits clear (i.e., are in {0, 4, 8, . . . , 252})</li>
|
||||
/// </ul>
|
||||
/// </summary>
|
||||
/// <param name="key">a 32 byte key value <code>k[0] ... k[15], r[0] ... r[15]</code></param>
|
||||
public static void Clamp(byte[] key)
|
||||
{
|
||||
/*
|
||||
* Key is k[0] ... k[15], r[0] ... r[15] as per poly1305_aes_clamp in ref impl.
|
||||
*/
|
||||
if (key.Length != 32)
|
||||
throw new ArgumentException("Poly1305 key must be 256 bits.");
|
||||
|
||||
/*
|
||||
* r[3], r[7], r[11], r[15] have top four bits clear (i.e., are {0, 1, . . . , 15})
|
||||
*/
|
||||
key[3] &= R_MASK_HIGH_4;
|
||||
key[7] &= R_MASK_HIGH_4;
|
||||
key[11] &= R_MASK_HIGH_4;
|
||||
key[15] &= R_MASK_HIGH_4;
|
||||
|
||||
/*
|
||||
* r[4], r[8], r[12] have bottom two bits clear (i.e., are in {0, 4, 8, . . . , 252}).
|
||||
*/
|
||||
key[4] &= R_MASK_LOW_2;
|
||||
key[8] &= R_MASK_LOW_2;
|
||||
key[12] &= R_MASK_LOW_2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks a 32 byte key for compliance with the Poly1305 key requirements, e.g.
|
||||
/// <code>k[0] ... k[15], r[0] ... r[15]</code> with the required bits in <code>r</code> cleared
|
||||
/// as per <see cref="Clamp(byte[])"/>.
|
||||
/// </summary>
|
||||
/// <param name="key">Key.</param>
|
||||
/// <exception cref="System.ArgumentException">if the key is of the wrong length, or has invalid bits set
|
||||
/// in the <code>r</code> portion of the key.</exception>
|
||||
public static void CheckKey(byte[] key)
|
||||
{
|
||||
if (key.Length != 32)
|
||||
throw new ArgumentException("Poly1305 key must be 256 bits.");
|
||||
|
||||
CheckMask(key[3], R_MASK_HIGH_4);
|
||||
CheckMask(key[7], R_MASK_HIGH_4);
|
||||
CheckMask(key[11], R_MASK_HIGH_4);
|
||||
CheckMask(key[15], R_MASK_HIGH_4);
|
||||
|
||||
CheckMask(key[4], R_MASK_LOW_2);
|
||||
CheckMask(key[8], R_MASK_LOW_2);
|
||||
CheckMask(key[12], R_MASK_LOW_2);
|
||||
}
|
||||
|
||||
private static void CheckMask(byte b, byte mask)
|
||||
{
|
||||
if ((b & (~mask)) != 0)
|
||||
throw new ArgumentException("Invalid format for r portion of Poly1305 key.");
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7cdc89ee4e677e24fb9024bb1979fa6d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,70 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* Generate a random factor suitable for use with RSA blind signatures
|
||||
* as outlined in Chaum's blinding and unblinding as outlined in
|
||||
* "Handbook of Applied Cryptography", page 475.
|
||||
*/
|
||||
public class RsaBlindingFactorGenerator
|
||||
{
|
||||
private RsaKeyParameters key;
|
||||
private SecureRandom random;
|
||||
|
||||
/**
|
||||
* Initialise the factor generator
|
||||
*
|
||||
* @param param the necessary RSA key parameters.
|
||||
*/
|
||||
public void Init(ICipherParameters param)
|
||||
{
|
||||
if (param is ParametersWithRandom rParam)
|
||||
{
|
||||
key = (RsaKeyParameters)rParam.Parameters;
|
||||
random = rParam.Random;
|
||||
}
|
||||
else
|
||||
{
|
||||
key = (RsaKeyParameters)param;
|
||||
random = CryptoServicesRegistrar.GetSecureRandom();
|
||||
}
|
||||
|
||||
if (key.IsPrivate)
|
||||
throw new ArgumentException("generator requires RSA public key");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a suitable blind factor for the public key the generator was initialised with.
|
||||
*
|
||||
* @return a random blind factor
|
||||
*/
|
||||
public BigInteger GenerateBlindingFactor()
|
||||
{
|
||||
if (key == null)
|
||||
throw new InvalidOperationException("generator not initialised");
|
||||
|
||||
BigInteger m = key.Modulus;
|
||||
int length = m.BitLength - 1; // must be less than m.BitLength
|
||||
BigInteger factor;
|
||||
BigInteger gcd;
|
||||
|
||||
do
|
||||
{
|
||||
factor = new BigInteger(length, random);
|
||||
gcd = factor.Gcd(m);
|
||||
}
|
||||
while (factor.SignValue == 0 || factor.Equals(BigInteger.One) || !gcd.Equals(BigInteger.One));
|
||||
|
||||
return factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8ea6007ca73d3104e99c0a18f45e9079
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,167 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Multiplier;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* an RSA key pair generator.
|
||||
*/
|
||||
public class RsaKeyPairGenerator
|
||||
: IAsymmetricCipherKeyPairGenerator
|
||||
{
|
||||
private static readonly int[] SPECIAL_E_VALUES = new int[]{ 3, 5, 17, 257, 65537 };
|
||||
private static readonly int SPECIAL_E_HIGHEST = SPECIAL_E_VALUES[SPECIAL_E_VALUES.Length - 1];
|
||||
private static readonly int SPECIAL_E_BITS = BigInteger.ValueOf(SPECIAL_E_HIGHEST).BitLength;
|
||||
|
||||
protected static readonly BigInteger One = BigInteger.One;
|
||||
protected static readonly BigInteger DefaultPublicExponent = BigInteger.ValueOf(0x10001);
|
||||
protected const int DefaultTests = 100;
|
||||
|
||||
protected RsaKeyGenerationParameters parameters;
|
||||
|
||||
public virtual void Init(
|
||||
KeyGenerationParameters parameters)
|
||||
{
|
||||
if (parameters is RsaKeyGenerationParameters)
|
||||
{
|
||||
this.parameters = (RsaKeyGenerationParameters)parameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.parameters = new RsaKeyGenerationParameters(
|
||||
DefaultPublicExponent, parameters.Random, parameters.Strength, DefaultTests);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual AsymmetricCipherKeyPair GenerateKeyPair()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
//
|
||||
// p and q values should have a length of half the strength in bits
|
||||
//
|
||||
int strength = parameters.Strength;
|
||||
int pBitlength = (strength + 1) / 2;
|
||||
int qBitlength = strength - pBitlength;
|
||||
int mindiffbits = strength / 3;
|
||||
int minWeight = strength >> 2;
|
||||
|
||||
BigInteger e = parameters.PublicExponent;
|
||||
|
||||
// TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes)
|
||||
// (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm")
|
||||
|
||||
BigInteger p = ChooseRandomPrime(pBitlength, e);
|
||||
BigInteger q, n;
|
||||
|
||||
//
|
||||
// generate a modulus of the required length
|
||||
//
|
||||
for (;;)
|
||||
{
|
||||
q = ChooseRandomPrime(qBitlength, e);
|
||||
|
||||
// p and q should not be too close together (or equal!)
|
||||
BigInteger diff = q.Subtract(p).Abs();
|
||||
if (diff.BitLength < mindiffbits)
|
||||
continue;
|
||||
|
||||
//
|
||||
// calculate the modulus
|
||||
//
|
||||
n = p.Multiply(q);
|
||||
|
||||
if (n.BitLength != strength)
|
||||
{
|
||||
//
|
||||
// if we get here our primes aren't big enough, make the largest
|
||||
// of the two p and try again
|
||||
//
|
||||
p = p.Max(q);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Require a minimum weight of the NAF representation, since low-weight composites may
|
||||
* be weak against a version of the number-field-sieve for factoring.
|
||||
*
|
||||
* See "The number field sieve for integers of low weight", Oliver Schirokauer.
|
||||
*/
|
||||
if (WNafUtilities.GetNafWeight(n) < minWeight)
|
||||
{
|
||||
p = ChooseRandomPrime(pBitlength, e);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (p.CompareTo(q) < 0)
|
||||
{
|
||||
BigInteger tmp = p;
|
||||
p = q;
|
||||
q = tmp;
|
||||
}
|
||||
|
||||
BigInteger pSub1 = p.Subtract(One);
|
||||
BigInteger qSub1 = q.Subtract(One);
|
||||
//BigInteger phi = pSub1.Multiply(qSub1);
|
||||
BigInteger gcd = pSub1.Gcd(qSub1);
|
||||
BigInteger lcm = pSub1.Divide(gcd).Multiply(qSub1);
|
||||
|
||||
//
|
||||
// calculate the private exponent
|
||||
//
|
||||
BigInteger d = e.ModInverse(lcm);
|
||||
|
||||
if (d.BitLength <= qBitlength)
|
||||
continue;
|
||||
|
||||
//
|
||||
// calculate the CRT factors
|
||||
//
|
||||
BigInteger dP = d.Remainder(pSub1);
|
||||
BigInteger dQ = d.Remainder(qSub1);
|
||||
BigInteger qInv = BigIntegers.ModOddInverse(p, q);
|
||||
|
||||
return new AsymmetricCipherKeyPair(
|
||||
new RsaKeyParameters(false, n, e),
|
||||
new RsaPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Choose a random prime value for use with RSA</summary>
|
||||
/// <param name="bitlength">the bit-length of the returned prime</param>
|
||||
/// <param name="e">the RSA public exponent</param>
|
||||
/// <returns>a prime p, with (p-1) relatively prime to e</returns>
|
||||
protected virtual BigInteger ChooseRandomPrime(int bitlength, BigInteger e)
|
||||
{
|
||||
bool eIsKnownOddPrime = (e.BitLength <= SPECIAL_E_BITS) && Arrays.Contains(SPECIAL_E_VALUES, e.IntValue);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
BigInteger p = new BigInteger(bitlength, 1, parameters.Random);
|
||||
|
||||
if (p.Mod(e).Equals(One))
|
||||
continue;
|
||||
|
||||
if (!p.IsProbablePrime(parameters.Certainty, true))
|
||||
continue;
|
||||
|
||||
if (!eIsKnownOddPrime && !e.Gcd(p.Subtract(One)).Equals(One))
|
||||
continue;
|
||||
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e558ccd1a254f649a6d7b6a46ce918f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
276
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/SCrypt.cs
vendored
Normal file
276
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/SCrypt.cs
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/// <summary>Implementation of the scrypt a password-based key derivation function.</summary>
|
||||
/// <remarks>
|
||||
/// Scrypt was created by Colin Percival and is specified in
|
||||
/// <a href="http://tools.ietf.org/html/draft-josefsson-scrypt-kdf-01">draft-josefsson-scrypt-kd</a>.
|
||||
/// </remarks>
|
||||
public class SCrypt
|
||||
{
|
||||
/// <summary>Generate a key using the scrypt key derivation function.</summary>
|
||||
/// <param name="P">the bytes of the pass phrase.</param>
|
||||
/// <param name="S">the salt to use for this invocation.</param>
|
||||
/// <param name="N">CPU/Memory cost parameter. Must be larger than 1, a power of 2 and less than
|
||||
/// <code>2^(128 * r / 8)</code>.</param>
|
||||
/// <param name="r">the block size, must be >= 1.</param>
|
||||
/// <param name="p">Parallelization parameter. Must be a positive integer less than or equal to
|
||||
/// <code>int.MaxValue / (128 * r * 8)</code>.</param>
|
||||
/// <param name="dkLen">the length of the key to generate.</param>
|
||||
/// <returns>the generated key.</returns>
|
||||
public static byte[] Generate(byte[] P, byte[] S, int N, int r, int p, int dkLen)
|
||||
{
|
||||
if (P == null)
|
||||
throw new ArgumentNullException("Passphrase P must be provided.");
|
||||
if (S == null)
|
||||
throw new ArgumentNullException("Salt S must be provided.");
|
||||
if (N <= 1 || !IsPowerOf2(N))
|
||||
throw new ArgumentException("Cost parameter N must be > 1 and a power of 2.");
|
||||
// Only value of r that cost (as an int) could be exceeded for is 1
|
||||
if (r == 1 && N >= 65536)
|
||||
throw new ArgumentException("Cost parameter N must be > 1 and < 65536.");
|
||||
if (r < 1)
|
||||
throw new ArgumentException("Block size r must be >= 1.");
|
||||
int maxParallel = int.MaxValue / (128 * r * 8);
|
||||
if (p < 1 || p > maxParallel)
|
||||
{
|
||||
throw new ArgumentException("Parallelisation parameter p must be >= 1 and <= " + maxParallel
|
||||
+ " (based on block size r of " + r + ")");
|
||||
}
|
||||
if (dkLen < 1)
|
||||
throw new ArgumentException("Generated key length dkLen must be >= 1.");
|
||||
|
||||
return MFcrypt(P, S, N, r, p, dkLen);
|
||||
}
|
||||
|
||||
private static byte[] MFcrypt(byte[] P, byte[] S, int N, int r, int p, int dkLen)
|
||||
{
|
||||
int MFLenBytes = r * 128;
|
||||
byte[] bytes = SingleIterationPBKDF2(P, S, p * MFLenBytes);
|
||||
|
||||
uint[] B = null;
|
||||
|
||||
try
|
||||
{
|
||||
int BLen = bytes.Length >> 2;
|
||||
B = new uint[BLen];
|
||||
|
||||
Pack.LE_To_UInt32(bytes, 0, B);
|
||||
|
||||
/*
|
||||
* Chunk memory allocations; We choose 'd' so that there will be 2**d chunks, each not
|
||||
* larger than 32KiB, except that the minimum chunk size is 2 * r * 32.
|
||||
*/
|
||||
int d = 0, total = N * r;
|
||||
while ((N - d) > 2 && total > (1 << 10))
|
||||
{
|
||||
++d;
|
||||
total >>= 1;
|
||||
}
|
||||
|
||||
int MFLenWords = MFLenBytes >> 2;
|
||||
for (int BOff = 0; BOff < BLen; BOff += MFLenWords)
|
||||
{
|
||||
// TODO These can be done in parallel threads
|
||||
SMix(B, BOff, N, d, r);
|
||||
}
|
||||
|
||||
Pack.UInt32_To_LE(B, bytes, 0);
|
||||
|
||||
return SingleIterationPBKDF2(P, bytes, dkLen);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ClearAll(bytes, B);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] SingleIterationPBKDF2(byte[] P, byte[] S, int dkLen)
|
||||
{
|
||||
PbeParametersGenerator pGen = new Pkcs5S2ParametersGenerator(new Sha256Digest());
|
||||
pGen.Init(P, S, 1);
|
||||
KeyParameter key = (KeyParameter)pGen.GenerateDerivedMacParameters(dkLen * 8);
|
||||
return key.GetKey();
|
||||
}
|
||||
|
||||
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
|
||||
private static void SMix(uint[] B, int BOff, int N, int d, int r)
|
||||
{
|
||||
int powN = Integers.NumberOfTrailingZeros(N);
|
||||
int blocksPerChunk = N >> d;
|
||||
int chunkCount = 1 << d, chunkMask = blocksPerChunk - 1, chunkPow = powN - d;
|
||||
|
||||
int BCount = r * 32;
|
||||
|
||||
uint[] blockY = new uint[BCount];
|
||||
|
||||
uint[][] VV = new uint[chunkCount][];
|
||||
|
||||
try
|
||||
{
|
||||
var X = B.AsSpan(BOff, BCount);
|
||||
|
||||
for (int c = 0; c < chunkCount; ++c)
|
||||
{
|
||||
uint[] V = new uint[blocksPerChunk * BCount];
|
||||
VV[c] = V;
|
||||
|
||||
Nat.Copy(BCount, X, V);
|
||||
int off = 0;
|
||||
for (int i = 1; i < blocksPerChunk; ++i)
|
||||
{
|
||||
BlockMix(V.AsSpan(off, BCount), V.AsSpan(off + BCount));
|
||||
off += BCount;
|
||||
}
|
||||
BlockMix(V.AsSpan()[^BCount..], X);
|
||||
}
|
||||
|
||||
uint mask = (uint)N - 1;
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
int j = (int)(X[BCount - 16] & mask);
|
||||
uint[] V = VV[j >> chunkPow];
|
||||
int VOff = (j & chunkMask) * BCount;
|
||||
Nat.Xor(BCount, V.AsSpan(VOff), X, blockY);
|
||||
BlockMix(blockY, X);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
ClearAll(VV);
|
||||
Clear(blockY);
|
||||
}
|
||||
}
|
||||
|
||||
private static void BlockMix(Span<uint> B, Span<uint> Y)
|
||||
{
|
||||
int BCount = B.Length;
|
||||
int half = BCount >> 1;
|
||||
var y1 = B[^16..];
|
||||
|
||||
for (int pos = 0; pos < BCount; pos += 32)
|
||||
{
|
||||
var b0 = B[pos..];
|
||||
var y0 = Y[(pos >> 1)..];
|
||||
Nat512.Xor(y1, b0, y0);
|
||||
Salsa20Engine.SalsaCore(8, y0, y0);
|
||||
|
||||
var b1 = b0[16..];
|
||||
y1 = y0[half..];
|
||||
Nat512.Xor(y0, b1, y1);
|
||||
Salsa20Engine.SalsaCore(8, y1, y1);
|
||||
}
|
||||
}
|
||||
#else
|
||||
private static void SMix(uint[] B, int BOff, int N, int d, int r)
|
||||
{
|
||||
int powN = Integers.NumberOfTrailingZeros(N);
|
||||
int blocksPerChunk = N >> d;
|
||||
int chunkCount = 1 << d, chunkMask = blocksPerChunk - 1, chunkPow = powN - d;
|
||||
|
||||
int BCount = r * 32;
|
||||
|
||||
uint[] blockX1 = new uint[16];
|
||||
uint[] blockY = new uint[BCount];
|
||||
|
||||
uint[] X = new uint[BCount];
|
||||
uint[][] VV = new uint[chunkCount][];
|
||||
|
||||
try
|
||||
{
|
||||
Array.Copy(B, BOff, X, 0, BCount);
|
||||
|
||||
for (int c = 0; c < chunkCount; ++c)
|
||||
{
|
||||
uint[] V = new uint[blocksPerChunk * BCount];
|
||||
VV[c] = V;
|
||||
|
||||
int off = 0;
|
||||
for (int i = 0; i < blocksPerChunk; i += 2)
|
||||
{
|
||||
Array.Copy(X, 0, V, off, BCount);
|
||||
off += BCount;
|
||||
BlockMix(X, blockX1, blockY, r);
|
||||
Array.Copy(blockY, 0, V, off, BCount);
|
||||
off += BCount;
|
||||
BlockMix(blockY, blockX1, X, r);
|
||||
}
|
||||
}
|
||||
|
||||
uint mask = (uint)N - 1;
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
int j = (int)(X[BCount - 16] & mask);
|
||||
uint[] V = VV[j >> chunkPow];
|
||||
int VOff = (j & chunkMask) * BCount;
|
||||
Nat.Xor(BCount, V, VOff, X, 0, blockY, 0);
|
||||
|
||||
BlockMix(blockY, blockX1, X, r);
|
||||
}
|
||||
|
||||
Array.Copy(X, 0, B, BOff, BCount);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ClearAll(VV);
|
||||
ClearAll(X, blockX1, blockY);
|
||||
}
|
||||
}
|
||||
|
||||
private static void BlockMix(uint[] B, uint[] X1, uint[] Y, int r)
|
||||
{
|
||||
Array.Copy(B, B.Length - 16, X1, 0, 16);
|
||||
|
||||
int BOff = 0, YOff = 0, halfLen = B.Length >> 1;
|
||||
|
||||
for (int i = 2 * r; i > 0; --i)
|
||||
{
|
||||
Nat512.XorTo(B, BOff, X1, 0);
|
||||
|
||||
Salsa20Engine.SalsaCore(8, X1, X1);
|
||||
Array.Copy(X1, 0, Y, YOff, 16);
|
||||
|
||||
YOff = halfLen + BOff - YOff;
|
||||
BOff += 16;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private static void Clear(Array array)
|
||||
{
|
||||
if (array != null)
|
||||
{
|
||||
Array.Clear(array, 0, array.Length);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ClearAll(params Array[] arrays)
|
||||
{
|
||||
foreach (Array array in arrays)
|
||||
{
|
||||
Clear(array);
|
||||
}
|
||||
}
|
||||
|
||||
// note: we know X is non-zero
|
||||
private static bool IsPowerOf2(int x)
|
||||
{
|
||||
Debug.Assert(x != 0);
|
||||
|
||||
return (x & (x - 1)) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/SCrypt.cs.meta
vendored
Normal file
11
Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/generators/SCrypt.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 810ca4047bb07d94fb6b01735a6f373b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
public class X25519KeyPairGenerator
|
||||
: IAsymmetricCipherKeyPairGenerator
|
||||
{
|
||||
private SecureRandom random;
|
||||
|
||||
public virtual void Init(KeyGenerationParameters parameters)
|
||||
{
|
||||
this.random = parameters.Random;
|
||||
}
|
||||
|
||||
public virtual AsymmetricCipherKeyPair GenerateKeyPair()
|
||||
{
|
||||
X25519PrivateKeyParameters privateKey = new X25519PrivateKeyParameters(random);
|
||||
X25519PublicKeyParameters publicKey = privateKey.GeneratePublicKey();
|
||||
return new AsymmetricCipherKeyPair(publicKey, privateKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b43e76289d056544f8e8535095496a95
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||||
#pragma warning disable
|
||||
using System;
|
||||
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
|
||||
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||||
|
||||
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
public class X448KeyPairGenerator
|
||||
: IAsymmetricCipherKeyPairGenerator
|
||||
{
|
||||
private SecureRandom random;
|
||||
|
||||
public virtual void Init(KeyGenerationParameters parameters)
|
||||
{
|
||||
this.random = parameters.Random;
|
||||
}
|
||||
|
||||
public virtual AsymmetricCipherKeyPair GenerateKeyPair()
|
||||
{
|
||||
X448PrivateKeyParameters privateKey = new X448PrivateKeyParameters(random);
|
||||
X448PublicKeyParameters publicKey = privateKey.GeneratePublicKey();
|
||||
return new AsymmetricCipherKeyPair(publicKey, privateKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f00986353db0fca488b921e47e7029cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user