Secp256k1 von C++ bzw. C# nach VB.NET

  • VB.NET

Es gibt 35 Antworten in diesem Thema. Der letzte Beitrag () ist von evolver.

    Secp256k1 von C++ bzw. C# nach VB.NET

    Hallo wertes Forum,
    ich progge gerade mal wieder Krypto-Zeugs und arbeite mich gerade in das Thema Bitcoin ein. Ich habe mir dafür das Buch "Bitcoin & Blockchain - Grundlagen und Programmierung" geholt. Nun möchte ich die elliptische Kurve "Secp256k1" von C# nach VB.NET übersetzen. als Referenz habe ich mich an "NBitcoin" orientiert. Leider scheint der C#-Code nicht ganz kompatibel zu sein, sodass die Online-Konverter die ich benutze den Quellcode nicht immer übersetzen können.

    Z.B. kann VB.NET nichts mit "schreibgeschützten Verweisen" in der Parameterübergabe etwas anfangen, gibt es dafür eine Alternative?

    C#-Quellcode

    1. public GE(in FE x, in FE y, bool infinity)
    2. {
    3. this.x = x;
    4. this.y = y;
    5. this.infinity = infinity;
    6. }


    Hier mal der Ganze Code von der Klasse "GE":
    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Diagnostics;
    4. using System.Runtime.CompilerServices;
    5. using System.Text;
    6. namespace NBitcoin.Secp256k1
    7. {
    8. #if SECP256K1_LIB
    9. public
    10. #endif
    11. readonly struct GE
    12. {
    13. /** Prefix byte used to tag various encoded curvepoints for specific purposes */
    14. public const byte SECP256K1_TAG_PUBKEY_EVEN = 0x02;
    15. public const byte SECP256K1_TAG_PUBKEY_ODD = 0x03;
    16. public const byte SECP256K1_TAG_PUBKEY_UNCOMPRESSED = 0x04;
    17. public const byte SECP256K1_TAG_PUBKEY_HYBRID_EVEN = 0x06;
    18. public const byte SECP256K1_TAG_PUBKEY_HYBRID_ODD = 0x07;
    19. #if SECP256K1_LIB
    20. public
    21. #else
    22. internal
    23. #endif
    24. readonly FE x, y;
    25. #if SECP256K1_LIB
    26. public
    27. #else
    28. internal
    29. #endif
    30. readonly bool infinity; /* whether this represents the point at infinity */
    31. static readonly GE _Infinity = new GE(FE.Zero, FE.Zero, true);
    32. /** Generator for secp256k1, value 'g' defined in
    33. * "Standards for Efficient Cryptography" (SEC2) 2.7.1.
    34. */
    35. public static ref readonly GE Infinity => ref _Infinity;
    36. public static GE CONST(uint a, uint b, uint c, uint d, uint e, uint f, uint g, uint h, uint i, uint j, uint k, uint l, uint m, uint n, uint o, uint p)
    37. {
    38. return new GE(
    39. FE.CONST(a, b, c, d, e, f, g, h),
    40. FE.CONST(i, j, k, l, m, n, o, p),
    41. false
    42. );
    43. }
    44. public readonly bool IsInfinity
    45. {
    46. [MethodImpl(MethodImplOptions.AggressiveInlining)]
    47. get
    48. {
    49. return infinity;
    50. }
    51. }
    52. static readonly GE _Zero = new GE(FE.Zero, FE.Zero, false);
    53. public static ref readonly GE Zero => ref _Zero;
    54. public bool IsValidVariable
    55. {
    56. get
    57. {
    58. FE y2, x3, c;
    59. if (infinity)
    60. {
    61. return false;
    62. }
    63. /* y^2 = x^3 + 7 */
    64. y2 = y.Sqr();
    65. x3 = x.Sqr();
    66. x3 = x3 * x;
    67. c = new FE(EC.CURVE_B);
    68. x3 += c;
    69. x3 = x3.NormalizeWeak();
    70. return y2.EqualsVariable(x3);
    71. }
    72. }
    73. const int SIZE_MAX = int.MaxValue;
    74. public static void SetAllGroupElementJacobianVariable(Span<GE> r, ReadOnlySpan<GEJ> a, int len)
    75. {
    76. FE u;
    77. int i;
    78. int last_i = SIZE_MAX;
    79. for (i = 0; i < len; i++)
    80. {
    81. if (!a[i].infinity)
    82. {
    83. /* Use destination's x coordinates as scratch space */
    84. if (last_i == SIZE_MAX)
    85. {
    86. r[i] = new GE(a[i].z, r[i].y, r[i].infinity);
    87. }
    88. else
    89. {
    90. FE rx = r[last_i].x * a[i].z;
    91. r[i] = new GE(rx, r[i].y, r[i].infinity);
    92. }
    93. last_i = i;
    94. }
    95. }
    96. if (last_i == SIZE_MAX)
    97. {
    98. return;
    99. }
    100. u = r[last_i].x.InverseVariable();
    101. i = last_i;
    102. while (i > 0)
    103. {
    104. i--;
    105. if (!a[i].infinity)
    106. {
    107. FE rx = r[i].x * u;
    108. r[last_i] = new GE(rx, r[last_i].y, r[last_i].infinity);
    109. u = u * a[last_i].z;
    110. last_i = i;
    111. }
    112. }
    113. VERIFY_CHECK(!a[last_i].infinity);
    114. r[last_i] = new GE(u, r[last_i].y, r[last_i].infinity);
    115. for (i = 0; i < len; i++)
    116. {
    117. r[i] = new GE(r[i].x, r[i].y, a[i].infinity);
    118. if (!a[i].infinity)
    119. {
    120. r[i] = a[i].ToGroupElementZInv(r[i].x);
    121. }
    122. }
    123. }
    124. [Conditional("SECP256K1_VERIFY")]
    125. private static void VERIFY_CHECK(bool value)
    126. {
    127. if (!value)
    128. throw new InvalidOperationException("VERIFY_CHECK failed (bug in C# secp256k1)");
    129. }
    130. public static bool TryCreateXQuad(FE x, out GE result)
    131. {
    132. result = GE.Zero;
    133. FE rx, ry;
    134. bool rinfinity;
    135. FE x2, x3, c;
    136. rx = x;
    137. x2 = x.Sqr();
    138. x3 = x * x2;
    139. rinfinity = false;
    140. c = new FE(EC.CURVE_B);
    141. c += x3;
    142. if (!c.Sqrt(out ry))
    143. return false;
    144. result = new GE(rx, ry, rinfinity);
    145. return true;
    146. }
    147. public static bool TryCreateXOVariable(FE x, bool odd, out GE result)
    148. {
    149. if (!TryCreateXQuad(x, out result))
    150. return false;
    151. var ry = result.y.NormalizeVariable();
    152. if (ry.IsOdd != odd)
    153. {
    154. ry = ry.Negate(1);
    155. }
    156. result = new GE(result.x, ry, result.infinity);
    157. return true;
    158. }
    159. static readonly FE beta = FE.CONST(
    160. 0x7ae96a2bu, 0x657c0710u, 0x6e64479eu, 0xac3434e9u,
    161. 0x9cf04975u, 0x12f58995u, 0xc1396c28u, 0x719501eeu
    162. );
    163. [MethodImpl(MethodImplOptions.AggressiveInlining)]
    164. public readonly GE MultiplyLambda()
    165. {
    166. return new GE(x * beta, y, infinity);
    167. }
    168. public GE(in FE x, in FE y, bool infinity)
    169. {
    170. this.x = x;
    171. this.y = y;
    172. this.infinity = infinity;
    173. }
    174. public GE(in FE x, in FE y)
    175. {
    176. this.x = x;
    177. this.y = y;
    178. this.infinity = false;
    179. }
    180. public readonly void Deconstruct(out FE x, out FE y, out bool infinity)
    181. {
    182. x = this.x;
    183. y = this.y;
    184. infinity = this.infinity;
    185. }
    186. [MethodImpl(MethodImplOptions.NoOptimization)]
    187. public readonly GE ZInv(in GE a, in FE zi)
    188. {
    189. var (x, y, infinity) = this;
    190. FE zi2 = zi.Sqr();
    191. FE zi3 = zi2 * zi;
    192. x = a.x * zi2;
    193. y = a.y * zi3;
    194. infinity = a.infinity;
    195. return new GE(x, y, infinity);
    196. }
    197. [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.AggressiveInlining)]
    198. public readonly GE NormalizeY()
    199. {
    200. return new GE(x, this.y.Normalize(), infinity);
    201. }
    202. [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.AggressiveInlining)]
    203. public readonly GE NormalizeXVariable()
    204. {
    205. return new GE(x.NormalizeVariable(), this.y, infinity);
    206. }
    207. [MethodImpl(MethodImplOptions.AggressiveInlining)]
    208. public readonly GE NormalizeYVariable()
    209. {
    210. return new GE(x, this.y.NormalizeVariable(), infinity);
    211. }
    212. [MethodImpl(MethodImplOptions.NoOptimization)]
    213. public readonly GE Negate()
    214. {
    215. var ry = y.NormalizeWeak();
    216. ry = ry.Negate(1);
    217. return new GE(x, ry, infinity);
    218. }
    219. public static bool TryParse(ReadOnlySpan<byte> pub, out GE elem)
    220. {
    221. return TryParse(pub, out _, out elem);
    222. }
    223. public static bool TryParse(ReadOnlySpan<byte> pub, out bool compressed, out GE elem)
    224. {
    225. compressed = false;
    226. elem = default;
    227. if (pub.Length == 33 && (pub[0] == SECP256K1_TAG_PUBKEY_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_ODD))
    228. {
    229. compressed = true;
    230. return
    231. FE.TryCreate(pub.Slice(1), out var x) &&
    232. GE.TryCreateXOVariable(x, pub[0] == SECP256K1_TAG_PUBKEY_ODD, out elem);
    233. }
    234. else if (pub.Length == 65 && (pub[0] == SECP256K1_TAG_PUBKEY_UNCOMPRESSED || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD))
    235. {
    236. if (!FE.TryCreate(pub.Slice(1), out var x) || !FE.TryCreate(pub.Slice(33), out var y))
    237. {
    238. return false;
    239. }
    240. elem = new GE(x, y);
    241. if ((pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD) &&
    242. y.IsOdd != (pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD))
    243. {
    244. return false;
    245. }
    246. return elem.IsValidVariable;
    247. }
    248. else
    249. {
    250. return false;
    251. }
    252. }
    253. [MethodImpl(MethodImplOptions.AggressiveInlining)]
    254. public readonly GEJ ToGroupElementJacobian()
    255. {
    256. return new GEJ(x, y, new FE(1), infinity);
    257. }
    258. /// <summary>
    259. /// Keeps a group element as is if it has an even Y and otherwise negates it.
    260. /// parity is set to 0 in the former case and to 1 in the latter case.
    261. /// Requires that the coordinates of r are normalized.
    262. /// </summary>
    263. public readonly GE ToEvenY(out bool parity)
    264. {
    265. if (IsInfinity)
    266. throw new InvalidOperationException("Should not be infinity point");
    267. if (!y.IsOdd)
    268. {
    269. parity = false;
    270. return this;
    271. }
    272. parity = true;
    273. return new GE(x, y.Negate(1));
    274. }
    275. /// <summary>
    276. /// Keeps a group element as is if it has an even Y and otherwise negates it.
    277. /// Requires that the coordinates of r are normalized.
    278. /// </summary>
    279. public readonly GE ToEvenY()
    280. {
    281. return ToEvenY(out _);
    282. }
    283. public readonly string ToC(string varName)
    284. {
    285. StringBuilder b = new StringBuilder();
    286. b.AppendLine(x.ToC($"{varName}x"));
    287. b.AppendLine(y.ToC($"{varName}y"));
    288. var infinitystr = infinity ? 1 : 0;
    289. b.AppendLine($"int {varName}infinity = {infinitystr};");
    290. b.AppendLine($"secp256k1_ge {varName} = {{ {varName}x, {varName}y, {varName}infinity }};");
    291. return b.ToString();
    292. }
    293. public readonly GEStorage ToStorage()
    294. {
    295. VERIFY_CHECK(!infinity);
    296. return new GEStorage(x, y);
    297. }
    298. public static GEJ operator *(in GE groupElement, in Scalar scalar)
    299. {
    300. return groupElement.MultConst(scalar, 256);
    301. }
    302. /// <summary>
    303. /// Multiply this group element by q in constant time
    304. /// (secp256k1_ecmult_const)
    305. /// </summary>
    306. /// <param name="q">The scalar to multiply to</param>
    307. /// <param name="bits">Here `bits` should be set to the maximum bitlength of the _absolute value_ of `q` plus one because we internally sometimes add 2 to the number during the WNAF conversion.</param>
    308. /// <returns></returns>
    309. public readonly GEJ MultConst(in Scalar q, int bits)
    310. {
    311. Span<GE> pre_a = stackalloc GE[ECMultContext.ArraySize_A];
    312. GE tmpa;
    313. FE Z = default;
    314. int skew_1;
    315. Span<GE> pre_a_lam = stackalloc GE[ECMultContext.ArraySize_A];
    316. Span<int> wnaf_lam = stackalloc int[1 + ECMultContext.WNAFT_SIZE_A];
    317. int skew_lam;
    318. Scalar q_1, q_lam;
    319. Span<int> wnaf_1 = stackalloc int[1 + ECMultContext.WNAFT_SIZE_A];
    320. int i;
    321. Scalar sc = q;
    322. /* build wnaf representation for q. */
    323. int rsize = bits;
    324. if (bits > 128)
    325. {
    326. rsize = 128;
    327. /* split q into q_1 and q_lam (where q = q_1 + q_lam*lambda, and q_1 and q_lam are ~128 bit) */
    328. sc.SplitLambda(out q_1, out q_lam);
    329. skew_1 = Wnaf.Const(wnaf_1, q_1, ECMultContext.WINDOW_A - 1, 128);
    330. skew_lam = Wnaf.Const(wnaf_lam, q_lam, ECMultContext.WINDOW_A - 1, 128);
    331. }
    332. else
    333. {
    334. skew_1 = Wnaf.Const(wnaf_1, sc, ECMultContext.WINDOW_A - 1, bits);
    335. skew_lam = 0;
    336. }
    337. /* Calculate odd multiples of a.
    338. * All multiples are brought to the same Z 'denominator', which is stored
    339. * in Z. Due to secp256k1' isomorphism we can do all operations pretending
    340. * that the Z coordinate was 1, use affine addition formulae, and correct
    341. * the Z coordinate of the result once at the end.
    342. */
    343. GEJ r = this.ToGroupElementJacobian();
    344. ECMultContext.secp256k1_ecmult_odd_multiples_table_globalz_windowa(pre_a, ref Z, r);
    345. for (i = 0; i < ECMultContext.ArraySize_A; i++)
    346. {
    347. pre_a[i] = new GE(pre_a[i].x, pre_a[i].y.NormalizeWeak(), pre_a[i].infinity);
    348. }
    349. if (bits > 128)
    350. {
    351. for (i = 0; i < ECMultContext.ArraySize_A; i++)
    352. {
    353. pre_a_lam[i] = pre_a[i].MultiplyLambda();
    354. }
    355. }
    356. /* first loop iteration (separated out so we can directly set r, rather
    357. * than having it start at infinity, get doubled several times, then have
    358. * its new value added to it) */
    359. i = wnaf_1[Wnaf.SIZE_BITS(rsize, ECMultContext.WINDOW_A - 1)];
    360. VERIFY_CHECK(i != 0);
    361. tmpa = ECMULT_CONST_TABLE_GET_GE(pre_a, i, ECMultContext.WINDOW_A);
    362. r = tmpa.ToGroupElementJacobian();
    363. if (bits > 128)
    364. {
    365. i = wnaf_lam[Wnaf.SIZE_BITS(rsize, ECMultContext.WINDOW_A - 1)];
    366. VERIFY_CHECK(i != 0);
    367. tmpa = ECMULT_CONST_TABLE_GET_GE(pre_a_lam, i, ECMultContext.WINDOW_A);
    368. r = r + tmpa;
    369. }
    370. /* remaining loop iterations */
    371. for (i = Wnaf.SIZE_BITS(rsize, ECMultContext.WINDOW_A - 1) - 1; i >= 0; i--)
    372. {
    373. int n;
    374. int j;
    375. for (j = 0; j < ECMultContext.WINDOW_A - 1; ++j)
    376. {
    377. r = r.Double();
    378. }
    379. n = wnaf_1[i];
    380. tmpa = ECMULT_CONST_TABLE_GET_GE(pre_a, n, ECMultContext.WINDOW_A);
    381. VERIFY_CHECK(n != 0);
    382. r = r + tmpa;
    383. if (bits > 128)
    384. {
    385. n = wnaf_lam[i];
    386. tmpa = tmpa.ECMULT_CONST_TABLE_GET_GE(pre_a_lam, n, ECMultContext.WINDOW_A);
    387. VERIFY_CHECK(n != 0);
    388. r = r + tmpa;
    389. }
    390. }
    391. r = new GEJ(r.x, r.y, r.z * Z, r.infinity);
    392. {
    393. /* Correct for wNAF skew */
    394. GE correction = this;
    395. GEStorage correction_1_stor;
    396. GEStorage correction_lam_stor = default;
    397. GEStorage a2_stor;
    398. GEJ tmpj = correction.ToGroupElementJacobian();
    399. tmpj = tmpj.DoubleVariable();
    400. correction = tmpj.ToGroupElement();
    401. correction_1_stor = this.ToStorage();
    402. if (bits > 128)
    403. {
    404. correction_lam_stor = this.ToStorage();
    405. }
    406. a2_stor = correction.ToStorage();
    407. /* For odd numbers this is 2a (so replace it), for even ones a (so no-op) */
    408. GEStorage.CMov(ref correction_1_stor, a2_stor, skew_1 == 2 ? 1 : 0);
    409. if (bits > 128)
    410. {
    411. GEStorage.CMov(ref correction_lam_stor, a2_stor, skew_lam == 2 ? 1 : 0);
    412. }
    413. /* Apply the correction */
    414. correction = correction_1_stor.ToGroupElement();
    415. correction = correction.Negate();
    416. r = r + correction;
    417. if (bits > 128)
    418. {
    419. correction = correction_lam_stor.ToGroupElement();
    420. correction = correction.Negate();
    421. correction = correction.MultiplyLambda();
    422. r = r + correction;
    423. }
    424. }
    425. return r;
    426. }
    427. public static void Clear(ref GE groupElement)
    428. {
    429. groupElement = new GE();
    430. }
    431. /* This is like `ECMULT_TABLE_GET_GE` but is constant time */
    432. private GE ECMULT_CONST_TABLE_GET_GE(Span<GE> pre, int n, int w)
    433. {
    434. int m;
    435. int abs_n = (n) * (((n) > 0 ? 1 : 0) * 2 - 1);
    436. int idx_n = abs_n / 2;
    437. FE neg_y;
    438. VERIFY_CHECK(((n) & 1) == 1);
    439. VERIFY_CHECK((n) >= -((1 << ((w) - 1)) - 1));
    440. VERIFY_CHECK((n) <= ((1 << ((w) - 1)) - 1));
    441. var rx = FE.Zero;
    442. var ry = FE.Zero;
    443. for (m = 0; m < ECMULT_TABLE_SIZE(w); m++)
    444. {
    445. /* This loop is used to avoid secret data in array indices. See
    446. * the comment in ecmult_gen_impl.h for rationale. */
    447. FE.CMov(ref rx, (pre)[m].x, m == idx_n ? 1 : 0);
    448. FE.CMov(ref ry, (pre)[m].y, m == idx_n ? 1 : 0);
    449. }
    450. var rinfinity = false;
    451. neg_y = ry.Negate(1);
    452. FE.CMov(ref ry, neg_y, (n) != abs_n ? 1 : 0);
    453. return new GE(rx, ry, rinfinity);
    454. }
    455. [MethodImpl(MethodImplOptions.AggressiveInlining)]
    456. private static int ECMULT_TABLE_SIZE(int w)
    457. {
    458. return 1 << ((w) - 2);
    459. }
    460. }
    461. }



    Grüße
    @evolver Compiliere den Code in C#, ziehe die Exe/DLL in den IlSpy rein und lass den dass übersetzen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @evolver IlSpy downloaden und in Dein zielverzeichnis kopieren, der wird nicht installiert.
    marketplace.visualstudio.com/i…me=SharpDevelopTeam.ILSpy
    IlSpy starten.
    Deine Exe/DLL per Drag 'n Drop in das linke Panel ziehen.
    Im linken Panel suchst Du Dir Deine Klasse / Prozedur raus ...
    Ich merke grade, dass der neue IlSpy nur C# anzeigt, nicht aber VB.NET, das konnte die ältere Version.
    Plan B:
    Installiere den CodeConverter als PlugIn des Visual Studios:
    marketplace.visualstudio.com/i…DevelopTeam.CodeConverter
    (Doppelklick auf die CodeConverter.VsExtension.vsix),
    Dein Projekt im Studio starten
    Im Projekt-Explorer Rechtsklick auf das Projekt / die Klasse

    und (fast) feddich.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Danke dir @RodFromGermany,
    wenn du mir jetzt noch sagen könntest, wie ich den CodeConverter.VsExtension.vsix wieder deinstallieren kann, da nun mein Visual Studio 2017 sich nun beim starten immer verabschiedet, wäre ich noch glücklicher.

    1. CodeConverter.VsExtension.vsix herunter geladen
    2. Visual Studio 2017 geschlossen
    3. CodeConverter.VsExtension.vsix erfolgreich installiert
    4. Visual Studio 2017 gestartet
    5. Visual Studio 2017 schließt sich wieder

    ...gleiches passiert auch nach einem Neustart
    ...und auch nach update-Suche

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „evolver“ ()

    evolver schrieb:

    wie ich den CodeConverter.VsExtension.vsix wieder deinstallieren kann
    Nur bei laufendem Studio.
    Ansonsten: Studio deinstallieren, Studio installieren.
    Ich hatte den unter VS 2017 auch problemlos laufen.
    ====
    Hat das 17er Studio einen Installer?
    Wenn ja, dann über den.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @evolver Tut mir Leid, mit solchen Problemen hatte ich noch nix zu tun.
    Welches Betriebssystem hast Du?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Das ist mir völlig unklar.
    Vielleicht steigst Du auf VS 2019 um, VS 2022 ist mir noch zu neu.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Das ist sehr bedauerlich.
    Nun dann versuch ich es zu fuß.

    wer kann mir folgendes C#-Schnippsel genauer erklären?:

    C#-Quellcode

    1. public readonly GE ZInv(in GE a, in FE zi)
    2. {
    3. var (x, y, infinity) = this;
    4. FE zi2 = zi.Sqr();
    5. FE zi3 = zi2 * zi;
    6. x = a.x * zi2;
    7. y = a.y * zi3;
    8. infinity = a.infinity;
    9. return new GE(x, y, infinity);
    10. }


    Ich habs versucht mit nem Online-Converter zu übersetzen, dieser hat es mir allerdings mit diversen Fehlermeldungen quittiert.
    Schon das

    C#-Quellcode

    1. var (x, y, infinity) = this;
    meckert er mir an, obwohl es mir recht simpel erscheint. Da werden 3 Variablen deklariert die jeweils den Inhalt der entsprechenden Klasseneigenschaften bekommen, warum meckert der Converter dort?
    @evolver Gibt es etwas mehr als nur dierses Snippet was bei Dir compiliert?
    Wenn ja, poste so viel, dass es compiliert.
    Dann versuchen wir, es zu übersetzen.
    Wenn da Klassen und Strukturen dran hängen, nimm eine leere Hülse davon.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany aber klar gibt's da noch viel mehr,
    wie ich am Anfang geschrieben habe orientiere ich mich an 'NBitcoin' welches unter dem nachfolgenden Link (Sry an dieser Stelle an @ErfinderDesRades für die externe "Herumklickserei"):
    github.com/MetacoSA/NBitcoin/tree/master/NBitcoin/Secp256k1
    ich habe dort allerdings festgestellt, dass dort scheinbar auch bereits abgekündigte Typen zum Einsatz kommen.
    @evolver Ich habe jetzt keine Lust, da so n Haufen Dateien zu laden.
    Kannst Du ein kleines compilierendes Projekt machen und anhängen?
    Ich probiere dann mal, das komplett zu übersetzen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany achso du wolltest was lauffähiges,
    jedoch ist das eher eine Quick'n'Dirty-Version und beinhaltet keinen 'NBitcoin'-Code. Dafür aber einen riesen Haufen DLL-Dateien + NuGet-Zeugs, davon wollte ich halt gerne wegkommen. Und ob ich das so einfach anhängen darf ist hier auch sehr fraglich (ich bitte den Mods das entsprechend zu entfernen, sollte es nicht erlaubt sein) (gelöscht)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „evolver“ ()

    @evolver Lösch mal die ZIP, die 11 MB sind doch etwas üppig.
    ====
    Das ist doch ein VB-Projekt.
    Ich dachte, es sei C# und Du wolltest VB draus machen?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @evolver Im Projekt finde ich eine Secp256k1.Net.dll und eine secp256k1.dll.
    Die Secp256k1.Net.dll ist ein .NET-Wrapper der secp256k1.dll, erstere in unsafe C# geschrieben, letztere ist nativ.
    Was ganz genau schwebt Dir deenn nun vor?
    Secp256k1.Net.dll nach VB zu übersetzen?
    Das solltest Du einfach bleiben lassen.
    ====
    Die DLLs im Bin-Verzeichnis kannst Du alle löschen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    evolver schrieb:

    mir schwebt vor, gar keine DLL mehr benutzen zu müssen.
    Wie soll das funktionieren?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!