init commit

This commit is contained in:
2025-10-09 09:57:24 +09:00
commit 4d551bd74f
6636 changed files with 1218703 additions and 0 deletions

View File

@@ -0,0 +1,362 @@
using System;
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Generators;
public sealed class BCrypt
{
internal const int MAGIC_STRING_LENGTH = 6;
private const int ROUNDS = 16;
private const int SBOX_SK = 256;
private const int SBOX_SK2 = 512;
private const int SBOX_SK3 = 768;
private const int P_SZ = 18;
internal const int SALT_SIZE_BYTES = 16;
internal const int MIN_COST = 4;
internal const int MAX_COST = 31;
internal const int MAX_PASSWORD_BYTES = 72;
private static readonly uint[] MAGIC_STRING = new uint[6] { 1332899944u, 1700884034u, 1701343084u, 1684370003u, 1668446532u, 1869963892u };
private static readonly uint[] KP = new uint[18]
{
608135816u, 2242054355u, 320440878u, 57701188u, 2752067618u, 698298832u, 137296536u, 3964562569u, 1160258022u, 953160567u,
3193202383u, 887688300u, 3232508343u, 3380367581u, 1065670069u, 3041331479u, 2450970073u, 2306472731u
};
private static readonly uint[] KS0 = new uint[256]
{
3509652390u, 2564797868u, 805139163u, 3491422135u, 3101798381u, 1780907670u, 3128725573u, 4046225305u, 614570311u, 3012652279u,
134345442u, 2240740374u, 1667834072u, 1901547113u, 2757295779u, 4103290238u, 227898511u, 1921955416u, 1904987480u, 2182433518u,
2069144605u, 3260701109u, 2620446009u, 720527379u, 3318853667u, 677414384u, 3393288472u, 3101374703u, 2390351024u, 1614419982u,
1822297739u, 2954791486u, 3608508353u, 3174124327u, 2024746970u, 1432378464u, 3864339955u, 2857741204u, 1464375394u, 1676153920u,
1439316330u, 715854006u, 3033291828u, 289532110u, 2706671279u, 2087905683u, 3018724369u, 1668267050u, 732546397u, 1947742710u,
3462151702u, 2609353502u, 2950085171u, 1814351708u, 2050118529u, 680887927u, 999245976u, 1800124847u, 3300911131u, 1713906067u,
1641548236u, 4213287313u, 1216130144u, 1575780402u, 4018429277u, 3917837745u, 3693486850u, 3949271944u, 596196993u, 3549867205u,
258830323u, 2213823033u, 772490370u, 2760122372u, 1774776394u, 2652871518u, 566650946u, 4142492826u, 1728879713u, 2882767088u,
1783734482u, 3629395816u, 2517608232u, 2874225571u, 1861159788u, 326777828u, 3124490320u, 2130389656u, 2716951837u, 967770486u,
1724537150u, 2185432712u, 2364442137u, 1164943284u, 2105845187u, 998989502u, 3765401048u, 2244026483u, 1075463327u, 1455516326u,
1322494562u, 910128902u, 469688178u, 1117454909u, 936433444u, 3490320968u, 3675253459u, 1240580251u, 122909385u, 2157517691u,
634681816u, 4142456567u, 3825094682u, 3061402683u, 2540495037u, 79693498u, 3249098678u, 1084186820u, 1583128258u, 426386531u,
1761308591u, 1047286709u, 322548459u, 995290223u, 1845252383u, 2603652396u, 3431023940u, 2942221577u, 3202600964u, 3727903485u,
1712269319u, 422464435u, 3234572375u, 1170764815u, 3523960633u, 3117677531u, 1434042557u, 442511882u, 3600875718u, 1076654713u,
1738483198u, 4213154764u, 2393238008u, 3677496056u, 1014306527u, 4251020053u, 793779912u, 2902807211u, 842905082u, 4246964064u,
1395751752u, 1040244610u, 2656851899u, 3396308128u, 445077038u, 3742853595u, 3577915638u, 679411651u, 2892444358u, 2354009459u,
1767581616u, 3150600392u, 3791627101u, 3102740896u, 284835224u, 4246832056u, 1258075500u, 768725851u, 2589189241u, 3069724005u,
3532540348u, 1274779536u, 3789419226u, 2764799539u, 1660621633u, 3471099624u, 4011903706u, 913787905u, 3497959166u, 737222580u,
2514213453u, 2928710040u, 3937242737u, 1804850592u, 3499020752u, 2949064160u, 2386320175u, 2390070455u, 2415321851u, 4061277028u,
2290661394u, 2416832540u, 1336762016u, 1754252060u, 3520065937u, 3014181293u, 791618072u, 3188594551u, 3933548030u, 2332172193u,
3852520463u, 3043980520u, 413987798u, 3465142937u, 3030929376u, 4245938359u, 2093235073u, 3534596313u, 375366246u, 2157278981u,
2479649556u, 555357303u, 3870105701u, 2008414854u, 3344188149u, 4221384143u, 3956125452u, 2067696032u, 3594591187u, 2921233993u,
2428461u, 544322398u, 577241275u, 1471733935u, 610547355u, 4027169054u, 1432588573u, 1507829418u, 2025931657u, 3646575487u,
545086370u, 48609733u, 2200306550u, 1653985193u, 298326376u, 1316178497u, 3007786442u, 2064951626u, 458293330u, 2589141269u,
3591329599u, 3164325604u, 727753846u, 2179363840u, 146436021u, 1461446943u, 4069977195u, 705550613u, 3059967265u, 3887724982u,
4281599278u, 3313849956u, 1404054877u, 2845806497u, 146425753u, 1854211946u
};
private static readonly uint[] KS1 = new uint[256]
{
1266315497u, 3048417604u, 3681880366u, 3289982499u, 2909710000u, 1235738493u, 2632868024u, 2414719590u, 3970600049u, 1771706367u,
1449415276u, 3266420449u, 422970021u, 1963543593u, 2690192192u, 3826793022u, 1062508698u, 1531092325u, 1804592342u, 2583117782u,
2714934279u, 4024971509u, 1294809318u, 4028980673u, 1289560198u, 2221992742u, 1669523910u, 35572830u, 157838143u, 1052438473u,
1016535060u, 1802137761u, 1753167236u, 1386275462u, 3080475397u, 2857371447u, 1040679964u, 2145300060u, 2390574316u, 1461121720u,
2956646967u, 4031777805u, 4028374788u, 33600511u, 2920084762u, 1018524850u, 629373528u, 3691585981u, 3515945977u, 2091462646u,
2486323059u, 586499841u, 988145025u, 935516892u, 3367335476u, 2599673255u, 2839830854u, 265290510u, 3972581182u, 2759138881u,
3795373465u, 1005194799u, 847297441u, 406762289u, 1314163512u, 1332590856u, 1866599683u, 4127851711u, 750260880u, 613907577u,
1450815602u, 3165620655u, 3734664991u, 3650291728u, 3012275730u, 3704569646u, 1427272223u, 778793252u, 1343938022u, 2676280711u,
2052605720u, 1946737175u, 3164576444u, 3914038668u, 3967478842u, 3682934266u, 1661551462u, 3294938066u, 4011595847u, 840292616u,
3712170807u, 616741398u, 312560963u, 711312465u, 1351876610u, 322626781u, 1910503582u, 271666773u, 2175563734u, 1594956187u,
70604529u, 3617834859u, 1007753275u, 1495573769u, 4069517037u, 2549218298u, 2663038764u, 504708206u, 2263041392u, 3941167025u,
2249088522u, 1514023603u, 1998579484u, 1312622330u, 694541497u, 2582060303u, 2151582166u, 1382467621u, 776784248u, 2618340202u,
3323268794u, 2497899128u, 2784771155u, 503983604u, 4076293799u, 907881277u, 423175695u, 432175456u, 1378068232u, 4145222326u,
3954048622u, 3938656102u, 3820766613u, 2793130115u, 2977904593u, 26017576u, 3274890735u, 3194772133u, 1700274565u, 1756076034u,
4006520079u, 3677328699u, 720338349u, 1533947780u, 354530856u, 688349552u, 3973924725u, 1637815568u, 332179504u, 3949051286u,
53804574u, 2852348879u, 3044236432u, 1282449977u, 3583942155u, 3416972820u, 4006381244u, 1617046695u, 2628476075u, 3002303598u,
1686838959u, 431878346u, 2686675385u, 1700445008u, 1080580658u, 1009431731u, 832498133u, 3223435511u, 2605976345u, 2271191193u,
2516031870u, 1648197032u, 4164389018u, 2548247927u, 300782431u, 375919233u, 238389289u, 3353747414u, 2531188641u, 2019080857u,
1475708069u, 455242339u, 2609103871u, 448939670u, 3451063019u, 1395535956u, 2413381860u, 1841049896u, 1491858159u, 885456874u,
4264095073u, 4001119347u, 1565136089u, 3898914787u, 1108368660u, 540939232u, 1173283510u, 2745871338u, 3681308437u, 4207628240u,
3343053890u, 4016749493u, 1699691293u, 1103962373u, 3625875870u, 2256883143u, 3830138730u, 1031889488u, 3479347698u, 1535977030u,
4236805024u, 3251091107u, 2132092099u, 1774941330u, 1199868427u, 1452454533u, 157007616u, 2904115357u, 342012276u, 595725824u,
1480756522u, 206960106u, 497939518u, 591360097u, 863170706u, 2375253569u, 3596610801u, 1814182875u, 2094937945u, 3421402208u,
1082520231u, 3463918190u, 2785509508u, 435703966u, 3908032597u, 1641649973u, 2842273706u, 3305899714u, 1510255612u, 2148256476u,
2655287854u, 3276092548u, 4258621189u, 236887753u, 3681803219u, 274041037u, 1734335097u, 3815195456u, 3317970021u, 1899903192u,
1026095262u, 4050517792u, 356393447u, 2410691914u, 3873677099u, 3682840055u
};
private static readonly uint[] KS2 = new uint[256]
{
3913112168u, 2491498743u, 4132185628u, 2489919796u, 1091903735u, 1979897079u, 3170134830u, 3567386728u, 3557303409u, 857797738u,
1136121015u, 1342202287u, 507115054u, 2535736646u, 337727348u, 3213592640u, 1301675037u, 2528481711u, 1895095763u, 1721773893u,
3216771564u, 62756741u, 2142006736u, 835421444u, 2531993523u, 1442658625u, 3659876326u, 2882144922u, 676362277u, 1392781812u,
170690266u, 3921047035u, 1759253602u, 3611846912u, 1745797284u, 664899054u, 1329594018u, 3901205900u, 3045908486u, 2062866102u,
2865634940u, 3543621612u, 3464012697u, 1080764994u, 553557557u, 3656615353u, 3996768171u, 991055499u, 499776247u, 1265440854u,
648242737u, 3940784050u, 980351604u, 3713745714u, 1749149687u, 3396870395u, 4211799374u, 3640570775u, 1161844396u, 3125318951u,
1431517754u, 545492359u, 4268468663u, 3499529547u, 1437099964u, 2702547544u, 3433638243u, 2581715763u, 2787789398u, 1060185593u,
1593081372u, 2418618748u, 4260947970u, 69676912u, 2159744348u, 86519011u, 2512459080u, 3838209314u, 1220612927u, 3339683548u,
133810670u, 1090789135u, 1078426020u, 1569222167u, 845107691u, 3583754449u, 4072456591u, 1091646820u, 628848692u, 1613405280u,
3757631651u, 526609435u, 236106946u, 48312990u, 2942717905u, 3402727701u, 1797494240u, 859738849u, 992217954u, 4005476642u,
2243076622u, 3870952857u, 3732016268u, 765654824u, 3490871365u, 2511836413u, 1685915746u, 3888969200u, 1414112111u, 2273134842u,
3281911079u, 4080962846u, 172450625u, 2569994100u, 980381355u, 4109958455u, 2819808352u, 2716589560u, 2568741196u, 3681446669u,
3329971472u, 1835478071u, 660984891u, 3704678404u, 4045999559u, 3422617507u, 3040415634u, 1762651403u, 1719377915u, 3470491036u,
2693910283u, 3642056355u, 3138596744u, 1364962596u, 2073328063u, 1983633131u, 926494387u, 3423689081u, 2150032023u, 4096667949u,
1749200295u, 3328846651u, 309677260u, 2016342300u, 1779581495u, 3079819751u, 111262694u, 1274766160u, 443224088u, 298511866u,
1025883608u, 3806446537u, 1145181785u, 168956806u, 3641502830u, 3584813610u, 1689216846u, 3666258015u, 3200248200u, 1692713982u,
2646376535u, 4042768518u, 1618508792u, 1610833997u, 3523052358u, 4130873264u, 2001055236u, 3610705100u, 2202168115u, 4028541809u,
2961195399u, 1006657119u, 2006996926u, 3186142756u, 1430667929u, 3210227297u, 1314452623u, 4074634658u, 4101304120u, 2273951170u,
1399257539u, 3367210612u, 3027628629u, 1190975929u, 2062231137u, 2333990788u, 2221543033u, 2438960610u, 1181637006u, 548689776u,
2362791313u, 3372408396u, 3104550113u, 3145860560u, 296247880u, 1970579870u, 3078560182u, 3769228297u, 1714227617u, 3291629107u,
3898220290u, 166772364u, 1251581989u, 493813264u, 448347421u, 195405023u, 2709975567u, 677966185u, 3703036547u, 1463355134u,
2715995803u, 1338867538u, 1343315457u, 2802222074u, 2684532164u, 233230375u, 2599980071u, 2000651841u, 3277868038u, 1638401717u,
4028070440u, 3237316320u, 6314154u, 819756386u, 300326615u, 590932579u, 1405279636u, 3267499572u, 3150704214u, 2428286686u,
3959192993u, 3461946742u, 1862657033u, 1266418056u, 963775037u, 2089974820u, 2263052895u, 1917689273u, 448879540u, 3550394620u,
3981727096u, 150775221u, 3627908307u, 1303187396u, 508620638u, 2975983352u, 2726630617u, 1817252668u, 1876281319u, 1457606340u,
908771278u, 3720792119u, 3617206836u, 2455994898u, 1729034894u, 1080033504u
};
private static readonly uint[] KS3 = new uint[256]
{
976866871u, 3556439503u, 2881648439u, 1522871579u, 1555064734u, 1336096578u, 3548522304u, 2579274686u, 3574697629u, 3205460757u,
3593280638u, 3338716283u, 3079412587u, 564236357u, 2993598910u, 1781952180u, 1464380207u, 3163844217u, 3332601554u, 1699332808u,
1393555694u, 1183702653u, 3581086237u, 1288719814u, 691649499u, 2847557200u, 2895455976u, 3193889540u, 2717570544u, 1781354906u,
1676643554u, 2592534050u, 3230253752u, 1126444790u, 2770207658u, 2633158820u, 2210423226u, 2615765581u, 2414155088u, 3127139286u,
673620729u, 2805611233u, 1269405062u, 4015350505u, 3341807571u, 4149409754u, 1057255273u, 2012875353u, 2162469141u, 2276492801u,
2601117357u, 993977747u, 3918593370u, 2654263191u, 753973209u, 36408145u, 2530585658u, 25011837u, 3520020182u, 2088578344u,
530523599u, 2918365339u, 1524020338u, 1518925132u, 3760827505u, 3759777254u, 1202760957u, 3985898139u, 3906192525u, 674977740u,
4174734889u, 2031300136u, 2019492241u, 3983892565u, 4153806404u, 3822280332u, 352677332u, 2297720250u, 60907813u, 90501309u,
3286998549u, 1016092578u, 2535922412u, 2839152426u, 457141659u, 509813237u, 4120667899u, 652014361u, 1966332200u, 2975202805u,
55981186u, 2327461051u, 676427537u, 3255491064u, 2882294119u, 3433927263u, 1307055953u, 942726286u, 933058658u, 2468411793u,
3933900994u, 4215176142u, 1361170020u, 2001714738u, 2830558078u, 3274259782u, 1222529897u, 1679025792u, 2729314320u, 3714953764u,
1770335741u, 151462246u, 3013232138u, 1682292957u, 1483529935u, 471910574u, 1539241949u, 458788160u, 3436315007u, 1807016891u,
3718408830u, 978976581u, 1043663428u, 3165965781u, 1927990952u, 4200891579u, 2372276910u, 3208408903u, 3533431907u, 1412390302u,
2931980059u, 4132332400u, 1947078029u, 3881505623u, 4168226417u, 2941484381u, 1077988104u, 1320477388u, 886195818u, 18198404u,
3786409000u, 2509781533u, 112762804u, 3463356488u, 1866414978u, 891333506u, 18488651u, 661792760u, 1628790961u, 3885187036u,
3141171499u, 876946877u, 2693282273u, 1372485963u, 791857591u, 2686433993u, 3759982718u, 3167212022u, 3472953795u, 2716379847u,
445679433u, 3561995674u, 3504004811u, 3574258232u, 54117162u, 3331405415u, 2381918588u, 3769707343u, 4154350007u, 1140177722u,
4074052095u, 668550556u, 3214352940u, 367459370u, 261225585u, 2610173221u, 4209349473u, 3468074219u, 3265815641u, 314222801u,
3066103646u, 3808782860u, 282218597u, 3406013506u, 3773591054u, 379116347u, 1285071038u, 846784868u, 2669647154u, 3771962079u,
3550491691u, 2305946142u, 453669953u, 1268987020u, 3317592352u, 3279303384u, 3744833421u, 2610507566u, 3859509063u, 266596637u,
3847019092u, 517658769u, 3462560207u, 3443424879u, 370717030u, 4247526661u, 2224018117u, 4143653529u, 4112773975u, 2788324899u,
2477274417u, 1456262402u, 2901442914u, 1517677493u, 1846949527u, 2295493580u, 3734397586u, 2176403920u, 1280348187u, 1908823572u,
3871786941u, 846861322u, 1172426758u, 3287448474u, 3383383037u, 1655181056u, 3139813346u, 901632758u, 1897031941u, 2986607138u,
3066810236u, 3447102507u, 1393639104u, 373351379u, 950779232u, 625454576u, 3124240540u, 4148612726u, 2007998917u, 544563296u,
2244738638u, 2330496472u, 2058025392u, 1291430526u, 424198748u, 50039436u, 29584100u, 3605783033u, 2429876329u, 2791104160u,
1057563949u, 3255363231u, 3075367218u, 3463963227u, 1469046755u, 985887462u
};
private readonly uint[] S;
private readonly uint[] P;
private BCrypt()
{
S = new uint[1024];
P = new uint[18];
}
private uint F(uint x)
{
return ((S[x >> 24] + S[256 + ((x >> 16) & 0xFF)]) ^ S[512 + ((x >> 8) & 0xFF)]) + S[768 + (x & 0xFF)];
}
private void ProcessTable(uint xl, uint xr, uint[] table)
{
int num = table.Length;
for (int i = 0; i < num; i += 2)
{
xl ^= P[0];
for (int j = 1; j < 16; j += 2)
{
xr ^= F(xl) ^ P[j];
xl ^= F(xr) ^ P[j + 1];
}
xr ^= P[17];
table[i] = xr;
table[i + 1] = xl;
xr = xl;
xl = table[i];
}
}
private void InitState()
{
Array.Copy(KS0, 0, S, 0, 256);
Array.Copy(KS1, 0, S, 256, 256);
Array.Copy(KS2, 0, S, 512, 256);
Array.Copy(KS3, 0, S, 768, 256);
Array.Copy(KP, 0, P, 0, 18);
}
private void CyclicXorKey(byte[] key)
{
int num = key.Length;
int num2 = 0;
for (int i = 0; i < 18; i++)
{
uint num3 = 0u;
for (int j = 0; j < 4; j++)
{
num3 = (num3 << 8) | key[num2];
if (++num2 >= num)
{
num2 = 0;
}
}
uint[] p;
uint[] array = (p = P);
int num4 = i;
nint num5 = num4;
array[num4] = p[num5] ^ num3;
}
}
private byte[] EncryptMagicString()
{
uint[] array = new uint[6]
{
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 < 6; j += 2)
{
uint num = array[j];
uint num2 = array[j + 1];
num ^= P[0];
for (int k = 1; k < 16; k += 2)
{
num2 ^= F(num) ^ P[k];
num ^= F(num2) ^ P[k + 1];
}
num2 ^= P[17];
array[j] = num2;
array[j + 1] = num;
}
}
byte[] array2 = new byte[24];
Pack.UInt32_To_BE(array, array2, 0);
Array.Clear(array, 0, array.Length);
Array.Clear(P, 0, P.Length);
Array.Clear(S, 0, S.Length);
return array2;
}
private void ProcessTableWithSalt(uint[] table, uint[] salt32Bit, uint iv1, uint iv2)
{
uint num = iv1 ^ salt32Bit[0];
uint num2 = iv2 ^ salt32Bit[1];
int num3 = table.Length;
for (int i = 0; i < num3; i += 4)
{
num ^= P[0];
for (int j = 1; j < 16; j += 2)
{
num2 ^= F(num) ^ P[j];
num ^= F(num2) ^ P[j + 1];
}
num2 = (table[i] = num2 ^ P[17]);
table[i + 1] = num;
uint num4 = salt32Bit[2] ^ num2;
uint num5 = salt32Bit[3] ^ num;
if (i + 2 >= num3)
{
break;
}
num4 ^= P[0];
for (int k = 1; k < 16; k += 2)
{
num5 ^= F(num4) ^ P[k];
num4 ^= F(num5) ^ P[k + 1];
}
num5 = (table[i + 2] = num5 ^ P[17]);
table[i + 3] = num4;
num = salt32Bit[0] ^ num5;
num2 = salt32Bit[1] ^ num4;
}
}
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];
}
InitState();
uint[] array = new uint[4];
Pack.BE_To_UInt32(salt, 0, array);
uint[] array2 = new uint[salt.Length];
array2[0] = array[2];
array2[1] = array[3];
array2[2] = array[0];
array2[3] = array[1];
CyclicXorKey(psw);
ProcessTableWithSalt(P, array, 0u, 0u);
Array.Clear(array, 0, array.Length);
ProcessTableWithSalt(S, array2, P[P.Length - 2], P[P.Length - 1]);
Array.Clear(array2, 0, array2.Length);
int num = 1 << cost;
for (int i = 0; i != num; i++)
{
CyclicXorKey(psw);
ProcessTable(0u, 0u, P);
ProcessTable(P[16], P[17], S);
CyclicXorKey(salt);
ProcessTable(0u, 0u, P);
ProcessTable(P[16], P[17], S);
}
return EncryptMagicString();
}
public static byte[] PasswordToByteArray(char[] password)
{
return Arrays.Append(Strings.ToUtf8ByteArray(password), 0);
}
public static byte[] Generate(byte[] password, byte[] salt, int cost)
{
if (password == null)
{
throw new ArgumentNullException("password");
}
if (password.Length > 72)
{
throw new ArgumentException("BCrypt password must be <= 72 bytes", "password");
}
if (salt == null)
{
throw new ArgumentNullException("salt");
}
if (salt.Length != 16)
{
throw new ArgumentException("BCrypt salt must be 128 bits", "salt");
}
if (cost < 4 || cost > 31)
{
throw new ArgumentException("BCrypt cost must be from 4..31", "cost");
}
return new BCrypt().DeriveRawKey(cost, salt, password);
}
}

View File

@@ -0,0 +1,90 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
namespace Org.BouncyCastle.Crypto.Generators;
public class BaseKdfBytesGenerator : IDerivationFunction
{
private int counterStart;
private IDigest digest;
private byte[] shared;
private byte[] iv;
public virtual IDigest Digest => digest;
public BaseKdfBytesGenerator(int counterStart, IDigest digest)
{
this.counterStart = counterStart;
this.digest = digest;
}
public virtual void Init(IDerivationParameters parameters)
{
if (parameters is KdfParameters)
{
KdfParameters kdfParameters = (KdfParameters)parameters;
shared = kdfParameters.GetSharedSecret();
iv = kdfParameters.GetIV();
return;
}
if (parameters is Iso18033KdfParameters)
{
Iso18033KdfParameters iso18033KdfParameters = (Iso18033KdfParameters)parameters;
shared = iso18033KdfParameters.GetSeed();
iv = null;
return;
}
throw new ArgumentException("KDF parameters required for KDF Generator");
}
public virtual int GenerateBytes(byte[] output, int outOff, int length)
{
if (output.Length - length < outOff)
{
throw new DataLengthException("output buffer too small");
}
long num = length;
int digestSize = digest.GetDigestSize();
if (num > 8589934591L)
{
throw new ArgumentException("Output length too large");
}
int num2 = (int)((num + digestSize - 1) / digestSize);
byte[] array = new byte[digest.GetDigestSize()];
byte[] array2 = new byte[4];
Pack.UInt32_To_BE((uint)counterStart, array2, 0);
uint num3 = (uint)(counterStart & -256);
for (int i = 0; i < num2; i++)
{
digest.BlockUpdate(shared, 0, shared.Length);
digest.BlockUpdate(array2, 0, 4);
if (iv != null)
{
digest.BlockUpdate(iv, 0, iv.Length);
}
digest.DoFinal(array, 0);
if (length > digestSize)
{
Array.Copy(array, 0, output, outOff, digestSize);
outOff += digestSize;
length -= digestSize;
}
else
{
Array.Copy(array, 0, output, outOff, length);
}
byte[] array3;
if (((array3 = array2)[3] = (byte)(array3[3] + 1)) == 0)
{
num3 += 256;
Pack.UInt32_To_BE(num3, array2, 0);
}
}
digest.Reset();
return (int)num;
}
}

View File

@@ -0,0 +1,23 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Crypto.Generators;
public class DHBasicKeyPairGenerator : IAsymmetricCipherKeyPairGenerator
{
private DHKeyGenerationParameters param;
public virtual void Init(KeyGenerationParameters parameters)
{
param = (DHKeyGenerationParameters)parameters;
}
public virtual AsymmetricCipherKeyPair GenerateKeyPair()
{
DHKeyGeneratorHelper instance = DHKeyGeneratorHelper.Instance;
DHParameters parameters = param.Parameters;
BigInteger x = instance.CalculatePrivate(parameters, param.Random);
BigInteger y = instance.CalculatePublic(parameters, x);
return new AsymmetricCipherKeyPair(new DHPublicKeyParameters(y, parameters), new DHPrivateKeyParameters(x, parameters));
}
}

View File

@@ -0,0 +1,57 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Generators;
internal class DHKeyGeneratorHelper
{
internal static readonly DHKeyGeneratorHelper Instance = new DHKeyGeneratorHelper();
private DHKeyGeneratorHelper()
{
}
internal BigInteger CalculatePrivate(DHParameters dhParams, SecureRandom random)
{
int l = dhParams.L;
if (l != 0)
{
int num = l >> 2;
BigInteger bigInteger;
do
{
bigInteger = new BigInteger(l, random).SetBit(l - 1);
}
while (WNafUtilities.GetNafWeight(bigInteger) < num);
return bigInteger;
}
BigInteger min = BigInteger.Two;
int m = dhParams.M;
if (m != 0)
{
min = BigInteger.One.ShiftLeft(m - 1);
}
BigInteger bigInteger2 = dhParams.Q;
if (bigInteger2 == null)
{
bigInteger2 = dhParams.P;
}
BigInteger bigInteger3 = bigInteger2.Subtract(BigInteger.Two);
int num2 = bigInteger3.BitLength >> 2;
BigInteger bigInteger4;
do
{
bigInteger4 = BigIntegers.CreateRandomInRange(min, bigInteger3, random);
}
while (WNafUtilities.GetNafWeight(bigInteger4) < num2);
return bigInteger4;
}
internal BigInteger CalculatePublic(DHParameters dhParams, BigInteger x)
{
return dhParams.G.ModPow(x, dhParams.P);
}
}

View File

@@ -0,0 +1,23 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Crypto.Generators;
public class DHKeyPairGenerator : IAsymmetricCipherKeyPairGenerator
{
private DHKeyGenerationParameters param;
public virtual void Init(KeyGenerationParameters parameters)
{
param = (DHKeyGenerationParameters)parameters;
}
public virtual AsymmetricCipherKeyPair GenerateKeyPair()
{
DHKeyGeneratorHelper instance = DHKeyGeneratorHelper.Instance;
DHParameters parameters = param.Parameters;
BigInteger x = instance.CalculatePrivate(parameters, param.Random);
BigInteger y = instance.CalculatePublic(parameters, x);
return new AsymmetricCipherKeyPair(new DHPublicKeyParameters(y, parameters), new DHPrivateKeyParameters(x, parameters));
}
}

View File

@@ -0,0 +1,30 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace 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;
}
public virtual DHParameters GenerateParameters()
{
BigInteger[] array = DHParametersHelper.GenerateSafePrimes(size, certainty, random);
BigInteger p = array[0];
BigInteger q = array[1];
BigInteger g = DHParametersHelper.SelectGenerator(p, q, random);
return new DHParameters(p, g, q, BigInteger.Two, null);
}
}

View File

@@ -0,0 +1,102 @@
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Generators;
internal class DHParametersHelper
{
private static readonly BigInteger Six = BigInteger.ValueOf(6L);
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[] array = new BigInteger[primeProducts.Length];
for (int i = 0; i < array.Length; i++)
{
array[i] = BigInteger.ValueOf(primeProducts[i]);
}
return array;
}
internal static BigInteger[] GenerateSafePrimes(int size, int certainty, SecureRandom random)
{
int num = size - 1;
int num2 = size >> 2;
BigInteger bigInteger;
BigInteger bigInteger2;
if (size <= 32)
{
do
{
bigInteger = new BigInteger(num, 2, random);
bigInteger2 = bigInteger.ShiftLeft(1).Add(BigInteger.One);
}
while (!bigInteger2.IsProbablePrime(certainty, randomlySelected: true) || (certainty > 2 && !bigInteger.IsProbablePrime(certainty, randomlySelected: true)));
}
else
{
while (true)
{
bigInteger = new BigInteger(num, 0, random);
while (true)
{
for (int i = 0; i < primeLists.Length; i++)
{
int num3 = bigInteger.Remainder(BigPrimeProducts[i]).IntValue;
if (i == 0)
{
int num4 = num3 % 3;
if (num4 != 2)
{
int num5 = 2 * num4 + 2;
bigInteger = bigInteger.Add(BigInteger.ValueOf(num5));
num3 = (num3 + num5) % primeProducts[i];
}
}
int[] array = primeLists[i];
foreach (int num6 in array)
{
int num7 = num3 % num6;
if (num7 == 0 || num7 == num6 >> 1)
{
goto IL_00cd;
}
}
}
break;
IL_00cd:
bigInteger = bigInteger.Add(Six);
}
if (bigInteger.BitLength == num && bigInteger.RabinMillerTest(2, random, randomlySelected: true))
{
bigInteger2 = bigInteger.ShiftLeft(1).Add(BigInteger.One);
if (bigInteger2.RabinMillerTest(certainty, random, randomlySelected: true) && (certainty <= 2 || bigInteger.RabinMillerTest(certainty - 2, random, randomlySelected: true)) && WNafUtilities.GetNafWeight(bigInteger2) >= num2)
{
break;
}
}
}
}
return new BigInteger[2] { bigInteger2, bigInteger };
}
internal static BigInteger SelectGenerator(BigInteger p, BigInteger q, SecureRandom random)
{
BigInteger max = p.Subtract(BigInteger.Two);
BigInteger bigInteger2;
do
{
BigInteger bigInteger = BigIntegers.CreateRandomInRange(BigInteger.Two, max, random);
bigInteger2 = bigInteger.ModPow(BigInteger.Two, p);
}
while (bigInteger2.Equals(BigInteger.One));
return bigInteger2;
}
}

View File

@@ -0,0 +1,46 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Crypto.Generators;
public class DesEdeKeyGenerator : DesKeyGenerator
{
public DesEdeKeyGenerator()
{
}
internal DesEdeKeyGenerator(int defaultStrength)
: base(defaultStrength)
{
}
protected override void engineInit(KeyGenerationParameters parameters)
{
random = parameters.Random;
strength = (parameters.Strength + 7) / 8;
if (strength == 0 || strength == 21)
{
strength = 24;
}
else if (strength == 14)
{
strength = 16;
}
else if (strength != 24 && strength != 16)
{
throw new ArgumentException("DESede key must be " + 192 + " or " + 128 + " bits long.");
}
}
protected override byte[] engineGenerateKey()
{
byte[] array = new byte[strength];
do
{
random.NextBytes(array);
DesParameters.SetOddParity(array);
}
while (DesEdeParameters.IsWeakKey(array, 0, array.Length) || !DesEdeParameters.IsRealEdeKey(array, 0));
return array;
}
}

View File

@@ -0,0 +1,41 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Crypto.Generators;
public class DesKeyGenerator : CipherKeyGenerator
{
public DesKeyGenerator()
{
}
internal DesKeyGenerator(int defaultStrength)
: base(defaultStrength)
{
}
protected override void engineInit(KeyGenerationParameters parameters)
{
base.engineInit(parameters);
if (strength == 0 || strength == 7)
{
strength = 8;
}
else if (strength != 8)
{
throw new ArgumentException("DES key must be " + 64 + " bits long.");
}
}
protected override byte[] engineGenerateKey()
{
byte[] array = new byte[8];
do
{
random.NextBytes(array);
DesParameters.SetOddParity(array);
}
while (DesParameters.IsWeakKey(array, 0));
return array;
}
}

View File

@@ -0,0 +1,49 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Generators;
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");
}
param = (DsaKeyGenerationParameters)parameters;
}
public AsymmetricCipherKeyPair GenerateKeyPair()
{
DsaParameters parameters = param.Parameters;
BigInteger x = GeneratePrivateKey(parameters.Q, param.Random);
BigInteger y = CalculatePublicKey(parameters.P, parameters.G, x);
return new AsymmetricCipherKeyPair(new DsaPublicKeyParameters(y, parameters), new DsaPrivateKeyParameters(x, parameters));
}
private static BigInteger GeneratePrivateKey(BigInteger q, SecureRandom random)
{
int num = q.BitLength >> 2;
BigInteger bigInteger;
do
{
bigInteger = BigIntegers.CreateRandomInRange(One, q.Subtract(One), random);
}
while (WNafUtilities.GetNafWeight(bigInteger) < num);
return bigInteger;
}
private static BigInteger CalculatePublicKey(BigInteger p, BigInteger g, BigInteger x)
{
return g.ModPow(x, p);
}
}

View File

@@ -0,0 +1,280 @@
using System;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Crypto.Generators;
public class DsaParametersGenerator
{
private IDigest digest;
private int L;
private int 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;
}
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");
}
use186_3 = false;
L = size;
N = GetDefaultN(size);
this.certainty = certainty;
this.random = random;
}
public virtual void Init(DsaParameterGenerationParameters parameters)
{
use186_3 = true;
L = parameters.L;
N = parameters.N;
certainty = parameters.Certainty;
random = parameters.Random;
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");
}
}
public virtual DsaParameters GenerateParameters()
{
if (!use186_3)
{
return GenerateParameters_FIPS186_2();
}
return GenerateParameters_FIPS186_3();
}
protected virtual DsaParameters GenerateParameters_FIPS186_2()
{
byte[] array = new byte[20];
byte[] array2 = new byte[20];
byte[] array3 = new byte[20];
byte[] array4 = new byte[20];
int num = (L - 1) / 160;
byte[] array5 = new byte[L / 8];
if (!(digest is Sha1Digest))
{
throw new InvalidOperationException("can only use SHA-1 for generating FIPS 186-2 parameters");
}
while (true)
{
random.NextBytes(array);
Hash(digest, array, array2);
Array.Copy(array, 0, array3, 0, array.Length);
Inc(array3);
Hash(digest, array3, array3);
for (int i = 0; i != array4.Length; i++)
{
array4[i] = (byte)(array2[i] ^ array3[i]);
}
byte[] array6;
(array6 = array4)[0] = (byte)(array6[0] | 0x80);
(array6 = array4)[19] = (byte)(array6[19] | 1);
BigInteger bigInteger = new BigInteger(1, array4);
if (!bigInteger.IsProbablePrime(certainty))
{
continue;
}
byte[] array7 = Arrays.Clone(array);
Inc(array7);
for (int j = 0; j < 4096; j++)
{
for (int k = 0; k < num; k++)
{
Inc(array7);
Hash(digest, array7, array2);
Array.Copy(array2, 0, array5, array5.Length - (k + 1) * array2.Length, array2.Length);
}
Inc(array7);
Hash(digest, array7, array2);
Array.Copy(array2, array2.Length - (array5.Length - num * array2.Length), array5, 0, array5.Length - num * array2.Length);
(array6 = array5)[0] = (byte)(array6[0] | 0x80);
BigInteger bigInteger2 = new BigInteger(1, array5);
BigInteger bigInteger3 = bigInteger2.Mod(bigInteger.ShiftLeft(1));
BigInteger bigInteger4 = bigInteger2.Subtract(bigInteger3.Subtract(BigInteger.One));
if (bigInteger4.BitLength == L && bigInteger4.IsProbablePrime(certainty))
{
BigInteger g = CalculateGenerator_FIPS186_2(bigInteger4, bigInteger, random);
return new DsaParameters(bigInteger4, bigInteger, g, new DsaValidationParameters(array, j));
}
}
}
}
protected virtual BigInteger CalculateGenerator_FIPS186_2(BigInteger p, BigInteger q, SecureRandom r)
{
BigInteger e = p.Subtract(BigInteger.One).Divide(q);
BigInteger max = p.Subtract(BigInteger.Two);
BigInteger bigInteger2;
do
{
BigInteger bigInteger = BigIntegers.CreateRandomInRange(BigInteger.Two, max, r);
bigInteger2 = bigInteger.ModPow(e, p);
}
while (bigInteger2.BitLength <= 1);
return bigInteger2;
}
protected virtual DsaParameters GenerateParameters_FIPS186_3()
{
IDigest digest = this.digest;
int num = digest.GetDigestSize() * 8;
int n = N;
byte[] array = new byte[n / 8];
int num2 = (L - 1) / num;
int n2 = (L - 1) % num;
byte[] array2 = new byte[digest.GetDigestSize()];
while (true)
{
random.NextBytes(array);
Hash(digest, array, array2);
BigInteger bigInteger = new BigInteger(1, array2).Mod(BigInteger.One.ShiftLeft(N - 1));
BigInteger bigInteger2 = bigInteger.SetBit(0).SetBit(N - 1);
if (!bigInteger2.IsProbablePrime(certainty))
{
continue;
}
byte[] array3 = Arrays.Clone(array);
int num3 = 4 * L;
for (int i = 0; i < num3; i++)
{
BigInteger bigInteger3 = BigInteger.Zero;
int num4 = 0;
int num5 = 0;
while (num4 <= num2)
{
Inc(array3);
Hash(digest, array3, array2);
BigInteger bigInteger4 = new BigInteger(1, array2);
if (num4 == num2)
{
bigInteger4 = bigInteger4.Mod(BigInteger.One.ShiftLeft(n2));
}
bigInteger3 = bigInteger3.Add(bigInteger4.ShiftLeft(num5));
num4++;
num5 += num;
}
BigInteger bigInteger5 = bigInteger3.Add(BigInteger.One.ShiftLeft(L - 1));
BigInteger bigInteger6 = bigInteger5.Mod(bigInteger2.ShiftLeft(1));
BigInteger bigInteger7 = bigInteger5.Subtract(bigInteger6.Subtract(BigInteger.One));
if (bigInteger7.BitLength != L || !bigInteger7.IsProbablePrime(certainty))
{
continue;
}
if (usageIndex >= 0)
{
BigInteger bigInteger8 = CalculateGenerator_FIPS186_3_Verifiable(digest, bigInteger7, bigInteger2, array, usageIndex);
if (bigInteger8 != null)
{
return new DsaParameters(bigInteger7, bigInteger2, bigInteger8, new DsaValidationParameters(array, i, usageIndex));
}
}
BigInteger g = CalculateGenerator_FIPS186_3_Unverifiable(bigInteger7, bigInteger2, random);
return new DsaParameters(bigInteger7, bigInteger2, g, new DsaValidationParameters(array, i));
}
}
}
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)
{
BigInteger e = p.Subtract(BigInteger.One).Divide(q);
byte[] array = Hex.Decode("6767656E");
byte[] array2 = new byte[seed.Length + array.Length + 1 + 2];
Array.Copy(seed, 0, array2, 0, seed.Length);
Array.Copy(array, 0, array2, seed.Length, array.Length);
array2[^3] = (byte)index;
byte[] array3 = new byte[d.GetDigestSize()];
for (int i = 1; i < 65536; i++)
{
Inc(array2);
Hash(d, array2, array3);
BigInteger bigInteger = new BigInteger(1, array3);
BigInteger bigInteger2 = bigInteger.ModPow(e, p);
if (bigInteger2.CompareTo(BigInteger.Two) >= 0)
{
return bigInteger2;
}
}
return null;
}
private static bool IsValidDsaStrength(int strength)
{
if (strength >= 512 && strength <= 1024)
{
return strength % 64 == 0;
}
return false;
}
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)
{
if (L <= 1024)
{
return 160;
}
return 256;
}
protected static void Inc(byte[] buf)
{
int num = buf.Length - 1;
while (num >= 0 && ++buf[num] == 0)
{
num--;
}
}
}

View File

@@ -0,0 +1,112 @@
using System;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto.EC;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Security;
namespace 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 eCKeyGenerationParameters = (ECKeyGenerationParameters)parameters;
publicKeyParamSet = eCKeyGenerationParameters.PublicKeyParamSet;
this.parameters = eCKeyGenerationParameters.DomainParameters;
}
else
{
DerObjectIdentifier oid = parameters.Strength switch
{
192 => X9ObjectIdentifiers.Prime192v1,
224 => SecObjectIdentifiers.SecP224r1,
239 => X9ObjectIdentifiers.Prime239v1,
256 => X9ObjectIdentifiers.Prime256v1,
384 => SecObjectIdentifiers.SecP384r1,
521 => SecObjectIdentifiers.SecP521r1,
_ => throw new InvalidParameterException("unknown key size."),
};
X9ECParameters x9ECParameters = FindECCurveByOid(oid);
publicKeyParamSet = oid;
this.parameters = new ECDomainParameters(x9ECParameters.Curve, x9ECParameters.G, x9ECParameters.N, x9ECParameters.H, x9ECParameters.GetSeed());
}
random = parameters.Random;
if (random == null)
{
random = new SecureRandom();
}
}
public AsymmetricCipherKeyPair GenerateKeyPair()
{
BigInteger n = parameters.N;
int num = n.BitLength >> 2;
BigInteger bigInteger;
do
{
bigInteger = new BigInteger(n.BitLength, random);
}
while (bigInteger.CompareTo(BigInteger.Two) < 0 || bigInteger.CompareTo(n) >= 0 || WNafUtilities.GetNafWeight(bigInteger) < num);
ECPoint q = CreateBasePointMultiplier().Multiply(parameters.G, bigInteger);
if (publicKeyParamSet != null)
{
return new AsymmetricCipherKeyPair(new ECPublicKeyParameters(algorithm, q, publicKeyParamSet), new ECPrivateKeyParameters(algorithm, bigInteger, publicKeyParamSet));
}
return new AsymmetricCipherKeyPair(new ECPublicKeyParameters(algorithm, q, parameters), new ECPrivateKeyParameters(algorithm, bigInteger, parameters));
}
protected virtual ECMultiplier CreateBasePointMultiplier()
{
return new FixedPointCombMultiplier();
}
internal static X9ECParameters FindECCurveByOid(DerObjectIdentifier oid)
{
X9ECParameters byOid = CustomNamedCurves.GetByOid(oid);
if (byOid == null)
{
byOid = ECNamedCurveTable.GetByOid(oid);
}
return byOid;
}
internal static ECPublicKeyParameters GetCorrespondingPublicKey(ECPrivateKeyParameters privKey)
{
ECDomainParameters eCDomainParameters = privKey.Parameters;
ECPoint q = new FixedPointCombMultiplier().Multiply(eCDomainParameters.G, privKey.D);
if (privKey.PublicKeyParamSet != null)
{
return new ECPublicKeyParameters(privKey.AlgorithmName, q, privKey.PublicKeyParamSet);
}
return new ECPublicKeyParameters(privKey.AlgorithmName, q, eCDomainParameters);
}
}

View File

@@ -0,0 +1,21 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Generators;
public class Ed25519KeyPairGenerator : IAsymmetricCipherKeyPairGenerator
{
private SecureRandom random;
public virtual void Init(KeyGenerationParameters parameters)
{
random = parameters.Random;
}
public virtual AsymmetricCipherKeyPair GenerateKeyPair()
{
Ed25519PrivateKeyParameters ed25519PrivateKeyParameters = new Ed25519PrivateKeyParameters(random);
Ed25519PublicKeyParameters publicParameter = ed25519PrivateKeyParameters.GeneratePublicKey();
return new AsymmetricCipherKeyPair(publicParameter, ed25519PrivateKeyParameters);
}
}

View File

@@ -0,0 +1,21 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Generators;
public class Ed448KeyPairGenerator : IAsymmetricCipherKeyPairGenerator
{
private SecureRandom random;
public virtual void Init(KeyGenerationParameters parameters)
{
random = parameters.Random;
}
public virtual AsymmetricCipherKeyPair GenerateKeyPair()
{
Ed448PrivateKeyParameters ed448PrivateKeyParameters = new Ed448PrivateKeyParameters(random);
Ed448PublicKeyParameters publicParameter = ed448PrivateKeyParameters.GeneratePublicKey();
return new AsymmetricCipherKeyPair(publicParameter, ed448PrivateKeyParameters);
}
}

View File

@@ -0,0 +1,24 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Crypto.Generators;
public class ElGamalKeyPairGenerator : IAsymmetricCipherKeyPairGenerator
{
private ElGamalKeyGenerationParameters param;
public void Init(KeyGenerationParameters parameters)
{
param = (ElGamalKeyGenerationParameters)parameters;
}
public AsymmetricCipherKeyPair GenerateKeyPair()
{
DHKeyGeneratorHelper instance = DHKeyGeneratorHelper.Instance;
ElGamalParameters parameters = param.Parameters;
DHParameters dhParams = new DHParameters(parameters.P, parameters.G, null, 0, parameters.L);
BigInteger x = instance.CalculatePrivate(dhParams, param.Random);
BigInteger y = instance.CalculatePublic(dhParams, x);
return new AsymmetricCipherKeyPair(new ElGamalPublicKeyParameters(y, parameters), new ElGamalPrivateKeyParameters(x, parameters));
}
}

View File

@@ -0,0 +1,30 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace 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;
}
public ElGamalParameters GenerateParameters()
{
BigInteger[] array = DHParametersHelper.GenerateSafePrimes(size, certainty, random);
BigInteger p = array[0];
BigInteger q = array[1];
BigInteger g = DHParametersHelper.SelectGenerator(p, q, random);
return new ElGamalParameters(p, g);
}
}

View File

@@ -0,0 +1,47 @@
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Generators;
public class Gost3410KeyPairGenerator : IAsymmetricCipherKeyPairGenerator
{
private Gost3410KeyGenerationParameters param;
public void Init(KeyGenerationParameters parameters)
{
if (parameters is Gost3410KeyGenerationParameters)
{
param = (Gost3410KeyGenerationParameters)parameters;
return;
}
Gost3410KeyGenerationParameters gost3410KeyGenerationParameters = new Gost3410KeyGenerationParameters(parameters.Random, CryptoProObjectIdentifiers.GostR3410x94CryptoProA);
_ = parameters.Strength;
_ = gost3410KeyGenerationParameters.Parameters.P.BitLength - 1;
param = gost3410KeyGenerationParameters;
}
public AsymmetricCipherKeyPair GenerateKeyPair()
{
SecureRandom random = param.Random;
Gost3410Parameters parameters = param.Parameters;
BigInteger q = parameters.Q;
int num = 64;
BigInteger bigInteger;
do
{
bigInteger = new BigInteger(256, random);
}
while (bigInteger.SignValue < 1 || bigInteger.CompareTo(q) >= 0 || WNafUtilities.GetNafWeight(bigInteger) < num);
BigInteger p = parameters.P;
BigInteger a = parameters.A;
BigInteger y = a.ModPow(bigInteger, p);
if (param.PublicKeyParamSet != null)
{
return new AsymmetricCipherKeyPair(new Gost3410PublicKeyParameters(y, param.PublicKeyParamSet), new Gost3410PrivateKeyParameters(bigInteger, param.PublicKeyParamSet));
}
return new AsymmetricCipherKeyPair(new Gost3410PublicKeyParameters(y, parameters), new Gost3410PrivateKeyParameters(bigInteger, parameters));
}
}

View File

@@ -0,0 +1,363 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Generators;
public class Gost3410ParametersGenerator
{
private int size;
private int typeproc;
private SecureRandom init_random;
public void Init(int size, int typeProcedure, SecureRandom random)
{
this.size = size;
typeproc = typeProcedure;
init_random = random;
}
private int procedure_A(int x0, int c, BigInteger[] pq, int size)
{
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 value = BigInteger.ValueOf(c);
BigInteger val = BigInteger.ValueOf(19381L);
BigInteger[] array = new BigInteger[1] { BigInteger.ValueOf(x0) };
int[] array2 = new int[1] { size };
int num = 0;
for (int i = 0; array2[i] >= 17; i++)
{
int[] array3 = new int[array2.Length + 1];
Array.Copy(array2, 0, array3, 0, array2.Length);
array2 = new int[array3.Length];
Array.Copy(array3, 0, array2, 0, array3.Length);
array2[i + 1] = array2[i] / 2;
num = i + 1;
}
BigInteger[] array4 = new BigInteger[num + 1];
array4[num] = new BigInteger("8003", 16);
int num2 = num - 1;
for (int j = 0; j < num; j++)
{
int num3 = array2[num2] / 16;
while (true)
{
BigInteger[] array5 = new BigInteger[array.Length];
Array.Copy(array, 0, array5, 0, array.Length);
array = new BigInteger[num3 + 1];
Array.Copy(array5, 0, array, 0, array5.Length);
for (int k = 0; k < num3; k++)
{
array[k + 1] = array[k].Multiply(val).Add(value).Mod(BigInteger.Two.Pow(16));
}
BigInteger bigInteger = BigInteger.Zero;
for (int l = 0; l < num3; l++)
{
bigInteger = bigInteger.Add(array[l].ShiftLeft(16 * l));
}
array[0] = array[num3];
BigInteger bigInteger2 = BigInteger.One.ShiftLeft(array2[num2] - 1).Divide(array4[num2 + 1]).Add(bigInteger.ShiftLeft(array2[num2] - 1).Divide(array4[num2 + 1].ShiftLeft(16 * num3)));
if (bigInteger2.TestBit(0))
{
bigInteger2 = bigInteger2.Add(BigInteger.One);
}
while (true)
{
BigInteger bigInteger3 = bigInteger2.Multiply(array4[num2 + 1]);
if (bigInteger3.BitLength > array2[num2])
{
break;
}
array4[num2] = bigInteger3.Add(BigInteger.One);
if (BigInteger.Two.ModPow(bigInteger3, array4[num2]).CompareTo(BigInteger.One) == 0 && BigInteger.Two.ModPow(bigInteger2, array4[num2]).CompareTo(BigInteger.One) != 0)
{
goto end_IL_0106;
}
bigInteger2 = bigInteger2.Add(BigInteger.Two);
}
continue;
end_IL_0106:
break;
}
if (--num2 < 0)
{
pq[0] = array4[0];
pq[1] = array4[1];
return array[0].IntValue;
}
}
return array[0].IntValue;
}
private long procedure_Aa(long x0, long c, BigInteger[] pq, int size)
{
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 value = BigInteger.ValueOf(c);
BigInteger val = BigInteger.ValueOf(97781173L);
BigInteger[] array = new BigInteger[1] { BigInteger.ValueOf(x0) };
int[] array2 = new int[1] { size };
int num = 0;
for (int i = 0; array2[i] >= 33; i++)
{
int[] array3 = new int[array2.Length + 1];
Array.Copy(array2, 0, array3, 0, array2.Length);
array2 = new int[array3.Length];
Array.Copy(array3, 0, array2, 0, array3.Length);
array2[i + 1] = array2[i] / 2;
num = i + 1;
}
BigInteger[] array4 = new BigInteger[num + 1];
array4[num] = new BigInteger("8000000B", 16);
int num2 = num - 1;
for (int j = 0; j < num; j++)
{
int num3 = array2[num2] / 32;
while (true)
{
BigInteger[] array5 = new BigInteger[array.Length];
Array.Copy(array, 0, array5, 0, array.Length);
array = new BigInteger[num3 + 1];
Array.Copy(array5, 0, array, 0, array5.Length);
for (int k = 0; k < num3; k++)
{
array[k + 1] = array[k].Multiply(val).Add(value).Mod(BigInteger.Two.Pow(32));
}
BigInteger bigInteger = BigInteger.Zero;
for (int l = 0; l < num3; l++)
{
bigInteger = bigInteger.Add(array[l].ShiftLeft(32 * l));
}
array[0] = array[num3];
BigInteger bigInteger2 = BigInteger.One.ShiftLeft(array2[num2] - 1).Divide(array4[num2 + 1]).Add(bigInteger.ShiftLeft(array2[num2] - 1).Divide(array4[num2 + 1].ShiftLeft(32 * num3)));
if (bigInteger2.TestBit(0))
{
bigInteger2 = bigInteger2.Add(BigInteger.One);
}
while (true)
{
BigInteger bigInteger3 = bigInteger2.Multiply(array4[num2 + 1]);
if (bigInteger3.BitLength > array2[num2])
{
break;
}
array4[num2] = bigInteger3.Add(BigInteger.One);
if (BigInteger.Two.ModPow(bigInteger3, array4[num2]).CompareTo(BigInteger.One) == 0 && BigInteger.Two.ModPow(bigInteger2, array4[num2]).CompareTo(BigInteger.One) != 0)
{
goto end_IL_010b;
}
bigInteger2 = bigInteger2.Add(BigInteger.Two);
}
continue;
end_IL_010b:
break;
}
if (--num2 < 0)
{
pq[0] = array4[0];
pq[1] = array4[1];
return array[0].LongValue;
}
}
return array[0].LongValue;
}
private void procedure_B(int x0, int c, BigInteger[] pq)
{
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[] array = new BigInteger[2];
BigInteger bigInteger = null;
BigInteger bigInteger2 = null;
BigInteger bigInteger3 = null;
BigInteger value = BigInteger.ValueOf(c);
BigInteger val = BigInteger.ValueOf(19381L);
x0 = procedure_A(x0, c, array, 256);
bigInteger = array[0];
x0 = procedure_A(x0, c, array, 512);
bigInteger2 = array[0];
BigInteger[] array2 = new BigInteger[65];
array2[0] = BigInteger.ValueOf(x0);
BigInteger bigInteger4 = bigInteger.Multiply(bigInteger2);
while (true)
{
for (int i = 0; i < 64; i++)
{
array2[i + 1] = array2[i].Multiply(val).Add(value).Mod(BigInteger.Two.Pow(16));
}
BigInteger bigInteger5 = BigInteger.Zero;
for (int j = 0; j < 64; j++)
{
bigInteger5 = bigInteger5.Add(array2[j].ShiftLeft(16 * j));
}
array2[0] = array2[64];
BigInteger bigInteger6 = BigInteger.One.ShiftLeft(1023).Divide(bigInteger4).Add(bigInteger5.ShiftLeft(1023).Divide(bigInteger4.ShiftLeft(1024)));
if (bigInteger6.TestBit(0))
{
bigInteger6 = bigInteger6.Add(BigInteger.One);
}
while (true)
{
BigInteger bigInteger7 = bigInteger4.Multiply(bigInteger6);
if (bigInteger7.BitLength > 1024)
{
break;
}
bigInteger3 = bigInteger7.Add(BigInteger.One);
if (BigInteger.Two.ModPow(bigInteger7, bigInteger3).CompareTo(BigInteger.One) == 0 && BigInteger.Two.ModPow(bigInteger.Multiply(bigInteger6), bigInteger3).CompareTo(BigInteger.One) != 0)
{
pq[0] = bigInteger3;
pq[1] = bigInteger;
return;
}
bigInteger6 = bigInteger6.Add(BigInteger.Two);
}
}
}
private void procedure_Bb(long x0, long c, BigInteger[] pq)
{
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[] array = new BigInteger[2];
BigInteger bigInteger = null;
BigInteger bigInteger2 = null;
BigInteger bigInteger3 = null;
BigInteger value = BigInteger.ValueOf(c);
BigInteger val = BigInteger.ValueOf(97781173L);
x0 = procedure_Aa(x0, c, array, 256);
bigInteger = array[0];
x0 = procedure_Aa(x0, c, array, 512);
bigInteger2 = array[0];
BigInteger[] array2 = new BigInteger[33];
array2[0] = BigInteger.ValueOf(x0);
BigInteger bigInteger4 = bigInteger.Multiply(bigInteger2);
while (true)
{
for (int i = 0; i < 32; i++)
{
array2[i + 1] = array2[i].Multiply(val).Add(value).Mod(BigInteger.Two.Pow(32));
}
BigInteger bigInteger5 = BigInteger.Zero;
for (int j = 0; j < 32; j++)
{
bigInteger5 = bigInteger5.Add(array2[j].ShiftLeft(32 * j));
}
array2[0] = array2[32];
BigInteger bigInteger6 = BigInteger.One.ShiftLeft(1023).Divide(bigInteger4).Add(bigInteger5.ShiftLeft(1023).Divide(bigInteger4.ShiftLeft(1024)));
if (bigInteger6.TestBit(0))
{
bigInteger6 = bigInteger6.Add(BigInteger.One);
}
while (true)
{
BigInteger bigInteger7 = bigInteger4.Multiply(bigInteger6);
if (bigInteger7.BitLength > 1024)
{
break;
}
bigInteger3 = bigInteger7.Add(BigInteger.One);
if (BigInteger.Two.ModPow(bigInteger7, bigInteger3).CompareTo(BigInteger.One) == 0 && BigInteger.Two.ModPow(bigInteger.Multiply(bigInteger6), bigInteger3).CompareTo(BigInteger.One) != 0)
{
pq[0] = bigInteger3;
pq[1] = bigInteger;
return;
}
bigInteger6 = bigInteger6.Add(BigInteger.Two);
}
}
}
private BigInteger procedure_C(BigInteger p, BigInteger q)
{
BigInteger bigInteger = p.Subtract(BigInteger.One);
BigInteger e = bigInteger.Divide(q);
BigInteger bigInteger3;
while (true)
{
BigInteger bigInteger2 = new BigInteger(p.BitLength, init_random);
if (bigInteger2.CompareTo(BigInteger.One) > 0 && bigInteger2.CompareTo(bigInteger) < 0)
{
bigInteger3 = bigInteger2.ModPow(e, p);
if (bigInteger3.CompareTo(BigInteger.One) != 0)
{
break;
}
}
}
return bigInteger3;
}
public Gost3410Parameters GenerateParameters()
{
BigInteger[] array = new BigInteger[2];
BigInteger bigInteger = null;
BigInteger bigInteger2 = null;
BigInteger bigInteger3 = null;
if (typeproc == 1)
{
int x = init_random.NextInt();
int c = init_random.NextInt();
switch (size)
{
case 512:
procedure_A(x, c, array, 512);
break;
case 1024:
procedure_B(x, c, array);
break;
default:
throw new ArgumentException("Ooops! key size 512 or 1024 bit.");
}
bigInteger2 = array[0];
bigInteger = array[1];
bigInteger3 = procedure_C(bigInteger2, bigInteger);
return new Gost3410Parameters(bigInteger2, bigInteger, bigInteger3, new Gost3410ValidationParameters(x, c));
}
long num = init_random.NextLong();
long num2 = init_random.NextLong();
switch (size)
{
case 512:
procedure_Aa(num, num2, array, 512);
break;
case 1024:
procedure_Bb(num, num2, array);
break;
default:
throw new InvalidOperationException("Ooops! key size 512 or 1024 bit.");
}
bigInteger2 = array[0];
bigInteger = array[1];
bigInteger3 = procedure_C(bigInteger2, bigInteger);
return new Gost3410Parameters(bigInteger2, bigInteger, bigInteger3, new Gost3410ValidationParameters(num, num2));
}
}

View File

@@ -0,0 +1,108 @@
using System;
using Org.BouncyCastle.Crypto.Macs;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Crypto.Generators;
public class HkdfBytesGenerator : IDerivationFunction
{
private HMac hMacHash;
private int hashLen;
private byte[] info;
private byte[] currentT;
private int generatedBytes;
public virtual IDigest Digest => hMacHash.GetUnderlyingDigest();
public HkdfBytesGenerator(IDigest hash)
{
hMacHash = new HMac(hash);
hashLen = hash.GetDigestSize();
}
public virtual void Init(IDerivationParameters parameters)
{
if (!(parameters is HkdfParameters))
{
throw new ArgumentException("HKDF parameters required for HkdfBytesGenerator", "parameters");
}
HkdfParameters hkdfParameters = (HkdfParameters)parameters;
if (hkdfParameters.SkipExtract)
{
hMacHash.Init(new KeyParameter(hkdfParameters.GetIkm()));
}
else
{
hMacHash.Init(Extract(hkdfParameters.GetSalt(), hkdfParameters.GetIkm()));
}
info = hkdfParameters.GetInfo();
generatedBytes = 0;
currentT = new byte[hashLen];
}
private KeyParameter Extract(byte[] salt, byte[] ikm)
{
if (salt == null)
{
hMacHash.Init(new KeyParameter(new byte[hashLen]));
}
else
{
hMacHash.Init(new KeyParameter(salt));
}
hMacHash.BlockUpdate(ikm, 0, ikm.Length);
byte[] array = new byte[hashLen];
hMacHash.DoFinal(array, 0);
return new KeyParameter(array);
}
private void ExpandNext()
{
int num = generatedBytes / hashLen + 1;
if (num >= 256)
{
throw new DataLengthException("HKDF cannot generate more than 255 blocks of HashLen size");
}
if (generatedBytes != 0)
{
hMacHash.BlockUpdate(currentT, 0, hashLen);
}
hMacHash.BlockUpdate(info, 0, info.Length);
hMacHash.Update((byte)num);
hMacHash.DoFinal(currentT, 0);
}
public virtual int GenerateBytes(byte[] output, int outOff, int len)
{
if (generatedBytes + len > 255 * hashLen)
{
throw new DataLengthException("HKDF may only be used for 255 * HashLen bytes of output");
}
if (generatedBytes % hashLen == 0)
{
ExpandNext();
}
int num = len;
int sourceIndex = generatedBytes % hashLen;
int val = hashLen - generatedBytes % hashLen;
int num2 = System.Math.Min(val, num);
Array.Copy(currentT, sourceIndex, output, outOff, num2);
generatedBytes += num2;
num -= num2;
outOff += num2;
while (num > 0)
{
ExpandNext();
num2 = System.Math.Min(hashLen, num);
Array.Copy(currentT, 0, output, outOff, num2);
generatedBytes += num2;
num -= num2;
outOff += num2;
}
return len;
}
}

View File

@@ -0,0 +1,9 @@
namespace Org.BouncyCastle.Crypto.Generators;
public class Kdf1BytesGenerator : BaseKdfBytesGenerator
{
public Kdf1BytesGenerator(IDigest digest)
: base(0, digest)
{
}
}

View File

@@ -0,0 +1,9 @@
namespace Org.BouncyCastle.Crypto.Generators;
public class Kdf2BytesGenerator : BaseKdfBytesGenerator
{
public Kdf2BytesGenerator(IDigest digest)
: base(1, digest)
{
}
}

View File

@@ -0,0 +1,72 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Crypto.Generators;
public class Mgf1BytesGenerator : IDerivationFunction
{
private IDigest digest;
private byte[] seed;
private int hLen;
public IDigest Digest => digest;
public Mgf1BytesGenerator(IDigest digest)
{
this.digest = digest;
hLen = digest.GetDigestSize();
}
public void Init(IDerivationParameters parameters)
{
if (!typeof(MgfParameters).IsInstanceOfType(parameters))
{
throw new ArgumentException("MGF parameters required for MGF1Generator");
}
MgfParameters mgfParameters = (MgfParameters)parameters;
seed = mgfParameters.GetSeed();
}
private void ItoOSP(int i, byte[] sp)
{
sp[0] = (byte)((uint)i >> 24);
sp[1] = (byte)((uint)i >> 16);
sp[2] = (byte)((uint)i >> 8);
sp[3] = (byte)i;
}
public int GenerateBytes(byte[] output, int outOff, int length)
{
if (output.Length - length < outOff)
{
throw new DataLengthException("output buffer too small");
}
byte[] array = new byte[hLen];
byte[] array2 = new byte[4];
int num = 0;
digest.Reset();
if (length > hLen)
{
do
{
ItoOSP(num, array2);
digest.BlockUpdate(seed, 0, seed.Length);
digest.BlockUpdate(array2, 0, array2.Length);
digest.DoFinal(array, 0);
Array.Copy(array, 0, output, outOff + num * hLen, hLen);
}
while (++num < length / hLen);
}
if (num * hLen < length)
{
ItoOSP(num, array2);
digest.BlockUpdate(seed, 0, seed.Length);
digest.BlockUpdate(array2, 0, array2.Length);
digest.DoFinal(array, 0);
Array.Copy(array, 0, output, outOff + num * hLen, length - num * hLen);
}
return length;
}
}

View File

@@ -0,0 +1,153 @@
using System.Collections;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Generators;
public class NaccacheSternKeyPairGenerator : IAsymmetricCipherKeyPairGenerator
{
private static readonly int[] smallPrimes = new int[101]
{
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;
public void Init(KeyGenerationParameters parameters)
{
param = (NaccacheSternKeyGenerationParameters)parameters;
}
public AsymmetricCipherKeyPair GenerateKeyPair()
{
int strength = param.Strength;
SecureRandom random = param.Random;
int certainty = param.Certainty;
IList arr = findFirstPrimes(param.CountSmallPrimes);
arr = permuteList(arr, random);
BigInteger bigInteger = BigInteger.One;
BigInteger bigInteger2 = BigInteger.One;
for (int i = 0; i < arr.Count / 2; i++)
{
bigInteger = bigInteger.Multiply((BigInteger)arr[i]);
}
for (int j = arr.Count / 2; j < arr.Count; j++)
{
bigInteger2 = bigInteger2.Multiply((BigInteger)arr[j]);
}
BigInteger bigInteger3 = bigInteger.Multiply(bigInteger2);
int num = strength - bigInteger3.BitLength - 48;
BigInteger bigInteger4 = generatePrime(num / 2 + 1, certainty, random);
BigInteger bigInteger5 = generatePrime(num / 2 + 1, certainty, random);
long num2 = 0L;
BigInteger val = bigInteger4.Multiply(bigInteger).ShiftLeft(1);
BigInteger val2 = bigInteger5.Multiply(bigInteger2).ShiftLeft(1);
BigInteger bigInteger6;
BigInteger bigInteger7;
BigInteger bigInteger8;
BigInteger bigInteger9;
while (true)
{
num2++;
bigInteger6 = generatePrime(24, certainty, random);
bigInteger7 = bigInteger6.Multiply(val).Add(BigInteger.One);
if (!bigInteger7.IsProbablePrime(certainty, randomlySelected: true))
{
continue;
}
while (true)
{
bigInteger8 = generatePrime(24, certainty, random);
if (!bigInteger6.Equals(bigInteger8))
{
bigInteger9 = bigInteger8.Multiply(val2).Add(BigInteger.One);
if (bigInteger9.IsProbablePrime(certainty, randomlySelected: true))
{
break;
}
}
}
if (bigInteger3.Gcd(bigInteger6.Multiply(bigInteger8)).Equals(BigInteger.One) && bigInteger7.Multiply(bigInteger9).BitLength >= strength)
{
break;
}
}
BigInteger bigInteger10 = bigInteger7.Multiply(bigInteger9);
BigInteger bigInteger11 = bigInteger7.Subtract(BigInteger.One).Multiply(bigInteger9.Subtract(BigInteger.One));
num2 = 0L;
BigInteger bigInteger12;
bool flag;
do
{
IList list = Platform.CreateArrayList();
for (int k = 0; k != arr.Count; k++)
{
BigInteger val3 = (BigInteger)arr[k];
BigInteger e = bigInteger11.Divide(val3);
do
{
num2++;
bigInteger12 = generatePrime(strength, certainty, random);
}
while (bigInteger12.ModPow(e, bigInteger10).Equals(BigInteger.One));
list.Add(bigInteger12);
}
bigInteger12 = BigInteger.One;
for (int l = 0; l < arr.Count; l++)
{
BigInteger bigInteger13 = (BigInteger)list[l];
BigInteger val4 = (BigInteger)arr[l];
bigInteger12 = bigInteger12.Multiply(bigInteger13.ModPow(bigInteger3.Divide(val4), bigInteger10)).Mod(bigInteger10);
}
flag = false;
for (int m = 0; m < arr.Count; m++)
{
if (bigInteger12.ModPow(bigInteger11.Divide((BigInteger)arr[m]), bigInteger10).Equals(BigInteger.One))
{
flag = true;
break;
}
}
}
while (flag || bigInteger12.ModPow(bigInteger11.ShiftRight(2), bigInteger10).Equals(BigInteger.One) || bigInteger12.ModPow(bigInteger11.Divide(bigInteger6), bigInteger10).Equals(BigInteger.One) || bigInteger12.ModPow(bigInteger11.Divide(bigInteger8), bigInteger10).Equals(BigInteger.One) || bigInteger12.ModPow(bigInteger11.Divide(bigInteger4), bigInteger10).Equals(BigInteger.One) || bigInteger12.ModPow(bigInteger11.Divide(bigInteger5), bigInteger10).Equals(BigInteger.One));
return new AsymmetricCipherKeyPair(new NaccacheSternKeyParameters(privateKey: false, bigInteger12, bigInteger10, bigInteger3.BitLength), new NaccacheSternPrivateKeyParameters(bigInteger12, bigInteger10, bigInteger3.BitLength, arr, bigInteger11));
}
private static BigInteger generatePrime(int bitLength, int certainty, SecureRandom rand)
{
return new BigInteger(bitLength, certainty, rand);
}
private static IList permuteList(IList arr, SecureRandom rand)
{
IList list = Platform.CreateArrayList(arr.Count);
foreach (object item in arr)
{
int index = rand.Next(list.Count + 1);
list.Insert(index, item);
}
return list;
}
private static IList findFirstPrimes(int count)
{
IList list = Platform.CreateArrayList(count);
for (int i = 0; i != count; i++)
{
list.Add(BigInteger.ValueOf(smallPrimes[i]));
}
return list;
}
}

View File

@@ -0,0 +1,280 @@
using System;
using System.IO;
using System.Text;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
namespace Org.BouncyCastle.Crypto.Generators;
public class OpenBsdBCrypt
{
private static readonly byte[] EncodingTable;
private static readonly byte[] DecodingTable;
private static readonly string DefaultVersion;
private static readonly ISet AllowedVersions;
static OpenBsdBCrypt()
{
EncodingTable = new byte[64]
{
46, 47, 65, 66, 67, 68, 69, 70, 71, 72,
73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
83, 84, 85, 86, 87, 88, 89, 90, 97, 98,
99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
119, 120, 121, 122, 48, 49, 50, 51, 52, 53,
54, 55, 56, 57
};
DecodingTable = new byte[128];
DefaultVersion = "2y";
AllowedVersions = new HashSet();
AllowedVersions.Add("2a");
AllowedVersions.Add("2y");
AllowedVersions.Add("2b");
for (int i = 0; i < DecodingTable.Length; i++)
{
DecodingTable[i] = byte.MaxValue;
}
for (int j = 0; j < EncodingTable.Length; j++)
{
DecodingTable[EncodingTable[j]] = (byte)j;
}
}
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 stringBuilder = new StringBuilder(60);
stringBuilder.Append('$');
stringBuilder.Append(version);
stringBuilder.Append('$');
stringBuilder.Append((cost < 10) ? ("0" + cost) : cost.ToString());
stringBuilder.Append('$');
stringBuilder.Append(EncodeData(salt));
byte[] data = BCrypt.Generate(password, salt, cost);
stringBuilder.Append(EncodeData(data));
return stringBuilder.ToString();
}
public static string Generate(char[] password, byte[] salt, int cost)
{
return Generate(DefaultVersion, password, salt, cost);
}
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)
{
throw new ArgumentException("Invalid cost factor.", "cost");
}
byte[] array = Strings.ToUtf8ByteArray(password);
byte[] array2 = new byte[(array.Length >= 72) ? 72 : (array.Length + 1)];
int length = System.Math.Min(array.Length, array2.Length);
Array.Copy(array, 0, array2, 0, length);
Array.Clear(array, 0, array.Length);
string result = CreateBcryptString(version, array2, salt, cost);
Array.Clear(array2, 0, array2.Length);
return result;
}
public static bool CheckPassword(string bcryptString, char[] password)
{
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 text = bcryptString.Substring(1, 2);
if (!AllowedVersions.Contains(text))
{
throw new ArgumentException("Bcrypt version '" + text + "' is not supported by this implementation", "bcryptString");
}
int num = 0;
try
{
num = int.Parse(bcryptString.Substring(4, 2));
}
catch (Exception innerException)
{
throw new ArgumentException("Invalid cost factor: " + bcryptString.Substring(4, 2), "bcryptString", innerException);
}
if (num < 4 || num > 31)
{
throw new ArgumentException("Invalid cost factor: " + num + ", 4 < cost < 31 expected.");
}
if (password == null)
{
throw new ArgumentNullException("Missing password.");
}
int num2 = bcryptString.LastIndexOf('$') + 1;
int num3 = bcryptString.Length - 31;
byte[] salt = DecodeSaltString(bcryptString.Substring(num2, num3 - num2));
string value = Generate(text, password, salt, num);
return bcryptString.Equals(value);
}
private static string EncodeData(byte[] data)
{
if (data.Length != 24 && data.Length != 16)
{
throw new DataLengthException("Invalid length: " + data.Length + ", 24 for key or 16 for salt expected");
}
bool flag = false;
if (data.Length == 16)
{
flag = true;
byte[] array = new byte[18];
Array.Copy(data, 0, array, 0, data.Length);
data = array;
}
else
{
data[^1] = 0;
}
MemoryStream memoryStream = new MemoryStream();
int num = data.Length;
for (int i = 0; i < num; i += 3)
{
uint num2 = data[i];
uint num3 = data[i + 1];
uint num4 = data[i + 2];
memoryStream.WriteByte(EncodingTable[(num2 >> 2) & 0x3F]);
memoryStream.WriteByte(EncodingTable[((num2 << 4) | (num3 >> 4)) & 0x3F]);
memoryStream.WriteByte(EncodingTable[((num3 << 2) | (num4 >> 6)) & 0x3F]);
memoryStream.WriteByte(EncodingTable[num4 & 0x3F]);
}
string text = Strings.FromByteArray(memoryStream.ToArray());
return text[..(flag ? 22 : (text.Length - 1))];
}
private static byte[] DecodeSaltString(string saltString)
{
char[] array = saltString.ToCharArray();
MemoryStream memoryStream = new MemoryStream(16);
if (array.Length != 22)
{
throw new DataLengthException("Invalid base64 salt length: " + array.Length + " , 22 required.");
}
foreach (int num in array)
{
switch (num)
{
case 46:
case 47:
case 48:
case 49:
case 50:
case 51:
case 52:
case 53:
case 54:
case 55:
case 56:
case 57:
case 65:
case 66:
case 67:
case 68:
case 69:
case 70:
case 71:
case 72:
case 73:
case 74:
case 75:
case 76:
case 77:
case 78:
case 79:
case 80:
case 81:
case 82:
case 83:
case 84:
case 85:
case 86:
case 87:
case 88:
case 89:
case 90:
case 91:
case 92:
case 93:
case 94:
case 95:
case 96:
case 97:
case 98:
case 99:
case 100:
case 101:
case 102:
case 103:
case 104:
case 105:
case 106:
case 107:
case 108:
case 109:
case 110:
case 111:
case 112:
case 113:
case 114:
case 115:
case 116:
case 117:
case 118:
case 119:
case 120:
case 121:
case 122:
continue;
}
throw new ArgumentException("Salt string contains invalid character: " + num, "saltString");
}
char[] array2 = new char[24];
Array.Copy(array, 0, array2, 0, array.Length);
array = array2;
int num2 = array.Length;
for (int j = 0; j < num2; j += 4)
{
byte b = DecodingTable[(uint)array[j]];
byte b2 = DecodingTable[(uint)array[j + 1]];
byte b3 = DecodingTable[(uint)array[j + 2]];
byte b4 = DecodingTable[(uint)array[j + 3]];
memoryStream.WriteByte((byte)((b << 2) | (b2 >> 4)));
memoryStream.WriteByte((byte)((b2 << 4) | (b3 >> 2)));
memoryStream.WriteByte((byte)((b3 << 6) | b4));
}
byte[] sourceArray = memoryStream.ToArray();
byte[] array3 = new byte[16];
Array.Copy(sourceArray, 0, array3, 0, array3.Length);
return array3;
}
}

View File

@@ -0,0 +1,83 @@
using System;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Generators;
public class OpenSslPbeParametersGenerator : PbeParametersGenerator
{
private readonly IDigest digest = new MD5Digest();
public override void Init(byte[] password, byte[] salt, int iterationCount)
{
base.Init(password, salt, 1);
}
public virtual void Init(byte[] password, byte[] salt)
{
base.Init(password, salt, 1);
}
private byte[] GenerateDerivedKey(int bytesNeeded)
{
byte[] array = new byte[digest.GetDigestSize()];
byte[] array2 = new byte[bytesNeeded];
int num = 0;
while (true)
{
digest.BlockUpdate(mPassword, 0, mPassword.Length);
digest.BlockUpdate(mSalt, 0, mSalt.Length);
digest.DoFinal(array, 0);
int num2 = ((bytesNeeded > array.Length) ? array.Length : bytesNeeded);
Array.Copy(array, 0, array2, num, num2);
num += num2;
bytesNeeded -= num2;
if (bytesNeeded == 0)
{
break;
}
digest.Reset();
digest.BlockUpdate(array, 0, array.Length);
}
return array2;
}
[Obsolete("Use version with 'algorithm' parameter")]
public override ICipherParameters GenerateDerivedParameters(int keySize)
{
return GenerateDerivedMacParameters(keySize);
}
public override ICipherParameters GenerateDerivedParameters(string algorithm, int keySize)
{
keySize /= 8;
byte[] keyBytes = GenerateDerivedKey(keySize);
return ParameterUtilities.CreateKeyParameter(algorithm, keyBytes, 0, keySize);
}
[Obsolete("Use version with 'algorithm' parameter")]
public override ICipherParameters GenerateDerivedParameters(int keySize, int ivSize)
{
keySize /= 8;
ivSize /= 8;
byte[] array = GenerateDerivedKey(keySize + ivSize);
return new ParametersWithIV(new KeyParameter(array, 0, keySize), array, keySize, ivSize);
}
public override ICipherParameters GenerateDerivedParameters(string algorithm, int keySize, int ivSize)
{
keySize /= 8;
ivSize /= 8;
byte[] array = GenerateDerivedKey(keySize + ivSize);
KeyParameter parameters = ParameterUtilities.CreateKeyParameter(algorithm, array, 0, keySize);
return new ParametersWithIV(parameters, array, keySize, ivSize);
}
public override ICipherParameters GenerateDerivedMacParameters(int keySize)
{
keySize /= 8;
byte[] key = GenerateDerivedKey(keySize);
return new KeyParameter(key, 0, keySize);
}
}

View File

@@ -0,0 +1,150 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Generators;
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;
public Pkcs12ParametersGenerator(IDigest digest)
{
this.digest = digest;
u = digest.GetDigestSize();
v = digest.GetByteLength();
}
private void Adjust(byte[] a, int aOff, byte[] b)
{
int num = (b[^1] & 0xFF) + (a[aOff + b.Length - 1] & 0xFF) + 1;
a[aOff + b.Length - 1] = (byte)num;
num >>>= 8;
for (int num2 = b.Length - 2; num2 >= 0; num2--)
{
num += (b[num2] & 0xFF) + (a[aOff + num2] & 0xFF);
a[aOff + num2] = (byte)num;
num >>>= 8;
}
}
private byte[] GenerateDerivedKey(int idByte, int n)
{
byte[] array = new byte[v];
byte[] array2 = new byte[n];
for (int i = 0; i != array.Length; i++)
{
array[i] = (byte)idByte;
}
byte[] array3;
if (mSalt != null && mSalt.Length != 0)
{
array3 = new byte[v * ((mSalt.Length + v - 1) / v)];
for (int j = 0; j != array3.Length; j++)
{
array3[j] = mSalt[j % mSalt.Length];
}
}
else
{
array3 = new byte[0];
}
byte[] array4;
if (mPassword != null && mPassword.Length != 0)
{
array4 = new byte[v * ((mPassword.Length + v - 1) / v)];
for (int k = 0; k != array4.Length; k++)
{
array4[k] = mPassword[k % mPassword.Length];
}
}
else
{
array4 = new byte[0];
}
byte[] array5 = new byte[array3.Length + array4.Length];
Array.Copy(array3, 0, array5, 0, array3.Length);
Array.Copy(array4, 0, array5, array3.Length, array4.Length);
byte[] array6 = new byte[v];
int num = (n + u - 1) / u;
byte[] array7 = new byte[u];
for (int l = 1; l <= num; l++)
{
digest.BlockUpdate(array, 0, array.Length);
digest.BlockUpdate(array5, 0, array5.Length);
digest.DoFinal(array7, 0);
for (int m = 1; m != mIterationCount; m++)
{
digest.BlockUpdate(array7, 0, array7.Length);
digest.DoFinal(array7, 0);
}
for (int num2 = 0; num2 != array6.Length; num2++)
{
array6[num2] = array7[num2 % array7.Length];
}
for (int num3 = 0; num3 != array5.Length / v; num3++)
{
Adjust(array5, num3 * v, array6);
}
if (l == num)
{
Array.Copy(array7, 0, array2, (l - 1) * u, array2.Length - (l - 1) * u);
}
else
{
Array.Copy(array7, 0, array2, (l - 1) * u, array7.Length);
}
}
return array2;
}
public override ICipherParameters GenerateDerivedParameters(int keySize)
{
keySize /= 8;
byte[] key = GenerateDerivedKey(1, keySize);
return new KeyParameter(key, 0, keySize);
}
public override ICipherParameters GenerateDerivedParameters(string algorithm, int keySize)
{
keySize /= 8;
byte[] keyBytes = GenerateDerivedKey(1, keySize);
return ParameterUtilities.CreateKeyParameter(algorithm, keyBytes, 0, keySize);
}
public override ICipherParameters GenerateDerivedParameters(int keySize, int ivSize)
{
keySize /= 8;
ivSize /= 8;
byte[] key = GenerateDerivedKey(1, keySize);
byte[] iv = GenerateDerivedKey(2, ivSize);
return new ParametersWithIV(new KeyParameter(key, 0, keySize), iv, 0, ivSize);
}
public override ICipherParameters GenerateDerivedParameters(string algorithm, int keySize, int ivSize)
{
keySize /= 8;
ivSize /= 8;
byte[] keyBytes = GenerateDerivedKey(1, keySize);
KeyParameter parameters = ParameterUtilities.CreateKeyParameter(algorithm, keyBytes, 0, keySize);
byte[] iv = GenerateDerivedKey(2, ivSize);
return new ParametersWithIV(parameters, iv, 0, ivSize);
}
public override ICipherParameters GenerateDerivedMacParameters(int keySize)
{
keySize /= 8;
byte[] key = GenerateDerivedKey(3, keySize);
return new KeyParameter(key, 0, keySize);
}
}

View File

@@ -0,0 +1,81 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Generators;
public class Pkcs5S1ParametersGenerator : PbeParametersGenerator
{
private readonly IDigest digest;
public Pkcs5S1ParametersGenerator(IDigest digest)
{
this.digest = digest;
}
private byte[] GenerateDerivedKey()
{
byte[] array = new byte[digest.GetDigestSize()];
digest.BlockUpdate(mPassword, 0, mPassword.Length);
digest.BlockUpdate(mSalt, 0, mSalt.Length);
digest.DoFinal(array, 0);
for (int i = 1; i < mIterationCount; i++)
{
digest.BlockUpdate(array, 0, array.Length);
digest.DoFinal(array, 0);
}
return array;
}
public override ICipherParameters GenerateDerivedParameters(int keySize)
{
return GenerateDerivedMacParameters(keySize);
}
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[] keyBytes = GenerateDerivedKey();
return ParameterUtilities.CreateKeyParameter(algorithm, keyBytes, 0, keySize);
}
public override ICipherParameters GenerateDerivedParameters(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[] array = GenerateDerivedKey();
return new ParametersWithIV(new KeyParameter(array, 0, keySize), array, keySize, ivSize);
}
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[] array = GenerateDerivedKey();
KeyParameter parameters = ParameterUtilities.CreateKeyParameter(algorithm, array, 0, keySize);
return new ParametersWithIV(parameters, array, keySize, ivSize);
}
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[] key = GenerateDerivedKey();
return new KeyParameter(key, 0, keySize);
}
}

View File

@@ -0,0 +1,119 @@
using System;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Macs;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Generators;
public class Pkcs5S2ParametersGenerator : PbeParametersGenerator
{
private readonly IMac hMac;
private readonly byte[] state;
public Pkcs5S2ParametersGenerator()
: this(new Sha1Digest())
{
}
public Pkcs5S2ParametersGenerator(IDigest digest)
{
hMac = new HMac(digest);
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 i = 1; i < c; i++)
{
hMac.BlockUpdate(state, 0, state.Length);
hMac.DoFinal(state, 0);
for (int j = 0; j < state.Length; j++)
{
byte[] array2;
byte[] array = (array2 = outBytes);
int num = outOff + j;
nint num2 = num;
array[num] = (byte)(array2[num2] ^ state[j]);
}
}
}
private byte[] GenerateDerivedKey(int dkLen)
{
int macSize = hMac.GetMacSize();
int num = (dkLen + macSize - 1) / macSize;
byte[] array = new byte[4];
byte[] array2 = new byte[num * macSize];
int num2 = 0;
ICipherParameters parameters = new KeyParameter(mPassword);
hMac.Init(parameters);
for (int i = 1; i <= num; i++)
{
int num3 = 3;
while (true)
{
byte[] array4;
byte[] array3 = (array4 = array);
int num4 = num3;
nint num5 = num4;
if ((array3[num4] = (byte)(array4[num5] + 1)) != 0)
{
break;
}
num3--;
}
F(mSalt, mIterationCount, array, array2, num2);
num2 += macSize;
}
return array2;
}
public override ICipherParameters GenerateDerivedParameters(int keySize)
{
return GenerateDerivedMacParameters(keySize);
}
public override ICipherParameters GenerateDerivedParameters(string algorithm, int keySize)
{
keySize /= 8;
byte[] keyBytes = GenerateDerivedKey(keySize);
return ParameterUtilities.CreateKeyParameter(algorithm, keyBytes, 0, keySize);
}
public override ICipherParameters GenerateDerivedParameters(int keySize, int ivSize)
{
keySize /= 8;
ivSize /= 8;
byte[] array = GenerateDerivedKey(keySize + ivSize);
return new ParametersWithIV(new KeyParameter(array, 0, keySize), array, keySize, ivSize);
}
public override ICipherParameters GenerateDerivedParameters(string algorithm, int keySize, int ivSize)
{
keySize /= 8;
ivSize /= 8;
byte[] array = GenerateDerivedKey(keySize + ivSize);
KeyParameter parameters = ParameterUtilities.CreateKeyParameter(algorithm, array, 0, keySize);
return new ParametersWithIV(parameters, array, keySize, ivSize);
}
public override ICipherParameters GenerateDerivedMacParameters(int keySize)
{
keySize /= 8;
byte[] key = GenerateDerivedKey(keySize);
return new KeyParameter(key, 0, keySize);
}
}

View File

@@ -0,0 +1,62 @@
using System;
namespace Org.BouncyCastle.Crypto.Generators;
public class Poly1305KeyGenerator : CipherKeyGenerator
{
private const byte R_MASK_LOW_2 = 252;
private const byte R_MASK_HIGH_4 = 15;
protected override void engineInit(KeyGenerationParameters param)
{
random = param.Random;
strength = 32;
}
protected override byte[] engineGenerateKey()
{
byte[] array = base.engineGenerateKey();
Clamp(array);
return array;
}
public static void Clamp(byte[] key)
{
if (key.Length != 32)
{
throw new ArgumentException("Poly1305 key must be 256 bits.");
}
byte[] array;
(array = key)[3] = (byte)(array[3] & 0xF);
(array = key)[7] = (byte)(array[7] & 0xF);
(array = key)[11] = (byte)(array[11] & 0xF);
(array = key)[15] = (byte)(array[15] & 0xF);
(array = key)[4] = (byte)(array[4] & 0xFC);
(array = key)[8] = (byte)(array[8] & 0xFC);
(array = key)[12] = (byte)(array[12] & 0xFC);
}
public static void CheckKey(byte[] key)
{
if (key.Length != 32)
{
throw new ArgumentException("Poly1305 key must be 256 bits.");
}
CheckMask(key[3], 15);
CheckMask(key[7], 15);
CheckMask(key[11], 15);
CheckMask(key[15], 15);
CheckMask(key[4], 252);
CheckMask(key[8], 252);
CheckMask(key[12], 252);
}
private static void CheckMask(byte b, byte mask)
{
if ((b & ~mask) != 0)
{
throw new ArgumentException("Invalid format for r portion of Poly1305 key.");
}
}
}

View File

@@ -0,0 +1,51 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Generators;
public class RsaBlindingFactorGenerator
{
private RsaKeyParameters key;
private SecureRandom random;
public void Init(ICipherParameters param)
{
if (param is ParametersWithRandom)
{
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)param;
key = (RsaKeyParameters)parametersWithRandom.Parameters;
random = parametersWithRandom.Random;
}
else
{
key = (RsaKeyParameters)param;
random = new SecureRandom();
}
if (key.IsPrivate)
{
throw new ArgumentException("generator requires RSA public key");
}
}
public BigInteger GenerateBlindingFactor()
{
if (key == null)
{
throw new InvalidOperationException("generator not initialised");
}
BigInteger modulus = key.Modulus;
int sizeInBits = modulus.BitLength - 1;
BigInteger bigInteger;
BigInteger bigInteger2;
do
{
bigInteger = new BigInteger(sizeInBits, random);
bigInteger2 = bigInteger.Gcd(modulus);
}
while (bigInteger.SignValue == 0 || bigInteger.Equals(BigInteger.One) || !bigInteger2.Equals(BigInteger.One));
return bigInteger;
}
}

View File

@@ -0,0 +1,105 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Generators;
public class RsaKeyPairGenerator : IAsymmetricCipherKeyPairGenerator
{
protected const int DefaultTests = 100;
private static readonly int[] SPECIAL_E_VALUES = new int[5] { 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(65537L);
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, 100);
}
}
public virtual AsymmetricCipherKeyPair GenerateKeyPair()
{
int num2;
BigInteger publicExponent;
BigInteger bigInteger;
BigInteger bigInteger2;
BigInteger bigInteger4;
BigInteger bigInteger6;
BigInteger bigInteger7;
BigInteger bigInteger8;
do
{
int strength = parameters.Strength;
int num = (strength + 1) / 2;
num2 = strength - num;
int num3 = strength / 3;
int num4 = strength >> 2;
publicExponent = parameters.PublicExponent;
bigInteger = ChooseRandomPrime(num, publicExponent);
while (true)
{
bigInteger2 = ChooseRandomPrime(num2, publicExponent);
BigInteger bigInteger3 = bigInteger2.Subtract(bigInteger).Abs();
if (bigInteger3.BitLength < num3)
{
continue;
}
bigInteger4 = bigInteger.Multiply(bigInteger2);
if (bigInteger4.BitLength != strength)
{
bigInteger = bigInteger.Max(bigInteger2);
continue;
}
if (WNafUtilities.GetNafWeight(bigInteger4) >= num4)
{
break;
}
bigInteger = ChooseRandomPrime(num, publicExponent);
}
if (bigInteger.CompareTo(bigInteger2) < 0)
{
BigInteger bigInteger5 = bigInteger;
bigInteger = bigInteger2;
bigInteger2 = bigInteger5;
}
bigInteger6 = bigInteger.Subtract(One);
bigInteger7 = bigInteger2.Subtract(One);
BigInteger val = bigInteger6.Gcd(bigInteger7);
BigInteger m = bigInteger6.Divide(val).Multiply(bigInteger7);
bigInteger8 = publicExponent.ModInverse(m);
}
while (bigInteger8.BitLength <= num2);
BigInteger dP = bigInteger8.Remainder(bigInteger6);
BigInteger dQ = bigInteger8.Remainder(bigInteger7);
BigInteger qInv = bigInteger2.ModInverse(bigInteger);
return new AsymmetricCipherKeyPair(new RsaKeyParameters(isPrivate: false, bigInteger4, publicExponent), new RsaPrivateCrtKeyParameters(bigInteger4, publicExponent, bigInteger8, bigInteger, bigInteger2, dP, dQ, qInv));
}
protected virtual BigInteger ChooseRandomPrime(int bitlength, BigInteger e)
{
bool flag = e.BitLength <= SPECIAL_E_BITS && Arrays.Contains(SPECIAL_E_VALUES, e.IntValue);
BigInteger bigInteger;
do
{
bigInteger = new BigInteger(bitlength, 1, parameters.Random);
}
while (bigInteger.Mod(e).Equals(One) || !bigInteger.IsProbablePrime(parameters.Certainty, randomlySelected: true) || (!flag && !e.Gcd(bigInteger.Subtract(One)).Equals(One)));
return bigInteger;
}
}

View File

@@ -0,0 +1,154 @@
using System;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
namespace Org.BouncyCastle.Crypto.Generators;
public class SCrypt
{
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.");
}
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 num = int.MaxValue / (128 * r * 8);
if (p < 1 || p > num)
{
throw new ArgumentException("Parallelisation parameter p must be >= 1 and <= " + num + " (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 num = r * 128;
byte[] array = SingleIterationPBKDF2(P, S, p * num);
uint[] array2 = null;
try
{
int num2 = array.Length >> 2;
array2 = new uint[num2];
Pack.LE_To_UInt32(array, 0, array2);
int num3 = num >> 2;
for (int i = 0; i < num2; i += num3)
{
SMix(array2, i, N, r);
}
Pack.UInt32_To_LE(array2, array, 0);
return SingleIterationPBKDF2(P, array, dkLen);
}
finally
{
ClearAll(array, array2);
}
}
private static byte[] SingleIterationPBKDF2(byte[] P, byte[] S, int dkLen)
{
PbeParametersGenerator pbeParametersGenerator = new Pkcs5S2ParametersGenerator(new Sha256Digest());
pbeParametersGenerator.Init(P, S, 1);
KeyParameter keyParameter = (KeyParameter)pbeParametersGenerator.GenerateDerivedMacParameters(dkLen * 8);
return keyParameter.GetKey();
}
private static void SMix(uint[] B, int BOff, int N, int r)
{
int num = r * 32;
uint[] array = new uint[16];
uint[] array2 = new uint[16];
uint[] array3 = new uint[num];
uint[] array4 = new uint[num];
uint[][] array5 = new uint[N][];
try
{
Array.Copy(B, BOff, array4, 0, num);
for (int i = 0; i < N; i++)
{
array5[i] = (uint[])array4.Clone();
BlockMix(array4, array, array2, array3, r);
}
uint num2 = (uint)(N - 1);
for (int j = 0; j < N; j++)
{
uint num3 = array4[num - 16] & num2;
Xor(array4, array5[num3], 0, array4);
BlockMix(array4, array, array2, array3, r);
}
Array.Copy(array4, 0, B, BOff, num);
}
finally
{
ClearAll(array5);
ClearAll(array4, array, array2, array3);
}
}
private static void BlockMix(uint[] B, uint[] X1, uint[] X2, uint[] Y, int r)
{
Array.Copy(B, B.Length - 16, X1, 0, 16);
int num = 0;
int num2 = 0;
int num3 = B.Length >> 1;
for (int num4 = 2 * r; num4 > 0; num4--)
{
Xor(X1, B, num, X2);
Salsa20Engine.SalsaCore(8, X2, X1);
Array.Copy(X1, 0, Y, num2, 16);
num2 = num3 + num - num2;
num += 16;
}
Array.Copy(Y, 0, B, 0, Y.Length);
}
private static void Xor(uint[] a, uint[] b, int bOff, uint[] output)
{
for (int num = output.Length - 1; num >= 0; num--)
{
output[num] = a[num] ^ b[bOff + num];
}
}
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);
}
}
private static bool IsPowerOf2(int x)
{
return (x & (x - 1)) == 0;
}
}

View File

@@ -0,0 +1,21 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Generators;
public class X25519KeyPairGenerator : IAsymmetricCipherKeyPairGenerator
{
private SecureRandom random;
public virtual void Init(KeyGenerationParameters parameters)
{
random = parameters.Random;
}
public virtual AsymmetricCipherKeyPair GenerateKeyPair()
{
X25519PrivateKeyParameters x25519PrivateKeyParameters = new X25519PrivateKeyParameters(random);
X25519PublicKeyParameters publicParameter = x25519PrivateKeyParameters.GeneratePublicKey();
return new AsymmetricCipherKeyPair(publicParameter, x25519PrivateKeyParameters);
}
}

View File

@@ -0,0 +1,21 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Generators;
public class X448KeyPairGenerator : IAsymmetricCipherKeyPairGenerator
{
private SecureRandom random;
public virtual void Init(KeyGenerationParameters parameters)
{
random = parameters.Random;
}
public virtual AsymmetricCipherKeyPair GenerateKeyPair()
{
X448PrivateKeyParameters x448PrivateKeyParameters = new X448PrivateKeyParameters(random);
X448PublicKeyParameters publicParameter = x448PrivateKeyParameters.GeneratePublicKey();
return new AsymmetricCipherKeyPair(publicParameter, x448PrivateKeyParameters);
}
}