Xor-el / CryptoLib4Pascal

Crypto for Modern Object Pascal
MIT License
213 stars 65 forks source link

About ed25519 signature verification #21

Closed terrylao closed 3 years ago

terrylao commented 3 years ago

Is your feature request related to a problem? Please describe. In SSH, I got remote public key, remote signature with 64 bytes length. But look into your ed25518signer, I provide them, but verification always fail. What I did is

  1. Ted25519.create;
  2. Ted25519signer.create with above;
  3. Ted25519publickeyparameters.create with remote public key;
  4. Verify signature with remote signature;

Describe the solution you'd like Please provide the step of verification.

Xor-el commented 3 years ago

here are test samples for ED25519 please do ensure you are using the correct specification as there are many variations that use different hashes too.

terrylao commented 3 years ago

i had read your test sample, but none of them same as SSH usage. i dump and make a test code below: //---------- s:='0D272BAD5D29C8ECE802C3B9D8A2C43EE341F6130CD93B5FD7E9124FFC2F9348'; remotePubKey:=THex.Decode(s); edinstance:=TEd25519.Create; edsigner:=TEd25519Signer.Create(edinstance); pubkey:=TEd25519PublicKeyParameters.Create(remotePubKey,0); edsigner.Init(false,pubkey); //remote signature s:='6AA8F2B39DF94A767BE445B615DCB7BF8F8BDF09137F8D825858454F79202C7781CB1F40320509ED575F89E6AF5E37DC33F8C0D70AA4C8E0A9AA1CB463C9730C'; remotesig:=THex.Decode(s); if not edsigner.VerifySignature(remotesig) then begin writeln(stdout,'ed25519 Verify fail'); end; //---------- from SSH Spec, Signatures are encoded as follows: mpint r mpint s and get from PUTTY: Verify that sG == r + HpublicKey where H = eddsa_signing_exponent_from_data( extra, r, HASH VALUE CALC FROM PROTOCOL);

that all infor what i got

Xor-el commented 3 years ago

you will need to do more than just dumping some values here. where is the specs defined? what hash is used for the ssh ed25519 implementation in putty? these are the information you need to provide if I am going to be able to help you.

terrylao commented 3 years ago

i check my dump the exchange_hash: A7FB2B3C5B81C02BBABA58EA7B3A0537A0A6C54EF3F61A49E4A12D45B59C0CC5

Xor-el commented 3 years ago

the length of the hash you just provided means it is a 32 byte hash. now there are various hashes that their output are 32 bytes in length. how do we know which putty uses? that is why I am asking if there is any specs document that putty provides that we can use to understand what they do exactly.

terrylao commented 3 years ago

HASH2-256

Xor-el commented 3 years ago

any other details?

terrylao commented 3 years ago

from SSH Spec , i get https://tools.ietf.org/html/rfc8709 AND verification algo from https://tools.ietf.org/html/rfc8032#section-5.1.7

Xor-el commented 3 years ago

can you share the private key and message been signed?

terrylao commented 3 years ago

PUTTY Private Key: length of int 32 E0712AD341699FDCFDC490963F652BC2B758A8E0D3F900400E44A11B64214046 and the code part of PUTTY that verify EdwardsPoint r = eddsa_decode(rstr, ek->curve); mp_int s = mp_from_bytes_le(sstr); mp_int H = eddsa_signing_exponent_from_data(ek, extra, rstr, data); //<--- exchange_hash = data / Verify that sG == r + HpublicKey / EdwardsPoint lhs = ecc_edwards_multiply(ek->curve->e.G, s); EdwardsPoint hpk = ecc_edwards_multiply(ek->publicKey, H); EdwardsPoint rhs = ecc_edwards_add(r, hpk); unsigned valid = ecc_edwards_eq(lhs, rhs);

terrylao commented 3 years ago

from https://tools.ietf.org/html/rfc8032#section-5.1.7 it looks like your ClpEd25519.implverify() but your s need 64 bytes.

terrylao commented 3 years ago

i found there is an miss from me

  1. PUBLIC KEY IS : 3AA337590966B82B63AB241AA5464FF2477A8651B9396744EDFC214284CDA5B4 exchange_hash: A7FB2B3C5B81C02BBABA58EA7B3A0537A0A6C54EF3F61A49E4A12D45B59C0CC5 remotesig: 6AA8F2B39DF94A767BE445B615DCB7BF8F8BDF09137F8D825858454F79202C7781CB1F40320509ED575F89E6AF5E37DC33F8C0D70AA4C8E0A9AA1CB463C9730C;

  2. by calling ClpEd25519.implverify(), no matter phflag=0 or phflag=1 and ctx just generate like your high level test. the result was fail .

  3. ClpEd25519.implverify() call EncodePoint(pR, check, 0); twice

  4. failed because of TArrayUtils.ConstantTimeAreEqual(check, r) return false;

Xor-el commented 3 years ago

still trying to figure out why your input data are not verifying. we must be missing something related to the input.

terrylao commented 3 years ago

i got from http://ed25519.herokuapp.com/ Private Key: n0htabTRTpckjTd8tQqPvN/Pr5J5uZSGGiK12Z1ucqxopyoZ1aRoRknWAud+PZfrl/CTquyYGXld6H5aS09p4g== Public Key: aKcqGdWkaEZJ1gLnfj2X65fwk6rsmBl5Xeh+WktPaeI= Message: (Text to be signed or verified) testing Signature: 2xh3zLhpi+TGSXESwe7ff17QaaGCiwasJFG25GrgfqvTf1BwYIX4qEyIdriLarTXvTcKLIKzxdVzctKbdKudCA== and write test code qb:=TBase64.Decode('aKcqGdWkaEZJ1gLnfj2X65fwk6rsmBl5Xeh+WktPaeI='); hexstring:=TBase64.Decode('2xh3zLhpi+TGSXESwe7ff17QaaGCiwasJFG25GrgfqvTf1BwYIX4qEyIdriLarTXvTcKLIKzxdVzctKbdKudCA=='); h:=TEncoding.ASCII.GetAnsiBytes('testing'); if not edinstance.implverify(hexstring,0,qb,0,LCtx,1,h,0,length(h)) then begin writeln(stdout,'ed25519 Verify fail'); exit(-2); end; but still fail, i just confuse, did i make wrong LCtx? or ?

terrylao commented 3 years ago

i found that's my mis understanding. just use TEd25519Signer and TEd25519PublicKeyParameters get public key from remote site. than verify is correct

Xor-el commented 3 years ago

glad you have resolved your issue and thanks for the feedback. closing this ticket for now.