This commit is contained in:
2026-06-15 18:18:16 +08:00
parent 97c9fba14e
commit 2b9f134e5f
4164 changed files with 386922 additions and 79 deletions

View 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 &lt;- 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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6023682d710547a4db596e974c58e5bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3439e9d02faadfd4b96c0da140cc3051
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7987a02369f45bf46be2bd071b00bd3a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 607f394ddbca4cd458888bdefd99ead6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6fc29e9fe66ed4e4c9b1fc1e27d211e3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 462a00ee0abde8b44abc08366c0e7cb8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: feb64c5411c6a6944b3cbf866130ab0d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fd71f83ea2b09164bb2499d7f019ebf0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7bd86a459e7b0794c8e95b09994cb052
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2d7a9505dee25094a95be5c48c579f41
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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^(N1).
Hash(d, seed, output);
BigInteger U = new BigInteger(1, output).Mod(BigInteger.One.ShiftLeft(N - 1));
// 7. q = 2^(N1) + 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^(n1) 2^((n1) 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^(L1). Comment: 0 ≤ W < 2L1; hence, 2L1 ≤ 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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1b909747924741146803cbe3be2e7280
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e92a9e0fd2d687a4ab1287c7157ec5a3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 05a4d5644f5c6e64f85d8825a8bb766c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 226ca45f4849c5344b748d2d66f408ff
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8cdb2b6491a41e14c9390d896b88a607
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2d37f120fe9417b489fddcaf24464bcf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a0d6deb37aecdd74681d22229adbb1f0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 85de73367cf272f47b6a49d02a0536b1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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 &amp; 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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5dc8bb4a7ea06e64ca30ed36950729de
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dc39111d8cdbba34ebdc8e5e74231af5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fb0bf8409b479ee47a685ff2f36a07f0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 58963baccfc1e0f4fbca340b6726abb7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 71c746db80178644ebaf39e5b0218ead
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d8f69934c97758b4fbbfa9b80e47aa3f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7578f8928ecb36d4186cb9e9e9248c93
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c29fa55407fbbe5459cec743e9286b87
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d2fd5c2633a8c524499774e3ee4da6c2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 44c24ce050670094cbeacc6ed9cc61f0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a87fe1cd419e1934eb8c093990d78809
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 879260314ed88734c969c559f2b3b846
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1734f017d19ae4945b8c2694150c953a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7cdc89ee4e677e24fb9024bb1979fa6d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8ea6007ca73d3104e99c0a18f45e9079
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5e558ccd1a254f649a6d7b6a46ce918f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 810ca4047bb07d94fb6b01735a6f373b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b43e76289d056544f8e8535095496a95
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f00986353db0fca488b921e47e7029cb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: