Xor-el / CryptoLib4Pascal

Crypto for Modern Object Pascal
MIT License
209 stars 63 forks source link

Error TECPrivateKeyParameters create 'Scalar is not in the interval[1, n-1]' #38

Closed elcharlie closed 11 months ago

elcharlie commented 11 months ago

hello. I need to calculate the ECDH ('secp256k1) shared secret, but I have problem when I create a Private key Parameters with the hex value of the private key of the server. When I create TECPrivateKeyParameters always get this error message 'Scalar is not in the interval[1, n-1]' this is the code of my test project:

procedure TFrmMain.Button5Click(Sender: TObject);
const
  SERVER_PRIVATE_KEY  = 'D295A6B1CC85A489EF49C28104DF254483734E54CC949315095D04E8891D3299';
var
  FCurve: IX9ECParameters;
  FRandom: ISecureRandom;
  domain: IECDomainParameters;
  generator: IECKeyPairGenerator;
  keygenParams: IECKeyGenerationParameters;

  KeyPair: IAsymmetricCipherKeyPair;
  privParams: IECPrivateKeyParameters;
  pubParams: IECPublicKeyParameters;

  agreement: IBasicAgreement;
  bigInteger: TBigInteger;

  serverprivkey: IECPrivateKeyParameters;
  SharedSecret: TBigInteger;
begin
  try
    FCurve :=  TCustomNamedCurves.GetByName('secp256k1');
    FRandom := TSecureRandom.Create();

    domain := TECDomainParameters.Create(FCurve.Curve, FCurve.G, FCurve.N, FCurve.H, FCurve.GetSeed);
    generator := TECKeyPairGenerator.Create('ECDSA');
    keygenParams := TECKeyGenerationParameters.Create(domain, FRandom);
    generator.Init(keygenParams);

    KeyPair := generator.GenerateKeyPair();
    privParams := KeyPair.Private as IECPrivateKeyParameters;
    pubParams := KeyPair.Public as IECPublicKeyParameters;

    Memo.Lines.Add('Private Key: ' + UpperCase(privParams.D.ToString(16)));
    Memo.Lines.Add('Public Key: ' + BytesToString(pubParams.Q.Normalize.GetEncoded));

    agreement := TECDHBasicAgreement.Create();

    bigInteger := TBigInteger.Create(THex.Decode(SERVER_PRIVATE_KEY));
    Memo.Lines.Add('Server Private Key: ' + BytesToString(bigInteger.ToByteArray));
    //Memo.Lines.Add('Server Private Key: ' + bigInteger.ToString);

    serverprivkey := TECPrivateKeyParameters.Create('ECDSA', bigInteger, domain); //Here gets the error

    agreement.Init(privParams);
    SharedSecret := agreement.CalculateAgreement(serverprivkey);

    Memo.Lines.Add('Shared Secret: ' + THex.Encode(SharedSecret.ToByteArray, true));
  except on E: Exception do
    ShowMessage(e.ToString);
  end;
end;

Can someboby help me?

Thank you.

Xor-el commented 11 months ago

Hello @elcharlie Instead of bigInteger := TBigInteger.Create(THex.Decode(SERVER_PRIVATE_KEY)); do this bigInteger := TBigInteger.Create(1, THex.Decode(SERVER_PRIVATE_KEY));

elcharlie commented 11 months ago

Hello @elcharlie Instead of bigInteger := TBigInteger.Create(THex.Decode(SERVER_PRIVATE_KEY)); do this bigInteger := TBigInteger.Create(1, THex.Decode(SERVER_PRIVATE_KEY));

Thank you very much for your help, that was the problem. But One question, What would it be like to create a TECPublicKeyParameters with a hexadecimal value?

Best regards, and thanks again

elcharlie commented 11 months ago

Sorry, What would it be like to create a TECPublicKeyParameters with a hexadecimal value?

Xor-el commented 11 months ago

Sorry, What would it be like to create a TECPublicKeyParameters with a hexadecimal value?

here is an example

elcharlie commented 11 months ago

thanks again