Codul tău este în regulă dacă îi ceri lui BouncyCastle să genereze perechea de chei:
var gen = new Ed25519KeyPairGenerator();
gen.init(nou Ed25519KeyGenerationParameters(nou SecureRandom()));
var keyPair = gen.generateKeyPair();
var sk = octet nou[32];
((Ed25519PrivateKeyParameters) keyPair.getPrivate()).encode(sk, 0);
var pk = ((Ed25519PublicKeyParameters) keyPair.getPublic()).getEncoded();
Motivul pentru care nu funcționează pentru perechea de chei Tor este că BouncyCastle nu calculează cheia publică prin multiplicarea scalară a punctului de bază cu cheia secretă little-endian.
În schimb, urmează RFC 8032 și să faci SHA-512 pe materialul cheii tale inițiale, ștergând și setând anumiți biți, apoi folosind asta ca cheie secretă pentru a determina cheia publică.
Face asta:
MessageDigest md = MessageDigest.getInstance("SHA-512");
byte [] digest = md.digest(initialKeyMaterial);
var sk = subbarray(digest, 0, 32);
sk[0] &= 248;
sk[31] &= 127;
sk[31] |= 64;
var pk = basePoint.scalarMultiply(sk);
Dacă cheia secretă pe care o specificați a trecut deja prin această transformare SHA-512, atunci codul dvs. nu reușește, deoarece acum face SHA-512 de două ori. Deoarece nu puteți inversa operația SHA-512, atunci dacă trebuie să utilizați BouncyCastle, va trebui să generați cheia secretă în BouncyCastle și apoi să o utilizați cu tor, în loc de invers.
Cu toate acestea, deoarece probabil că trebuie să începeți cu perechea de chei Tor, ați putea lua în considerare modificarea codului BouncyCastle pentru a nu efectua transformarea SHA-512 înainte de a o folosi ca cheie de semnare.