⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lbdsa.pas

📁 tool pour ubuntu 8.10
💻 PAS
📖 第 1 页 / 共 3 页
字号:
  U, SHAseed, SHAseed1 : TLbBigInt;
  Digest : TSHA1Digest;
  Counter : Word;                                                    {!!.06}
begin
  U := TLbBigInt.Create(SizeOf(TLbDSABlock));
  SHAseed := TLbBigInt.Create(SizeOf(TLbDSABlock));
  SHAseed1 := TLbBigInt.Create(SizeOf(TLbDSABlock));

  Counter := 0;
  try
    { Step 2: U = SHA(seed) xor SHA((seed+1) mod 2^g) }
    SHAseed.CopyBuffer(ASeed, SizeOf(ASeed));
    repeat
      FQ.Clear;
      {         SHA(Seed) }
      HashSHA1(Digest, SHAseed.IntBuf^, SHAseed.Size);
      SHAseed.CopyBuffer(Digest, SizeOf(Digest));    { SHASeed is big to little }
      SHAseed.ReverseBytes;                          { SHASeed -> little to big for math }

      {         SHA((seed+1) mod 2^g }
      SHAseed1.CopyBuffer(ASeed, SizeOf(ASeed));     { SHASeed1 is big to little }
      SHASeed1.ReverseBytes;                         { SHASeed1 -> little to big for math }
      SHAseed1.AddByte(1);
      SHAseed1.Modulus(F2Tog);
      SHASeed1.ReverseBytes;                         { SHASeed1 -> big to little for SHA }
      HashSHA1(Digest, SHAseed1.IntBuf^, SHAseed1.Size);
      SHAseed1.CopyBuffer(Digest, SizeOf(Digest));
      SHASeed1.ReverseBytes;                         { SHASeed1 -> little to big for math }

      {         U = SHASeed xor SHASeed1 }
      U.Copy(SHAseed);
      U.XOR_(SHAseed1);

      { Step 3: q = q or 2^159 or 1 }
      FQ.Copy(U);
      FQ.OR_(FMostLeast);

      { Step 4,5: fail if q is composite }
      Result := not FQ.IsComposite(FPrimeTestIterations);

      { if q is not composite then try again with another random seed }
      if not Result then begin
        Inc(Counter);
        SHASeed.RandomBytes(SizeOf(TLbDSABlock));
      end;
    until Result or (Counter >= MaxTries);
  finally
    U.Free;
    SHAseed.Free;
    SHAseed1.Free;
  end;
end;

{ -------------------------------------------------------------------------- }
function TLbDSAParameters.GenerateP(const ASeed : TLbDSABlock) : Boolean;
  { generate parameter p }
const
  MaxTries = 4096;
var
  V, W, TwoToN, ModN, c, X : TLbBigInt;
  tmp : TLbBigInt;
  Lminus1, Counter : DWord;
  Offset : word;
  k, N, B : Byte;
  Digest : TSHA1Digest;
  Abort : Boolean;
  Prime : Boolean;
begin
  Abort := False;
  Prime := False;
  V      := TLbBigInt.Create(SizeOf(TLbDSABlock));
  W      := TLbBigInt.Create(SizeOf(TLbDSABlock));
  TwoToN := TLbBigInt.Create(SizeOf(TLbDSABlock));
  ModN   := TLbBigInt.Create(SizeOf(TLbDSABlock));
  c      := TLbBigInt.Create(SizeOf(TLbDSABlock));
  X      := TLbBigInt.Create(SizeOf(TLbDSABlock));
  tmp    := TLbBigInt.Create(SizeOf(TLbDSABlock));

  { L-1 = sizeof(P) - 1 }
  Lminus1 := (cLbAsymKeyBytes[FKeySize] * 8) - 1;
  N := Lminus1 div 160;
  B := Lminus1 mod 160;
  Counter := 0;
  Offset := 2;

  try
    while not (Prime or Abort) or (Counter > MaxTries) do begin
      { 2^0 }
      W.CopyByte(0);

      for k := 0 to n do begin
        { Step 7: V = SHA((seed+offset+k) mod 2^g) }
        V.CopyBuffer(ASeed, SizeOf(ASeed));  { V = Seed, is big to little }
        V.ReverseBytes;                      { V -> little to big for math }

        tmp.Clear;
        tmp.CopyDWord(k + Offset);
        V.Add( tmp );
        V.Modulus(F2Tog);

        V.ReverseBytes;                      { V -> big to little for SHA }
        HashSHA1(Digest, V.IntBuf^, V.Size);
        V.CopyBuffer(Digest, SizeOf(Digest));
        V.ReverseBytes;                      { V -> little to big for math }


        { Step 8: W = W + V*2^(160 * k) }
        if (k = n) then begin
          { mod last V to b bits }
          ModN.CopyByte( 1 );
          ModN.Shl_( b );
          V.Modulus(ModN);
        end;
        V.Shl_(160 * k);
        W.Add(V);
      end;

      { more Step 8: X = W + 2^(L-1) }
      TwoToN.CopyByte(1);
      TwoToN.Shl_(Lminus1);
      X.Copy(W);
      X.Add(TwoToN);

      { Step 9: c = X mod 2q }
      c.Copy(X);
      ModN.Copy(FQ);
      ModN.Shl_(1);
      c.Modulus(ModN);

      { more Step 9: p = X - (c - 1) }
      FP.Copy(X);
      FP.Subtract(c);
      FP.AddByte(1);

      { Step 10: fail if p < 2^(L-1) }
      if (FP.Compare(TwoToN) <> cLESS_THAN) then
        { Step 11: fail if p is composite }
      Prime := not FP.IsComposite(FPrimeTestIterations);

      { see if caller wants to abort }
      if not Prime then
        if Assigned(FCallBack) then
          FCallBack(Abort);

      { Step 13: bump counter and offset }
      Inc(Counter);
      Inc(Offset, n+1);
    end;
  finally
    V.Free;
    W.Free;
    TwoToN.Free;
    ModN.Free;
    X.Free;
    c.Free;
    tmp.Free;
  end;
  Result := Prime;
end;
{ -------------------------------------------------------------------------- }
function TLbDSAParameters.GenerateG : Boolean;
  { generate parameter g }
var
  h, p1q, tmp, c1 : TLbBigInt;
begin
  Result := False;
  if (FP.Size < 2) then
    Exit;

  h   := TLbBigInt.Create(20);
  p1q := TLbBigInt.Create(20);
  tmp := TLbBigInt.Create(20);
  c1 := TLbBigInt.Create(20);
  try
    c1.CopyByte(1);

    { (p-1)/q }
    p1q.Copy(FP);
    p1q.SubtractByte(1);
    p1q.Divide(FQ);

    h.CopyByte( $01 );
    repeat { until valid h }
      h.AddByte( $01 );
      tmp.Copy(h);
      tmp.PowerAndMod(p1q, FP);
    until (tmp.Compare(c1) = cGREATER_THAN);

    { g = h^((p-1)/q) }
    FG.Copy(h);
    FG.PowerAndMod(p1q, FP);
    Result := True;
  finally
    h.Free;
    p1q.Free;
    tmp.Free;
    c1.Free;
  end;
end;




{ == TLbDSAPrivateKey =================================================== }
constructor TLbDSAPrivateKey.Create(aKeySize : TLbAsymKeySize);
  {initialization }
begin
  inherited Create(aKeySize);
  FX := TLbBigInt.Create(SizeOf(TLbDSABlock));
  FillChar(FXKey, SizeOf(FXKey), #0);
end;
{ -------------------------------------------------------------------------- }
destructor TLbDSAPrivateKey.Destroy;
  { finalization }
begin
  FX.Free;
  inherited Destroy;
end;
{ -------------------------------------------------------------------------- }
procedure TLbDSAPrivateKey.Clear;
  { reset everything }
begin
  inherited Clear;
  FX.Clear;
  FillChar(FXKey, SizeOf(FXKey), #0);
end;
{ -------------------------------------------------------------------------- }
procedure TLbDSAPrivateKey.GenerateX(const AXKey : TLbDSABlock);
  { generate parameter x }
var
  XVal : TSHA1Digest;
begin
  Move(AXKey, FXKey, SizeOf(FXKey));
  FillChar(XVal, SizeOf(XVal), #0);

  { X = SHA(XKey), XKey is big to little }
  HashSHA1(XVal, FXKey, SizeOf(FXKey));
  FX.CopyBuffer(XVal, SizeOf(XVal));
  FX.ReverseBytes;                         { X -> little to big for math }

  { X = XVal mod q, }
  FX.Modulus(FQ);
end;
{ -------------------------------------------------------------------------- }
function TLbDSAPrivateKey.GetXAsString : string;
  { return "big to little" hex string representation of x }
begin
  Result := FX.IntStr;
end;
{ -------------------------------------------------------------------------- }
procedure TLbDSAPrivateKey.SetXAsString(const Value : string);
  { set x to value represented by "big to little" hex string }
var
  Buf : TLbDSABlock;
begin
  FillChar(Buf, SizeOf(Buf), #0);
  HexToBuffer(Value, Buf, SizeOf(Buf));
  FX.CopyBuffer(Buf, SizeOf(Buf));
  FX.Trim;
end;
{ -------------------------------------------------------------------------- }
{!!.06}
function  TLbDSAPrivateKey.CreateASNKey(Input : pByteArray; Length : Integer) : Integer;
const
  TAG30 = $30;
var
  PSize : Integer;
  QSize : Integer;
  GSize : Integer;
  XSize : Integer;
  Total : Integer;
  pInput : PByteArray;
  Max : Integer;
begin
  pInput := Input;
  Max := Length;
  PSize := EncodeASN1(FP, pInput, Max);
  QSize := EncodeASN1(FQ, pInput, Max);
  GSize := EncodeASN1(FG, pInput, Max);
  XSize := EncodeASN1(FX, pInput, Max);
  Total := PSize + QSize + GSize + XSize;
  CreateASN1(Input^, Total, TAG30);
  Result := Total;
end;
{ -------------------------------------------------------------------------- }
{!!.06}
function TLbDSAPrivateKey.ParseASNKey(Input : PByte; Length : Integer ) : Boolean;
var
  Tag : Integer;
  Max : Integer;
  pInput : PByte;
begin
  Max := Length;
  pInput := Input;

  { check for sequence }
  Tag := GetASN1StructNum(pInput, Max);
  GetASN1StructLen(pInput, Max);

  if (Tag <> ASN1_TYPE_SEQUENCE) then
    raise Exception.Create(sDSAKeyBadKey);

  ParseASN1(pInput, Max, FP);
  ParseASN1(pInput, Max, FQ);
  ParseASN1(pInput, Max, FG);
  ParseASN1(pInput, Max, FX);

  Result := (Max = 0);
end;




{ == TLbDSAPublicKey ==================================================== }
constructor TLbDSAPublicKey.Create(aKeySize : TLbAsymKeySize);
  {initialization }
begin
  inherited Create(aKeySize);
  FY := TLbBigInt.Create(cLbAsymKeyBytes[FKeySize]);
end;
{ -------------------------------------------------------------------------- }
destructor TLbDSAPublicKey.Destroy;
  { finalization }
begin
  FY.Free;
  inherited Destroy;
end;
{ -------------------------------------------------------------------------- }
procedure TLbDSAPublicKey.Clear;
  { reset everything }
begin
  inherited Clear;
  FY.Clear;
end;
{ -------------------------------------------------------------------------- }
procedure TLbDSAPublicKey.GenerateY(aX : TLbBigInt);
  { generate parameter y }
begin
  FY.Copy(FG);
  FY.PowerAndMod(aX, FP);
end;
{ -------------------------------------------------------------------------- }
function TLbDSAPublicKey.GetYAsString : string;
  { return "big to little" hex string representation of y }
begin
  Result := FY.IntStr;
end;
{ -------------------------------------------------------------------------- }
procedure TLbDSAPublicKey.SetYAsString(const Value : string);
  { set y to value represented by "big to little" hex string }
var
  Buf : array[Byte] of Byte;
begin
  FillChar(Buf, SizeOf(Buf), #0);
  HexToBuffer(Value, Buf, cLbAsymKeyBytes[FKeySize]);
  FY.CopyBuffer(Buf, cLbAsymKeyBytes[FKeySize]);
  FY.Trim;
end;
{ -------------------------------------------------------------------------- }
{!!.06}
function  TLbDSAPublicKey.CreateASNKey(Input : pByteArray; Length : Integer) : Integer;
const
  TAG30 = $30;
var
  PSize : Integer;
  QSize : Integer;
  GSize : Integer;
  YSize : Integer;
  Total : Integer;
  pInput : PByteArray;
  Max : Integer;
begin
  pInput := Input;
  Max := Length;
  PSize := EncodeASN1(FP, pInput, Max);
  QSize := EncodeASN1(FQ, pInput, Max);
  GSize := EncodeASN1(FG, pInput, Max);
  YSize := EncodeASN1(FY, pInput, Max);
  Total := PSize + QSize + GSize + YSize;
  CreateASN1(Input^, Total, TAG30);
  Result := Total;
end;
{ -------------------------------------------------------------------------- }
{!!.06}
function TLbDSAPublicKey.ParseASNKey(input : pByte; length : Integer) : Boolean;
var
  Tag : Integer;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -